Foxed some EntersBattlefieldTriggeredAbilities with Intervening-If-Clause not handled correctly.

This commit is contained in:
LevelX2 2016-03-01 17:00:02 +01:00
parent b19b43c4c8
commit 570a6d92dc
9 changed files with 93 additions and 99 deletions

View file

@ -29,10 +29,9 @@ package mage.sets.commander2014;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.CastFromHandCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ExileAllEffect;
import mage.abilities.keyword.FlashAbility;
import mage.abilities.keyword.FlyingAbility;
@ -61,10 +60,11 @@ public class AngelOfTheDireHour extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Angel of the Dire Hour enters the battlefield, if you cast it from your hand, exile all attacking creatures.
Ability ability = new EntersBattlefieldTriggeredAbility(
new ConditionalOneShotEffect(new ExileAllEffect(new FilterAttackingCreature("attacking creatures")), new CastFromHandCondition(),
" if you cast it from your hand, exile all attacking creatures"));
this.addAbility(ability, new CastFromHandWatcher());
this.addAbility(new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new ExileAllEffect(new FilterAttackingCreature("attacking creatures")), false),
new CastFromHandCondition(),
"When {this} enters the battlefield, if you cast it from your hand, exile all attacking creatures."),
new CastFromHandWatcher());
}
public AngelOfTheDireHour(final AngelOfTheDireHour card) {

View file

@ -33,7 +33,7 @@ import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.CastFromHandCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
@ -64,10 +64,11 @@ public class BreachingLeviathan extends CardImpl {
this.toughness = new MageInt(9);
// When Breaching Leviathan enters the battlefield, if you cast it from your hand, tap all nonblue creatures. Those creatures don't untap during their controllers' next untap steps.
Ability ability = new EntersBattlefieldTriggeredAbility(
new ConditionalOneShotEffect(new BreachingLeviathanEffect(), new CastFromHandCondition(),
"if you cast it from your hand, tap all nonblue creatures. Those creatures don't untap during their controllers' next untap steps"));
this.addAbility(ability, new CastFromHandWatcher());
this.addAbility(new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new BreachingLeviathanEffect(), false),
new CastFromHandCondition(),
"When {this} enters the battlefield, if you cast it from your hand, tap all nonblue creatures. Those creatures don't untap during their controllers' next untap steps."),
new CastFromHandWatcher());
}
public BreachingLeviathan(final BreachingLeviathan card) {
@ -104,7 +105,7 @@ class BreachingLeviathanEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
for (Permanent creature: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
creature.tap(game);
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect();
effect.setTargetPointer(new FixedTarget(creature.getId()));

View file

@ -29,10 +29,9 @@ package mage.sets.darksteel;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.condition.common.CastFromHandCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ExileAllEffect;
import mage.abilities.keyword.AffinityForArtifactsAbility;
import mage.abilities.keyword.FlyingAbility;
@ -41,9 +40,6 @@ import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.watchers.Watcher;
import mage.watchers.common.CastFromHandWatcher;
/**
@ -51,7 +47,7 @@ import mage.watchers.common.CastFromHandWatcher;
* @author fireshoes
*/
public class FurnaceDragon extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("artifacts");
static {
@ -67,12 +63,16 @@ public class FurnaceDragon extends CardImpl {
// Affinity for artifacts
this.addAbility(new AffinityForArtifactsAbility());
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Furnace Dragon enters the battlefield, if you cast it from your hand, exile all artifacts.
this.addAbility(new EntersBattlefieldTriggeredAbility(new ConditionalOneShotEffect(new ExileAllEffect(filter), new FurnaceDragonCondition()), false), new CastFromHandWatcher());
this.addAbility(new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new ExileAllEffect(filter), false),
new CastFromHandCondition(),
"When {this} enters the battlefield, if you cast it from your hand, exile all artifacts."),
new CastFromHandWatcher());
}
public FurnaceDragon(final FurnaceDragon card) {
@ -84,24 +84,3 @@ public class FurnaceDragon extends CardImpl {
return new FurnaceDragon(this);
}
}
class FurnaceDragonCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
boolean applies = false;
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
Watcher watcher = game.getState().getWatchers().get("CastFromHand", source.getSourceId());
if (watcher != null && watcher.conditionMet()) {
applies = true;
}
}
return applies;
}
@Override
public String toString() {
return "you cast it from your hand";
}
}

