diff --git a/Mage.Sets/src/mage/cards/a/AmuletOfSafekeeping.java b/Mage.Sets/src/mage/cards/a/AmuletOfSafekeeping.java index 609f18f196a..fc149d9c60e 100644 --- a/Mage.Sets/src/mage/cards/a/AmuletOfSafekeeping.java +++ b/Mage.Sets/src/mage/cards/a/AmuletOfSafekeeping.java @@ -1,7 +1,7 @@ package mage.cards.a; +import mage.abilities.common.BecomesTargetControllerTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.TargetOfOpponentsSpellOrAbilityTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.CounterUnlessPaysEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; @@ -9,6 +9,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.filter.StaticFilters; @@ -24,7 +25,8 @@ public final class AmuletOfSafekeeping extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); // Whenever you become the target of a spell or ability an opponent controls, counter that spell or ability unless its controller pays {1}. - this.addAbility(new TargetOfOpponentsSpellOrAbilityTriggeredAbility(new CounterUnlessPaysEffect(new GenericManaCost(1)), false, true)); + this.addAbility(new BecomesTargetControllerTriggeredAbility(new CounterUnlessPaysEffect(new GenericManaCost(1)), + null, StaticFilters.FILTER_SPELL_OR_ABILITY_OPPONENTS, SetTargetPointer.SPELL, false)); // Creature tokens get -1/-0. this.addAbility(new SimpleStaticAbility( diff --git a/Mage.Sets/src/mage/cards/d/DormantGomazoa.java b/Mage.Sets/src/mage/cards/d/DormantGomazoa.java index a1e3732b1c1..f1a3d32dbcb 100644 --- a/Mage.Sets/src/mage/cards/d/DormantGomazoa.java +++ b/Mage.Sets/src/mage/cards/d/DormantGomazoa.java @@ -1,9 +1,8 @@ - package mage.cards.d; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.BecomesTargetControllerSpellTriggeredAbility; +import mage.abilities.common.BecomesTargetControllerTriggeredAbility; import mage.abilities.common.EntersBattlefieldTappedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect; @@ -12,8 +11,10 @@ import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SetTargetPointer; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; /** * @@ -37,7 +38,8 @@ public final class DormantGomazoa extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect())); // Whenever you become the target of a spell, you may untap Dormant Gomazoa. - this.addAbility(new BecomesTargetControllerSpellTriggeredAbility(new UntapSourceEffect(), true).setTriggerPhrase("Whenever you become the target of a spell, ")); + this.addAbility(new BecomesTargetControllerTriggeredAbility(new UntapSourceEffect(), + null, StaticFilters.FILTER_SPELL_A, SetTargetPointer.NONE, true)); } private DormantGomazoa(final DormantGomazoa card) { diff --git a/Mage.Sets/src/mage/cards/l/LeovoldEmissaryOfTrest.java b/Mage.Sets/src/mage/cards/l/LeovoldEmissaryOfTrest.java index a872ffee356..41a08bdb4d5 100644 --- a/Mage.Sets/src/mage/cards/l/LeovoldEmissaryOfTrest.java +++ b/Mage.Sets/src/mage/cards/l/LeovoldEmissaryOfTrest.java @@ -1,15 +1,15 @@ - package mage.cards.l; import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.BecomesTargetControllerTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.TargetOfOpponentsSpellOrAbilityTriggeredAbility; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; @@ -35,7 +35,8 @@ public final class LeovoldEmissaryOfTrest extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LeovoldEmissaryOfTrestEffect()), new CardsAmountDrawnThisTurnWatcher()); // Whenever you or a permanent you control becomes the target of a spell or ability an opponent controls, you may draw a card. - this.addAbility(new TargetOfOpponentsSpellOrAbilityTriggeredAbility(new DrawCardSourceControllerEffect(1), true, false)); + this.addAbility(new BecomesTargetControllerTriggeredAbility(new DrawCardSourceControllerEffect(1), + StaticFilters.FILTER_CONTROLLED_A_PERMANENT, StaticFilters.FILTER_SPELL_OR_ABILITY_OPPONENTS, SetTargetPointer.NONE, true)); } private LeovoldEmissaryOfTrest(final LeovoldEmissaryOfTrest card) { @@ -81,4 +82,4 @@ class LeovoldEmissaryOfTrestEffect extends ContinuousRuleModifyingEffectImpl { return watcher != null && controller != null && watcher.getAmountCardsDrawn(event.getPlayerId()) >= 1 && game.isOpponent(controller, event.getPlayerId()); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/p/ParnesseTheSubtleBrush.java b/Mage.Sets/src/mage/cards/p/ParnesseTheSubtleBrush.java index 6e8267d3d5e..528fc9882b0 100644 --- a/Mage.Sets/src/mage/cards/p/ParnesseTheSubtleBrush.java +++ b/Mage.Sets/src/mage/cards/p/ParnesseTheSubtleBrush.java @@ -3,13 +3,14 @@ package mage.cards.p; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.TargetOfOpponentsSpellOrAbilityTriggeredAbility; +import mage.abilities.common.BecomesTargetControllerTriggeredAbility; import mage.abilities.costs.common.PayLifeCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CounterUnlessPaysEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.stack.Spell; @@ -35,7 +36,8 @@ public class ParnesseTheSubtleBrush extends CardImpl { // Whenever you or a permanent you control becomes the target of a spell or ability an opponent controls, // counter that spell or ability unless that player pays 4 life. - this.addAbility(new TargetOfOpponentsSpellOrAbilityTriggeredAbility(new CounterUnlessPaysEffect(new PayLifeCost(4).setText("4 life")))); + this.addAbility(new BecomesTargetControllerTriggeredAbility(new CounterUnlessPaysEffect(new PayLifeCost(4).setText("4 life")), + StaticFilters.FILTER_CONTROLLED_A_PERMANENT, StaticFilters.FILTER_SPELL_OR_ABILITY_OPPONENTS, SetTargetPointer.SPELL, false)); // Whenever you copy a spell, up to one target opponent may also copy that spell. // They may choose new targets for that copy. diff --git a/Mage.Sets/src/mage/cards/r/RayneAcademyChancellor.java b/Mage.Sets/src/mage/cards/r/RayneAcademyChancellor.java index a2a49b2c2e4..03ef29027f5 100644 --- a/Mage.Sets/src/mage/cards/r/RayneAcademyChancellor.java +++ b/Mage.Sets/src/mage/cards/r/RayneAcademyChancellor.java @@ -2,7 +2,7 @@ package mage.cards.r; import mage.MageInt; -import mage.abilities.common.TargetOfOpponentsSpellOrAbilityTriggeredAbility; +import mage.abilities.common.BecomesTargetControllerTriggeredAbility; import mage.abilities.condition.common.EnchantedSourceCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.Effect; @@ -10,8 +10,10 @@ import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SetTargetPointer; import mage.constants.SubType; import mage.constants.SuperType; +import mage.filter.StaticFilters; import java.util.UUID; @@ -38,7 +40,8 @@ public final class RayneAcademyChancellor extends CardImpl { new EnchantedSourceCondition(), "you may draw a card. You may draw an additional card if {this} is enchanted" ); - this.addAbility(new TargetOfOpponentsSpellOrAbilityTriggeredAbility(drawEffect, true, false)); + this.addAbility(new BecomesTargetControllerTriggeredAbility(drawEffect, + StaticFilters.FILTER_CONTROLLED_A_PERMANENT, StaticFilters.FILTER_SPELL_OR_ABILITY_OPPONENTS, SetTargetPointer.NONE, true)); } private RayneAcademyChancellor(final RayneAcademyChancellor card) { diff --git a/Mage.Sets/src/mage/cards/u/UnsettledMariner.java b/Mage.Sets/src/mage/cards/u/UnsettledMariner.java index 36097f1a93d..7f945c7da06 100644 --- a/Mage.Sets/src/mage/cards/u/UnsettledMariner.java +++ b/Mage.Sets/src/mage/cards/u/UnsettledMariner.java @@ -1,21 +1,16 @@ package mage.cards.u; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.TargetOfOpponentsSpellOrAbilityTriggeredAbility; +import mage.abilities.common.BecomesTargetControllerTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.CounterUnlessPaysEffect; import mage.abilities.keyword.ChangelingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SetTargetPointer; import mage.constants.SubType; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; +import mage.filter.StaticFilters; import java.util.UUID; @@ -36,7 +31,8 @@ public final class UnsettledMariner extends CardImpl { // Whenever you or a permanent you control becomes the target of a spell or ability an opponent controls, // counter that spell or ability unless its controller pays {1}. - this.addAbility(new TargetOfOpponentsSpellOrAbilityTriggeredAbility(new CounterUnlessPaysEffect(new GenericManaCost(1)))); + this.addAbility(new BecomesTargetControllerTriggeredAbility(new CounterUnlessPaysEffect(new GenericManaCost(1)), + StaticFilters.FILTER_CONTROLLED_A_PERMANENT, StaticFilters.FILTER_SPELL_OR_ABILITY_OPPONENTS, SetTargetPointer.SPELL, false)); } private UnsettledMariner(final UnsettledMariner card) { diff --git a/Mage/src/main/java/mage/abilities/common/BecomesTargetControllerSpellTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BecomesTargetControllerSpellTriggeredAbility.java deleted file mode 100644 index c7322c34017..00000000000 --- a/Mage/src/main/java/mage/abilities/common/BecomesTargetControllerSpellTriggeredAbility.java +++ /dev/null @@ -1,45 +0,0 @@ - - -package mage.abilities.common; - -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.Effect; -import mage.game.events.GameEvent; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.stack.Spell; - -/** - * @author jeffwadsworth - */ -public class BecomesTargetControllerSpellTriggeredAbility extends TriggeredAbilityImpl { - - public BecomesTargetControllerSpellTriggeredAbility(Effect effect, boolean optional) { - super(Zone.BATTLEFIELD, effect, optional); - setTriggerPhrase("When you become the target of a spell, "); - } - - protected BecomesTargetControllerSpellTriggeredAbility(final BecomesTargetControllerSpellTriggeredAbility ability) { - super(ability); - } - - @Override - public BecomesTargetControllerSpellTriggeredAbility copy() { - return new BecomesTargetControllerSpellTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.TARGETED; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getTargetId().equals(controllerId)) { - if (game.getObject(event.getSourceId()) instanceof Spell) { - return true; - } - } - return false; - } -} diff --git a/Mage/src/main/java/mage/abilities/common/BecomesTargetControllerTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BecomesTargetControllerTriggeredAbility.java new file mode 100644 index 00000000000..b3eb9434c0a --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/BecomesTargetControllerTriggeredAbility.java @@ -0,0 +1,84 @@ +package mage.abilities.common; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.SetTargetPointer; +import mage.filter.FilterPermanent; +import mage.filter.FilterStackObject; +import mage.game.events.GameEvent; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.StackObject; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +/** + * @author xenohedron + */ +public class BecomesTargetControllerTriggeredAbility extends TriggeredAbilityImpl { + + private final FilterPermanent filterTarget; + private final FilterStackObject filterStack; + private final SetTargetPointer setTargetPointer; + + /** + * Note: filterTarget can be null for "whenever you become the target of..."; + * if set, then "whenever you or a [filterTarget] becomes the target of..." + */ + public BecomesTargetControllerTriggeredAbility(Effect effect, FilterPermanent filterTarget, FilterStackObject filterStack, + SetTargetPointer setTargetPointer, boolean optional) { + super(Zone.BATTLEFIELD, effect, optional); + this.filterTarget = filterTarget; + this.filterStack = filterStack; + this.setTargetPointer = setTargetPointer; + String filterMessage = (filterTarget == null) + ? "you become" + : "you or " + filterTarget.getMessage() + " becomes"; + setTriggerPhrase("Whenever " + filterMessage + " the target of " + filterStack.getMessage() + ", "); + } + + protected BecomesTargetControllerTriggeredAbility(final BecomesTargetControllerTriggeredAbility ability) { + super(ability); + this.filterTarget = ability.filterTarget; + this.filterStack = ability.filterStack; + this.setTargetPointer = ability.setTargetPointer; + } + + @Override + public BecomesTargetControllerTriggeredAbility copy() { + return new BecomesTargetControllerTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.TARGETED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!event.getTargetId().equals(getControllerId())) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); + if (permanent == null || filterTarget == null || !filterTarget.match(permanent, getControllerId(), this, game)) { + return false; + } + } + StackObject targetingObject = CardUtil.getTargetingStackObject(event, game); + if (targetingObject == null || !filterStack.match(targetingObject, getControllerId(), this, game)) { + return false; + } + if (!CardUtil.checkTargetMap(this.id, targetingObject, event, game)) { + return false; + } + switch (setTargetPointer) { + case SPELL: + this.getAllEffects().setTargetPointer(new FixedTarget(targetingObject.getId())); + break; + case NONE: + break; + default: + throw new IllegalArgumentException("Unsupported SetTargetPointer in BecomesTargetControllerTriggeredAbility"); + } + return true; + } +} diff --git a/Mage/src/main/java/mage/abilities/common/TargetOfOpponentsSpellOrAbilityTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/TargetOfOpponentsSpellOrAbilityTriggeredAbility.java deleted file mode 100644 index 29bf7131c98..00000000000 --- a/Mage/src/main/java/mage/abilities/common/TargetOfOpponentsSpellOrAbilityTriggeredAbility.java +++ /dev/null @@ -1,82 +0,0 @@ -package mage.abilities.common; - -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.Effect; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.targetpointer.FixedTarget; - -/** - * "Whenever you or a permanent you control becomes the target of a spell or ability an opponent controls," - * AND - * "Whenever you become the target of a spell or ability an opponent controls," - * - * @author Alex-Vasile - */ -public class TargetOfOpponentsSpellOrAbilityTriggeredAbility extends TriggeredAbilityImpl { - - private boolean onlyController = false; - - public TargetOfOpponentsSpellOrAbilityTriggeredAbility(Effect effect) { - this(effect, false, false); - } - - public TargetOfOpponentsSpellOrAbilityTriggeredAbility(Effect effect, boolean optional, boolean onlyController) { - super(Zone.BATTLEFIELD, effect, optional); - this.onlyController = onlyController; - if (this.onlyController) { - setTriggerPhrase("Whenever you become the target of a spell or ability an opponent controls, "); - } else { - setTriggerPhrase("Whenever you or a permanent you control becomes the target of a spell or ability an opponent controls, "); - } - } - - private TargetOfOpponentsSpellOrAbilityTriggeredAbility(final TargetOfOpponentsSpellOrAbilityTriggeredAbility ability) { - super(ability); - this.onlyController = ability.onlyController; - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.TARGETED; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Player controller = game.getPlayer(this.getControllerId()); - Player targetter = game.getPlayer(event.getPlayerId()); - if (controller == null || targetter == null || controller.getId().equals(targetter.getId())) { - return false; - } - - // Check if player was targeted - if (controller.getId().equals(event.getTargetId())) { - // Add target for effects which need it (e.g. the counter effect from AmuletOfSafekeeping) - this.getEffects().setTargetPointer(new FixedTarget(event.getSourceId())); - return true; - } - - // If only the controller is - if (this.onlyController) { - return false; - } - - // Check if permanent was targeted - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); - if (permanent == null || !controller.getId().equals(permanent.getControllerId())) { - return false; - } - - // Add target for effects which need it (e.g. the counter effect from AmuletOfSafekeeping) - this.getEffects().setTargetPointer(new FixedTarget(event.getSourceId())); - return true; - } - - @Override - public TargetOfOpponentsSpellOrAbilityTriggeredAbility copy() { - return new TargetOfOpponentsSpellOrAbilityTriggeredAbility(this); - } -}