View file

@ -30,10 +30,9 @@ package mage.sets.divinevsdemonic;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.CastFromHandCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DestroyAllEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
@ -50,9 +49,9 @@ import mage.watchers.common.CastFromHandWatcher;
* @author daagar
*/
public class ReiverDemon extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonartifact, nonblack creatures");
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.ARTIFACT)));
filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK)));
@ -67,12 +66,13 @@ public class ReiverDemon extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Reiver Demon enters the battlefield, if you cast it from your hand, destroy all nonartifact, nonblack creatures. They can't be regenerated.
Ability ability = new EntersBattlefieldTriggeredAbility(
new ConditionalOneShotEffect(new DestroyAllEffect(filter), new CastFromHandCondition(),
"if you cast it from your hand, destroy all nonartifact, nonblack creatures. They can't be regenerated"));
this.addAbility(ability, new CastFromHandWatcher());
this.addAbility(new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new DestroyAllEffect(filter, true), false),
new CastFromHandCondition(),
"When {this} enters the battlefield, if you cast it from your hand, destroy all nonartifact, nonblack creatures. They can't be regenerated."),
new CastFromHandWatcher());
}
public ReiverDemon(final ReiverDemon card) {

View file

@ -32,7 +32,8 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.condition.common.CastFromHandCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DestroyAllEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
@ -41,8 +42,6 @@ import mage.constants.Rarity;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.watchers.Watcher;
import mage.watchers.common.CastFromHandWatcher;
/**
@ -50,9 +49,9 @@ import mage.watchers.common.CastFromHandWatcher;
* @author jeffwadsworth
*/
public class DeathbringerRegent extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other creatures");
static {
filter.add(new AnotherPredicate());
}
@ -66,10 +65,13 @@ public class DeathbringerRegent extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Deathbringer Regent enters the battlefield, if you cast it from your hand and there are five or more other creatures on the battlefield, destroy all other creatures.
this.addAbility(new EntersBattlefieldTriggeredAbility(new ConditionalOneShotEffect(new DestroyAllEffect(filter), new DeathbringerRegentCondition()), false), new CastFromHandWatcher());
this.addAbility(new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new DestroyAllEffect(filter), false),
new DeathbringerRegentCondition(),
"When {this} enters the battlefield, if you cast it from your hand and there are five or more other creatures on the battlefield, destroy all other creatures."),
new CastFromHandWatcher());
}
public DeathbringerRegent(final DeathbringerRegent card) {
@ -86,22 +88,7 @@ class DeathbringerRegentCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
boolean applies = false;
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
Watcher watcher = game.getState().getWatchers().get("CastFromHand", source.getSourceId());
if (watcher != null && watcher.conditionMet()) {
applies = true;
}
}
if (applies) {
applies = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), game).size() >= 6;
}
return applies;
return new CastFromHandCondition().apply(game, source)
&& game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), game).size() >= 6;
}
@Override
public String toString() {
return "you cast it from your hand and there are five or more other creatures on the battlefield";
}
}
}

View file

@ -34,7 +34,7 @@ import mage.abilities.Ability;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.CastFromHandCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileSourceEffect;
@ -75,13 +75,14 @@ public class InameAsOne extends CardImpl {
this.toughness = new MageInt(8);
// When Iname as One enters the battlefield, if you cast it from your hand, you may search your library for a Spirit permanent card, put it onto the battlefield, then shuffle your library.
Ability ability = new EntersBattlefieldTriggeredAbility(
new ConditionalOneShotEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, filter), false),
new CastFromHandCondition()));
this.addAbility(ability, new CastFromHandWatcher());
this.addAbility(new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, filter)), true),
new CastFromHandCondition(),
"When {this} enters the battlefield, if you cast it from your hand, you may search your library for a Spirit permanent card, put it onto the battlefield, then shuffle your library."),
new CastFromHandWatcher());
// When Iname as One dies, you may exile it. If you do, return target Spirit permanent card from your graveyard to the battlefield.
ability = new DiesTriggeredAbility(new InameAsOneEffect(), false);
Ability ability = new DiesTriggeredAbility(new InameAsOneEffect(), false);
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
}

View file

@ -30,16 +30,13 @@ package mage.sets.sorinvstibalt;
import java.util.UUID;
import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.CastFromHandCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.effects.common.ExileAllEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.common.FilterAttackingCreature;
import mage.watchers.common.CastFromHandWatcher;
/**
@ -56,10 +53,11 @@ public class CoalStoker extends CardImpl {
this.toughness = new MageInt(3);
// When Coal Stoker enters the battlefield, if you cast it from your hand, add {R}{R}{R} to your mana pool.
Ability ability = new EntersBattlefieldTriggeredAbility(
new ConditionalOneShotEffect(new BasicManaEffect(new Mana(3, 0, 0, 0, 0, 0, 0, 0)), new CastFromHandCondition(),
" if you cast it from your hand, add {R}{R}{R} to your mana pool."));
this.addAbility(ability, new CastFromHandWatcher());
this.addAbility(new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new BasicManaEffect(new Mana(3, 0, 0, 0, 0, 0, 0, 0)), false),
new CastFromHandCondition(),
"When {this} enters the battlefield, if you cast it from your hand, add {R}{R}{R} to your mana pool."),
new CastFromHandWatcher());
}
public CoalStoker(final CoalStoker card) {

View file

@ -6,7 +6,7 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.watchers.Watcher;
import mage.watchers.common.CastFromHandWatcher;
/**
* Warning: CastFromHandWatcher must be installed to card for proper working.
@ -31,9 +31,8 @@ public class CastFromHandCondition implements Condition {
return false;
}
}
// Probably watcher is no longer needed
Watcher watcher = game.getState().getWatchers().get("CastFromHand", source.getSourceId());
if (watcher != null && watcher.conditionMet()) {
CastFromHandWatcher watcher = (CastFromHandWatcher) game.getState().getWatchers().get(CastFromHandWatcher.class.getName(), source.getSourceId());
if (watcher != null && watcher.spellWasCastFromHand(source.getSourceId()) {
return true;
}
}

View file

@ -1,15 +1,23 @@
package mage.watchers.common;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.constants.WatcherScope;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
import mage.game.turn.Step;
import mage.watchers.Watcher;
public class CastFromHandWatcher extends Watcher {
private final Set<UUID> spellsCastFromHand = new HashSet<>();
private Step step;
public CastFromHandWatcher() {
super("CastFromHand", WatcherScope.CARD);
super(CastFromHandWatcher.class.getName(), WatcherScope.GAME);
}
public CastFromHandWatcher(final CastFromHandWatcher watcher) {
@ -18,14 +26,35 @@ public class CastFromHandWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST && event.getZone() == Zone.HAND) {
/**
* This does still not handle if a spell is cast from hand and comes to
* play from other zones during the same step. But at least the state is
* reset if the game comes to a new step
*/
if (step != null && game.getTurn().getStep() != step) {
spellsCastFromHand.clear();
step = null;
}
if (event.getType() == GameEvent.EventType.SPELL_CAST && event.getZone().equals(Zone.HAND)) {
step = game.getTurn().getStep();
Spell spell = (Spell) game.getObject(event.getTargetId());
if (this.getSourceId().equals(spell.getSourceId())) {
condition = true;
condition = true;
}
}
}
public boolean spellWasCastFromHand(UUID sourceId) {
return spellsCastFromHand.contains(sourceId);
}
@Override
public void reset() {
super.reset();
spellsCastFromHand.clear();
}
@Override
public CastFromHandWatcher copy() {
return new CastFromHandWatcher(this);