diff --git a/Mage.Sets/src/mage/cards/a/AbandonHope.java b/Mage.Sets/src/mage/cards/a/AbandonHope.java index a89f540751..a1adea968a 100644 --- a/Mage.Sets/src/mage/cards/a/AbandonHope.java +++ b/Mage.Sets/src/mage/cards/a/AbandonHope.java @@ -1,26 +1,26 @@ package mage.cards.a; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.common.DiscardTargetCost; import mage.abilities.dynamicvalue.common.ManacostVariableValue; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.target.TargetPlayer; import mage.target.common.TargetCardInHand; +import java.util.UUID; + /** - * * @author fireshoes */ public final class AbandonHope extends CardImpl { @@ -29,7 +29,7 @@ public final class AbandonHope extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{1}{B}"); // As an additional cost to cast Abandon Hope, discard X cards. - Ability ability = new SimpleStaticAbility(Zone.ALL, new AbandonHopeRuleEffect()); + Ability ability = new SimpleStaticAbility(Zone.ALL, new InfoEffect("As an additional cost to cast this spell, discard X cards")); ability.setRuleAtTheTop(true); this.addAbility(ability); @@ -37,44 +37,27 @@ public final class AbandonHope extends CardImpl { ManacostVariableValue manaX = new ManacostVariableValue(); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(manaX, TargetController.ANY)); this.getSpellAbility().addTarget(new TargetPlayer()); + this.getSpellAbility().setCostAdjuster(AbandonHopeAdjuster.instance); } public AbandonHope(final AbandonHope card) { super(card); } - @Override - public void adjustCosts(Ability ability, Game game) { - int xValue = ability.getManaCostsToPay().getX(); - if (xValue > 0) { - ability.addCost(new DiscardTargetCost(new TargetCardInHand(xValue, xValue, new FilterCard("cards")))); - } - } - @Override public AbandonHope copy() { return new AbandonHope(this); } } -class AbandonHopeRuleEffect extends OneShotEffect { - - public AbandonHopeRuleEffect() { - super(Outcome.Benefit); - this.staticText = "As an additional cost to cast this spell, discard X cards"; - } - - public AbandonHopeRuleEffect(final AbandonHopeRuleEffect effect) { - super(effect); - } +enum AbandonHopeAdjuster implements CostAdjuster { + instance; @Override - public AbandonHopeRuleEffect copy() { - return new AbandonHopeRuleEffect(this); + public void adjustCosts(Ability ability, Game game) { + int xValue = ability.getManaCostsToPay().getX(); + if (xValue > 0) { + ability.addCost(new DiscardTargetCost(new TargetCardInHand(xValue, xValue, StaticFilters.FILTER_CARD_CARDS))); + } } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/a/AetherBurst.java b/Mage.Sets/src/mage/cards/a/AetherBurst.java index 54355a980a..fdda9a8727 100644 --- a/Mage.Sets/src/mage/cards/a/AetherBurst.java +++ b/Mage.Sets/src/mage/cards/a/AetherBurst.java @@ -13,29 +13,42 @@ import mage.game.Game; import mage.players.Player; import mage.target.Target; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; import java.util.UUID; import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES; /** - * * @author magenoxx_at_gmail.com */ public final class AetherBurst extends CardImpl { - - private static final FilterCard filter = new FilterCard("cards named Aether Burst"); - - static { - filter.add(new NamePredicate("Aether Burst")); - } - public AetherBurst(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Return up to X target creatures to their owners' hands, where X is one plus the number of cards named Aether Burst in all graveyards as you cast Aether Burst. this.getSpellAbility().addEffect(new DynamicReturnToHandTargetEffect()); this.getSpellAbility().addTarget(new DynamicTargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(AetherBurstAdjuster.instance); + } + + + public AetherBurst(final AetherBurst card) { + super(card); + } + + @Override + public AetherBurst copy() { + return new AetherBurst(this); + } +} + +enum AetherBurstAdjuster implements TargetAdjuster { + instance; + private static final FilterCard filter = new FilterCard("cards named Aether Burst"); + + static { + filter.add(new NamePredicate("Aether Burst")); } @Override @@ -55,15 +68,6 @@ public final class AetherBurst extends CardImpl { target.setMaxNumberOfTargets(amount + 1); } } - - public AetherBurst(final AetherBurst card) { - super(card); - } - - @Override - public AetherBurst copy() { - return new AetherBurst(this); - } } class DynamicTargetCreaturePermanent extends TargetPermanent { diff --git a/Mage.Sets/src/mage/cards/a/AetherstormRoc.java b/Mage.Sets/src/mage/cards/a/AetherstormRoc.java index 3424b95a3a..aff1bf10b0 100644 --- a/Mage.Sets/src/mage/cards/a/AetherstormRoc.java +++ b/Mage.Sets/src/mage/cards/a/AetherstormRoc.java @@ -1,7 +1,6 @@ package mage.cards.a; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; @@ -21,17 +20,17 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class AetherstormRoc extends CardImpl { - private final UUID originalId; - public AetherstormRoc(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); this.subtype.add(SubType.BIRD); this.power = new MageInt(3); this.toughness = new MageInt(3); @@ -47,30 +46,32 @@ public final class AetherstormRoc extends CardImpl { Ability ability = new AttacksTriggeredAbility(doIfCostPaidEffect, false, "Whenever {this} attacks you may pay {E}{E}. If you do, put a +1/+1 counter on it and tap up to one target creature defending player controls."); ability.addTarget(new TargetCreaturePermanent(0, 1, new FilterCreaturePermanent("creature defending player controls"), false)); - originalId = ability.getOriginalId(); + ability.setTargetAdjuster(AetherstormRocAdjuster.instance); this.addAbility(ability); } public AetherstormRoc(final AetherstormRoc card) { super(card); - this.originalId = card.originalId; } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - ability.getTargets().clear(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); - UUID defenderId = game.getCombat().getDefenderId(ability.getSourceId()); - filter.add(new ControllerIdPredicate(defenderId)); - TargetCreaturePermanent target = new TargetCreaturePermanent(0, 1, filter, false); - ability.addTarget(target); - } - } @Override public AetherstormRoc copy() { return new AetherstormRoc(this); } } + +enum AetherstormRocAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); + UUID defenderId = game.getCombat().getDefenderId(ability.getSourceId()); + filter.add(new ControllerIdPredicate(defenderId)); + TargetCreaturePermanent target = new TargetCreaturePermanent(0, 1, filter, false); + ability.addTarget(target); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/a/AphettoDredging.java b/Mage.Sets/src/mage/cards/a/AphettoDredging.java index 5dcd18c3df..9309b1bd80 100644 --- a/Mage.Sets/src/mage/cards/a/AphettoDredging.java +++ b/Mage.Sets/src/mage/cards/a/AphettoDredging.java @@ -1,9 +1,7 @@ package mage.cards.a; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.cards.CardImpl; @@ -18,9 +16,11 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author Quercitron */ public final class AphettoDredging extends CardImpl { @@ -32,20 +32,7 @@ public final class AphettoDredging extends CardImpl { Effect effect = new ReturnFromGraveyardToHandTargetEffect(); effect.setText("Return up to three target creature cards of the creature type of your choice from your graveyard to your hand"); this.getSpellAbility().addEffect(effect); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - Player controller = game.getPlayer(ability.getControllerId()); - Choice typeChoice = new ChoiceCreatureType(game.getObject(ability.getSourceId())); - if (controller != null && controller.choose(Outcome.PutCreatureInPlay, typeChoice, game)) { - String chosenType = typeChoice.getChoice(); - FilterCreatureCard filter = new FilterCreatureCard(chosenType + " cards"); - filter.add(new SubtypePredicate(SubType.byDescription(chosenType))); - ability.addTarget(new TargetCardInYourGraveyard(0, 3, filter)); - } - } + this.getSpellAbility().setTargetAdjuster(AphettoDredgingAdjuster.instance); } public AphettoDredging(final AphettoDredging card) { @@ -57,3 +44,19 @@ public final class AphettoDredging extends CardImpl { return new AphettoDredging(this); } } + +enum AphettoDredgingAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + Player controller = game.getPlayer(ability.getControllerId()); + Choice typeChoice = new ChoiceCreatureType(game.getObject(ability.getSourceId())); + if (controller != null && controller.choose(Outcome.PutCreatureInPlay, typeChoice, game)) { + String chosenType = typeChoice.getChoice(); + FilterCreatureCard filter = new FilterCreatureCard(chosenType + " cards"); + filter.add(new SubtypePredicate(SubType.byDescription(chosenType))); + ability.addTarget(new TargetCardInYourGraveyard(0, 3, filter)); + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/a/Avalanche.java b/Mage.Sets/src/mage/cards/a/Avalanche.java index ed9bbbeb21..703bd8f95a 100644 --- a/Mage.Sets/src/mage/cards/a/Avalanche.java +++ b/Mage.Sets/src/mage/cards/a/Avalanche.java @@ -1,40 +1,32 @@ package mage.cards.a; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SuperType; +import mage.filter.FilterPermanent; import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.SupertypePredicate; import mage.game.Game; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class Avalanche extends CardImpl { - private static final FilterLandPermanent filter = new FilterLandPermanent("snow lands"); - public Avalanche(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{2}{R}{R}"); // Destroy X target snow lands. this.getSpellAbility().addEffect(new DestroyTargetEffect("Destroy X target snow lands")); - this.getSpellAbility().addTarget(new TargetPermanent(filter)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - ability.addTarget(new TargetPermanent(xValue, xValue, filter, false)); - } + this.getSpellAbility().setTargetAdjuster(AvalancheAdjuster.instance); } public Avalanche(final Avalanche card) { @@ -46,3 +38,19 @@ public final class Avalanche extends CardImpl { return new Avalanche(this); } } + +enum AvalancheAdjuster implements TargetAdjuster { + instance; + private static final FilterPermanent filter = new FilterLandPermanent("snow lands"); + + static { + filter.add(new SupertypePredicate(SuperType.SNOW)); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + ability.addTarget(new TargetPermanent(xValue, xValue, filter, false)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/BlatantThievery.java b/Mage.Sets/src/mage/cards/b/BlatantThievery.java index 39bfb83a74..3a65bbec7d 100644 --- a/Mage.Sets/src/mage/cards/b/BlatantThievery.java +++ b/Mage.Sets/src/mage/cards/b/BlatantThievery.java @@ -1,9 +1,7 @@ - package mage.cards.b; import java.util.*; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; @@ -18,6 +16,7 @@ import mage.game.Game; import mage.players.Player; import mage.target.Target; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.FixedTarget; /** @@ -31,34 +30,37 @@ public final class BlatantThievery extends CardImpl { // For each opponent, gain control of target permanent that player controls. this.getSpellAbility().addEffect(new BlatantThieveryEffect()); + this.getSpellAbility().setTargetAdjuster(BlatantThieveryAdjuster.instance); } public BlatantThievery(final BlatantThievery card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - for (UUID opponentId : game.getOpponents(ability.getControllerId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - FilterPermanent filter = new FilterPermanent("Permanent of player " + opponent.getName()); - filter.add(new ControllerIdPredicate(opponentId)); - TargetPermanent targetPermanent = new TargetPermanent(filter); - ability.addTarget(targetPermanent); - } - } - } - } - @Override public BlatantThievery copy() { return new BlatantThievery(this); } } +enum BlatantThieveryAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + for (UUID opponentId : game.getOpponents(ability.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null) { + FilterPermanent filter = new FilterPermanent("Permanent of player " + opponent.getName()); + filter.add(new ControllerIdPredicate(opponentId)); + TargetPermanent targetPermanent = new TargetPermanent(filter); + ability.addTarget(targetPermanent); + } + } + } +} + class BlatantThieveryEffect extends OneShotEffect { BlatantThieveryEffect() { diff --git a/Mage.Sets/src/mage/cards/b/BuildersBane.java b/Mage.Sets/src/mage/cards/b/BuildersBane.java index 094a17f47e..7ee8821d2e 100644 --- a/Mage.Sets/src/mage/cards/b/BuildersBane.java +++ b/Mage.Sets/src/mage/cards/b/BuildersBane.java @@ -1,11 +1,7 @@ package mage.cards.b; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -16,9 +12,13 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetArtifactPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; /** - * * @author sinsedrix */ public final class BuildersBane extends CardImpl { @@ -29,15 +29,7 @@ public final class BuildersBane extends CardImpl { // Destroy X target artifacts. Builder's Bane deals damage to each player equal to the number of artifacts he or she controlled put into a graveyard this way. this.getSpellAbility().addTarget(new TargetArtifactPermanent()); this.getSpellAbility().addEffect(new BuildersBaneEffect()); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - ability.addTarget(new TargetArtifactPermanent(xValue, xValue)); - } + this.getSpellAbility().setTargetAdjuster(BuildersBaneAdjuster.instance); } public BuildersBane(final BuildersBane card) { @@ -50,11 +42,22 @@ public final class BuildersBane extends CardImpl { } } +enum BuildersBaneAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + ability.addTarget(new TargetArtifactPermanent(xValue, xValue)); + } +} + class BuildersBaneEffect extends OneShotEffect { public BuildersBaneEffect() { super(Outcome.DestroyPermanent); - this.staticText = "Destroy X target artifacts. {this} deals damage to each player equal to the number of artifacts he or she controlled put into a graveyard this way"; + this.staticText = "Destroy X target artifacts. {this} deals damage to each player equal to the number of artifacts they controlled that were put into a graveyard this way"; } public BuildersBaneEffect(final BuildersBaneEffect effect) { diff --git a/Mage.Sets/src/mage/cards/b/BurningSands.java b/Mage.Sets/src/mage/cards/b/BurningSands.java index a8c0af943b..01f30e5a5d 100644 --- a/Mage.Sets/src/mage/cards/b/BurningSands.java +++ b/Mage.Sets/src/mage/cards/b/BurningSands.java @@ -1,7 +1,6 @@ package mage.cards.b; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.effects.common.SacrificeEffect; @@ -12,39 +11,29 @@ import mage.constants.Zone; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class BurningSands extends CardImpl { - private final UUID originalId; - public BurningSands(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}{R}"); // Whenever a creature dies, that creature's controller sacrifices a land. - Ability ability = new DiesCreatureTriggeredAbility(new SacrificeEffect(StaticFilters.FILTER_LAND, 1, "that creature's controller"), false, false, true); - originalId = ability.getOriginalId(); + Ability ability = new DiesCreatureTriggeredAbility(new SacrificeEffect( + StaticFilters.FILTER_LAND, 1, "that creature's controller" + ), false, false, true); + ability.setTargetAdjuster(BurningSandsAdjuster.instance); this.addAbility(ability); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - UUID creatureId = ability.getEffects().get(0).getTargetPointer().getFirst(game, ability); - Permanent creature = (Permanent) game.getLastKnownInformation(creatureId, Zone.BATTLEFIELD); - if (creature != null) { - ability.getEffects().get(0).setTargetPointer(new FixedTarget(creature.getControllerId())); - } - } - } - public BurningSands(final BurningSands card) { super(card); - this.originalId = card.originalId; } @Override @@ -52,3 +41,16 @@ public final class BurningSands extends CardImpl { return new BurningSands(this); } } + +enum BurningSandsAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + UUID creatureId = ability.getEffects().get(0).getTargetPointer().getFirst(game, ability); + Permanent creature = game.getPermanentOrLKIBattlefield(creatureId); + if (creature != null) { + ability.getEffects().get(0).setTargetPointer(new FixedTarget(creature.getControllerId())); + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/ByForce.java b/Mage.Sets/src/mage/cards/b/ByForce.java index 2263b8fc36..5c42282251 100644 --- a/Mage.Sets/src/mage/cards/b/ByForce.java +++ b/Mage.Sets/src/mage/cards/b/ByForce.java @@ -1,18 +1,18 @@ package mage.cards.b; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.game.Game; import mage.target.common.TargetArtifactPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author spjspj */ public final class ByForce extends CardImpl { @@ -23,15 +23,7 @@ public final class ByForce extends CardImpl { // Destroy X target artifacts. this.getSpellAbility().addEffect(new DestroyTargetEffect("Destroy X target artifacts")); this.getSpellAbility().addTarget(new TargetArtifactPermanent()); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - ability.addTarget(new TargetArtifactPermanent(xValue, xValue)); - } + this.getSpellAbility().setTargetAdjuster(ByForceAdjuster.instance); } public ByForce(final ByForce card) { @@ -43,3 +35,14 @@ public final class ByForce extends CardImpl { return new ByForce(this); } } + +enum ByForceAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + ability.addTarget(new TargetArtifactPermanent(xValue, xValue)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java b/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java index f05249eeac..37eb08abbe 100644 --- a/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java +++ b/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java @@ -1,14 +1,15 @@ package mage.cards.c; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.CostAdjuster; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.SetPowerSourceEffect; import mage.abilities.effects.common.continuous.SetToughnessSourceEffect; import mage.cards.CardImpl; @@ -21,8 +22,9 @@ import mage.filter.predicate.mageobject.ChosenSubtypePredicate; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class CallerOfTheHunt extends CardImpl { @@ -34,14 +36,24 @@ public final class CallerOfTheHunt extends CardImpl { // As an additional cost to cast Caller of the Hunt, choose a creature type. // Caller of the Hunt's power and toughness are each equal to the number of creatures of the chosen type on the battlefield. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new CallerOfTheHuntAdditionalCostEffect())); - + this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("as an additional cost to cast this spell, choose a creature type. \r" + + "{this}'s power and toughness are each equal to the number of creatures of the chosen type on the battlefield"))); + this.getSpellAbility().setCostAdjuster(CallerOfTheHuntAdjuster.instance); } public CallerOfTheHunt(final CallerOfTheHunt card) { super(card); } + @Override + public CallerOfTheHunt copy() { + return new CallerOfTheHunt(this); + } +} + +enum CallerOfTheHuntAdjuster implements CostAdjuster { + instance; + @Override public void adjustCosts(Ability ability, Game game) { MageObject mageObject = game.getObject(ability.getSourceId()); @@ -56,34 +68,6 @@ public final class CallerOfTheHunt extends CardImpl { game.addEffect(effectToughness, ability); } } - - @Override - public CallerOfTheHunt copy() { - return new CallerOfTheHunt(this); - } -} - -class CallerOfTheHuntAdditionalCostEffect extends OneShotEffect { - - public CallerOfTheHuntAdditionalCostEffect() { - super(Outcome.Benefit); - this.staticText = "as an additional cost to cast this spell, choose a creature type. \r" - + "{this}'s power and toughness are each equal to the number of creatures of the chosen type on the battlefield"; - } - - public CallerOfTheHuntAdditionalCostEffect(final CallerOfTheHuntAdditionalCostEffect effect) { - super(effect); - } - - @Override - public CallerOfTheHuntAdditionalCostEffect copy() { - return new CallerOfTheHuntAdditionalCostEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } } class ChooseCreatureTypeEffect extends OneShotEffect { // code by LevelX2, but that other version is not compatible with this card @@ -116,5 +100,4 @@ class ChooseCreatureTypeEffect extends OneShotEffect { // code by LevelX2, but t public ChooseCreatureTypeEffect copy() { return new ChooseCreatureTypeEffect(this); } - } diff --git a/Mage.Sets/src/mage/cards/c/CauldronHaze.java b/Mage.Sets/src/mage/cards/c/CauldronHaze.java index db95a2d1e1..28f0e6d9c7 100644 --- a/Mage.Sets/src/mage/cards/c/CauldronHaze.java +++ b/Mage.Sets/src/mage/cards/c/CauldronHaze.java @@ -1,7 +1,6 @@ package mage.cards.c; -import java.util.UUID; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.PersistAbility; import mage.cards.CardImpl; @@ -10,13 +9,14 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class CauldronHaze extends CardImpl { - private final String rule = "Choose any number of target creatures. Each of those creatures gains persist until end of turn"; + private static final String rule = "Choose any number of target creatures. Each of those creatures gains persist until end of turn"; public CauldronHaze(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W/B}"); @@ -24,7 +24,6 @@ public final class CauldronHaze extends CardImpl { // Choose any number of target creatures. Each of those creatures gains persist until end of turn. this.getSpellAbility().addEffect(new GainAbilityTargetEffect(new PersistAbility(), Duration.EndOfTurn, rule)); this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE)); - } public CauldronHaze(final CauldronHaze card) { diff --git a/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java b/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java index 24434b01b7..9bfb91786e 100644 --- a/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java +++ b/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java @@ -1,7 +1,6 @@ package mage.cards.c; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -22,14 +21,15 @@ import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.permanent.AnotherPredicate; import mage.game.Game; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class ChampionOfStraySouls extends CardImpl { - private final UUID originalId; private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other creatures"); static { @@ -37,7 +37,7 @@ public final class ChampionOfStraySouls extends CardImpl { } public ChampionOfStraySouls(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); this.subtype.add(SubType.SKELETON); this.subtype.add(SubType.WARRIOR); @@ -49,7 +49,6 @@ public final class ChampionOfStraySouls extends CardImpl { * ability, before you pay any costs. You can't target any of the * creatures you sacrifice. */ - //TODO: Make ability properly copiable // {3}{B}{B}, {T}, Sacrifice X other creatures: Return X target creatures from your graveyard to the battlefield. Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect(); effect.setText("Return X target creatures from your graveyard to the battlefield"); @@ -57,32 +56,17 @@ public final class ChampionOfStraySouls extends CardImpl { ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeXTargetCost(filter)); ability.addTarget(new TargetCardInYourGraveyard(0, Integer.MAX_VALUE, new FilterCreatureCard("creature cards from your graveyard"))); - originalId = ability.getOriginalId(); + ability.setTargetAdjuster(ChampionOfStraySoulsAdjuster.instance); this.addAbility(ability); // {5}{B}{B}: Put Champion of Stray Souls on top of your library from your graveyard. this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new PutOnLibrarySourceEffect(true, "Put {this} on top of your library from your graveyard"), new ManaCostsImpl("{5}{B}{B}"))); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - for (Effect effect : ability.getEffects()) { - if (effect instanceof ReturnFromGraveyardToBattlefieldTargetEffect) { - int xValue = new GetXValue().calculate(game, ability, null); - ability.getTargets().clear(); - ability.addTarget(new TargetCardInYourGraveyard(xValue, xValue, new FilterCreatureCard("creature cards from your graveyard"))); - } - } - } } public ChampionOfStraySouls(final ChampionOfStraySouls card) { super(card); - this.originalId = card.originalId; } @Override @@ -90,3 +74,18 @@ public final class ChampionOfStraySouls extends CardImpl { return new ChampionOfStraySouls(this); } } + +enum ChampionOfStraySoulsAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + for (Effect effect : ability.getEffects()) { + if (effect instanceof ReturnFromGraveyardToBattlefieldTargetEffect) { + int xValue = new GetXValue().calculate(game, ability, null); + ability.getTargets().clear(); + ability.addTarget(new TargetCardInYourGraveyard(xValue, xValue, new FilterCreatureCard("creature cards from your graveyard"))); + } + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CitadelSiege.java b/Mage.Sets/src/mage/cards/c/CitadelSiege.java index 86093720e5..99948a4706 100644 --- a/Mage.Sets/src/mage/cards/c/CitadelSiege.java +++ b/Mage.Sets/src/mage/cards/c/CitadelSiege.java @@ -15,28 +15,33 @@ import mage.constants.CardType; import mage.constants.TargetController; import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.filter.predicate.Predicate; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; /** - * * @author LevelX2 */ public final class CitadelSiege extends CardImpl { private final static String ruleTrigger1 = "&bull Khans — At the beginning of combat on your turn, put two +1/+1 counters on target creature you control."; private final static String ruleTrigger2 = "&bull Dragons — At the beginning of combat on each opponent's turn, tap target creature that player controls."; + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("creature controlled by the active player"); + + static { + filter.add(CitadelSiegePredicate.instance); + } public CitadelSiege(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); // As Citadel Siege enters the battlefield, choose Khans or Dragons. - this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, - "As {this} enters the battlefield, choose Khans or Dragons.","")); + this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, + "As {this} enters the battlefield, choose Khans or Dragons.", "")); // * Khans - At the beginning of combat on your turn, put two +1/+1 counters on target creature you control. Ability ability = new ConditionalTriggeredAbility( @@ -51,21 +56,10 @@ public final class CitadelSiege extends CardImpl { new BeginningOfCombatTriggeredAbility(new TapTargetEffect(), TargetController.OPPONENT, false), new ModeChoiceSourceCondition("Dragons"), ruleTrigger2); - ability.addTarget(new TargetCreaturePermanent()); + ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (this.getAbilities().contains(ability) && ability.getRule().startsWith("&bull Dragons")) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that player controls"); - filter.add(new ControllerIdPredicate(game.getCombat().getAttackingPlayerId())); - ability.getTargets().clear(); - ability.addTarget(new TargetCreaturePermanent(filter)); - } - } - - public CitadelSiege(final CitadelSiege card) { super(card); } @@ -75,3 +69,12 @@ public final class CitadelSiege extends CardImpl { return new CitadelSiege(this); } } + +enum CitadelSiegePredicate implements Predicate { + instance; + + @Override + public boolean apply(Permanent input, Game game) { + return input.getControllerId().equals(game.getActivePlayerId()); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CometStorm.java b/Mage.Sets/src/mage/cards/c/CometStorm.java index c88df06c34..0c331d3d7b 100644 --- a/Mage.Sets/src/mage/cards/c/CometStorm.java +++ b/Mage.Sets/src/mage/cards/c/CometStorm.java @@ -1,9 +1,7 @@ - package mage.cards.c; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.dynamicvalue.common.MultikickerCount; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.MultikickerAbility; @@ -15,6 +13,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetAnyTarget; +import mage.target.targetadjustment.TargetAdjuster; /** * @@ -31,27 +30,30 @@ public final class CometStorm extends CardImpl { // Choose any target, then choose another any target for each time Comet Storm was kicked. Comet Storm deals X damage to each of them. this.getSpellAbility().addEffect(new CometStormEffect()); this.getSpellAbility().addTarget(new TargetAnyTarget(1)); + this.getSpellAbility().setTargetAdjuster(CometStormAdjuster.instance); } public CometStorm(final CometStorm card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int numbTargets = new MultikickerCount().calculate(game, ability, null) + 1; - ability.addTarget(new TargetAnyTarget(numbTargets)); - } - } - @Override public CometStorm copy() { return new CometStorm(this); } } +enum CometStormAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int numbTargets = new MultikickerCount().calculate(game, ability, null) + 1; + ability.addTarget(new TargetAnyTarget(numbTargets)); + } +} + class CometStormEffect extends OneShotEffect { public CometStormEffect() { diff --git a/Mage.Sets/src/mage/cards/c/ConfusionInTheRanks.java b/Mage.Sets/src/mage/cards/c/ConfusionInTheRanks.java index 388e46d2bc..fe65023e65 100644 --- a/Mage.Sets/src/mage/cards/c/ConfusionInTheRanks.java +++ b/Mage.Sets/src/mage/cards/c/ConfusionInTheRanks.java @@ -1,10 +1,6 @@ package mage.cards.c; -import java.util.HashSet; -import java.util.Locale; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.effects.Effect; @@ -22,9 +18,14 @@ import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import java.util.UUID; /** - * * @author anonymous */ public final class ConfusionInTheRanks extends CardImpl { @@ -38,7 +39,6 @@ public final class ConfusionInTheRanks extends CardImpl { new CardTypePredicate(CardType.ENCHANTMENT) )); } - private final UUID originalId; public ConfusionInTheRanks(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}{R}"); @@ -49,54 +49,18 @@ public final class ConfusionInTheRanks extends CardImpl { new ExchangeControlTargetEffect( Duration.EndOfGame, "its controller chooses target permanent " - + "another player controls that shares a card type with it. " - + "Exchange control of those permanents" + + "another player controls that shares a card type with it. " + + "Exchange control of those permanents" ), filter, false, SetTargetPointer.PERMANENT, null ); ability.addTarget(new TargetPermanent()); - originalId = ability.getOriginalId(); + ability.setTargetAdjuster(ConfusionInTheRanksAdjuster.instance); this.addAbility(ability); } public ConfusionInTheRanks(final ConfusionInTheRanks card) { super(card); - this.originalId = card.originalId; - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - UUID enteringPermanentId = null; - for (Effect effect : ability.getEffects()) { - enteringPermanentId = effect.getTargetPointer().getFirst(game, ability); - } - if (enteringPermanentId == null) { - return; - } - Permanent enteringPermanent = game.getPermanent(enteringPermanentId); - if (enteringPermanent == null) { - return; - } - ability.getTargets().clear(); - FilterPermanent filterTarget = new FilterPermanent(); - String message = ""; - filterTarget.add(Predicates.not(new ControllerIdPredicate(enteringPermanent.getControllerId()))); - Set cardTypesPredicates = new HashSet<>(1); - for (CardType cardTypeEntering : enteringPermanent.getCardType()) { - cardTypesPredicates.add(new CardTypePredicate(cardTypeEntering)); - if (!message.isEmpty()) { - message += "or "; - } - message += cardTypeEntering.toString().toLowerCase(Locale.ENGLISH) + ' '; - } - filterTarget.add(Predicates.or(cardTypesPredicates)); - message += "you don't control"; - filterTarget.setMessage(message); - TargetPermanent target = new TargetPermanent(filterTarget); - target.setTargetController(enteringPermanent.getControllerId()); - ability.getTargets().add(target); - } } @Override @@ -104,3 +68,40 @@ public final class ConfusionInTheRanks extends CardImpl { return new ConfusionInTheRanks(this); } } + +enum ConfusionInTheRanksAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + UUID enteringPermanentId = null; + for (Effect effect : ability.getEffects()) { + enteringPermanentId = effect.getTargetPointer().getFirst(game, ability); + } + if (enteringPermanentId == null) { + return; + } + Permanent enteringPermanent = game.getPermanent(enteringPermanentId); + if (enteringPermanent == null) { + return; + } + ability.getTargets().clear(); + FilterPermanent filterTarget = new FilterPermanent(); + String message = ""; + filterTarget.add(Predicates.not(new ControllerIdPredicate(enteringPermanent.getControllerId()))); + Set cardTypesPredicates = new HashSet<>(1); + for (CardType cardTypeEntering : enteringPermanent.getCardType()) { + cardTypesPredicates.add(new CardTypePredicate(cardTypeEntering)); + if (!message.isEmpty()) { + message += "or "; + } + message += cardTypeEntering.toString().toLowerCase(Locale.ENGLISH) + ' '; + } + filterTarget.add(Predicates.or(cardTypesPredicates)); + message += "you don't control"; + filterTarget.setMessage(message); + TargetPermanent target = new TargetPermanent(filterTarget); + target.setTargetController(enteringPermanent.getControllerId()); + ability.getTargets().add(target); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CovetedPeacock.java b/Mage.Sets/src/mage/cards/c/CovetedPeacock.java index 9b748f4068..97502d3bee 100644 --- a/Mage.Sets/src/mage/cards/c/CovetedPeacock.java +++ b/Mage.Sets/src/mage/cards/c/CovetedPeacock.java @@ -1,7 +1,6 @@ package mage.cards.c; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; @@ -11,18 +10,23 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; +import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.target.common.TargetCreaturePermanent; +import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class CovetedPeacock extends CardImpl { - private final UUID originalId; + public static final FilterPermanent filter = new FilterCreaturePermanent("creature defending player controls"); + + static { + filter.add(new DefendingPlayerControlsPredicate()); + } public CovetedPeacock(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); @@ -36,26 +40,12 @@ public final class CovetedPeacock extends CardImpl { // Whenever Coveted Peacock attacks, you may goad target creature defending player controls. Ability ability = new AttacksTriggeredAbility(new GoadTargetEffect(), true, "Whenever {this} attacks, you may goad target creature defending player controls."); - ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls"))); - originalId = ability.getOriginalId(); + ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); } public CovetedPeacock(final CovetedPeacock card) { super(card); - this.originalId = card.originalId; - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - ability.getTargets().clear(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); - UUID defenderId = game.getCombat().getDefenderId(ability.getSourceId()); - filter.add(new ControllerIdPredicate(defenderId)); - TargetCreaturePermanent target = new TargetCreaturePermanent(filter); - ability.addTarget(target); - } } @Override diff --git a/Mage.Sets/src/mage/cards/c/CrookOfCondemnation.java b/Mage.Sets/src/mage/cards/c/CrookOfCondemnation.java index 71016541e7..8770fff76c 100644 --- a/Mage.Sets/src/mage/cards/c/CrookOfCondemnation.java +++ b/Mage.Sets/src/mage/cards/c/CrookOfCondemnation.java @@ -1,7 +1,6 @@ package mage.cards.c; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.ExileSourceCost; @@ -15,29 +14,28 @@ import mage.constants.CardType; import mage.constants.Zone; import mage.target.common.TargetCardInGraveyard; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class CrookOfCondemnation extends CardImpl { - - private UUID exileId = UUID.randomUUID(); public CrookOfCondemnation(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); - + // {1}, {t}: Exile target card from a graveyard. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetEffect(), new ManaCostsImpl("{1}")); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetCardInGraveyard()); this.addAbility(ability); - + // {1}, Exile Crook of Condemnation: Exile all cards from all graveyards. Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileGraveyardAllPlayersEffect(), new ManaCostsImpl("{1}")); ability2.addCost(new ExileSourceCost()); this.addAbility(ability2); - + } public CrookOfCondemnation(final CrookOfCondemnation card) { diff --git a/Mage.Sets/src/mage/cards/c/CuombajjWitches.java b/Mage.Sets/src/mage/cards/c/CuombajjWitches.java index 2bb7d7a777..5d58744bdb 100644 --- a/Mage.Sets/src/mage/cards/c/CuombajjWitches.java +++ b/Mage.Sets/src/mage/cards/c/CuombajjWitches.java @@ -1,7 +1,6 @@ package mage.cards.c; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -11,68 +10,42 @@ import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetAnyTarget; import mage.target.common.TargetOpponent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LoneFox - */ public final class CuombajjWitches extends CardImpl { - private final UUID originalId; - public CuombajjWitches(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); this.power = new MageInt(1); this.toughness = new MageInt(3); - //TODO: Make ability properly copiable // {T}: Cuombajj Witches deals 1 damage to any target and 1 damage to any target of an opponent's choice. Effect effect = new DamageTargetEffect(1); effect.setText("{this} deals 1 damage to any target and 1 damage to any target of an opponent's choice"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); ability.addTarget(new TargetAnyTarget()); ability.addTarget(new TargetAnyTarget()); + ability.setTargetAdjuster(CuombajjWitchesAdjuster.instance); this.addAbility(ability); - originalId = ability.getOriginalId(); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if(ability.getOriginalId().equals(originalId)) { - Player controller = game.getPlayer(ability.getControllerId()); - if(controller != null) { - UUID opponentId = null; - if(game.getOpponents(controller.getId()).size() > 1) { - Target target = new TargetOpponent(true); - if(controller.chooseTarget(Outcome.Neutral, target, ability, game)) { - opponentId = target.getFirstTarget(); - } - } - else { - opponentId = game.getOpponents(controller.getId()).iterator().next(); - } - - if(opponentId != null) { - ability.getTargets().get(1).setTargetController(opponentId); - } - } - } } public CuombajjWitches(final CuombajjWitches card) { super(card); - this.originalId = card.originalId; } @Override @@ -80,3 +53,26 @@ public final class CuombajjWitches extends CardImpl { return new CuombajjWitches(this); } } + +enum CuombajjWitchesAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + Player controller = game.getPlayer(ability.getControllerId()); + if (controller != null) { + UUID opponentId = null; + if (game.getOpponents(controller.getId()).size() > 1) { + Target target = new TargetOpponent(true); + if (controller.chooseTarget(Outcome.Neutral, target, ability, game)) { + opponentId = target.getFirstTarget(); + } + } else { + opponentId = game.getOpponents(controller.getId()).iterator().next(); + } + if (opponentId != null) { + ability.getTargets().get(1).setTargetController(opponentId); + } + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java b/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java index cc40d56084..0414cd2ef0 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java @@ -1,15 +1,10 @@ package mage.cards.c; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AbilityType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; @@ -18,9 +13,13 @@ import mage.game.permanent.Permanent; import mage.game.permanent.token.CurseOfTheSwineBoarToken; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; /** - * * @author LevelX2 */ public final class CurseOfTheSwine extends CardImpl { @@ -31,15 +30,7 @@ public final class CurseOfTheSwine extends CardImpl { // Exile X target creatures. For each creature exiled this way, its controller creates a 2/2 green Boar creature token. this.getSpellAbility().addEffect(new CurseOfTheSwineEffect()); // Correct number of targets will be set in adjustTargets - this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility && ability.getAbilityType() == AbilityType.SPELL) { - ability.getTargets().clear(); - ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); - } + this.getSpellAbility().setTargetAdjuster(CurseOfTheSwineAdjuster.instance); } public CurseOfTheSwine(final CurseOfTheSwine card) { @@ -52,6 +43,16 @@ public final class CurseOfTheSwine extends CardImpl { } } +enum CurseOfTheSwineAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); + } +} + class CurseOfTheSwineEffect extends OneShotEffect { public CurseOfTheSwineEffect() { diff --git a/Mage.Sets/src/mage/cards/c/CustodiSoulcaller.java b/Mage.Sets/src/mage/cards/c/CustodiSoulcaller.java index 65b6340f1d..1f19992bec 100644 --- a/Mage.Sets/src/mage/cards/c/CustodiSoulcaller.java +++ b/Mage.Sets/src/mage/cards/c/CustodiSoulcaller.java @@ -1,10 +1,6 @@ package mage.cards.c; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; @@ -12,7 +8,10 @@ import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffec import mage.abilities.keyword.MeleeAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.constants.WatcherScope; import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.Predicates; @@ -23,16 +22,21 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; import mage.watchers.Watcher; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** - * * @author L_J */ public final class CustodiSoulcaller extends CardImpl { public CustodiSoulcaller(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(1); @@ -45,25 +49,10 @@ public final class CustodiSoulcaller extends CardImpl { Ability ability = new AttacksTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), false); ability.addWatcher(new CustodiSoulcallerWatcher()); ability.addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card with converted mana cost X or less from your graveyard, where X is the number of players you attacked with a creature this combat"))); + ability.setTargetAdjuster(CustodiSoulcallerAdjuster.instance); this.addAbility(ability); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getClass().equals(AttacksTriggeredAbility.class)) { - ability.getTargets().clear(); - CustodiSoulcallerWatcher watcher = game.getState().getWatcher(CustodiSoulcallerWatcher.class); - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(ability.getSourceId()); - if (watcher != null && watcher.playersAttacked != null) { - int xValue = watcher.getNumberOfAttackedPlayers(sourcePermanent.getControllerId()); - FilterCard filter = new FilterCard("creature card with converted mana cost " + xValue + " or less"); - filter.add(new CardTypePredicate(CardType.CREATURE)); - filter.add(Predicates.or(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue), new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue))); - ability.getTargets().add(new TargetCardInYourGraveyard(filter)); - } - } - } - public CustodiSoulcaller(final CustodiSoulcaller card) { super(card); } @@ -74,9 +63,27 @@ public final class CustodiSoulcaller extends CardImpl { } } +enum CustodiSoulcallerAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + CustodiSoulcallerWatcher watcher = (CustodiSoulcallerWatcher) game.getState().getWatchers().get(CustodiSoulcallerWatcher.class.getSimpleName()); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(ability.getSourceId()); + if (watcher != null) { + int xValue = watcher.getNumberOfAttackedPlayers(sourcePermanent.getControllerId()); + FilterCard filter = new FilterCard("creature card with converted mana cost " + xValue + " or less"); + filter.add(new CardTypePredicate(CardType.CREATURE)); + filter.add(Predicates.or(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue), new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue))); + ability.getTargets().add(new TargetCardInYourGraveyard(filter)); + } + } +} + class CustodiSoulcallerWatcher extends Watcher { - protected final HashMap> playersAttacked = new HashMap<>(0); + private final HashMap> playersAttacked = new HashMap<>(0); CustodiSoulcallerWatcher() { super("CustodiSoulcallerWatcher", WatcherScope.GAME); @@ -91,8 +98,7 @@ class CustodiSoulcallerWatcher extends Watcher { public void watch(GameEvent event, Game game) { if (event.getType() == EventType.BEGIN_COMBAT_STEP_PRE) { this.playersAttacked.clear(); - } - else if (event.getType() == EventType.ATTACKER_DECLARED) { + } else if (event.getType() == EventType.ATTACKER_DECLARED) { Set attackedPlayers = this.playersAttacked.getOrDefault(event.getPlayerId(), new HashSet<>(1)); attackedPlayers.add(event.getTargetId()); this.playersAttacked.put(event.getPlayerId(), attackedPlayers); diff --git a/Mage.Sets/src/mage/cards/d/DeathDenied.java b/Mage.Sets/src/mage/cards/d/DeathDenied.java index e54bf6697e..baf509a483 100644 --- a/Mage.Sets/src/mage/cards/d/DeathDenied.java +++ b/Mage.Sets/src/mage/cards/d/DeathDenied.java @@ -2,7 +2,6 @@ package mage.cards.d; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.cards.CardImpl; @@ -13,35 +12,24 @@ import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.target.Target; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; import java.util.UUID; /** - * * @author LevelX2 */ public final class DeathDenied extends CardImpl { public DeathDenied(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{B}{B}"); this.subtype.add(SubType.ARCANE); // Return X target creature cards from your graveyard to your hand. Effect effect = new ReturnFromGraveyardToHandTargetEffect(); effect.setText("Return X target creature cards from your graveyard to your hand"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(1, new FilterCreatureCard())); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - Target target = new TargetCardInYourGraveyard(xValue, new FilterCreatureCard((xValue != 1 ? " creature cards" : "creature card") + " from your graveyard")); - ability.addTarget(target); - } + this.getSpellAbility().setTargetAdjuster(DeathDeniedAdjuster.instance); } public DeathDenied(final DeathDenied card) { @@ -53,3 +41,15 @@ public final class DeathDenied extends CardImpl { return new DeathDenied(this); } } + +enum DeathDeniedAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + Target target = new TargetCardInYourGraveyard(xValue, new FilterCreatureCard(new StringBuilder(xValue).append(xValue != 1 ? " creature cards" : "creature card").append(" from your graveyard").toString())); + ability.addTarget(target); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DeathMatch.java b/Mage.Sets/src/mage/cards/d/DeathMatch.java index d5827dfbd0..389b27cd26 100644 --- a/Mage.Sets/src/mage/cards/d/DeathMatch.java +++ b/Mage.Sets/src/mage/cards/d/DeathMatch.java @@ -1,7 +1,5 @@ - package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -13,17 +11,16 @@ import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.FirstTargetPointer; +import java.util.UUID; + /** - * * @author LoneFox - * */ public final class DeathMatch extends CardImpl { - private final UUID originalId; - public DeathMatch(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); @@ -32,24 +29,12 @@ public final class DeathMatch extends CardImpl { Ability ability = new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new DeathMatchEffect(), StaticFilters.FILTER_PERMANENT_CREATURE, false, SetTargetPointer.PLAYER, ""); ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(DeathMatchAdjuster.instance); this.addAbility(ability); - originalId = ability.getOriginalId(); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - UUID controllerId = ability.getEffects().get(0).getTargetPointer().getFirst(game, ability); - if (controllerId != null) { - ability.getTargets().get(0).setTargetController(controllerId); - ability.getEffects().get(0).setTargetPointer(new FirstTargetPointer()); - } - } } public DeathMatch(final DeathMatch card) { super(card); - this.originalId = card.originalId; } @Override @@ -58,6 +43,19 @@ public final class DeathMatch extends CardImpl { } } +enum DeathMatchAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + UUID controllerId = ability.getEffects().get(0).getTargetPointer().getFirst(game, ability); + if (controllerId != null) { + ability.getTargets().get(0).setTargetController(controllerId); + ability.getEffects().get(0).setTargetPointer(new FirstTargetPointer()); + } + } +} + class DeathMatchEffect extends OneShotEffect { public DeathMatchEffect() { diff --git a/Mage.Sets/src/mage/cards/d/DecimatorBeetle.java b/Mage.Sets/src/mage/cards/d/DecimatorBeetle.java index 2d0c35432a..83060b5472 100644 --- a/Mage.Sets/src/mage/cards/d/DecimatorBeetle.java +++ b/Mage.Sets/src/mage/cards/d/DecimatorBeetle.java @@ -1,7 +1,6 @@ package mage.cards.d; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; @@ -13,24 +12,29 @@ import mage.abilities.effects.common.counter.RemoveCounterTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author spjspj */ public final class DecimatorBeetle extends CardImpl { - private final UUID originalId; + public static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); + + static { + filter.add(new DefendingPlayerControlsPredicate()); + } public DecimatorBeetle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{G}"); @@ -46,29 +50,14 @@ public final class DecimatorBeetle extends CardImpl { this.addAbility(ability); // Whenever Decimator Beetle attacks, remove a -1/-1 counter from target creature you control and put a -1/-1 counter on up to one target creature defending player controls. - Ability ability2 = new AttacksTriggeredAbility(new DecimatorBeetleEffect(), false); - ability2.addTarget(new TargetControlledCreaturePermanent()); - ability2.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls"))); - this.addAbility(ability2); - this.originalId = ability2.getOriginalId(); + ability = new AttacksTriggeredAbility(new DecimatorBeetleEffect(), false); + ability.addTarget(new TargetControlledCreaturePermanent()); + ability.addTarget(new TargetCreaturePermanent(0, 1, filter, false)); + this.addAbility(ability); } public DecimatorBeetle(final DecimatorBeetle card) { super(card); - this.originalId = card.originalId; - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - ability.getTargets().clear(); - ability.addTarget(new TargetControlledCreaturePermanent()); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); - UUID defenderId = game.getCombat().getDefenderId(ability.getSourceId()); - filter.add(new ControllerIdPredicate(defenderId)); - TargetCreaturePermanent target = new TargetCreaturePermanent(0, 1, filter, false); - ability.addTarget(target); - } } @Override diff --git a/Mage.Sets/src/mage/cards/d/Detonate.java b/Mage.Sets/src/mage/cards/d/Detonate.java index ff84de2a35..de1a4096ed 100644 --- a/Mage.Sets/src/mage/cards/d/Detonate.java +++ b/Mage.Sets/src/mage/cards/d/Detonate.java @@ -1,9 +1,7 @@ package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageTargetControllerEffect; @@ -16,15 +14,17 @@ import mage.filter.common.FilterArtifactPermanent; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.target.common.TargetArtifactPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LoneFox */ public final class Detonate extends CardImpl { public Detonate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}"); // Destroy target artifact with converted mana cost X. It can't be regenerated. Detonate deals X damage to that artifact's controller. this.getSpellAbility().addEffect(new DestroyTargetEffect(true)); @@ -32,17 +32,7 @@ public final class Detonate extends CardImpl { Effect effect = new DamageTargetControllerEffect(new ManacostVariableValue()); effect.setText("{this} deals X damage to that artifact's controller"); this.getSpellAbility().addEffect(effect); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if(ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterArtifactPermanent filter = new FilterArtifactPermanent("artifact with converted mana cost X"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); - ability.addTarget(new TargetArtifactPermanent(filter)); - } + this.getSpellAbility().setTargetAdjuster(DetonateAdjuster.instance); } public Detonate(final Detonate card) { @@ -54,3 +44,16 @@ public final class Detonate extends CardImpl { return new Detonate(this); } } + +enum DetonateAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + FilterArtifactPermanent filter = new FilterArtifactPermanent("artifact with converted mana cost X"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); + ability.addTarget(new TargetArtifactPermanent(filter)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java b/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java index ce7e86dcf0..98bde31f8f 100644 --- a/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java +++ b/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java @@ -1,7 +1,6 @@ package mage.cards.d; -import java.util.UUID; import mage.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; @@ -13,11 +12,7 @@ import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -29,10 +24,12 @@ import mage.game.events.ZoneChangeEvent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInOpponentsGraveyard; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class DiluvianPrimordial extends CardImpl { @@ -48,24 +45,9 @@ public final class DiluvianPrimordial extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Diluvian Primordial enters the battlefield, for each opponent, you may cast up to one target instant or sorcery card from that player's graveyard without paying its mana cost. If a card cast this way would be put into a graveyard this turn, exile it instead. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DiluvianPrimordialEffect(), false)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof EntersBattlefieldTriggeredAbility) { - ability.getTargets().clear(); - for (UUID opponentId : game.getOpponents(ability.getControllerId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - FilterCard filter = new FilterCard("instant or sorcery card from " + opponent.getLogName() + "'s graveyard"); - filter.add(new OwnerIdPredicate(opponentId)); - filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY))); - TargetCardInOpponentsGraveyard target = new TargetCardInOpponentsGraveyard(0, 1, filter); - ability.addTarget(target); - } - } - } + Ability ability = new EntersBattlefieldTriggeredAbility(new DiluvianPrimordialEffect(), false); + ability.setTargetAdjuster(DiluvianPrimordialAdjuster.instance); + this.addAbility(ability); } public DiluvianPrimordial(final DiluvianPrimordial card) { @@ -78,6 +60,26 @@ public final class DiluvianPrimordial extends CardImpl { } } +enum DiluvianPrimordialAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + for (UUID opponentId : game.getOpponents(ability.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent == null) { + continue; + } + FilterCard filter = new FilterCard("instant or sorcery card from " + opponent.getLogName() + "'s graveyard"); + filter.add(new OwnerIdPredicate(opponentId)); + filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY))); + TargetCardInOpponentsGraveyard target = new TargetCardInOpponentsGraveyard(0, 1, filter); + ability.addTarget(target); + } + } +} + class DiluvianPrimordialEffect extends OneShotEffect { public DiluvianPrimordialEffect() { diff --git a/Mage.Sets/src/mage/cards/d/Disembowel.java b/Mage.Sets/src/mage/cards/d/Disembowel.java index 3e1f1d500d..6aa70be2ab 100644 --- a/Mage.Sets/src/mage/cards/d/Disembowel.java +++ b/Mage.Sets/src/mage/cards/d/Disembowel.java @@ -1,9 +1,7 @@ package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -13,30 +11,21 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LoneFox */ public final class Disembowel extends CardImpl { public Disembowel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{B}"); // Destroy target creature with converted mana cost X. - this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature with converted mana cost X"))); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if(ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost X"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); - ability.addTarget(new TargetCreaturePermanent(filter)); - } + this.getSpellAbility().addEffect(new DestroyTargetEffect("creature with converted mana cost X")); + this.getSpellAbility().setTargetAdjuster(DisembowelAdjuster.instance); } public Disembowel(final Disembowel card) { @@ -48,3 +37,16 @@ public final class Disembowel extends CardImpl { return new Disembowel(this); } } + +enum DisembowelAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost X"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); + ability.addTarget(new TargetCreaturePermanent(filter)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DistortingWake.java b/Mage.Sets/src/mage/cards/d/DistortingWake.java index 6f0491c67b..e03c667af1 100644 --- a/Mage.Sets/src/mage/cards/d/DistortingWake.java +++ b/Mage.Sets/src/mage/cards/d/DistortingWake.java @@ -1,9 +1,7 @@ package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; @@ -13,22 +11,23 @@ import mage.filter.common.FilterNonlandPermanent; import mage.game.Game; import mage.target.Target; import mage.target.common.TargetNonlandPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class DistortingWake extends CardImpl { public DistortingWake(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{U}{U}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}{U}{U}"); // Return X target nonland permanents to their owners' hands. Effect effect = new ReturnToHandTargetEffect(); effect.setText("Return X target nonland permanents to their owners' hands"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addTarget(new TargetNonlandPermanent()); + this.getSpellAbility().setTargetAdjuster(DistortingWakeAdjuster.instance); } public DistortingWake(final DistortingWake card) { @@ -39,16 +38,17 @@ public final class DistortingWake extends CardImpl { public DistortingWake copy() { return new DistortingWake(this); } +} + +enum DistortingWakeAdjuster implements TargetAdjuster { + instance; @Override public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - int xValue = ability.getManaCostsToPay().getX(); - Target target = new TargetNonlandPermanent(xValue, xValue, - new FilterNonlandPermanent(xValue + " target nonland permanent(s)"), false); - ability.getTargets().clear(); - ability.getTargets().add(target); - } + int xValue = ability.getManaCostsToPay().getX(); + Target target = new TargetNonlandPermanent(xValue, xValue, + new FilterNonlandPermanent(xValue + " target nonland permanent(s)"), false); + ability.getTargets().clear(); + ability.getTargets().add(target); } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/Dominate.java b/Mage.Sets/src/mage/cards/d/Dominate.java index 7ad2e93a8c..d9c74afb3c 100644 --- a/Mage.Sets/src/mage/cards/d/Dominate.java +++ b/Mage.Sets/src/mage/cards/d/Dominate.java @@ -1,9 +1,6 @@ - package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -15,38 +12,43 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author fireshoes */ public final class Dominate extends CardImpl { public Dominate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{1}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{1}{U}{U}"); // Gain control of target creature with converted mana cost X or less. this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.Custom, true)); this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature with converted mana cost X or less"))); + this.getSpellAbility().setTargetAdjuster(DominateAdjuster.instance); } public Dominate(final Dominate card) { super(card); } - - @Override - public void adjustTargets(Ability ability, Game game) { - if(ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost X or less"); - filter.add(Predicates.not(new ConvertedManaCostPredicate(ComparisonType.MORE_THAN, xValue))); - ability.addTarget(new TargetCreaturePermanent(filter)); - } - } @Override public Dominate copy() { return new Dominate(this); } } + +enum DominateAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost X or less"); + filter.add(Predicates.not(new ConvertedManaCostPredicate(ComparisonType.MORE_THAN, xValue))); + ability.addTarget(new TargetCreaturePermanent(filter)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DraconicRoar.java b/Mage.Sets/src/mage/cards/d/DraconicRoar.java index f65e60f704..34102c4f39 100644 --- a/Mage.Sets/src/mage/cards/d/DraconicRoar.java +++ b/Mage.Sets/src/mage/cards/d/DraconicRoar.java @@ -1,15 +1,14 @@ package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.common.RevealTargetFromHandCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.InfoEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AbilityType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -22,23 +21,19 @@ import mage.target.common.TargetCardInHand; import mage.target.common.TargetCreaturePermanent; import mage.watchers.common.DragonOnTheBattlefieldWhileSpellWasCastWatcher; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class DraconicRoar extends CardImpl { - private static final FilterCard filter = new FilterCard("a Dragon card from your hand (you don't have to)"); - - static { - filter.add(new SubtypePredicate(SubType.DRAGON)); - } - public DraconicRoar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}"); // As an additional cost to cast Draconic Roar, you may reveal a Dragon card from your hand. this.getSpellAbility().addEffect(new InfoEffect("as an additional cost to cast this spell, you may reveal a Dragon card from your hand")); + this.getSpellAbility().setCostAdjuster(DraconicRoarAdjuster.instance); // Draconic Roar deals 3 damage to target creature. If you revealed a Dragon card or controlled a Dragon as you cast Draconic Roar, Draconic Roar deals 3 damage to that creature's controller. this.getSpellAbility().addEffect(new DamageTargetEffect(3)); @@ -47,18 +42,6 @@ public final class DraconicRoar extends CardImpl { this.getSpellAbility().addWatcher(new DragonOnTheBattlefieldWhileSpellWasCastWatcher()); } - @Override - public void adjustCosts(Ability ability, Game game) { - if (ability.getAbilityType() == AbilityType.SPELL) { - Player controller = game.getPlayer(ability.getControllerId()); - if (controller != null) { - if (controller.getHand().count(filter, game) > 0) { - ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0,1, filter))); - } - } - } - } - public DraconicRoar(final DraconicRoar card) { super(card); } @@ -69,6 +52,25 @@ public final class DraconicRoar extends CardImpl { } } +enum DraconicRoarAdjuster implements CostAdjuster { + instance; + + private static final FilterCard filter = new FilterCard("a Dragon card from your hand (you don't have to)"); + + static { + filter.add(new SubtypePredicate(SubType.DRAGON)); + } + + @Override + public void adjustCosts(Ability ability, Game game) { + Player controller = game.getPlayer(ability.getControllerId()); + if (controller != null) { + if (controller.getHand().count(filter, game) > 0) { + ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, 1, filter))); + } + } + } +} class DraconicRoarEffect extends OneShotEffect { diff --git a/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java b/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java index 6ce626db3f..f90f8c05ee 100644 --- a/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java +++ b/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java @@ -1,11 +1,11 @@ package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.costs.Cost; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.common.RevealTargetFromHandCost; import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect; import mage.abilities.effects.ContinuousRuleModifyingEffect; @@ -25,24 +25,20 @@ import mage.game.stack.Spell; import mage.players.Player; import mage.target.common.TargetCardInHand; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class DragonlordsPrerogative extends CardImpl { - private static final FilterCard filter = new FilterCard("a Dragon card from your hand"); - - static { - filter.add(new SubtypePredicate(SubType.DRAGON)); - } - public DragonlordsPrerogative(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{U}{U}"); // As an additional cost to cast Dragonlord's Prerogative, you may reveal a Dragon card from your hand. this.getSpellAbility().addEffect(new InfoEffect("as an additional cost to cast this spell, you may reveal a Dragon card from your hand")); - + this.getSpellAbility().setCostAdjuster(DragonlordsPrerogativeAdjuster.instance); + // If you revealed a Dragon card or controlled a Dragon as you cast Dragonlord's Prerogative, Dragonlord's Prerogative can't be countered. Condition condition = new DragonlordsPrerogativeCondition(); ContinuousRuleModifyingEffect cantBeCountered = new CantBeCounteredSourceEffect(); @@ -50,22 +46,12 @@ public final class DragonlordsPrerogative extends CardImpl { conditionalCantBeCountered.setText("
If you revealed a Dragon card or controlled a Dragon as you cast {this}, this spell can't be countered"); Ability ability = new SimpleStaticAbility(Zone.STACK, conditionalCantBeCountered); this.addAbility(ability); - + // Draw four cards. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(4)); } - - @Override - public void adjustCosts(Ability ability, Game game) { - Player controller = game.getPlayer(ability.getControllerId()); - if (controller != null) { - if (controller.getHand().count(filter, game) > 0) { - ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0,1, filter))); - } - } - } - + public DragonlordsPrerogative(final DragonlordsPrerogative card) { super(card); } @@ -76,6 +62,25 @@ public final class DragonlordsPrerogative extends CardImpl { } } +enum DragonlordsPrerogativeAdjuster implements CostAdjuster { + instance; + private static final FilterCard filter = new FilterCard("a Dragon card from your hand"); + + static { + filter.add(new SubtypePredicate(SubType.DRAGON)); + } + + @Override + public void adjustCosts(Ability ability, Game game) { + Player controller = game.getPlayer(ability.getControllerId()); + if (controller != null) { + if (controller.getHand().count(filter, game) > 0) { + ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, 1, filter))); + } + } + } +} + class DragonlordsPrerogativeCondition implements Condition { private final static FilterControlledPermanent filter = new FilterControlledPermanent("Dragon"); @@ -89,7 +94,7 @@ class DragonlordsPrerogativeCondition implements Condition { boolean applies = false; Spell spell = game.getStack().getSpell(source.getSourceId()); if (spell != null && spell.getSpellAbility() != null) { - for(Cost cost: spell.getSpellAbility().getCosts()) { + for (Cost cost : spell.getSpellAbility().getCosts()) { if (cost instanceof RevealTargetFromHandCost) { applies = !cost.getTargets().isEmpty(); break; diff --git a/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java b/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java index a819a8abf7..082731e051 100644 --- a/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java +++ b/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java @@ -1,10 +1,7 @@ - package mage.cards.d; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; @@ -16,39 +13,25 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class DregsOfSorrow extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creatures"); - - static { - filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); - } - public DregsOfSorrow(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{4}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{4}{B}"); // Destroy X target nonblack creatures. Draw X cards. this.getSpellAbility().addEffect(new DestroyTargetEffect("Destroy X target nonblack creatures")); this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(new ManacostVariableValue())); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + this.getSpellAbility().setTargetAdjuster(DregsOfSorrowAdjuster.instance); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - ability.addTarget(new TargetCreaturePermanent(xValue, xValue, filter, false)); - } - } - - public DregsOfSorrow(final DregsOfSorrow card) { super(card); } @@ -58,3 +41,19 @@ public final class DregsOfSorrow extends CardImpl { return new DregsOfSorrow(this); } } + +enum DregsOfSorrowAdjuster implements TargetAdjuster { + instance; + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creatures"); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + ability.addTarget(new TargetCreaturePermanent(xValue, xValue, filter, false)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DwarvenLandslide.java b/Mage.Sets/src/mage/cards/d/DwarvenLandslide.java index 1b7f92f62a..056980f895 100644 --- a/Mage.Sets/src/mage/cards/d/DwarvenLandslide.java +++ b/Mage.Sets/src/mage/cards/d/DwarvenLandslide.java @@ -1,9 +1,7 @@ - package mage.cards.d; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.common.KickedCondition; import mage.abilities.costs.Cost; import mage.abilities.costs.Costs; @@ -19,6 +17,7 @@ import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetLandPermanent; +import mage.target.targetadjustment.TargetAdjuster; /** * @@ -27,34 +26,38 @@ import mage.target.common.TargetLandPermanent; public final class DwarvenLandslide extends CardImpl { public DwarvenLandslide(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}"); // Kicker-{2}{R}, Sacrifice a land. Costs kickerCosts = new CostsImpl<>(); kickerCosts.add(new ManaCostsImpl<>("{2}{R}")); kickerCosts.add(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); this.addAbility(new KickerAbility(kickerCosts)); + // Destroy target land. If Dwarven Landslide was kicked, destroy another target land. getSpellAbility().addEffect(new DestroyTargetEffect("Destroy target land. if this spell was kicked, destroy another target land")); getSpellAbility().addTarget(new TargetLandPermanent()); + getSpellAbility().setTargetAdjuster(DwarvenLandslideAdjuster.instance); } public DwarvenLandslide(final DwarvenLandslide card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - if (KickedCondition.instance.apply(game, ability)) { - ability.getTargets().clear(); - getSpellAbility().addTarget(new TargetLandPermanent(2)); - } - } - } - @Override public DwarvenLandslide copy() { return new DwarvenLandslide(this); } } + +enum DwarvenLandslideAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + if (KickedCondition.instance.apply(game, ability)) { + ability.getTargets().clear(); + ability.addTarget(new TargetLandPermanent(2)); + } + } +} diff --git a/Mage.Sets/src/mage/cards/e/EarthshakerKhenra.java b/Mage.Sets/src/mage/cards/e/EarthshakerKhenra.java index 0d399a8ab4..d00de4b0c0 100644 --- a/Mage.Sets/src/mage/cards/e/EarthshakerKhenra.java +++ b/Mage.Sets/src/mage/cards/e/EarthshakerKhenra.java @@ -1,38 +1,38 @@ package mage.cards.e; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.combat.CantBlockTargetEffect; import mage.abilities.keyword.EternalizeAbility; import mage.abilities.keyword.HasteAbility; +import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.ComparisonType; import mage.constants.Duration; -import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.mageobject.PowerPredicate; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; /** - * * @author jeffwadsworth */ public final class EarthshakerKhenra extends CardImpl { - private final UUID originalId; - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power less than or equal to {this}'s power"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power less than or equal to this creature's power"); + + static { + filter.add(EarthshakerKhenraPredicate.instance); + } public EarthshakerKhenra(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); @@ -46,32 +46,20 @@ public final class EarthshakerKhenra extends CardImpl { this.addAbility(HasteAbility.getInstance()); // When Earthshaker Khenra enters the battlefield, target creature with power less than or equal to Earthshaker Khenra's power can't block this turn. - Ability ability = new EntersBattlefieldTriggeredAbility(new EarthshakerKhenraEffect()); + Ability ability = new EntersBattlefieldTriggeredAbility( + new CantBlockTargetEffect(Duration.EndOfTurn) + .setText("target creature with power less than or equal " + + "to {this}'s power can't block this turn") + ); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); - originalId = ability.getOriginalId(); // Eternalize {4}{R}{R} this.addAbility(new EternalizeAbility(new ManaCostsImpl("{4}{R}{R}"), this)); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - Permanent sourcePermanent = game.getPermanent(ability.getSourceId()); - if (sourcePermanent != null) { - FilterCreaturePermanent targetFilter = new FilterCreaturePermanent("creature with power less than or equal to " + getLogName() + "'s power"); - targetFilter.add(new PowerPredicate(ComparisonType.FEWER_THAN, sourcePermanent.getPower().getValue() + 1)); - ability.getTargets().clear(); - ability.getTargets().add(new TargetCreaturePermanent(targetFilter)); - } - } } public EarthshakerKhenra(final EarthshakerKhenra card) { super(card); - this.originalId = card.originalId; } @Override @@ -80,39 +68,12 @@ public final class EarthshakerKhenra extends CardImpl { } } -class EarthshakerKhenraEffect extends OneShotEffect { - - public EarthshakerKhenraEffect() { - super(Outcome.UnboostCreature); - this.staticText = "target creature with power less than or equal to {this}'s power can't block this turn"; - } - - public EarthshakerKhenraEffect(final EarthshakerKhenraEffect effect) { - super(effect); - } +enum EarthshakerKhenraPredicate implements ObjectSourcePlayerPredicate> { + instance; @Override - public EarthshakerKhenraEffect copy() { - return new EarthshakerKhenraEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent sourceObject = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (sourceObject != null) { - Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); - /* - 27.06.2017 The target creature's power is checked when you target it with Earthshaker Khenra's ability - and when that ability resolves. Once the ability resolves, if the creature's power increases - or Earthshaker Khenra's power decreases, the target creature will still be unable to block. - */ - if (targetCreature != null && targetCreature.getPower().getValue() <= sourceObject.getPower().getValue()) { - ContinuousEffect effect = new CantBlockTargetEffect(Duration.EndOfTurn); - effect.setTargetPointer(new FixedTarget(targetCreature, game)); - game.addEffect(effect, source); - } - return true; - } - return false; + public boolean apply(ObjectSourcePlayer input, Game game) { + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(input.getSourceId()); + return sourcePermanent != null && input.getObject().getPower().getValue() <= sourcePermanent.getPower().getValue(); } } diff --git a/Mage.Sets/src/mage/cards/e/EliminateTheCompetition.java b/Mage.Sets/src/mage/cards/e/EliminateTheCompetition.java index 9b6b3c855a..03ad3ea31b 100644 --- a/Mage.Sets/src/mage/cards/e/EliminateTheCompetition.java +++ b/Mage.Sets/src/mage/cards/e/EliminateTheCompetition.java @@ -1,4 +1,3 @@ - package mage.cards.e; import java.util.UUID; @@ -9,11 +8,11 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AbilityType; import mage.constants.CardType; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; /** * @@ -22,7 +21,7 @@ import mage.target.common.TargetCreaturePermanent; public final class EliminateTheCompetition extends CardImpl { public EliminateTheCompetition(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}"); // As an additional cost to cast Eliminate the Competition, sacrifice X creatures. this.getSpellAbility().addCost(new SacrificeXTargetCost(new FilterControlledCreaturePermanent("creatures"), true)); @@ -32,23 +31,26 @@ public final class EliminateTheCompetition extends CardImpl { effect.setText("Destroy X target creatures"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(EliminateTheCompetitionAdjuster.instance); } public EliminateTheCompetition(final EliminateTheCompetition card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getAbilityType() == AbilityType.SPELL) { - ability.getTargets().clear(); - int sac = new GetXValue().calculate(game, ability, null); - ability.addTarget(new TargetCreaturePermanent(sac, sac)); - } - } - @Override public EliminateTheCompetition copy() { return new EliminateTheCompetition(this); } } + +enum EliminateTheCompetitionAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int sac = new GetXValue().calculate(game, ability, null); + ability.addTarget(new TargetCreaturePermanent(sac, sac)); + } +} diff --git a/Mage.Sets/src/mage/cards/e/EliteArcanist.java b/Mage.Sets/src/mage/cards/e/EliteArcanist.java index b44d6aef39..9ca13d7fa5 100644 --- a/Mage.Sets/src/mage/cards/e/EliteArcanist.java +++ b/Mage.Sets/src/mage/cards/e/EliteArcanist.java @@ -1,12 +1,12 @@ package mage.cards.e; -import java.util.UUID; import mage.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; @@ -25,8 +25,9 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetCard; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class EliteArcanist extends CardImpl { @@ -45,6 +46,7 @@ public final class EliteArcanist extends CardImpl { // {X}, {T}: Copy the exiled card. You may cast the copy without paying its mana cost. X is the converted mana cost of the exiled card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new EliteArcanistCopyEffect(), new ManaCostsImpl("{X}")); ability.addCost(new TapSourceCost()); + ability.setCostAdjuster(EliteArcanistAdjuster.instance); this.addAbility(ability); } @@ -52,29 +54,35 @@ public final class EliteArcanist extends CardImpl { super(card); } - @Override - public void adjustCosts(Ability ability, Game game) { - if (ability instanceof SimpleActivatedAbility) { - Permanent sourcePermanent = game.getPermanent(ability.getSourceId()); - if (sourcePermanent != null && sourcePermanent.getImprinted() != null && !sourcePermanent.getImprinted().isEmpty()) { - Card imprintedInstant = game.getCard(sourcePermanent.getImprinted().get(0)); - if (imprintedInstant != null) { - int cmc = imprintedInstant.getConvertedManaCost(); - if (cmc > 0) { - ability.getManaCostsToPay().clear(); - ability.getManaCostsToPay().add(new GenericManaCost(cmc)); - } - } - } - } - } - @Override public EliteArcanist copy() { return new EliteArcanist(this); } } +enum EliteArcanistAdjuster implements CostAdjuster { + instance; + + @Override + public void adjustCosts(Ability ability, Game game) { + Permanent sourcePermanent = game.getPermanent(ability.getSourceId()); + if (sourcePermanent == null + || sourcePermanent.getImprinted() == null + || sourcePermanent.getImprinted().isEmpty()) { + return; + } + Card imprintedInstant = game.getCard(sourcePermanent.getImprinted().get(0)); + if (imprintedInstant == null) { + return; + } + int cmc = imprintedInstant.getConvertedManaCost(); + if (cmc > 0) { + ability.getManaCostsToPay().clear(); + ability.getManaCostsToPay().add(new GenericManaCost(cmc)); + } + } +} + class EliteArcanistImprintEffect extends OneShotEffect { private static final FilterCard filter = new FilterCard("instant card from your hand"); diff --git a/Mage.Sets/src/mage/cards/e/EliteScaleguard.java b/Mage.Sets/src/mage/cards/e/EliteScaleguard.java index 332e040f55..1e52cb5160 100644 --- a/Mage.Sets/src/mage/cards/e/EliteScaleguard.java +++ b/Mage.Sets/src/mage/cards/e/EliteScaleguard.java @@ -1,12 +1,10 @@ package mage.cards.e; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.effects.keyword.BolsterEffect; import mage.cards.CardImpl; @@ -16,25 +14,29 @@ import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.filter.predicate.permanent.CounterPredicate; +import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author emerald000 */ public final class EliteScaleguard extends CardImpl { - + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature you control with a +1/+1 counter on it"); + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creature defending player controls"); + static { filter.add(new CounterPredicate(CounterType.P1P1)); + filter2.add(new DefendingPlayerControlsPredicate()); } public EliteScaleguard(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); this.power = new MageInt(2); @@ -42,32 +44,16 @@ public final class EliteScaleguard extends CardImpl { // When Elite Scaleguard enters the battlefield, bolster 2. this.addAbility(new EntersBattlefieldTriggeredAbility(new BolsterEffect(2))); - + // Whenever a creature you control with a +1/+1 counter on it attacks, tap target creature defending player controls. Ability ability = new AttacksCreatureYouControlTriggeredAbility(new EliteScaleguardTapEffect(), false, filter, true); - ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls"))); + ability.addTarget(new TargetCreaturePermanent(filter2)); this.addAbility(ability); } public EliteScaleguard(final EliteScaleguard card) { super(card); } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof AttacksCreatureYouControlTriggeredAbility) { - FilterCreaturePermanent filterDefender = new FilterCreaturePermanent("creature defending player controls"); - for (Effect effect : ability.getEffects()) { - if (effect instanceof EliteScaleguardTapEffect) { - filterDefender.add(new ControllerIdPredicate(game.getCombat().getDefendingPlayerId(effect.getTargetPointer().getFirst(game, ability), game))); - break; - } - } - ability.getTargets().clear(); - TargetCreaturePermanent target = new TargetCreaturePermanent(filterDefender); - ability.addTarget(target); - } - } @Override public EliteScaleguard copy() { @@ -76,20 +62,20 @@ public final class EliteScaleguard extends CardImpl { } class EliteScaleguardTapEffect extends TapTargetEffect { - + EliteScaleguardTapEffect() { super(); } - + EliteScaleguardTapEffect(final EliteScaleguardTapEffect effect) { super(effect); } - + @Override public EliteScaleguardTapEffect copy() { return new EliteScaleguardTapEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getFirstTarget()); diff --git a/Mage.Sets/src/mage/cards/e/EntrancingMelody.java b/Mage.Sets/src/mage/cards/e/EntrancingMelody.java index 4c14d0ee0c..5fb6288498 100644 --- a/Mage.Sets/src/mage/cards/e/EntrancingMelody.java +++ b/Mage.Sets/src/mage/cards/e/EntrancingMelody.java @@ -1,9 +1,7 @@ package mage.cards.e; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -14,38 +12,45 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class EntrancingMelody extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost X"); + public EntrancingMelody(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}{U}"); // Gain control of target creature with converted mana cost X. this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.Custom, true)); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature with converted mana cost X"))); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + this.getSpellAbility().setTargetAdjuster(EntrancingMelodyAdjuster.instance); } public EntrancingMelody(final EntrancingMelody card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost X"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); - ability.addTarget(new TargetCreaturePermanent(filter)); - } - } - @Override public EntrancingMelody copy() { return new EntrancingMelody(this); } } + +enum EntrancingMelodyAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost " + xValue); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); + ability.addTarget(new TargetCreaturePermanent(filter)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/e/EntreatTheDead.java b/Mage.Sets/src/mage/cards/e/EntreatTheDead.java index 86d76b7b4a..58b597c89f 100644 --- a/Mage.Sets/src/mage/cards/e/EntreatTheDead.java +++ b/Mage.Sets/src/mage/cards/e/EntreatTheDead.java @@ -2,7 +2,6 @@ package mage.cards.e; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.keyword.MiracleAbility; @@ -14,6 +13,7 @@ import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.target.Target; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; /** * @@ -27,25 +27,10 @@ public final class EntreatTheDead extends CardImpl { // Return X target creature cards from your graveyard to the battlefield. this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(1, StaticFilters.FILTER_CARD_CREATURE)); + this.getSpellAbility().setTargetAdjuster(EntreatTheDeadAdjuster.instance); // Miracle {X}{B}{B} this.addAbility(new MiracleAbility(this, new ManaCostsImpl("{X}{B}{B}"))); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - String filterName = xValue - + (xValue != 1 ? " creature cards" : "creature card") - + " from your graveyard"; - Target target = new TargetCardInYourGraveyard( - xValue, new FilterCreatureCard(filterName) - ); - ability.addTarget(target); - } } public EntreatTheDead(final EntreatTheDead card) { @@ -57,3 +42,20 @@ public final class EntreatTheDead extends CardImpl { return new EntreatTheDead(this); } } + +enum EntreatTheDeadAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + String filterName = xValue + + (xValue != 1 ? " creature cards" : "creature card") + + " from your graveyard"; + Target target = new TargetCardInYourGraveyard( + xValue, new FilterCreatureCard(filterName) + ); + ability.addTarget(target); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FallingTimber.java b/Mage.Sets/src/mage/cards/f/FallingTimber.java index 90a39c7614..492c7e6f34 100644 --- a/Mage.Sets/src/mage/cards/f/FallingTimber.java +++ b/Mage.Sets/src/mage/cards/f/FallingTimber.java @@ -1,4 +1,3 @@ - package mage.cards.f; import java.util.UUID; @@ -16,38 +15,30 @@ import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; /** * * @author LoneFox - + * */ public final class FallingTimber extends CardImpl { - private final UUID originalId; - public FallingTimber(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); // Kicker-Sacrifice a land. this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, new FilterControlledLandPermanent("a land"), true)))); + // Prevent all combat damage target creature would deal this turn. If Falling Timber was kicked, prevent all combat damage another target creature would deal this turn. Effect effect = new PreventDamageByTargetEffect(Duration.EndOfTurn, true); effect.setText("Prevent all combat damage target creature would deal this turn. if this spell was kicked, prevent all combat damage another target creature would deal this turn."); this.getSpellAbility().addEffect(effect); - originalId = this.getSpellAbility().getOriginalId(); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if(ability.getOriginalId().equals(originalId)) { - ability.addTarget(new TargetCreaturePermanent(KickedCondition.instance.apply(game, ability) ? 2 : 1)); - } + this.getSpellAbility().setTargetAdjuster(FallingTimberAdjuster.instance); } public FallingTimber(final FallingTimber card) { super(card); - this.originalId = card.originalId; } @Override @@ -55,3 +46,13 @@ public final class FallingTimber extends CardImpl { return new FallingTimber(this); } } + +enum FallingTimberAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(KickedCondition.instance.apply(game, ability) ? 2 : 1)); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FightWithFire.java b/Mage.Sets/src/mage/cards/f/FightWithFire.java index ebad07ad96..67b7b683a8 100644 --- a/Mage.Sets/src/mage/cards/f/FightWithFire.java +++ b/Mage.Sets/src/mage/cards/f/FightWithFire.java @@ -1,9 +1,7 @@ - package mage.cards.f; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.common.KickedCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.DamageMultiEffect; @@ -16,6 +14,7 @@ import mage.game.Game; import mage.target.common.TargetAnyTarget; import mage.target.common.TargetAnyTargetAmount; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; /** * @@ -39,26 +38,29 @@ public final class FightWithFire extends CardImpl { + " (Those targets can include players and planeswalkers.)" )); this.getSpellAbility().addTarget(new TargetAnyTarget()); + this.getSpellAbility().setTargetAdjuster(FightWithFireAdjuster.instance); } public FightWithFire(final FightWithFire card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - ability.getTargets().clear(); - if (ability instanceof SpellAbility) { - if (KickedCondition.instance.apply(game, ability)) { - ability.addTarget(new TargetAnyTargetAmount(10)); - } else { - ability.addTarget(new TargetCreaturePermanent()); - } - } - } - @Override public FightWithFire copy() { return new FightWithFire(this); } } + +enum FightWithFireAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + if (KickedCondition.instance.apply(game, ability)) { + ability.addTarget(new TargetAnyTargetAmount(10)); + } else { + ability.addTarget(new TargetCreaturePermanent()); + } + } +} diff --git a/Mage.Sets/src/mage/cards/f/Fireball.java b/Mage.Sets/src/mage/cards/f/Fireball.java index df0543c9c6..7e56cf8017 100644 --- a/Mage.Sets/src/mage/cards/f/Fireball.java +++ b/Mage.Sets/src/mage/cards/f/Fireball.java @@ -1,8 +1,8 @@ package mage.cards.f; -import java.util.*; import mage.abilities.Ability; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; @@ -14,8 +14,9 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetAnyTarget; +import java.util.*; + /** - * * @author BetaSteward_at_googlemail.com */ public final class Fireball extends CardImpl { @@ -27,14 +28,7 @@ public final class Fireball extends CardImpl { // Fireball costs 1 more to cast for each target beyond the first. this.getSpellAbility().addTarget(new FireballTargetCreatureOrPlayer(0, Integer.MAX_VALUE)); this.getSpellAbility().addEffect(new FireballEffect()); - } - - @Override - public void adjustCosts(Ability ability, Game game) { - int numTargets = ability.getTargets().isEmpty() ? 0 : ability.getTargets().get(0).getTargets().size(); - if (numTargets > 1) { - ability.getManaCostsToPay().add(new GenericManaCost(numTargets - 1)); - } + this.getSpellAbility().setCostAdjuster(FireballAdjuster.instance); } public Fireball(final Fireball card) { @@ -47,6 +41,18 @@ public final class Fireball extends CardImpl { } } +enum FireballAdjuster implements CostAdjuster { + instance; + + @Override + public void adjustCosts(Ability ability, Game game) { + int numTargets = ability.getTargets().isEmpty() ? 0 : ability.getTargets().get(0).getTargets().size(); + if (numTargets > 1) { + ability.getManaCostsToPay().add(new GenericManaCost(numTargets - 1)); + } + } +} + class FireballEffect extends OneShotEffect { public FireballEffect() { diff --git a/Mage.Sets/src/mage/cards/f/Firestorm.java b/Mage.Sets/src/mage/cards/f/Firestorm.java index 584afbec57..ba503d3790 100644 --- a/Mage.Sets/src/mage/cards/f/Firestorm.java +++ b/Mage.Sets/src/mage/cards/f/Firestorm.java @@ -1,4 +1,3 @@ - package mage.cards.f; import java.util.UUID; @@ -16,6 +15,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetAnyTarget; +import mage.target.targetadjustment.TargetAdjuster; /** * @@ -24,19 +24,28 @@ import mage.target.common.TargetAnyTarget; public final class Firestorm extends CardImpl { public Firestorm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); // As an additional cost to cast Firestorm, discard X cards. this.getSpellAbility().addCost(new DiscardXTargetCost(new FilterCard("cards"), true)); // Firestorm deals X damage to each of X target creatures and/or players. this.getSpellAbility().addEffect(new FirestormEffect()); + this.getSpellAbility().setTargetAdjuster(FirestormAdjuster.instance); } public Firestorm(final Firestorm card) { super(card); } + @Override + public Firestorm copy() { + return new Firestorm(this); + } +} + +enum FirestormAdjuster implements TargetAdjuster { + instance; + @Override public void adjustTargets(Ability ability, Game game) { int xValue = new GetXValue().calculate(game, ability, null); @@ -45,11 +54,6 @@ public final class Firestorm extends CardImpl { ability.addTarget(target); } } - - @Override - public Firestorm copy() { - return new Firestorm(this); - } } class FirestormEffect extends OneShotEffect { @@ -85,9 +89,6 @@ class FirestormEffect extends OneShotEffect { } return false; } - - - @Override public FirestormEffect copy() { diff --git a/Mage.Sets/src/mage/cards/f/FoulTongueInvocation.java b/Mage.Sets/src/mage/cards/f/FoulTongueInvocation.java index e2069077fd..cb2a1d7d70 100644 --- a/Mage.Sets/src/mage/cards/f/FoulTongueInvocation.java +++ b/Mage.Sets/src/mage/cards/f/FoulTongueInvocation.java @@ -1,15 +1,14 @@ package mage.cards.f; -import java.util.UUID; import mage.abilities.Ability; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.common.RevealTargetFromHandCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.SacrificeEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AbilityType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -22,23 +21,19 @@ import mage.target.TargetPlayer; import mage.target.common.TargetCardInHand; import mage.watchers.common.DragonOnTheBattlefieldWhileSpellWasCastWatcher; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class FoulTongueInvocation extends CardImpl { - private static final FilterCard filter = new FilterCard("a Dragon card from your hand (you don't have to)"); - - static { - filter.add(new SubtypePredicate(SubType.DRAGON)); - } - public FoulTongueInvocation(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}"); // As an additional cost to cast Foul-Tongue Invocation, you may reveal a Dragon card from your hand. this.getSpellAbility().addEffect(new InfoEffect("as an additional cost to cast this spell, you may reveal a Dragon card from your hand")); + this.getSpellAbility().setCostAdjuster(FoulTongueInvocationAdjuster.instance); // Target player sacrifices a creature. If you revealed a Dragon card or controlled a Dragon as you cast Foul-Tongue Invocation, you gain 4 life. this.getSpellAbility().addTarget(new TargetPlayer()); @@ -47,18 +42,6 @@ public final class FoulTongueInvocation extends CardImpl { this.getSpellAbility().addWatcher(new DragonOnTheBattlefieldWhileSpellWasCastWatcher()); } - @Override - public void adjustCosts(Ability ability, Game game) { - if (ability.getAbilityType() == AbilityType.SPELL) { - Player controller = game.getPlayer(ability.getControllerId()); - if (controller != null) { - if (controller.getHand().count(filter, game) > 0) { - ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, 1, filter))); - } - } - } - } - public FoulTongueInvocation(final FoulTongueInvocation card) { super(card); } @@ -69,6 +52,25 @@ public final class FoulTongueInvocation extends CardImpl { } } +enum FoulTongueInvocationAdjuster implements CostAdjuster { + instance; + private static final FilterCard filter = new FilterCard("a Dragon card from your hand (you don't have to)"); + + static { + filter.add(new SubtypePredicate(SubType.DRAGON)); + } + + @Override + public void adjustCosts(Ability ability, Game game) { + Player controller = game.getPlayer(ability.getControllerId()); + if (controller != null) { + if (controller.getHand().count(filter, game) > 0) { + ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, 1, filter))); + } + } + } +} + class FoulTongueInvocationEffect extends OneShotEffect { public FoulTongueInvocationEffect() { diff --git a/Mage.Sets/src/mage/cards/g/GangUp.java b/Mage.Sets/src/mage/cards/g/GangUp.java index 7c68d54158..a49f70ff1d 100644 --- a/Mage.Sets/src/mage/cards/g/GangUp.java +++ b/Mage.Sets/src/mage/cards/g/GangUp.java @@ -1,9 +1,7 @@ package mage.cards.g; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.AssistAbility; import mage.cards.CardImpl; @@ -14,9 +12,11 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.PowerPredicate; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class GangUp extends CardImpl { @@ -28,27 +28,29 @@ public final class GangUp extends CardImpl { this.addAbility(new AssistAbility()); // Destroy target creature with power X or less. - this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature with power X or less"))); + this.getSpellAbility().addEffect(new DestroyTargetEffect("destroy target creature with power X or less")); + this.getSpellAbility().setTargetAdjuster(GangUpAdjuster.instance); } public GangUp(final GangUp card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - int xValue = ability.getManaCostsToPay().getX(); - ability.getTargets().clear(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power " + xValue + " or less"); - filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, xValue + 1)); - ability.addTarget(new TargetCreaturePermanent(filter)); - } - } - @Override public GangUp copy() { return new GangUp(this); } } + +enum GangUpAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + int xValue = ability.getManaCostsToPay().getX(); + ability.getTargets().clear(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power " + xValue + " or less"); + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, xValue + 1)); + ability.addTarget(new TargetCreaturePermanent(filter)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GlimpseTheSunGod.java b/Mage.Sets/src/mage/cards/g/GlimpseTheSunGod.java index 4ab2832a67..f0c457aa4f 100644 --- a/Mage.Sets/src/mage/cards/g/GlimpseTheSunGod.java +++ b/Mage.Sets/src/mage/cards/g/GlimpseTheSunGod.java @@ -1,20 +1,21 @@ package mage.cards.g; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; + +import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES; /** - * * @author LevelX2 */ public final class GlimpseTheSunGod extends CardImpl { @@ -24,26 +25,27 @@ public final class GlimpseTheSunGod extends CardImpl { // Tap X target creatures. Scry 1. this.getSpellAbility().addEffect(new TapTargetEffect("X target creatures")); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1, FILTER_PERMANENT_CREATURES, false)); this.getSpellAbility().addEffect(new ScryEffect(1)); + this.getSpellAbility().setTargetAdjuster(GlimpseTheSunGodAdjuster.instance); } public GlimpseTheSunGod(final GlimpseTheSunGod card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int numberToTap = ability.getManaCostsToPay().getX(); - numberToTap = Math.min(game.getBattlefield().count(FILTER_PERMANENT_CREATURES, ability.getSourceId(), ability.getControllerId(), game), numberToTap); - ability.addTarget(new TargetCreaturePermanent(numberToTap, numberToTap, FILTER_PERMANENT_CREATURES, false)); - } - } - @Override public GlimpseTheSunGod copy() { return new GlimpseTheSunGod(this); } } + +enum GlimpseTheSunGodAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int numberToTap = ability.getManaCostsToPay().getX(); + ability.addTarget(new TargetCreaturePermanent(numberToTap, numberToTap, FILTER_PERMANENT_CREATURES, false)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GoblinBarrage.java b/Mage.Sets/src/mage/cards/g/GoblinBarrage.java index cfc82c9248..57f2fef6e7 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinBarrage.java +++ b/Mage.Sets/src/mage/cards/g/GoblinBarrage.java @@ -1,7 +1,6 @@ package mage.cards.g; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.condition.common.KickedCondition; import mage.abilities.costs.common.SacrificeTargetCost; @@ -19,19 +18,28 @@ import mage.game.Game; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetPlayerOrPlaneswalker; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class GoblinBarrage extends CardImpl { + private static final FilterControlledPermanent filter = new FilterControlledPermanent("an artifact or Goblin"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new SubtypePredicate(SubType.GOBLIN) + )); + } + public GoblinBarrage(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}"); // Kicker—Sacrifice an artifact or Goblin. - FilterControlledPermanent filter = new FilterControlledPermanent("an artifact or Goblin"); - filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new SubtypePredicate(SubType.GOBLIN))); this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(filter)))); // Goblin Barrage deals 4 damage to target creature. If this spell was kicked, it also deals 4 damage to target player or planeswalker. @@ -40,13 +48,7 @@ public final class GoblinBarrage extends CardImpl { + "it also deals 4 damage to target player or planeswalker") ); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (KickedCondition.instance.apply(game, ability)) { - ability.addTarget(new TargetPlayerOrPlaneswalker()); - } + this.getSpellAbility().setTargetAdjuster(GoblinBarrageAdjuster.instance); } public GoblinBarrage(final GoblinBarrage card) { @@ -58,3 +60,14 @@ public final class GoblinBarrage extends CardImpl { return new GoblinBarrage(this); } } + +enum GoblinBarrageAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + if (KickedCondition.instance.apply(game, ability)) { + ability.addTarget(new TargetPlayerOrPlaneswalker()); + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GoblinRacketeer.java b/Mage.Sets/src/mage/cards/g/GoblinRacketeer.java index a4c3c44b11..80e0d2b5b3 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinRacketeer.java +++ b/Mage.Sets/src/mage/cards/g/GoblinRacketeer.java @@ -1,8 +1,6 @@ package mage.cards.g; -import java.util.UUID; - import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; @@ -12,16 +10,21 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; +import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * @author TheElk801 */ public final class GoblinRacketeer extends CardImpl { - private final UUID originalId; + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); + + static { + filter.add(new DefendingPlayerControlsPredicate()); + } public GoblinRacketeer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); @@ -33,27 +36,12 @@ public final class GoblinRacketeer extends CardImpl { // Whenever Goblin Racketeer attacks, you may goad target creature defending player controls. Ability ability = new AttacksTriggeredAbility(new GoadTargetEffect(), true, "Whenever {this} attacks, you may goad target creature defending player controls"); - ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls"))); - originalId = ability.getOriginalId(); + ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } public GoblinRacketeer(final GoblinRacketeer card) { super(card); - this.originalId = card.originalId; - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - ability.getTargets().clear(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); - UUID defenderId = game.getCombat().getDefenderId(ability.getSourceId()); - filter.add(new ControllerIdPredicate(defenderId)); - TargetCreaturePermanent target = new TargetCreaturePermanent(filter); - ability.addTarget(target); - } } @Override diff --git a/Mage.Sets/src/mage/cards/g/GraspOfFate.java b/Mage.Sets/src/mage/cards/g/GraspOfFate.java index 271b67e730..3fbb816904 100644 --- a/Mage.Sets/src/mage/cards/g/GraspOfFate.java +++ b/Mage.Sets/src/mage/cards/g/GraspOfFate.java @@ -1,7 +1,6 @@ package mage.cards.g; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; @@ -23,10 +22,12 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.util.CardUtil; +import java.util.UUID; + /** - * * @author fireshoes */ public final class GraspOfFate extends CardImpl { @@ -36,8 +37,8 @@ public final class GraspOfFate extends CardImpl { // When Grasp of Fate enters the battlefield, for each opponent, exile up to one target nonland permanent that player controls until Grasp of Fate leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new GraspOfFateExileEffect()); - ability.addTarget(new TargetPermanent()); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); + ability.setTargetAdjuster(GraspOfFateAdjuster.instance); this.addAbility(ability); } @@ -45,29 +46,32 @@ public final class GraspOfFate extends CardImpl { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof EntersBattlefieldTriggeredAbility) { - ability.getTargets().clear(); - for (UUID opponentId : game.getOpponents(ability.getControllerId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - FilterPermanent filter = new FilterPermanent("nonland permanent from opponent " + opponent.getLogName()); - filter.add(new ControllerIdPredicate(opponentId)); - filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); - TargetPermanent target = new TargetPermanent(0, 1, filter, false); - ability.addTarget(target); - } - } - } - } - @Override public GraspOfFate copy() { return new GraspOfFate(this); } } +enum GraspOfFateAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + for (UUID opponentId : game.getOpponents(ability.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent == null) { + continue; + } + FilterPermanent filter = new FilterPermanent("nonland permanent from opponent " + opponent.getLogName()); + filter.add(new ControllerIdPredicate(opponentId)); + filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); + TargetPermanent target = new TargetPermanent(0, 1, filter, false); + ability.addTarget(target); + } + } +} + class GraspOfFateExileEffect extends OneShotEffect { public GraspOfFateExileEffect() { diff --git a/Mage.Sets/src/mage/cards/g/GravenAbomination.java b/Mage.Sets/src/mage/cards/g/GravenAbomination.java index c48c21d123..18f6730471 100644 --- a/Mage.Sets/src/mage/cards/g/GravenAbomination.java +++ b/Mage.Sets/src/mage/cards/g/GravenAbomination.java @@ -1,7 +1,6 @@ package mage.cards.g; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; @@ -11,20 +10,22 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.FilterCard; -import mage.filter.predicate.other.OwnerIdPredicate; -import mage.game.Game; -import mage.players.Player; +import mage.filter.predicate.permanent.DefendingPlayerOwnsCardPredicate; import mage.target.common.TargetCardInGraveyard; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class GravenAbomination extends CardImpl { - private final UUID originalId; + private static final String rule = "Whenever {this} attacks, exile target card from defending player's graveyard."; + private static final FilterCard filter = new FilterCard("card from defending player's graveyard"); - private final static String rule = "Whenever {this} attacks, exile target card from defending player's graveyard."; + static { + filter.add(new DefendingPlayerOwnsCardPredicate()); + } public GravenAbomination(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); @@ -35,30 +36,12 @@ public final class GravenAbomination extends CardImpl { // Whenever Graven Abomination attacks, exile target card from defending player's graveyard. Ability ability = new AttacksTriggeredAbility(new ExileTargetEffect(), false, rule); - ability.addTarget(new TargetCardInGraveyard()); + ability.addTarget(new TargetCardInGraveyard(filter)); this.addAbility(ability); - originalId = ability.getOriginalId(); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - UUID gravenAbominationId = ability.getSourceId(); - FilterCard filter = new FilterCard("target card from defending player's graveyard"); - if (ability.getOriginalId().equals(originalId)) { - UUID defendingPlayerId = game.getCombat().getDefendingPlayerId(gravenAbominationId, game); - Player defendingPlayer = game.getPlayer(defendingPlayerId); - if (defendingPlayer != null) { - filter.add(new OwnerIdPredicate(defendingPlayerId)); - ability.getTargets().clear(); - ability.getTargets().add(new TargetCardInGraveyard(filter)); - } - } } public GravenAbomination(final GravenAbomination card) { super(card); - this.originalId = card.originalId; } @Override diff --git a/Mage.Sets/src/mage/cards/g/Gridlock.java b/Mage.Sets/src/mage/cards/g/Gridlock.java index a94c6e7848..23c6be94f6 100644 --- a/Mage.Sets/src/mage/cards/g/Gridlock.java +++ b/Mage.Sets/src/mage/cards/g/Gridlock.java @@ -1,9 +1,7 @@ package mage.cards.g; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.TapTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -11,41 +9,40 @@ import mage.constants.CardType; import mage.filter.common.FilterNonlandPermanent; import mage.game.Game; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class Gridlock extends CardImpl { - private static final FilterNonlandPermanent filter = new FilterNonlandPermanent("nonland permanents"); public Gridlock(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{U}"); // Tap X target nonland permanents. - this.getSpellAbility().addEffect(new TapTargetEffect()); - // Correct number of targets will be set in adjustTargets - this.getSpellAbility().addTarget(new TargetPermanent(0, 1,filter, false)); - + this.getSpellAbility().addEffect(new TapTargetEffect("X target nonland permanents")); + this.getSpellAbility().setTargetAdjuster(GridlockAdjuster.instance); } public Gridlock(final Gridlock card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int numberToTap = ability.getManaCostsToPay().getX(); - numberToTap = Math.min(game.getBattlefield().count(filter, ability.getSourceId(), ability.getControllerId(), game), numberToTap); - ability.addTarget(new TargetPermanent(numberToTap, filter)); - } - } - @Override public Gridlock copy() { return new Gridlock(this); } } + +enum GridlockAdjuster implements TargetAdjuster { + instance; + private static final FilterNonlandPermanent filter = new FilterNonlandPermanent("nonland permanents"); + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetPermanent(ability.getManaCostsToPay().getX(), filter)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GrimReturn.java b/Mage.Sets/src/mage/cards/g/GrimReturn.java index e7a32a9dd1..9fb55552e8 100644 --- a/Mage.Sets/src/mage/cards/g/GrimReturn.java +++ b/Mage.Sets/src/mage/cards/g/GrimReturn.java @@ -1,9 +1,6 @@ package mage.cards.g; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.Effect; @@ -17,10 +14,14 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardIdPredicate; import mage.game.Game; import mage.target.common.TargetCardInGraveyard; +import mage.target.targetadjustment.TargetAdjuster; import mage.watchers.common.CardsPutIntoGraveyardWatcher; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class GrimReturn extends CardImpl { @@ -28,13 +29,13 @@ public final class GrimReturn extends CardImpl { private static final String textFilter = "creature card in a graveyard that was put there from the battlefield this turn"; public GrimReturn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}"); // Choose target creature card in a graveyard that was put there from the battlefield this turn. Put that card onto the battlefield under your control. Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect(); effect.setText("Choose target creature card in a graveyard that was put there from the battlefield this turn. Put that card onto the battlefield under your control"); this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); - this.getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterCreatureCard(textFilter))); + this.getSpellAbility().setTargetAdjuster(GrimReturnAdjuster.instance); this.getSpellAbility().addWatcher(new CardsPutIntoGraveyardWatcher()); } @@ -46,22 +47,27 @@ public final class GrimReturn extends CardImpl { public GrimReturn copy() { return new GrimReturn(this); } +} + +enum GrimReturnAdjuster implements TargetAdjuster { + instance; + private static final String textFilter = "creature card in a graveyard that was put there from the battlefield this turn"; @Override public void adjustTargets(Ability ability, Game game) { CardsPutIntoGraveyardWatcher watcher = game.getState().getWatcher(CardsPutIntoGraveyardWatcher.class); - if (watcher != null) { - FilterCard filter = new FilterCreatureCard(textFilter); - List uuidPredicates = new ArrayList<>(); - for (MageObjectReference mor : watcher.getCardsPutToGraveyardFromBattlefield()) { - if (game.getState().getZoneChangeCounter(mor.getSourceId()) == mor.getZoneChangeCounter()) { - uuidPredicates.add(new CardIdPredicate(mor.getSourceId())); - } - } - filter.add(Predicates.or(uuidPredicates)); - ability.getTargets().clear(); - ability.addTarget(new TargetCardInGraveyard(filter)); + if (watcher == null) { + return; } - + FilterCard filter = new FilterCreatureCard(textFilter); + List uuidPredicates = new ArrayList<>(); + for (MageObjectReference mor : watcher.getCardsPutToGraveyardFromBattlefield()) { + if (mor.zoneCounterIsCurrent(game)) { + uuidPredicates.add(new CardIdPredicate(mor.getSourceId())); + } + } + filter.add(Predicates.or(uuidPredicates)); + ability.getTargets().clear(); + ability.addTarget(new TargetCardInGraveyard(filter)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/h/HourOfEternity.java b/Mage.Sets/src/mage/cards/h/HourOfEternity.java index ed2ced0421..918d40620d 100644 --- a/Mage.Sets/src/mage/cards/h/HourOfEternity.java +++ b/Mage.Sets/src/mage/cards/h/HourOfEternity.java @@ -1,12 +1,8 @@ package mage.cards.h; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -21,10 +17,14 @@ import mage.game.permanent.token.EmptyToken; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; import mage.util.CardUtil; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** - * * @author emerald000 */ public final class HourOfEternity extends CardImpl { @@ -34,17 +34,7 @@ public final class HourOfEternity extends CardImpl { // Exile X target creature cards from your graveyard. For each card exiled this way, create a token that's a copy of that card, except it's a 4/4 black Zombie. this.getSpellAbility().addEffect(new HourOfEternityEffect()); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, Integer.MAX_VALUE, new FilterCreatureCard("creature cards from your graveyard"))); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - Target target = new TargetCardInYourGraveyard(xValue, new FilterCreatureCard((xValue != 1 ? " creature cards" : "creature card") + " from your graveyard")); - ability.addTarget(target); - } + this.getSpellAbility().setTargetAdjuster(HourOfEternityAdjuster.instance); } public HourOfEternity(final HourOfEternity card) { @@ -57,11 +47,25 @@ public final class HourOfEternity extends CardImpl { } } +enum HourOfEternityAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + Target target = new TargetCardInYourGraveyard(xValue, new FilterCreatureCard((xValue != 1 ? " creature cards" : "creature card") + " from your graveyard")); + ability.addTarget(target); + } +} + class HourOfEternityEffect extends OneShotEffect { HourOfEternityEffect() { super(Outcome.PutCreatureInPlay); - this.staticText = "Exile X target creature cards from your graveyard. For each card exiled this way, create a token that's a copy of that card, except it's a 4/4 black Zombie"; + this.staticText = "Exile X target creature cards from your graveyard. " + + "For each card exiled this way, create a token that's a copy of that card, " + + "except it's a 4/4 black Zombie"; } HourOfEternityEffect(final HourOfEternityEffect effect) { diff --git a/Mage.Sets/src/mage/cards/i/IcyBlast.java b/Mage.Sets/src/mage/cards/i/IcyBlast.java index cd37dd0a74..2df2b53a35 100644 --- a/Mage.Sets/src/mage/cards/i/IcyBlast.java +++ b/Mage.Sets/src/mage/cards/i/IcyBlast.java @@ -1,9 +1,7 @@ package mage.cards.i; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.LockedInCondition; import mage.abilities.condition.common.FerociousCondition; import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect; @@ -13,12 +11,13 @@ import mage.abilities.effects.common.TapTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.StaticFilters; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author emerald000 */ public final class IcyBlast extends CardImpl { @@ -28,7 +27,6 @@ public final class IcyBlast extends CardImpl { // Tap X target creatures. this.getSpellAbility().addEffect(new TapTargetEffect("X target creatures")); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1, StaticFilters.FILTER_PERMANENT_CREATURE, false)); // Ferocious — If you control a creature with power 4 or greater, those creatures don't untap during their controllers' next untap steps. Effect effect = new ConditionalContinuousRuleModifyingEffect( @@ -36,24 +34,25 @@ public final class IcyBlast extends CardImpl { new LockedInCondition(FerociousCondition.instance)); effect.setText("
Ferocious — If you control a creature with power 4 or greater, those creatures don't untap during their controllers' next untap steps"); this.getSpellAbility().addEffect(effect); + this.getSpellAbility().setTargetAdjuster(IcyBlastAdjuster.instance); } public IcyBlast(final IcyBlast card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int numberToTap = ability.getManaCostsToPay().getX(); - numberToTap = Math.min(game.getBattlefield().count(StaticFilters.FILTER_PERMANENT_CREATURE, ability.getSourceId(), ability.getControllerId(), game), numberToTap); - ability.addTarget(new TargetCreaturePermanent(numberToTap)); - } - } - @Override public IcyBlast copy() { return new IcyBlast(this); } } + +enum IcyBlastAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/i/IndomitableCreativity.java b/Mage.Sets/src/mage/cards/i/IndomitableCreativity.java index cc65732992..dd20946857 100644 --- a/Mage.Sets/src/mage/cards/i/IndomitableCreativity.java +++ b/Mage.Sets/src/mage/cards/i/IndomitableCreativity.java @@ -2,7 +2,6 @@ package mage.cards.i; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.*; import mage.constants.CardType; @@ -16,53 +15,64 @@ import mage.game.permanent.Permanent; import mage.players.Library; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; /** - * * @author LevelX2 */ public final class IndomitableCreativity extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("artifacts and/or creatures"); - - static { - filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE))); - } public IndomitableCreativity(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}{R}{R}"); // Destroy X target artifacts and/or creatures. For each permanent destroyed this way, its controller reveals cards from the top of their library until an artifact or creature card is revealed and exiles that card. Those players put the exiled card onto the battlefield, then shuffle their libraries. - getSpellAbility().addEffect(new IndomitableCreativityEffect()); - this.getSpellAbility().addTarget(new TargetPermanent(filter)); + this.getSpellAbility().addEffect(new IndomitableCreativityEffect()); + this.getSpellAbility().setTargetAdjuster(IndomitableCreativityAdjuster.instance); } public IndomitableCreativity(final IndomitableCreativity card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - ability.addTarget(new TargetPermanent(xValue, xValue, filter, false)); - } - } - @Override public IndomitableCreativity copy() { return new IndomitableCreativity(this); } } +enum IndomitableCreativityAdjuster implements TargetAdjuster { + instance; + private static final FilterPermanent filter = new FilterPermanent("artifacts and/or creatures"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.CREATURE) + )); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + ability.addTarget(new TargetPermanent(xValue, xValue, filter, false)); + } +} + class IndomitableCreativityEffect extends OneShotEffect { public IndomitableCreativityEffect() { super(Outcome.Benefit); - this.staticText = "Destroy X target artifacts and/or creatures. For each permanent destroyed this way, its controller reveals cards from the top of their library until an artifact or creature card is revealed and exiles that card. Those players put the exiled card onto the battlefield, then shuffle their libraries"; + this.staticText = "Destroy X target artifacts and/or creatures. " + + "For each permanent destroyed this way, " + + "its controller reveals cards from the top of their library" + + " until an artifact or creature card is revealed and exiles that card. " + + "Those players put the exiled card onto the battlefield, then shuffle their libraries"; } public IndomitableCreativityEffect(final IndomitableCreativityEffect effect) { diff --git a/Mage.Sets/src/mage/cards/j/Jilt.java b/Mage.Sets/src/mage/cards/j/Jilt.java index f1ab8a2f69..a66b94bdde 100644 --- a/Mage.Sets/src/mage/cards/j/Jilt.java +++ b/Mage.Sets/src/mage/cards/j/Jilt.java @@ -1,9 +1,7 @@ - package mage.cards.j; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.common.KickedCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.Effect; @@ -18,6 +16,7 @@ import mage.filter.predicate.mageobject.AnotherTargetPredicate; import mage.game.Game; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.SecondTargetPointer; /** @@ -43,18 +42,7 @@ public final class Jilt extends CardImpl { Target target = new TargetCreaturePermanent(); target.setTargetTag(1); this.getSpellAbility().addTarget(target); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility && KickedCondition.instance.apply(game, ability)) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("Another creature: Damaged"); - filter.add(new AnotherTargetPredicate(2)); - Target target = new TargetCreaturePermanent(filter); - target.setTargetTag(2); - ability.addTarget(target); - } - + this.getSpellAbility().setTargetAdjuster(JiltAdjuster.instance); } public Jilt(final Jilt card) { @@ -66,3 +54,20 @@ public final class Jilt extends CardImpl { return new Jilt(this); } } + +enum JiltAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + if (!KickedCondition.instance.apply(game, ability)) { + return; + } + FilterCreaturePermanent filter = new FilterCreaturePermanent("Another creature: Damaged"); + filter.add(new AnotherTargetPredicate(2)); + Target target = new TargetCreaturePermanent(filter); + target.setTargetTag(2); + ability.addTarget(target); + } + +} diff --git a/Mage.Sets/src/mage/cards/k/KaerveksPurge.java b/Mage.Sets/src/mage/cards/k/KaerveksPurge.java index 591f109a1b..077111812a 100644 --- a/Mage.Sets/src/mage/cards/k/KaerveksPurge.java +++ b/Mage.Sets/src/mage/cards/k/KaerveksPurge.java @@ -1,9 +1,7 @@ package mage.cards.k; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -17,9 +15,11 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author sinsedrix */ public final class KaerveksPurge extends CardImpl { @@ -28,19 +28,8 @@ public final class KaerveksPurge extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{R}"); // Destroy target creature with converted mana cost X. If that creature dies this way, Kaervek's Purge deals damage equal to the creature's power to the creature's controller. - this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature with converted mana cost X"))); this.getSpellAbility().addEffect(new KaerveksPurgeEffect()); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost X"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); - ability.addTarget(new TargetCreaturePermanent(filter)); - } + this.getSpellAbility().setTargetAdjuster(KaerveksPurgeAdjuster.instance); } public KaerveksPurge(final KaerveksPurge card) { @@ -53,11 +42,27 @@ public final class KaerveksPurge extends CardImpl { } } +enum KaerveksPurgeAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost " + xValue); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); + ability.addTarget(new TargetCreaturePermanent(filter)); + } +} + class KaerveksPurgeEffect extends OneShotEffect { public KaerveksPurgeEffect() { super(Outcome.DestroyPermanent); - this.staticText = "Destroy target creature with converted mana cost X. If that creature dies this way, {this} deals damage equal to the creature's power to the creature's controller"; + this.staticText = "Destroy target creature with converted mana cost X. " + + "If that creature dies this way, " + + "{this} deals damage equal to the creature's power" + + " to the creature's controller"; } public KaerveksPurgeEffect(final KaerveksPurgeEffect effect) { diff --git a/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java b/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java index eda2fdad62..4537348384 100644 --- a/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java +++ b/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java @@ -1,12 +1,11 @@ package mage.cards.k; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; -import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.CumulativeUpkeepAbility; import mage.cards.CardImpl; @@ -21,9 +20,11 @@ import mage.players.Player; import mage.target.Target; import mage.target.common.TargetAnyTarget; import mage.target.common.TargetOpponent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author L_J */ public final class KarplusanMinotaur extends CardImpl { @@ -39,36 +40,10 @@ public final class KarplusanMinotaur extends CardImpl { this.addAbility(new CumulativeUpkeepAbility(new KarplusanMinotaurCost())); // Whenever you win a coin flip, Karplusan Minotaur deals 1 damage to any target. - Ability abilityWin = new KarplusanMinotaurFlipWinTriggeredAbility(); - abilityWin.addTarget(new TargetAnyTarget()); - this.addAbility(abilityWin); + this.addAbility(new KarplusanMinotaurFlipWinTriggeredAbility()); - //TODO: Make ability properly copiable // Whenever you lose a coin flip, Karplusan Minotaur deals 1 damage to any target of an opponent's choice. - Ability abilityLose = new KarplusanMinotaurFlipLoseTriggeredAbility(); - abilityLose.addTarget(new TargetAnyTarget()); - this.addAbility(abilityLose); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof KarplusanMinotaurFlipLoseTriggeredAbility) { - Player controller = game.getPlayer(ability.getControllerId()); - if (controller != null) { - UUID opponentId = null; - if (game.getOpponents(controller.getId()).size() > 1) { - Target target = new TargetOpponent(true); - if (controller.chooseTarget(Outcome.Neutral, target, ability, game)) { - opponentId = target.getFirstTarget(); - } - } else { - opponentId = game.getOpponents(controller.getId()).iterator().next(); - } - if (opponentId != null) { - ability.getTargets().get(0).setTargetController(opponentId); - } - } - } + this.addAbility(new KarplusanMinotaurFlipLoseTriggeredAbility()); } public KarplusanMinotaur(final KarplusanMinotaur card) { @@ -81,10 +56,35 @@ public final class KarplusanMinotaur extends CardImpl { } } +enum KarplusanMinotaurAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + Player controller = game.getPlayer(ability.getControllerId()); + if (controller == null) { + return; + } + UUID opponentId = null; + if (game.getOpponents(controller.getId()).size() > 1) { + Target target = new TargetOpponent(true); + if (controller.chooseTarget(Outcome.Neutral, target, ability, game)) { + opponentId = target.getFirstTarget(); + } + } else { + opponentId = game.getOpponents(controller.getId()).iterator().next(); + } + if (opponentId != null) { + ability.getTargets().get(0).setTargetController(opponentId); + } + } +} + class KarplusanMinotaurFlipWinTriggeredAbility extends TriggeredAbilityImpl { public KarplusanMinotaurFlipWinTriggeredAbility() { super(Zone.BATTLEFIELD, new DamageTargetEffect(1), false); + this.addTarget(new TargetAnyTarget()); } public KarplusanMinotaurFlipWinTriggeredAbility(final KarplusanMinotaurFlipWinTriggeredAbility ability) { @@ -116,6 +116,8 @@ class KarplusanMinotaurFlipLoseTriggeredAbility extends TriggeredAbilityImpl { public KarplusanMinotaurFlipLoseTriggeredAbility() { super(Zone.BATTLEFIELD, new DamageTargetEffect(1), false); + this.addTarget(new TargetAnyTarget()); + targetAdjuster = KarplusanMinotaurAdjuster.instance; } public KarplusanMinotaurFlipLoseTriggeredAbility(final KarplusanMinotaurFlipLoseTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/cards/k/KeeperOfTheMind.java b/Mage.Sets/src/mage/cards/k/KeeperOfTheMind.java index 087fe044f6..eda3e048b1 100644 --- a/Mage.Sets/src/mage/cards/k/KeeperOfTheMind.java +++ b/Mage.Sets/src/mage/cards/k/KeeperOfTheMind.java @@ -27,7 +27,6 @@ */ package mage.cards.k; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -35,32 +34,25 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.filter.FilterOpponent; import mage.filter.predicate.ObjectSourcePlayer; import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; -import mage.target.common.TargetOpponent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author jeffwadsworth */ public class KeeperOfTheMind extends CardImpl { - public final UUID originalId; - private static final FilterOpponent filter = new FilterOpponent(); - - static { - filter.add(new KeeperOfTheMindPredicate()); - } - - public KeeperOfTheMind(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{U}"); @@ -74,28 +66,12 @@ public class KeeperOfTheMind extends CardImpl { effect.setText("Choose target opponent who had at least two more cards in hand than you did as you activated this ability. Draw a card."); Ability ability = new SimpleActivatedAbility(effect, new ManaCostsImpl("{U}")); ability.addCost(new TapSourceCost()); - ability.addTarget(new TargetOpponent()); + ability.setTargetAdjuster(KeeperOfTheMindAdjuster.instance); this.addAbility(ability); - originalId = ability.getOriginalId(); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - Player activePlayer = game.getPlayer(game.getActivePlayerId()); - if (activePlayer != null) { - ability.getTargets().clear(); - TargetPlayer target = new TargetPlayer(1, 1, false, filter); - target.setTargetController(activePlayer.getId()); - ability.getTargets().add(target); - } - } } public KeeperOfTheMind(final KeeperOfTheMind card) { super(card); - this.originalId = card.originalId; } @Override @@ -104,6 +80,28 @@ public class KeeperOfTheMind extends CardImpl { } } +enum KeeperOfTheMindAdjuster implements TargetAdjuster { + instance; + + private static final FilterOpponent filter = new FilterOpponent(); + + static { + filter.add(new KeeperOfTheMindPredicate()); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + Player activePlayer = game.getPlayer(game.getActivePlayerId()); + if (activePlayer == null) { + return; + } + ability.getTargets().clear(); + TargetPlayer target = new TargetPlayer(1, 1, false, filter); + target.setTargetController(activePlayer.getId()); + ability.addTarget(target); + } +} + class KeeperOfTheMindPredicate implements ObjectSourcePlayerPredicate> { @Override diff --git a/Mage.Sets/src/mage/cards/k/KillingGlare.java b/Mage.Sets/src/mage/cards/k/KillingGlare.java index 5382bf5557..16704117ad 100644 --- a/Mage.Sets/src/mage/cards/k/KillingGlare.java +++ b/Mage.Sets/src/mage/cards/k/KillingGlare.java @@ -1,9 +1,7 @@ package mage.cards.k; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -13,21 +11,21 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.PowerPredicate; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class KillingGlare extends CardImpl { - public KillingGlare (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{B}"); - + public KillingGlare(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{B}"); // Destroy target creature with power X or less. - this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature with power X or less"))); - + this.getSpellAbility().addEffect(new DestroyTargetEffect("destroy target creature with power X or less")); + this.getSpellAbility().setTargetAdjuster(KillingGlareAdjuster.instance); } public KillingGlare(final KillingGlare card) { @@ -35,19 +33,20 @@ public final class KillingGlare extends CardImpl { } @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - int xValue = ability.getManaCostsToPay().getX(); - ability.getTargets().clear(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power " + xValue + " or less"); - filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, xValue + 1)); - ability.addTarget(new TargetCreaturePermanent(filter)); - } - } - - - @Override - public KillingGlare copy() { + public KillingGlare copy() { return new KillingGlare(this); } } + +enum KillingGlareAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + int xValue = ability.getManaCostsToPay().getX(); + ability.getTargets().clear(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power " + xValue + " or less"); + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, xValue + 1)); + ability.addTarget(new TargetCreaturePermanent(filter)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/k/KukemssaPirates.java b/Mage.Sets/src/mage/cards/k/KukemssaPirates.java index 5464da339d..16cb3c70a9 100644 --- a/Mage.Sets/src/mage/cards/k/KukemssaPirates.java +++ b/Mage.Sets/src/mage/cards/k/KukemssaPirates.java @@ -1,29 +1,32 @@ package mage.cards.k; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksAndIsNotBlockedTriggeredAbility; import mage.abilities.effects.common.continuous.AssignNoCombatDamageSourceEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.common.FilterArtifactPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; +import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate; import mage.target.common.TargetArtifactPermanent; +import java.util.UUID; + /** - * * @author TheElk801 */ public final class KukemssaPirates extends CardImpl { - private final UUID originalId; + private static final FilterArtifactPermanent filter = new FilterArtifactPermanent("artifact defending player controls"); + + static { + filter.add(new DefendingPlayerControlsPredicate()); + } public KukemssaPirates(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); @@ -36,26 +39,12 @@ public final class KukemssaPirates extends CardImpl { // Whenever Kukemssa Pirates attacks and isn't blocked, you may gain control of target artifact defending player controls. If you do, Kukemssa Pirates assigns no combat damage this turn. Ability ability = new AttacksAndIsNotBlockedTriggeredAbility(new GainControlTargetEffect(Duration.Custom), true); ability.addEffect(new AssignNoCombatDamageSourceEffect(Duration.EndOfTurn, true)); - ability.addTarget(new TargetArtifactPermanent(new FilterArtifactPermanent("artifact defending player controls"))); - originalId = ability.getOriginalId(); + ability.addTarget(new TargetArtifactPermanent(filter)); this.addAbility(ability); } public KukemssaPirates(final KukemssaPirates card) { super(card); - this.originalId = card.originalId; - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - ability.getTargets().clear(); - FilterArtifactPermanent filter = new FilterArtifactPermanent("artifact defending player controls"); - UUID defenderId = game.getCombat().getDefenderId(ability.getSourceId()); - filter.add(new ControllerIdPredicate(defenderId)); - TargetArtifactPermanent target = new TargetArtifactPermanent(filter); - ability.addTarget(target); - } } @Override diff --git a/Mage.Sets/src/mage/cards/l/LilianaDefiantNecromancer.java b/Mage.Sets/src/mage/cards/l/LilianaDefiantNecromancer.java index f6a0956905..f4db5ab2b7 100644 --- a/Mage.Sets/src/mage/cards/l/LilianaDefiantNecromancer.java +++ b/Mage.Sets/src/mage/cards/l/LilianaDefiantNecromancer.java @@ -1,4 +1,3 @@ - package mage.cards.l; import java.util.UUID; @@ -21,6 +20,7 @@ import mage.filter.predicate.mageobject.SupertypePredicate; import mage.game.Game; import mage.game.command.emblems.LilianaDefiantNecromancerEmblem; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; /** * @@ -28,14 +28,12 @@ import mage.target.common.TargetCardInYourGraveyard; */ public final class LilianaDefiantNecromancer extends CardImpl { - private static final FilterCreatureCard filter = new FilterCreatureCard("nonlegendary creature with converted mana cost X from your graveyard"); + protected static final FilterCreatureCard filter = new FilterCreatureCard("nonlegendary creature with converted mana cost X from your graveyard"); static { filter.add(Predicates.not(new SupertypePredicate(SuperType.LEGENDARY))); } - UUID ability2Id; - public LilianaDefiantNecromancer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); this.addSuperType(SuperType.LEGENDARY); @@ -49,36 +47,18 @@ public final class LilianaDefiantNecromancer extends CardImpl { // +2: Each player discards a card. this.addAbility(new LoyaltyAbility(new DiscardEachPlayerEffect(1, false), 2)); - //TODO: Make ability properly copiable // -X: Return target nonlegendary creature with converted mana cost X from your graveyard to the battlefield. Ability ability = new LoyaltyAbility(new ReturnFromGraveyardToBattlefieldTargetEffect()); - ability2Id = ability.getOriginalId(); ability.addTarget(new TargetCardInYourGraveyard(filter)); + ability.setTargetAdjuster(LilianaDefiantNecromancerAdjuster.instance); this.addAbility(ability); //-8: You get an emblem with "Whenever a creature dies, return it to the battlefield under your control at the beginning of the next end step."; this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new LilianaDefiantNecromancerEmblem()), -8)); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(ability2Id)) { - int cmc = 0; - for (Cost cost : ability.getCosts()) { - if (cost instanceof PayVariableLoyaltyCost) { - cmc = ((PayVariableLoyaltyCost) cost).getAmount(); - } - } - FilterCard newFilter = filter.copy(); - newFilter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, cmc)); - ability.getTargets().clear(); - ability.addTarget(new TargetCardInYourGraveyard(newFilter)); - } - } - public LilianaDefiantNecromancer(final LilianaDefiantNecromancer card) { super(card); - this.ability2Id = card.ability2Id; } @Override @@ -86,3 +66,21 @@ public final class LilianaDefiantNecromancer extends CardImpl { return new LilianaDefiantNecromancer(this); } } + +enum LilianaDefiantNecromancerAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + int cmc = 0; + for (Cost cost : ability.getCosts()) { + if (cost instanceof PayVariableLoyaltyCost) { + cmc = ((PayVariableLoyaltyCost) cost).getAmount(); + } + } + FilterCard newFilter = LilianaDefiantNecromancer.filter.copy(); + newFilter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, cmc)); + ability.getTargets().clear(); + ability.addTarget(new TargetCardInYourGraveyard(newFilter)); + } +} diff --git a/Mage.Sets/src/mage/cards/l/LivingInferno.java b/Mage.Sets/src/mage/cards/l/LivingInferno.java index 5d8992a61e..50e31e7471 100644 --- a/Mage.Sets/src/mage/cards/l/LivingInferno.java +++ b/Mage.Sets/src/mage/cards/l/LivingInferno.java @@ -1,9 +1,6 @@ package mage.cards.l; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -12,50 +9,38 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.Target; import mage.target.common.TargetCreaturePermanentAmount; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; /** - * * @author LevelX2 & L_J */ public final class LivingInferno extends CardImpl { - private final UUID originalId; - public LivingInferno(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{6}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{R}{R}"); this.subtype.add(SubType.ELEMENTAL); this.power = new MageInt(8); this.toughness = new MageInt(5); // {T}: Living Inferno deals damage equal to its power divided as you choose among any number of target creatures. Each of those creatures deals damage equal to its power to Living Inferno. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LivingInfernoEffect(), new TapSourceCost()); - ability.addTarget(new TargetCreaturePermanentAmount(1)); + ability.setTargetAdjuster(LivingInfernoAdjuster.instance); this.addAbility(ability); - originalId = ability.getOriginalId(); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if(ability.getOriginalId().equals(originalId)) { - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(ability.getSourceId()); - if (sourcePermanent != null) { - int xValue = sourcePermanent.getPower().getValue(); - ability.getTargets().clear(); - ability.addTarget(new TargetCreaturePermanentAmount(xValue)); - } - } } public LivingInferno(final LivingInferno card) { super(card); - this.originalId = card.originalId; } @Override @@ -64,11 +49,26 @@ public final class LivingInferno extends CardImpl { } } +enum LivingInfernoAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(ability.getSourceId()); + if (sourcePermanent != null) { + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanentAmount(sourcePermanent.getPower().getValue())); + } + } +} + class LivingInfernoEffect extends OneShotEffect { public LivingInfernoEffect() { super(Outcome.Benefit); - this.staticText = "{this} deals damage equal to its power divided as you choose among any number of target creatures. Each of those creatures deals damage equal to its power to {this}"; + this.staticText = "{this} deals damage equal to its power " + + "divided as you choose among any number of target creatures. " + + "Each of those creatures deals damage equal to its power to {this}"; } public LivingInfernoEffect(final LivingInfernoEffect effect) { diff --git a/Mage.Sets/src/mage/cards/l/LuminarchAscension.java b/Mage.Sets/src/mage/cards/l/LuminarchAscension.java index 9f0758bf99..e0382cabbb 100644 --- a/Mage.Sets/src/mage/cards/l/LuminarchAscension.java +++ b/Mage.Sets/src/mage/cards/l/LuminarchAscension.java @@ -29,7 +29,7 @@ import mage.watchers.common.PlayerLostLifeWatcher; */ public final class LuminarchAscension extends CardImpl { - private String rule = "At the beginning of each opponent's end step, if you didn't lose life this turn, you may put a quest counter on {this}. (Damage causes loss of life.)"; + private static final String rule = "At the beginning of each opponent's end step, if you didn't lose life this turn, you may put a quest counter on {this}. (Damage causes loss of life.)"; public LuminarchAscension(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); diff --git a/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java b/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java index ce678715e6..e35a5c6b04 100644 --- a/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java +++ b/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java @@ -1,7 +1,6 @@ package mage.cards.l; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -10,8 +9,8 @@ import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; @@ -19,15 +18,17 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class LuminatePrimordial extends CardImpl { public LuminatePrimordial(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}{W}"); this.subtype.add(SubType.AVATAR); this.power = new MageInt(4); @@ -38,23 +39,9 @@ public final class LuminatePrimordial extends CardImpl { // When Luminate Primordial enters the battlefield, for each opponent, exile up to one target creature // that player controls and that player gains life equal to its power. - this.addAbility(new EntersBattlefieldTriggeredAbility(new LuminatePrimordialEffect(),false)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof EntersBattlefieldTriggeredAbility) { - ability.getTargets().clear(); - for(UUID opponentId : game.getOpponents(ability.getControllerId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature from opponent " + opponent.getLogName()); - filter.add(new ControllerIdPredicate(opponentId)); - TargetCreaturePermanent target = new TargetCreaturePermanent(0,1, filter,false); - ability.addTarget(target); - } - } - } + Ability ability = new EntersBattlefieldTriggeredAbility(new LuminatePrimordialEffect(), false); + ability.setTargetAdjuster(LuminatePrimordialAdjuster.instance); + this.addAbility(ability); } public LuminatePrimordial(final LuminatePrimordial card) { @@ -67,6 +54,24 @@ public final class LuminatePrimordial extends CardImpl { } } +enum LuminatePrimordialAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + for (UUID opponentId : game.getOpponents(ability.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature from opponent " + opponent.getLogName()); + filter.add(new ControllerIdPredicate(opponentId)); + TargetCreaturePermanent target = new TargetCreaturePermanent(0, 1, filter, false); + ability.addTarget(target); + } + } + } +} + class LuminatePrimordialEffect extends OneShotEffect { public LuminatePrimordialEffect() { @@ -85,7 +90,7 @@ class LuminatePrimordialEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (Target target: source.getTargets()) { + for (Target target : source.getTargets()) { if (target instanceof TargetCreaturePermanent) { Permanent targetCreature = game.getPermanent(target.getFirstTarget()); if (targetCreature != null && !targetCreature.isControlledBy(source.getControllerId())) { diff --git a/Mage.Sets/src/mage/cards/m/MagmaBurst.java b/Mage.Sets/src/mage/cards/m/MagmaBurst.java index 761e9fd419..5d81a3b4bd 100644 --- a/Mage.Sets/src/mage/cards/m/MagmaBurst.java +++ b/Mage.Sets/src/mage/cards/m/MagmaBurst.java @@ -1,7 +1,6 @@ package mage.cards.m; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.condition.common.KickedCondition; import mage.abilities.costs.common.SacrificeTargetCost; @@ -13,18 +12,17 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; -import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetAnyTarget; +import mage.target.common.TargetControlledPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LoneFox - * */ public final class MagmaBurst extends CardImpl { - private final UUID originalId; - public MagmaBurst(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}"); @@ -32,21 +30,13 @@ public final class MagmaBurst extends CardImpl { this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("two lands"), true)))); // Magma Burst deals 3 damage to any target. If Magma Burst was kicked, it deals 3 damage to another any target. Effect effect = new DamageTargetEffect(3); - effect.setText("{this} deals 3 damage to any target. if this spell was kicked, it deals 3 damage to another target."); + effect.setText("{this} deals 3 damage to any target. If this spell was kicked, it deals 3 damage to another target."); this.getSpellAbility().addEffect(effect); - originalId = this.getSpellAbility().getOriginalId(); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - ability.addTarget(new TargetAnyTarget(KickedCondition.instance.apply(game, ability) ? 2 : 1)); - } + this.getSpellAbility().setTargetAdjuster(MagmaBurstAdjuster.instance); } public MagmaBurst(final MagmaBurst card) { super(card); - this.originalId = card.originalId; } @Override @@ -54,3 +44,12 @@ public final class MagmaBurst extends CardImpl { return new MagmaBurst(this); } } + +enum MagmaBurstAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.addTarget(new TargetAnyTarget(KickedCondition.instance.apply(game, ability) ? 2 : 1)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java b/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java index 610edcb589..9f05a441e6 100644 --- a/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java +++ b/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java @@ -1,9 +1,7 @@ package mage.cards.m; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.effects.Effect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; @@ -16,38 +14,24 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.Game; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LoneFox */ public final class MaliciousAdvice extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("artifacts, creatures, and/or lands"); - - static { - filter.add(Predicates.or( - new CardTypePredicate(CardType.ARTIFACT), - new CardTypePredicate(CardType.CREATURE), - new CardTypePredicate(CardType.LAND))); - } - public MaliciousAdvice(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{U}{B}"); // Tap X target artifacts, creatures, and/or lands. You lose X life. Effect effect = new TapTargetEffect(); - effect.setText("X target artifacts, creatures, and/or lands"); + effect.setText("X target artifacts, creatures, and/or lands."); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(new ManacostVariableValue())); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - ability.addTarget(new TargetPermanent(ability.getManaCostsToPay().getX(), filter)); - } + this.getSpellAbility().setTargetAdjuster(MaliciousAdviceAdjuster.instance); } public MaliciousAdvice(final MaliciousAdvice card) { @@ -59,3 +43,22 @@ public final class MaliciousAdvice extends CardImpl { return new MaliciousAdvice(this); } } + +enum MaliciousAdviceAdjuster implements TargetAdjuster { + instance; + private static final FilterPermanent filter = new FilterPermanent("artifacts, creatures, and/or lands"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.CREATURE), + new CardTypePredicate(CardType.LAND) + )); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetPermanent(ability.getManaCostsToPay().getX(), filter)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java b/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java index 39c3a3503d..7ed4417d51 100644 --- a/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java +++ b/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java @@ -1,80 +1,55 @@ package mage.cards.m; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.common.KickedCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.dynamicvalue.common.MultikickerCount; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.keyword.MultikickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.mageobject.CardTypePredicate; -import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author jeffwadsworth - * */ public final class MarshalsAnthem extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures you control"); - private static final FilterCard filterCard = new FilterCard("creature card in your graveyard"); - - static { - filter.add(new ControllerPredicate(TargetController.YOU)); - filterCard.add(new CardTypePredicate(CardType.CREATURE)); - } - - private final UUID originalId; + private static final String rule = "return up to X target creature cards from your graveyard to the battlefield, " + + "where X is the number of times {this} was kicked"; public MarshalsAnthem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); // Multikicker {1}{W} this.addAbility(new MultikickerAbility("{1}{W}")); // Creatures you control get +1/+1. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, false))); + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield) + )); // When Marshal's Anthem enters the battlefield, return up to X target creature cards from your graveyard to the battlefield, where X is the number of times Marshal's Anthem was kicked. - //TODO this should always trigger, even if it wasn't kicked - Ability ability = new ConditionalInterveningIfTriggeredAbility( - new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), false), - KickedCondition.instance, - "When {this} enters the battlefield, return up to X target creature cards from your graveyard to the battlefield, where X is the number of times {this} was kicked."); - originalId = ability.getOriginalId(); + Ability ability = new EntersBattlefieldTriggeredAbility( + new ReturnFromGraveyardToBattlefieldTargetEffect().setText(rule), false + ); + ability.setTargetAdjuster(MarshalsAnthemAdjuster.instance); this.addAbility(ability); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - ability.getTargets().clear(); - int numbTargets = new MultikickerCount().calculate(game, ability, null); - if (numbTargets > 0) { - ability.addTarget(new TargetCardInYourGraveyard(0, numbTargets, filterCard)); - } - } } public MarshalsAnthem(final MarshalsAnthem card) { super(card); - this.originalId = card.originalId; } @Override @@ -82,3 +57,17 @@ public final class MarshalsAnthem extends CardImpl { return new MarshalsAnthem(this); } } + +enum MarshalsAnthemAdjuster implements TargetAdjuster { + instance; + private static final FilterCard filter = new FilterCreatureCard("creature card in your graveyard"); + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int numbTargets = new MultikickerCount().calculate(game, ability, null); + if (numbTargets > 0) { + ability.addTarget(new TargetCardInYourGraveyard(0, numbTargets, filter)); + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/MartyrOfBones.java b/Mage.Sets/src/mage/cards/m/MartyrOfBones.java index e280e71f9e..a90e986f1b 100644 --- a/Mage.Sets/src/mage/cards/m/MartyrOfBones.java +++ b/Mage.Sets/src/mage/cards/m/MartyrOfBones.java @@ -1,7 +1,6 @@ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.ObjectColor; import mage.abilities.Ability; @@ -25,17 +24,17 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInASingleGraveyard; import mage.target.common.TargetCardInHand; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author emerald000 */ public final class MartyrOfBones extends CardImpl { - private final UUID originalId; - public MartyrOfBones(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); @@ -49,27 +48,12 @@ public final class MartyrOfBones extends CardImpl { ability.addCost(new RevealVariableBlackCardsFromHandCost()); ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetCardInASingleGraveyard(0, 1, new FilterCard("cards in a single graveyard"))); - originalId = ability.getOriginalId(); + ability.setTargetAdjuster(MartyrOfBonesAdjuster.instance); this.addAbility(ability); } public MartyrOfBones(final MartyrOfBones card) { super(card); - this.originalId = card.originalId; - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - int amount = 0; - for (Cost cost : ability.getCosts()) { - if (cost instanceof RevealVariableBlackCardsFromHandCost) { - amount = ((VariableCost) cost).getAmount(); - } - } - ability.getTargets().clear(); - ability.addTarget(new TargetCardInASingleGraveyard(0, amount, new FilterCard())); - } } @Override @@ -78,6 +62,22 @@ public final class MartyrOfBones extends CardImpl { } } +enum MartyrOfBonesAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + int amount = 0; + for (Cost cost : ability.getCosts()) { + if (cost instanceof RevealVariableBlackCardsFromHandCost) { + amount = ((VariableCost) cost).getAmount(); + } + } + ability.getTargets().clear(); + ability.addTarget(new TargetCardInASingleGraveyard(0, amount, new FilterCard())); + } +} + class RevealVariableBlackCardsFromHandCost extends VariableCostImpl { private static final FilterCard filter = new FilterCard("X black cards from your hand"); diff --git a/Mage.Sets/src/mage/cards/m/MassMutiny.java b/Mage.Sets/src/mage/cards/m/MassMutiny.java index 10a9549d8b..1ca9b18e39 100644 --- a/Mage.Sets/src/mage/cards/m/MassMutiny.java +++ b/Mage.Sets/src/mage/cards/m/MassMutiny.java @@ -1,9 +1,7 @@ - package mage.cards.m; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; @@ -21,6 +19,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.FixedTarget; /** @@ -34,22 +33,7 @@ public final class MassMutiny extends CardImpl { // For each opponent, gain control of up to one target creature that player controls until end of turn. Untap those creatures. They gain haste until end of turn. this.getSpellAbility().addEffect(new MassMutinyEffect()); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - for (UUID opponentId : game.getOpponents(ability.getControllerId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature from opponent " + opponent.getName()); - filter.add(new ControllerIdPredicate(opponentId)); - TargetCreaturePermanent target = new TargetCreaturePermanent(0, 1, filter, false); - ability.addTarget(target); - } - } - } + this.getSpellAbility().setTargetAdjuster(MassMutinyAdjuster.instance); } public MassMutiny(final MassMutiny card) { @@ -62,6 +46,24 @@ public final class MassMutiny extends CardImpl { } } +enum MassMutinyAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + for (UUID opponentId : game.getOpponents(ability.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature from opponent " + opponent.getName()); + filter.add(new ControllerIdPredicate(opponentId)); + TargetCreaturePermanent target = new TargetCreaturePermanent(0, 1, filter, false); + ability.addTarget(target); + } + } + } +} + class MassMutinyEffect extends OneShotEffect { public MassMutinyEffect() { diff --git a/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java b/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java index 0b533c9260..f274496308 100644 --- a/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java +++ b/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java @@ -1,7 +1,6 @@ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.ObjectColor; import mage.abilities.Ability; @@ -20,14 +19,13 @@ import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ColorPredicate; import mage.target.TargetPlayer; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class MerrowBonegnawer extends CardImpl { - private UUID exileId = UUID.randomUUID(); - private static final FilterSpell filter = new FilterSpell("a black spell"); static { @@ -43,7 +41,7 @@ public final class MerrowBonegnawer extends CardImpl { this.toughness = new MageInt(1); // {tap}: Target player exiles a card from their graveyard. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileFromZoneTargetEffect(Zone.GRAVEYARD, exileId, getIdName(), new FilterCard()), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileFromZoneTargetEffect(Zone.GRAVEYARD, null, getIdName(), new FilterCard()), new TapSourceCost()); ability.addTarget(new TargetPlayer()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/m/MeteorBlast.java b/Mage.Sets/src/mage/cards/m/MeteorBlast.java index fb57f84cce..9331bce50d 100644 --- a/Mage.Sets/src/mage/cards/m/MeteorBlast.java +++ b/Mage.Sets/src/mage/cards/m/MeteorBlast.java @@ -1,4 +1,3 @@ - package mage.cards.m; import java.util.UUID; @@ -13,6 +12,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetAnyTarget; +import mage.target.targetadjustment.TargetAdjuster; /** * @@ -21,7 +21,7 @@ import mage.target.common.TargetAnyTarget; public final class MeteorBlast extends CardImpl { public MeteorBlast(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{R}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}{R}{R}"); // Meteor Blast deals 4 damage to each of X target creatures and/or players. this.getSpellAbility().addEffect(new MeteorBlastEffect()); @@ -31,6 +31,15 @@ public final class MeteorBlast extends CardImpl { super(card); } + @Override + public MeteorBlast copy() { + return new MeteorBlast(this); + } +} + +enum MeteorBlastAdjuster implements TargetAdjuster { + instance; + @Override public void adjustTargets(Ability ability, Game game) { int xValue = ability.getManaCostsToPay().getX(); @@ -39,11 +48,6 @@ public final class MeteorBlast extends CardImpl { ability.addTarget(target); } } - - @Override - public MeteorBlast copy() { - return new MeteorBlast(this); - } } class MeteorBlastEffect extends OneShotEffect { diff --git a/Mage.Sets/src/mage/cards/m/MidnightRitual.java b/Mage.Sets/src/mage/cards/m/MidnightRitual.java index 23205ab254..08ccd0518a 100644 --- a/Mage.Sets/src/mage/cards/m/MidnightRitual.java +++ b/Mage.Sets/src/mage/cards/m/MidnightRitual.java @@ -1,9 +1,7 @@ package mage.cards.m; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -17,9 +15,11 @@ import mage.game.Game; import mage.game.permanent.token.ZombieToken; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author Skyler Sell */ public final class MidnightRitual extends CardImpl { @@ -31,14 +31,7 @@ public final class MidnightRitual extends CardImpl { // For each creature card exiled this way, create a 2/2 black Zombie creature token. this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); this.getSpellAbility().addEffect(new MidnightRitualEffect()); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - ability.addTarget(new TargetCardInYourGraveyard(ability.getManaCostsToPay().getX(), StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); - } + this.getSpellAbility().setTargetAdjuster(MidnightRitualAdjuster.instance); } public MidnightRitual(final MidnightRitual card) { @@ -51,6 +44,16 @@ public final class MidnightRitual extends CardImpl { } } +enum MidnightRitualAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCardInYourGraveyard(ability.getManaCostsToPay().getX(), StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + } +} + class MidnightRitualEffect extends OneShotEffect { public MidnightRitualEffect() { diff --git a/Mage.Sets/src/mage/cards/m/MoggAssassin.java b/Mage.Sets/src/mage/cards/m/MoggAssassin.java index 1051e3a9fd..938bdbb799 100644 --- a/Mage.Sets/src/mage/cards/m/MoggAssassin.java +++ b/Mage.Sets/src/mage/cards/m/MoggAssassin.java @@ -2,7 +2,6 @@ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -11,8 +10,8 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; @@ -20,59 +19,36 @@ import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetOpponentsCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author L_J */ public final class MoggAssassin extends CardImpl { - private final UUID originalId; - public MoggAssassin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.GOBLIN); this.subtype.add(SubType.ASSASSIN); this.power = new MageInt(2); this.toughness = new MageInt(1); - - //TODO: Make ability properly copiable + // {T}: You choose target creature an opponent controls, and that opponent chooses target creature. Flip a coin. If you win the flip, destroy the creature you chose. If you lose the flip, destroy the creature your opponent chose. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MoggAssassinEffect(), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new MoggAssassinEffect(), + new TapSourceCost() + ); ability.addTarget(new TargetOpponentsCreaturePermanent()); ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(MoggAssassinAdjuster.instance); this.addAbility(ability); - originalId = ability.getOriginalId(); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - Player controller = game.getPlayer(ability.getControllerId()); - if (controller != null) { - UUID opponentId = null; - if (game.getOpponents(controller.getId()).size() > 1) { - Target target = ability.getTargets().get(0); - if (controller.chooseTarget(Outcome.DestroyPermanent, target, ability, game)) { - Permanent permanent = game.getPermanent(target.getFirstTarget()); - opponentId = permanent.getControllerId(); - } else { - opponentId = game.getOpponents(controller.getId()).iterator().next(); - } - } else { - opponentId = game.getOpponents(controller.getId()).iterator().next(); - } - - if (opponentId != null) { - ability.getTargets().get(1).setTargetController(opponentId); - } - } - } } public MoggAssassin(final MoggAssassin card) { super(card); - this.originalId = card.originalId; } @Override @@ -82,6 +58,34 @@ public final class MoggAssassin extends CardImpl { } +enum MoggAssassinAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + Player controller = game.getPlayer(ability.getControllerId()); + if (controller == null) { + return; + } + UUID opponentId = null; + if (game.getOpponents(controller.getId()).size() > 1) { + Target target = ability.getTargets().get(0); + if (controller.chooseTarget(Outcome.DestroyPermanent, target, ability, game)) { + Permanent permanent = game.getPermanent(target.getFirstTarget()); + opponentId = permanent.getControllerId(); + } else { + opponentId = game.getOpponents(controller.getId()).iterator().next(); + } + } else { + opponentId = game.getOpponents(controller.getId()).iterator().next(); + } + + if (opponentId != null) { + ability.getTargets().get(1).setTargetController(opponentId); + } + } +} + class MoggAssassinEffect extends OneShotEffect { public MoggAssassinEffect() { @@ -100,21 +104,21 @@ class MoggAssassinEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Permanent chosenPermanent = game.getPermanent(source.getTargets().get(0).getFirstTarget()); - Permanent opponentsPermanent = game.getPermanent(source.getTargets().get(1).getFirstTarget()); - if (controller.flipCoin(game)) { - if (chosenPermanent != null) { - chosenPermanent.destroy(source.getSourceId(), game, false); - return true; - } - } else { - if (opponentsPermanent != null) { - opponentsPermanent.destroy(source.getSourceId(), game, false); - return true; - } + if (controller == null) { + return false; + } + Permanent chosenPermanent = game.getPermanent(source.getTargets().get(0).getFirstTarget()); + Permanent opponentsPermanent = game.getPermanent(source.getTargets().get(1).getFirstTarget()); + if (controller.flipCoin(game)) { + if (chosenPermanent != null) { + chosenPermanent.destroy(source.getSourceId(), game, false); + return true; + } + } else { + if (opponentsPermanent != null) { + opponentsPermanent.destroy(source.getSourceId(), game, false); + return true; } } return false; diff --git a/Mage.Sets/src/mage/cards/m/MogissMarauder.java b/Mage.Sets/src/mage/cards/m/MogissMarauder.java index b5271f482d..d797c3fd00 100644 --- a/Mage.Sets/src/mage/cards/m/MogissMarauder.java +++ b/Mage.Sets/src/mage/cards/m/MogissMarauder.java @@ -1,7 +1,6 @@ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -12,20 +11,22 @@ import mage.abilities.keyword.IntimidateAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.ColoredManaSymbol; import mage.constants.Duration; +import mage.constants.SubType; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class MogissMarauder extends CardImpl { public MogissMarauder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.BERSERKER); @@ -35,24 +36,13 @@ public final class MogissMarauder extends CardImpl { // When Mogis's Marauder enters the battlefield, up to X target creatures each gain intimidate and haste, where X is your devotion to black. Ability ability = new EntersBattlefieldTriggeredAbility( new GainAbilityTargetEffect(IntimidateAbility.getInstance(), Duration.EndOfTurn, - "up to X target creatures each gain intimidate"), false); + "up to X target creatures each gain intimidate"), false); ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn, "and haste until end of turn, where X is your devotion to black")); - ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(MogissMarauderAdjuster.instance); this.addAbility(ability); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof EntersBattlefieldTriggeredAbility) { - ability.getTargets().clear(); - int numbTargets = new DevotionCount(ColoredManaSymbol.B).calculate(game, ability, null); - if (numbTargets > 0) { - ability.addTarget(new TargetCreaturePermanent(0,numbTargets)); - } - } - } - public MogissMarauder(final MogissMarauder card) { super(card); } @@ -62,3 +52,16 @@ public final class MogissMarauder extends CardImpl { return new MogissMarauder(this); } } + +enum MogissMarauderAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int numbTargets = new DevotionCount(ColoredManaSymbol.B).calculate(game, ability, null); + if (numbTargets > 0) { + ability.addTarget(new TargetCreaturePermanent(0, numbTargets)); + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/Molder.java b/Mage.Sets/src/mage/cards/m/Molder.java index 5501bbe933..ca23233ac7 100644 --- a/Mage.Sets/src/mage/cards/m/Molder.java +++ b/Mage.Sets/src/mage/cards/m/Molder.java @@ -1,9 +1,7 @@ package mage.cards.m; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.GainLifeEffect; @@ -11,13 +9,16 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ComparisonType; +import mage.filter.FilterPermanent; import mage.filter.common.FilterArtifactOrEnchantmentPermanent; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LoneFox */ public final class Molder extends CardImpl { @@ -26,20 +27,9 @@ public final class Molder extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{G}"); // Destroy target artifact or enchantment with converted mana cost X. It can't be regenerated. You gain X life. - this.getSpellAbility().addEffect(new DestroyTargetEffect(true)); - this.getSpellAbility().addTarget(new TargetPermanent(new FilterArtifactOrEnchantmentPermanent("artifact or enchantment with converted mana cost X"))); + this.getSpellAbility().addEffect(new DestroyTargetEffect("Destroy target artifact or enchantment with converted mana cost X.", true)); this.getSpellAbility().addEffect(new GainLifeEffect(new ManacostVariableValue())); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterArtifactOrEnchantmentPermanent filter = new FilterArtifactOrEnchantmentPermanent("artifact or enchantment with converted mana cost X"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); - ability.addTarget(new TargetPermanent(filter)); - } + this.getSpellAbility().setTargetAdjuster(MolderAdjuster.instance); } public Molder(final Molder card) { @@ -51,3 +41,16 @@ public final class Molder extends CardImpl { return new Molder(this); } } + +enum MolderAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + FilterPermanent filter = new FilterArtifactOrEnchantmentPermanent("artifact or enchantment with converted mana cost " + xValue); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); + ability.addTarget(new TargetPermanent(filter)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/MoltenPrimordial.java b/Mage.Sets/src/mage/cards/m/MoltenPrimordial.java index 58eaca7830..c557bcccf9 100644 --- a/Mage.Sets/src/mage/cards/m/MoltenPrimordial.java +++ b/Mage.Sets/src/mage/cards/m/MoltenPrimordial.java @@ -1,7 +1,6 @@ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -13,9 +12,9 @@ import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; @@ -23,16 +22,18 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class MoltenPrimordial extends CardImpl { public MoltenPrimordial(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{R}"); this.subtype.add(SubType.AVATAR); this.power = new MageInt(6); @@ -42,23 +43,9 @@ public final class MoltenPrimordial extends CardImpl { this.addAbility(HasteAbility.getInstance()); // When Molten Primordial enters the battlefield, for each opponent, take control of up to one target creature that player controls until end of turn. Untap those creatures. They have haste until end of turn. - this.addAbility(new EntersBattlefieldTriggeredAbility(new MoltenPrimordialEffect(),false)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof EntersBattlefieldTriggeredAbility) { - ability.getTargets().clear(); - for(UUID opponentId : game.getOpponents(ability.getControllerId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature from opponent " + opponent.getLogName()); - filter.add(new ControllerIdPredicate(opponentId)); - TargetCreaturePermanent target = new TargetCreaturePermanent(0,1, filter,false); - ability.addTarget(target); - } - } - } + Ability ability = new EntersBattlefieldTriggeredAbility(new MoltenPrimordialEffect(), false); + ability.setTargetAdjuster(MoltenPrimordialAdjuster.instance); + this.addAbility(ability); } public MoltenPrimordial(final MoltenPrimordial card) { @@ -71,6 +58,24 @@ public final class MoltenPrimordial extends CardImpl { } } +enum MoltenPrimordialAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + for (UUID opponentId : game.getOpponents(ability.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature from opponent " + opponent.getLogName()); + filter.add(new ControllerIdPredicate(opponentId)); + TargetCreaturePermanent target = new TargetCreaturePermanent(0, 1, filter, false); + ability.addTarget(target); + } + } + } +} + class MoltenPrimordialEffect extends OneShotEffect { public MoltenPrimordialEffect() { @@ -90,7 +95,7 @@ class MoltenPrimordialEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { boolean result = false; - for (Target target: source.getTargets()) { + for (Target target : source.getTargets()) { if (target instanceof TargetCreaturePermanent) { Permanent targetCreature = game.getPermanent(target.getFirstTarget()); if (targetCreature != null) { diff --git a/Mage.Sets/src/mage/cards/n/NahirisWrath.java b/Mage.Sets/src/mage/cards/n/NahirisWrath.java index 900a5afd36..0d4a764c73 100644 --- a/Mage.Sets/src/mage/cards/n/NahirisWrath.java +++ b/Mage.Sets/src/mage/cards/n/NahirisWrath.java @@ -1,7 +1,6 @@ package mage.cards.n; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.Cost; import mage.abilities.costs.VariableCost; @@ -19,15 +18,17 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInHand; import mage.target.common.TargetCreatureOrPlaneswalker; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class NahirisWrath extends CardImpl { public NahirisWrath(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); // As an additional cost to cast Nahiri's Wrath, discard X cards. this.getSpellAbility().addCost(new NahirisWrathAdditionalCost()); @@ -36,8 +37,22 @@ public final class NahirisWrath extends CardImpl { Effect effect = new DamageTargetEffect(new DiscardCostCardConvertedMana()); effect.setText("{this} deals damage equal to the total converted mana cost of the discarded cards to each of up to X target creatures and/or planeswalkers"); this.getSpellAbility().addEffect(effect); + this.getSpellAbility().setTargetAdjuster(NahirisWrathAdjuster.instance); } + public NahirisWrath(final NahirisWrath card) { + super(card); + } + + @Override + public NahirisWrath copy() { + return new NahirisWrath(this); + } +} + +enum NahirisWrathAdjuster implements TargetAdjuster { + instance; + @Override public void adjustTargets(Ability ability, Game game) { ability.getTargets().clear(); @@ -52,15 +67,6 @@ public final class NahirisWrath extends CardImpl { ability.addTarget(new TargetCreatureOrPlaneswalker(0, numTargets, new FilterCreatureOrPlaneswalkerPermanent(), false)); } } - - public NahirisWrath(final NahirisWrath card) { - super(card); - } - - @Override - public NahirisWrath copy() { - return new NahirisWrath(this); - } } class NahirisWrathAdditionalCost extends VariableCostImpl { diff --git a/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java b/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java index 2c3bf2f8f7..e90ec46868 100644 --- a/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java +++ b/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java @@ -26,11 +26,11 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; import java.util.UUID; /** - * * @author spjspj */ public final class NazahnReveredBladesmith extends CardImpl { @@ -65,25 +65,10 @@ public final class NazahnReveredBladesmith extends CardImpl { // Whenever an equipped creature you control attacks, you may tap target creature defending player controls. Ability ability = new AttacksCreatureYouControlTriggeredAbility(new NazahnTapEffect(), true, equippedFilter, true); ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls"))); + ability.setTargetAdjuster(NazahnReveredBladesmithAdjuster.instance); this.addAbility(ability); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof AttacksCreatureYouControlTriggeredAbility) { - FilterCreaturePermanent filterDefender = new FilterCreaturePermanent("creature defending player controls"); - for (Effect effect : ability.getEffects()) { - if (effect instanceof NazahnTapEffect) { - filterDefender.add(new ControllerIdPredicate(game.getCombat().getDefendingPlayerId(effect.getTargetPointer().getFirst(game, ability), game))); - break; - } - } - ability.getTargets().clear(); - TargetCreaturePermanent target = new TargetCreaturePermanent(filterDefender); - ability.addTarget(target); - } - } - public NazahnReveredBladesmith(final NazahnReveredBladesmith card) { super(card); } @@ -94,6 +79,24 @@ public final class NazahnReveredBladesmith extends CardImpl { } } +enum NazahnReveredBladesmithAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + FilterCreaturePermanent filterDefender = new FilterCreaturePermanent("creature defending player controls"); + for (Effect effect : ability.getEffects()) { + if (effect instanceof NazahnTapEffect) { + filterDefender.add(new ControllerIdPredicate(game.getCombat().getDefendingPlayerId(effect.getTargetPointer().getFirst(game, ability), game))); + break; + } + } + ability.getTargets().clear(); + TargetCreaturePermanent target = new TargetCreaturePermanent(filterDefender); + ability.addTarget(target); + } +} + class NazahnTapEffect extends TapTargetEffect { NazahnTapEffect() { diff --git a/Mage.Sets/src/mage/cards/n/NecropolisFiend.java b/Mage.Sets/src/mage/cards/n/NecropolisFiend.java index a4219545b3..db6e9c26c8 100644 --- a/Mage.Sets/src/mage/cards/n/NecropolisFiend.java +++ b/Mage.Sets/src/mage/cards/n/NecropolisFiend.java @@ -1,11 +1,11 @@ package mage.cards.n; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.Cost; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.VariableCost; import mage.abilities.costs.common.ExileFromGraveCost; import mage.abilities.costs.common.TapSourceCost; @@ -21,8 +21,8 @@ import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.game.Game; @@ -30,15 +30,17 @@ import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class NecropolisFiend extends CardImpl { public NecropolisFiend(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{7}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{7}{B}{B}"); this.subtype.add(SubType.DEMON); this.power = new MageInt(4); @@ -46,54 +48,29 @@ public final class NecropolisFiend extends CardImpl { // Delve this.addAbility(new DelveAbility()); + // Flying this.addAbility(FlyingAbility.getInstance()); - //TODO: Make ability properly copiable + // {X}, {T}, Exile X cards from your graveyard: Target creature gets -X/-X until end of turn. DynamicValue xValue = new SignInversionDynamicValue(new ManacostVariableValue()); - Effect effect = new BoostTargetEffect(xValue,xValue,Duration.EndOfTurn); + Effect effect = new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn); effect.setText("Target creature gets -X/-X until end of turn"); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}")); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, effect, + new ManaCostsImpl("{X}") + ); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent()); - ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(1,1,new FilterCard("cards from your graveyard")), "Exile X cards from your graveyard")); + ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard( + 1, 1, new FilterCard("cards from your graveyard") + ), "Exile X cards from your graveyard")); + ability.setTargetAdjuster(NecropolisFiendTargetAdjuster.instance); + ability.setCostAdjuster(NecropolisFiendCostAdjuster.instance); this.addAbility(ability); } - @Override - public void adjustCosts(Ability ability, Game game) { - if (ability instanceof SimpleActivatedAbility) { - Player controller = game.getPlayer(ability.getControllerId()); - if (controller != null) { - for (VariableCost variableCost: ability.getManaCostsToPay().getVariableCosts()) { - if (variableCost instanceof VariableManaCost) { - ((VariableManaCost)variableCost).setMaxX(controller.getGraveyard().size()); - } - } - } - } - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SimpleActivatedAbility) { - int xValue = ability.getManaCostsToPay().getX(); - for(Cost cost: ability.getCosts()) { - if (cost instanceof ExileFromGraveCost) { - ExileFromGraveCost exileCost = (ExileFromGraveCost) cost; - for(Target target: exileCost.getTargets()) { - if (target instanceof TargetCardInYourGraveyard) { - target.setMaxNumberOfTargets(xValue); - target.setMinNumberOfTargets(xValue); - } - } - - } - } - } - } - public NecropolisFiend(final NecropolisFiend card) { super(card); } @@ -103,3 +80,41 @@ public final class NecropolisFiend extends CardImpl { return new NecropolisFiend(this); } } + +enum NecropolisFiendCostAdjuster implements CostAdjuster { + instance; + + @Override + public void adjustCosts(Ability ability, Game game) { + Player controller = game.getPlayer(ability.getControllerId()); + if (controller == null) { + return; + } + for (VariableCost variableCost : ability.getManaCostsToPay().getVariableCosts()) { + if (variableCost instanceof VariableManaCost) { + ((VariableManaCost) variableCost).setMaxX(controller.getGraveyard().size()); + } + } + } +} + +enum NecropolisFiendTargetAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + int xValue = ability.getManaCostsToPay().getX(); + for (Cost cost : ability.getCosts()) { + if (!(cost instanceof ExileFromGraveCost)) { + continue; + } + ExileFromGraveCost exileCost = (ExileFromGraveCost) cost; + for (Target target : exileCost.getTargets()) { + if (target instanceof TargetCardInYourGraveyard) { + target.setMaxNumberOfTargets(xValue); + target.setMinNumberOfTargets(xValue); + } + } + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/n/NecroticPlague.java b/Mage.Sets/src/mage/cards/n/NecroticPlague.java index 00d17e6213..5bc9c3137a 100644 --- a/Mage.Sets/src/mage/cards/n/NecroticPlague.java +++ b/Mage.Sets/src/mage/cards/n/NecroticPlague.java @@ -1,7 +1,6 @@ package mage.cards.n; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.DiesAttachedTriggeredAbility; @@ -15,35 +14,24 @@ import mage.abilities.keyword.EnchantAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.TargetController; -import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerPredicate; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetOpponentsCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author BetaSteward_at_googlemail.com */ public final class NecroticPlague extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); - - static { - filter.add(new ControllerPredicate(TargetController.OPPONENT)); - } - public NecroticPlague(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); this.subtype.add(SubType.AURA); @@ -53,33 +41,18 @@ public final class NecroticPlague extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Enchanted creature has "At the beginning of your upkeep, sacrifice this creature." // When enchanted creature dies, its controller chooses target creature one of their opponents controls. Return Necrotic Plague from its owner's graveyard to the battlefield attached to that creature. - Ability gainedAbility = new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceEffect(), TargetController.YOU, false); - Effect effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA, Duration.WhileOnBattlefield); + ability = new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceEffect(), TargetController.YOU, false); + Effect effect = new GainAbilityAttachedEffect(ability, AttachmentType.AURA, Duration.WhileOnBattlefield); effect.setText("Enchanted creature has \"At the beginning of your upkeep, sacrifice this creature.\""); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); - this.addAbility(new DiesAttachedTriggeredAbility(new NecroticPlagueEffect(), "enchanted creature", false)); - } + ability = new DiesAttachedTriggeredAbility(new NecroticPlagueEffect(), "enchanted creature", false); + ability.setTargetAdjuster(NecroticPlagueAdjuster.instance); + this.addAbility(ability); - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof DiesAttachedTriggeredAbility) { - Permanent attachedTo = null; - for (Effect effect : ability.getEffects()) { - attachedTo = (Permanent) effect.getValue("attachedTo"); - } - if (attachedTo != null) { - Player creatureController = game.getPlayer(attachedTo.getControllerId()); - if (creatureController != null) { - ability.setControllerId(creatureController.getId()); - ability.getTargets().clear(); - TargetPermanent target = new TargetPermanent(filter); - ability.getTargets().add(target); - } - } - } } public NecroticPlague(final NecroticPlague card) { @@ -93,11 +66,35 @@ public final class NecroticPlague extends CardImpl { } +enum NecroticPlagueAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + Permanent attachedTo = null; + for (Effect effect : ability.getEffects()) { + attachedTo = (Permanent) effect.getValue("attachedTo"); + } + if (attachedTo == null) { + return; + } + Player creatureController = game.getPlayer(attachedTo.getControllerId()); + if (creatureController == null) { + return; + } + ability.setControllerId(creatureController.getId()); + ability.getTargets().clear(); + TargetPermanent target = new TargetOpponentsCreaturePermanent(); + ability.getTargets().add(target); + } +} + class NecroticPlagueEffect extends OneShotEffect { public NecroticPlagueEffect() { super(Outcome.PutCardInPlay); - staticText = "its controller chooses target creature one of their opponents controls. Return {this} from its owner's graveyard to the battlefield attached to that creature"; + staticText = "its controller chooses target creature one of their opponents controls. " + + "Return {this} from its owner's graveyard to the battlefield attached to that creature"; } public NecroticPlagueEffect(final NecroticPlagueEffect effect) { diff --git a/Mage.Sets/src/mage/cards/n/NostalgicDreams.java b/Mage.Sets/src/mage/cards/n/NostalgicDreams.java index b0de519a18..5570440c6d 100644 --- a/Mage.Sets/src/mage/cards/n/NostalgicDreams.java +++ b/Mage.Sets/src/mage/cards/n/NostalgicDreams.java @@ -1,9 +1,7 @@ package mage.cards.n; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.costs.common.DiscardXTargetCost; import mage.abilities.dynamicvalue.common.GetXValue; import mage.abilities.effects.Effect; @@ -15,11 +13,12 @@ import mage.constants.CardType; import mage.filter.FilterCard; import mage.filter.StaticFilters; import mage.game.Game; -import mage.target.Target; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class NostalgicDreams extends CardImpl { @@ -33,27 +32,31 @@ public final class NostalgicDreams extends CardImpl { Effect effect = new ReturnFromGraveyardToHandTargetEffect(); effect.setText("Return X target cards from your graveyard to your hand"); this.getSpellAbility().addEffect(effect); + this.getSpellAbility().setTargetAdjuster(NostalgicDreamsAdjuster.instance); + // Exile Nostalgic Dreams. this.getSpellAbility().addEffect(ExileSpellEffect.getInstance()); - } public NostalgicDreams(final NostalgicDreams card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - int xValue = new GetXValue().calculate(game, ability, null); - Target target = new TargetCardInYourGraveyard(xValue, StaticFilters.FILTER_CARD_FROM_YOUR_GRAVEYARD); - ability.addTarget(target); - } - - } - @Override public NostalgicDreams copy() { return new NostalgicDreams(this); } } + +enum NostalgicDreamsAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCardInYourGraveyard( + new GetXValue().calculate(game, ability, null), + StaticFilters.FILTER_CARD_FROM_YOUR_GRAVEYARD + )); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/n/NoxiousGhoul.java b/Mage.Sets/src/mage/cards/n/NoxiousGhoul.java index 6f7d180757..a789298444 100644 --- a/Mage.Sets/src/mage/cards/n/NoxiousGhoul.java +++ b/Mage.Sets/src/mage/cards/n/NoxiousGhoul.java @@ -1,7 +1,6 @@ package mage.cards.n; -import java.util.UUID; import mage.MageInt; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.effects.common.continuous.BoostAllEffect; @@ -10,42 +9,45 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.CardIdPredicate; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.UUID; /** - * * @author jeffwadsworth */ public final class NoxiousGhoul extends CardImpl { - final FilterPermanent filter = new FilterPermanent("Noxious Ghoul or another Zombie"); - final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("non-Zombie"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + private static final FilterPermanent filter2 = new FilterPermanent(); + + static { + filter.add(new CardTypePredicate(CardType.CREATURE)); + filter.add(Predicates.not(new SubtypePredicate(SubType.ZOMBIE))); + filter2.add(NoxiousGhoulPredicate.instance); + } public NoxiousGhoul(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(3); this.toughness = new MageInt(3); - filter.add(Predicates.or( - new CardIdPredicate(this.getId()), - new SubtypePredicate(SubType.ZOMBIE))); - - filter2.add(new CardTypePredicate(CardType.CREATURE)); - filter2.add(Predicates.not( - new SubtypePredicate(SubType.ZOMBIE))); - - final String rule = "Whenever {this} or another Zombie enters the battlefield, all non-Zombie creatures get -1/-1 until end of turn."; - // Whenever Noxious Ghoul or another Zombie enters the battlefield, all non-Zombie creatures get -1/-1 until end of turn. - this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new BoostAllEffect(-1, -1, Duration.EndOfTurn, filter2, false), filter, false, rule)); + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + new BoostAllEffect(-1, -1, Duration.EndOfTurn, filter, false), + filter2, "Whenever {this} or another Zombie enters the battlefield, " + + "all non-Zombie creatures get -1/-1 until end of turn." + )); } public NoxiousGhoul(final NoxiousGhoul card) { @@ -57,3 +59,13 @@ public final class NoxiousGhoul extends CardImpl { return new NoxiousGhoul(this); } } + +enum NoxiousGhoulPredicate implements ObjectSourcePlayerPredicate> { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + return input.getObject().hasSubtype(SubType.ZOMBIE, game) + || input.getObject().getId().equals(input.getSourceId()); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/o/OathOfDruids.java b/Mage.Sets/src/mage/cards/o/OathOfDruids.java index c8bb0d56eb..652548ad6f 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfDruids.java +++ b/Mage.Sets/src/mage/cards/o/OathOfDruids.java @@ -1,15 +1,10 @@ package mage.cards.o; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; +import mage.cards.*; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TargetController; @@ -21,20 +16,15 @@ import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author Plopman */ public final class OathOfDruids extends CardImpl { - private final UUID originalId; - private static final FilterPlayer filter = new FilterPlayer(); - - static { - filter.add(new OathOfDruidsPredicate()); - } - public OathOfDruids(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); @@ -42,27 +32,12 @@ public final class OathOfDruids extends CardImpl { // The first player may reveal cards from the top of their library until he or she reveals a creature card. // If he or she does, that player puts that card onto the battlefield and all other cards revealed this way into their graveyard. Ability ability = new BeginningOfUpkeepTriggeredAbility(new OathOfDruidsEffect(), TargetController.ANY, false); - ability.addTarget(new TargetPlayer(1, 1, false, filter)); - originalId = ability.getOriginalId(); + ability.setTargetAdjuster(OathOfDruidsAdjuster.instance); this.addAbility(ability); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - Player activePlayer = game.getPlayer(game.getActivePlayerId()); - if (activePlayer != null) { - ability.getTargets().clear(); - TargetPlayer target = new TargetPlayer(1, 1, false, filter); - target.setTargetController(activePlayer.getId()); - ability.getTargets().add(target); - } - } - } - public OathOfDruids(final OathOfDruids card) { super(card); - this.originalId = card.originalId; } @Override @@ -71,6 +46,26 @@ public final class OathOfDruids extends CardImpl { } } +enum OathOfDruidsAdjuster implements TargetAdjuster { + instance; + private static final FilterPlayer filter = new FilterPlayer(); + + static { + filter.add(new OathOfDruidsPredicate()); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + Player activePlayer = game.getPlayer(game.getActivePlayerId()); + if (activePlayer != null) { + ability.getTargets().clear(); + TargetPlayer target = new TargetPlayer(1, 1, false, filter); + target.setTargetController(activePlayer.getId()); + ability.getTargets().add(target); + } + } +} + class OathOfDruidsPredicate implements ObjectSourcePlayerPredicate> { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); diff --git a/Mage.Sets/src/mage/cards/o/OathOfGhouls.java b/Mage.Sets/src/mage/cards/o/OathOfGhouls.java index 310ab0a52a..73b5eb4677 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfGhouls.java +++ b/Mage.Sets/src/mage/cards/o/OathOfGhouls.java @@ -1,7 +1,6 @@ package mage.cards.o; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -15,57 +14,36 @@ import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.FilterPlayer; +import mage.filter.StaticFilters; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.ObjectSourcePlayer; import mage.filter.predicate.ObjectSourcePlayerPredicate; -import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.other.OwnerIdPredicate; import mage.game.Game; import mage.players.Player; import mage.target.Target; import mage.target.TargetPlayer; import mage.target.common.TargetCardInGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class OathOfGhouls extends CardImpl { - private final UUID originalId; - private static final FilterPlayer filter = new FilterPlayer(); - - static { - filter.add(new OathOfGhoulsPredicate()); - } - public OathOfGhouls(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); // At the beginning of each player's upkeep, that player chooses target player whose graveyard has fewer creature cards in it than their graveyard does and is their opponent. The first player may return a creature card from their graveyard to their hand. Ability ability = new BeginningOfUpkeepTriggeredAbility(new OathOfGhoulsEffect(), TargetController.ANY, false); - ability.addTarget(new TargetPlayer(1, 1, false, filter)); + ability.setTargetAdjuster(OathOfGhoulsAdjuster.instance); this.addAbility(ability); - originalId = ability.getOriginalId(); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - Player activePlayer = game.getPlayer(game.getActivePlayerId()); - if (activePlayer != null) { - ability.getTargets().clear(); - TargetPlayer target = new TargetPlayer(1, 1, false, filter); - target.setTargetController(activePlayer.getId()); - ability.getTargets().add(target); - } - } } public OathOfGhouls(final OathOfGhouls card) { super(card); - this.originalId = card.originalId; } @Override @@ -74,14 +52,28 @@ public final class OathOfGhouls extends CardImpl { } } -class OathOfGhoulsPredicate implements ObjectSourcePlayerPredicate> { - - private static final FilterCard filter = new FilterCard("creature cards"); +enum OathOfGhoulsAdjuster implements TargetAdjuster { + instance; + private static final FilterPlayer filter = new FilterPlayer(); static { - filter.add(new CardTypePredicate(CardType.CREATURE)); + filter.add(new OathOfGhoulsPredicate()); } + @Override + public void adjustTargets(Ability ability, Game game) { + Player activePlayer = game.getPlayer(game.getActivePlayerId()); + if (activePlayer != null) { + ability.getTargets().clear(); + TargetPlayer target = new TargetPlayer(1, 1, false, filter); + target.setTargetController(activePlayer.getId()); + ability.getTargets().add(target); + } + } +} + +class OathOfGhoulsPredicate implements ObjectSourcePlayerPredicate> { + @Override public boolean apply(ObjectSourcePlayer input, Game game) { Player targetPlayer = input.getObject(); @@ -91,8 +83,8 @@ class OathOfGhoulsPredicate implements ObjectSourcePlayerPredicate> { - private static final FilterLandPermanent FILTER = new FilterLandPermanent(); - @Override public boolean apply(ObjectSourcePlayer input, Game game) { - // input.getPlayerId() -- source controller id - // input.getObject() -- checking player - Player targetPlayer = input.getObject(); //Get active input.playerId because adjust target is used after canTarget function - Player activePlayer = game.getPlayer(game.getActivePlayerId()); - - if (targetPlayer == null || activePlayer == null) { + UUID activePlayerId = game.getActivePlayerId(); + if (targetPlayer == null || activePlayerId == null) { return false; } - - // must be opponent - if (!activePlayer.hasOpponent(targetPlayer.getId(), game)) { + if (!targetPlayer.hasOpponent(activePlayerId, game)) { return false; } + int countTargetPlayer = game.getBattlefield().countAll(StaticFilters.FILTER_LAND, targetPlayer.getId(), game); + int countActivePlayer = game.getBattlefield().countAll(StaticFilters.FILTER_LAND, activePlayerId, game); - // must have more lands than active player - int countTargetPlayer = game.getBattlefield().countAll(FILTER, targetPlayer.getId(), game); - int countActivePlayer = game.getBattlefield().countAll(FILTER, activePlayer.getId(), game); return countTargetPlayer > countActivePlayer; } diff --git a/Mage.Sets/src/mage/cards/o/OathOfMages.java b/Mage.Sets/src/mage/cards/o/OathOfMages.java index 4f43c74665..9621fcb8a7 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfMages.java +++ b/Mage.Sets/src/mage/cards/o/OathOfMages.java @@ -1,7 +1,6 @@ package mage.cards.o; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -17,46 +16,26 @@ import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class OathOfMages extends CardImpl { - private final UUID originalId; - private static final FilterPlayer filter = new FilterPlayer(); - - static { - filter.add(new OathOfMagesPredicate()); - } - public OathOfMages(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); // At the beginning of each player's upkeep, that player chooses target player who has more life than he or she does and is their opponent. The first player may have Oath of Mages deal 1 damage to the second player. Ability ability = new BeginningOfUpkeepTriggeredAbility(new OathOfMagesEffect(), TargetController.ANY, false); - ability.addTarget(new TargetPlayer(1, 1, false, filter)); + ability.setTargetAdjuster(OathOfMagesAdjuster.instance); this.addAbility(ability); - originalId = ability.getOriginalId(); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - Player activePlayer = game.getPlayer(game.getActivePlayerId()); - if (activePlayer != null) { - ability.getTargets().clear(); - TargetPlayer target = new TargetPlayer(1, 1, false, filter); - target.setTargetController(activePlayer.getId()); - ability.getTargets().add(target); - } - } } public OathOfMages(final OathOfMages card) { super(card); - this.originalId = card.originalId; } @Override @@ -65,6 +44,26 @@ public final class OathOfMages extends CardImpl { } } +enum OathOfMagesAdjuster implements TargetAdjuster { + instance; + private static final FilterPlayer filter = new FilterPlayer(); + + static { + filter.add(new OathOfMagesPredicate()); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + Player activePlayer = game.getPlayer(game.getActivePlayerId()); + if (activePlayer != null) { + ability.getTargets().clear(); + TargetPlayer target = new TargetPlayer(1, 1, false, filter); + target.setTargetController(activePlayer.getId()); + ability.getTargets().add(target); + } + } +} + class OathOfMagesPredicate implements ObjectSourcePlayerPredicate> { @Override diff --git a/Mage.Sets/src/mage/cards/o/OathOfScholars.java b/Mage.Sets/src/mage/cards/o/OathOfScholars.java index 9a61ce6de8..75d206ce16 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfScholars.java +++ b/Mage.Sets/src/mage/cards/o/OathOfScholars.java @@ -1,7 +1,6 @@ package mage.cards.o; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -17,47 +16,26 @@ import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author jeffwadsworth */ public final class OathOfScholars extends CardImpl { - private final UUID originalId; - private static final FilterPlayer filter = new FilterPlayer(); - - static { - filter.add(new OathOfScholarsPredicate()); - } - public OathOfScholars(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); // At the beginning of each player's upkeep, that player chooses target player who has more cards in hand than he or she does and is their opponent. The first player may discard their hand and draw three cards. Ability ability = new BeginningOfUpkeepTriggeredAbility(new OathOfScholarsEffect(), TargetController.ANY, false); - ability.addTarget(new TargetPlayer(1, 1, false, filter)); + ability.setTargetAdjuster(OathOfScholarsAdjuster.instance); this.addAbility(ability); - originalId = ability.getOriginalId(); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - Player activePlayer = game.getPlayer(game.getActivePlayerId()); - if (activePlayer != null) { - ability.getTargets().clear(); - TargetPlayer target = new TargetPlayer(1, 1, false, filter); - target.setTargetController(activePlayer.getId()); - ability.getTargets().add(target); - } - } } public OathOfScholars(final OathOfScholars card) { super(card); - this.originalId = card.originalId; } @Override @@ -66,6 +44,26 @@ public final class OathOfScholars extends CardImpl { } } +enum OathOfScholarsAdjuster implements TargetAdjuster { + instance; + private static final FilterPlayer filter = new FilterPlayer(); + + static { + filter.add(new OathOfScholarsPredicate()); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + Player activePlayer = game.getPlayer(game.getActivePlayerId()); + if (activePlayer != null) { + ability.getTargets().clear(); + TargetPlayer target = new TargetPlayer(1, 1, false, filter); + target.setTargetController(activePlayer.getId()); + ability.getTargets().add(target); + } + } +} + class OathOfScholarsPredicate implements ObjectSourcePlayerPredicate> { @Override diff --git a/Mage.Sets/src/mage/cards/o/OpenIntoWonder.java b/Mage.Sets/src/mage/cards/o/OpenIntoWonder.java index 41ef18e9eb..e92b99a2b5 100644 --- a/Mage.Sets/src/mage/cards/o/OpenIntoWonder.java +++ b/Mage.Sets/src/mage/cards/o/OpenIntoWonder.java @@ -1,9 +1,7 @@ package mage.cards.o; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; @@ -13,12 +11,13 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.filter.StaticFilters; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class OpenIntoWonder extends CardImpl { @@ -30,28 +29,28 @@ public final class OpenIntoWonder extends CardImpl { Effect effect = new CantBeBlockedTargetEffect(Duration.EndOfTurn); effect.setText("X target creatures can't be blocked this turn"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1, StaticFilters.FILTER_PERMANENT_CREATURE, false)); Ability abilityToGain = new DealsCombatDamageToAPlayerTriggeredAbility(new DrawCardSourceControllerEffect(1), false); this.getSpellAbility().addEffect(new GainAbilityTargetEffect(abilityToGain, Duration.EndOfTurn, "Until end of turn, those creatures gain \"Whenever this creature deals combat damage to a player, draw a card.\"")); + this.getSpellAbility().setTargetAdjuster(OpenIntoWonderAdjuster.instance); } public OpenIntoWonder(final OpenIntoWonder card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int numberOfTargets = ability.getManaCostsToPay().getX(); - numberOfTargets = Math.min(game.getBattlefield().count(StaticFilters.FILTER_PERMANENT_CREATURE, ability.getSourceId(), ability.getControllerId(), game), numberOfTargets); - ability.addTarget(new TargetCreaturePermanent(numberOfTargets)); - } - } - @Override public OpenIntoWonder copy() { return new OpenIntoWonder(this); } } + +enum OpenIntoWonderAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/o/OpenSeason.java b/Mage.Sets/src/mage/cards/o/OpenSeason.java index 74377fe722..c871340981 100644 --- a/Mage.Sets/src/mage/cards/o/OpenSeason.java +++ b/Mage.Sets/src/mage/cards/o/OpenSeason.java @@ -1,7 +1,6 @@ package mage.cards.o; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -22,10 +21,11 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; -import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author Styxo */ public final class OpenSeason extends CardImpl { @@ -37,7 +37,7 @@ public final class OpenSeason extends CardImpl { Effect effect = new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()); effect.setText("for each opponent, put a bounty counter on target creature that player controls"); Ability ability = new EntersBattlefieldTriggeredAbility(effect); - ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(OpenSeasonAdjuster.instance); this.addAbility(ability); // Creatures your opponent control with bounty counters on them can't activate abilities @@ -48,19 +48,6 @@ public final class OpenSeason extends CardImpl { } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof EntersBattlefieldTriggeredAbility) { - ability.getTargets().clear(); - for (UUID opponentId : game.getOpponents(ability.getControllerId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - ability.addTarget(new TargetPermanent(new FilterCreaturePermanent("creature from opponent " + opponent.getLogName()))); - } - } - } - } - public OpenSeason(final OpenSeason card) { super(card); } @@ -71,6 +58,21 @@ public final class OpenSeason extends CardImpl { } } +enum OpenSeasonAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + for (UUID opponentId : game.getOpponents(ability.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null) { + ability.addTarget(new TargetPermanent(new FilterCreaturePermanent("creature from opponent " + opponent.getLogName()))); + } + } + } +} + class OpenSeasonRestrictionEffect extends RestrictionEffect { public OpenSeasonRestrictionEffect() { diff --git a/Mage.Sets/src/mage/cards/o/OrimsThunder.java b/Mage.Sets/src/mage/cards/o/OrimsThunder.java index ca705f089d..b1f8a47c07 100644 --- a/Mage.Sets/src/mage/cards/o/OrimsThunder.java +++ b/Mage.Sets/src/mage/cards/o/OrimsThunder.java @@ -3,7 +3,6 @@ package mage.cards.o; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.common.KickedCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.OneShotEffect; @@ -18,17 +17,17 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; import java.util.UUID; /** - * * @author jeffwadsworth */ public final class OrimsThunder extends CardImpl { public OrimsThunder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); // Kicker {R} this.addAbility(new KickerAbility("{R}")); @@ -39,16 +38,9 @@ public final class OrimsThunder extends CardImpl { this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new OrimsThunderEffect2(), KickedCondition.instance, - "If Orim's Thunder was kicked, it deals damage equal to that permanent's converted mana cost to target creature")); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - if (KickedCondition.instance.apply(game, ability)) { - ability.addTarget(new TargetCreaturePermanent()); - } - } + "If Orim's Thunder was kicked, it deals damage equal to that permanent's converted mana cost to target creature") + ); + this.getSpellAbility().setTargetAdjuster(OrimsThunderAdjuster.instance); } public OrimsThunder(final OrimsThunder card) { @@ -61,6 +53,18 @@ public final class OrimsThunder extends CardImpl { } } +enum OrimsThunderAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + if (KickedCondition.instance.apply(game, ability)) { + ability.addTarget(new TargetCreaturePermanent()); + } + } + +} + class OrimsThunderEffect2 extends OneShotEffect { OrimsThunderEffect2() { diff --git a/Mage.Sets/src/mage/cards/p/Pandemonium.java b/Mage.Sets/src/mage/cards/p/Pandemonium.java index 82d3bfefe3..581cb03e13 100644 --- a/Mage.Sets/src/mage/cards/p/Pandemonium.java +++ b/Mage.Sets/src/mage/cards/p/Pandemonium.java @@ -1,7 +1,6 @@ package mage.cards.p; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -16,39 +15,31 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetAnyTarget; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class Pandemonium extends CardImpl { - private final UUID originalId; - public Pandemonium(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); // Whenever a creature enters the battlefield, that creature's controller may have it deal damage equal to its power to any target of their choice. - Ability ability = new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new PandemoniumEffect(), StaticFilters.FILTER_PERMANENT_CREATURE, false, SetTargetPointer.PERMANENT, ""); + Ability ability = new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, new PandemoniumEffect(), + StaticFilters.FILTER_PERMANENT_CREATURE, + false, SetTargetPointer.PERMANENT, "" + ); ability.addTarget(new TargetAnyTarget()); - originalId = ability.getOriginalId(); + ability.setTargetAdjuster(PandemoniumAdjuster.instance); this.addAbility(ability); } public Pandemonium(final Pandemonium card) { super(card); - this.originalId = card.originalId; - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - UUID creatureId = ability.getEffects().get(0).getTargetPointer().getFirst(game, ability); - Permanent creature = game.getPermanent(creatureId); - if (creature != null) { - ability.getTargets().get(0).setTargetController(creature.getControllerId()); - } - } } @Override @@ -57,6 +48,19 @@ public final class Pandemonium extends CardImpl { } } +enum PandemoniumAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + UUID creatureId = ability.getEffects().get(0).getTargetPointer().getFirst(game, ability); + Permanent creature = game.getPermanent(creatureId); + if (creature != null) { + ability.getTargets().get(0).setTargetController(creature.getControllerId()); + } + } +} + class PandemoniumEffect extends OneShotEffect { public PandemoniumEffect() { diff --git a/Mage.Sets/src/mage/cards/p/PartWater.java b/Mage.Sets/src/mage/cards/p/PartWater.java index 0e7c6c11b1..47afdfb31e 100644 --- a/Mage.Sets/src/mage/cards/p/PartWater.java +++ b/Mage.Sets/src/mage/cards/p/PartWater.java @@ -1,9 +1,7 @@ package mage.cards.p; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.IslandwalkAbility; @@ -11,34 +9,26 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author fireshoes */ public final class PartWater extends CardImpl { public PartWater(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{X}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{X}{U}"); // X target creatures gain islandwalk until end of turn. Effect effect = new GainAbilityTargetEffect(new IslandwalkAbility(false), Duration.EndOfTurn); effect.setText("X target creatures gain islandwalk until end of turn"); this.getSpellAbility().getEffects().add(effect); - this.getSpellAbility().getTargets().add(new TargetCreaturePermanent(1,1)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures gain islandwalk until end of turn"); - ability.getTargets().add(new TargetCreaturePermanent(0, xValue, filter, false)); - } + this.getSpellAbility().getTargets().add(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(PartWaterAdjuster.instance); } public PartWater(final PartWater card) { @@ -50,3 +40,13 @@ public final class PartWater extends CardImpl { return new PartWater(this); } } + +enum PartWaterAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.getTargets().add(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/PhantasmalImage.java b/Mage.Sets/src/mage/cards/p/PhantasmalImage.java index 003ff68f88..9c0b2db68f 100644 --- a/Mage.Sets/src/mage/cards/p/PhantasmalImage.java +++ b/Mage.Sets/src/mage/cards/p/PhantasmalImage.java @@ -21,14 +21,13 @@ import mage.util.functions.ApplyToPermanent; import java.util.UUID; /** - * * @author North */ public final class PhantasmalImage extends CardImpl { private static final String effectText = "a copy of any creature on the battlefield, except it's an Illusion in addition to its other types and it has \"When this creature becomes the target of a spell or ability, sacrifice it.\""; - ApplyToPermanent phantasmalImageApplier = new ApplyToPermanent() { + private static final ApplyToPermanent phantasmalImageApplier = new ApplyToPermanent() { @Override public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { if (!permanent.hasSubtype(SubType.ILLUSION, game)) { diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianPurge.java b/Mage.Sets/src/mage/cards/p/PhyrexianPurge.java index da92e7b58a..526c986b5b 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianPurge.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianPurge.java @@ -1,9 +1,8 @@ package mage.cards.p; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.common.PayLifeCost; import mage.abilities.effects.common.DestroyMultiTargetEffect; import mage.abilities.effects.common.InfoEffect; @@ -13,9 +12,11 @@ import mage.constants.CardType; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author escplan9 - Derek Monturo */ public final class PhyrexianPurge extends CardImpl { @@ -28,26 +29,8 @@ public final class PhyrexianPurge extends CardImpl { this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE)); this.getSpellAbility().addEffect(new DestroyMultiTargetEffect()); this.getSpellAbility().addEffect(new InfoEffect("

{this} costs 3 life more to cast for each target")); - } - - @Override - public void adjustCosts(Ability ability, Game game) { - int numTargets = ability.getTargets().get(0).getTargets().size(); - if (numTargets > 0) { - ability.getCosts().add(new PayLifeCost(numTargets * 3)); - } - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - Player you = game.getPlayer(ownerId); - if(you != null) { - int maxTargets = you.getLife() / 3; - ability.addTarget(new TargetCreaturePermanent(0, maxTargets)); - } - } + this.getSpellAbility().setTargetAdjuster(PhyrexianPurgeTargetAdjuster.instance); + this.getSpellAbility().setCostAdjuster(PhyrexianPurgeCostAdjuster.instance); } public PhyrexianPurge(final PhyrexianPurge card) { @@ -59,3 +42,27 @@ public final class PhyrexianPurge extends CardImpl { return new PhyrexianPurge(this); } } + +enum PhyrexianPurgeCostAdjuster implements CostAdjuster { + instance; + + @Override + public void adjustCosts(Ability ability, Game game) { + int numTargets = ability.getTargets().get(0).getTargets().size(); + if (numTargets > 0) { + ability.getCosts().add(new PayLifeCost(numTargets * 3)); + } + } +} + +enum PhyrexianPurgeTargetAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + Player you = game.getPlayer(ability.getControllerId()); + int maxTargets = you.getLife() / 3; + ability.addTarget(new TargetCreaturePermanent(0, maxTargets)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/PollenRemedy.java b/Mage.Sets/src/mage/cards/p/PollenRemedy.java index 65d5256973..b13dadd098 100644 --- a/Mage.Sets/src/mage/cards/p/PollenRemedy.java +++ b/Mage.Sets/src/mage/cards/p/PollenRemedy.java @@ -1,4 +1,3 @@ - package mage.cards.p; import java.util.UUID; @@ -17,39 +16,30 @@ import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetAnyTargetAmount; +import mage.target.targetadjustment.TargetAdjuster; /** * * @author LoneFox - + * */ public final class PollenRemedy extends CardImpl { - private final UUID originalId; - public PollenRemedy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); // Kicker-Sacrifice a land. this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, new FilterControlledLandPermanent("a land"), true)))); // Prevent the next 3 damage that would be dealt this turn to any number of target creatures and/or players, divided as you choose. If Pollen Remedy was kicked, prevent the next 6 damage this way instead. Effect effect = new ConditionalReplacementEffect(new PreventDamageToTargetMultiAmountEffect(Duration.EndOfTurn, 6), - KickedCondition.instance, new PreventDamageToTargetMultiAmountEffect(Duration.EndOfTurn, 3)); + KickedCondition.instance, new PreventDamageToTargetMultiAmountEffect(Duration.EndOfTurn, 3)); effect.setText("Prevent the next 3 damage that would be dealt this turn to any number of targets, divided as you choose. if this spell was kicked, prevent the next 6 damage this way instead."); this.getSpellAbility().addEffect(effect); - originalId = this.getSpellAbility().getOriginalId(); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if(ability.getOriginalId().equals(originalId)) { - ability.addTarget(new TargetAnyTargetAmount(KickedCondition.instance.apply(game, ability) ? 6 : 3)); - } + this.getSpellAbility().setTargetAdjuster(PollenRemedyAdjuster.instance); } public PollenRemedy(final PollenRemedy card) { super(card); - this.originalId = card.originalId; } @Override @@ -57,3 +47,12 @@ public final class PollenRemedy extends CardImpl { return new PollenRemedy(this); } } + +enum PollenRemedyAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.addTarget(new TargetAnyTargetAmount(KickedCondition.instance.apply(game, ability) ? 6 : 3)); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PolukranosWorldEater.java b/Mage.Sets/src/mage/cards/p/PolukranosWorldEater.java index 6f6b1ca6b6..0fa30f941f 100644 --- a/Mage.Sets/src/mage/cards/p/PolukranosWorldEater.java +++ b/Mage.Sets/src/mage/cards/p/PolukranosWorldEater.java @@ -1,9 +1,6 @@ package mage.cards.p; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility; @@ -12,47 +9,44 @@ import mage.abilities.keyword.MonstrosityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.SuperType; -import mage.constants.TargetController; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.Target; import mage.target.common.TargetCreaturePermanentAmount; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; /** - * * * The value of X in Polukranos's last ability is equal to the value chosen - * for X when its activated ability was activated. - * + * for X when its activated ability was activated. + *

* * The number of targets chosen for the triggered ability must be at least one - * (if X wasn't 0) and at most X. You choose the division of damage as you put - * the ability on the stack, not as it resolves. Each target must be assigned - * at least 1 damage. In multiplayer games, you may choose creatures controlled - * by different opponents. - * + * (if X wasn't 0) and at most X. You choose the division of damage as you put + * the ability on the stack, not as it resolves. Each target must be assigned + * at least 1 damage. In multiplayer games, you may choose creatures controlled + * by different opponents. + *

* * If some, but not all, of the ability's targets become illegal, you can't change - * the division of damage. Damage that would've been dealt to illegal targets - * simply isn't dealt. - * + * the division of damage. Damage that would've been dealt to illegal targets + * simply isn't dealt. + *

* * As Polukranos's triggered ability resolves, Polukranos deals damage first, then - * the target creatures do. Although no creature will die until after the ability - * finishes resolving, the order could matter if Polukranos has wither or infect. + * the target creatures do. Although no creature will die until after the ability + * finishes resolving, the order could matter if Polukranos has wither or infect. * * @author LevelX2 */ public final class PolukranosWorldEater extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); - static { - filter.add(new ControllerPredicate(TargetController.OPPONENT)); - } - public PolukranosWorldEater(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HYDRA); @@ -61,20 +55,11 @@ public final class PolukranosWorldEater extends CardImpl { // {X}{X}{G}: Monstrosity X. this.addAbility(new MonstrosityAbility("{X}{X}{G}", Integer.MAX_VALUE)); + // When Polukranos, World Eater becomes monstrous, it deals X damage divided as you choose among any number of target creatures your opponents control. Each of those creatures deals damage equal to its power to Polukranos. Ability ability = new BecomesMonstrousSourceTriggeredAbility(new PolukranosWorldEaterEffect()); - ability.addTarget(new TargetCreaturePermanentAmount(1, filter)); + ability.setTargetAdjuster(PolukranosWorldEaterAdjuster.instance); this.addAbility(ability); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof BecomesMonstrousSourceTriggeredAbility) { - int xValue = ((BecomesMonstrousSourceTriggeredAbility) ability).getMonstrosityValue(); - ability.getTargets().clear(); - ability.addTarget(new TargetCreaturePermanentAmount(xValue, filter)); - } } public PolukranosWorldEater(final PolukranosWorldEater card) { @@ -87,6 +72,17 @@ public final class PolukranosWorldEater extends CardImpl { } } +enum PolukranosWorldEaterAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + int xValue = ((BecomesMonstrousSourceTriggeredAbility) ability).getMonstrosityValue(); + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanentAmount(xValue, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); + } +} + class PolukranosWorldEaterEffect extends OneShotEffect { public PolukranosWorldEaterEffect() { @@ -108,7 +104,7 @@ class PolukranosWorldEaterEffect extends OneShotEffect { if (!source.getTargets().isEmpty()) { Target multiTarget = source.getTargets().get(0); Set permanents = new HashSet<>(); - for (UUID target: multiTarget.getTargets()) { + for (UUID target : multiTarget.getTargets()) { Permanent permanent = game.getPermanent(target); if (permanent != null) { permanents.add(permanent); @@ -118,7 +114,7 @@ class PolukranosWorldEaterEffect extends OneShotEffect { // Each of those creatures deals damage equal to its power to Polukranos Permanent sourceCreature = game.getPermanent(source.getSourceId()); if (sourceCreature != null) { - for (Permanent permanent :permanents) { + for (Permanent permanent : permanents) { sourceCreature.damage(permanent.getPower().getValue(), permanent.getId(), game, false, true); } } diff --git a/Mage.Sets/src/mage/cards/p/PostmortemLunge.java b/Mage.Sets/src/mage/cards/p/PostmortemLunge.java index 6372d91cf1..75f35c769a 100644 --- a/Mage.Sets/src/mage/cards/p/PostmortemLunge.java +++ b/Mage.Sets/src/mage/cards/p/PostmortemLunge.java @@ -19,6 +19,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -34,6 +35,7 @@ public final class PostmortemLunge extends CardImpl { // Return target creature card with converted mana cost X from your graveyard to the battlefield. It gains haste. Exile it at the beginning of the next end step. this.getSpellAbility().addEffect(new PostmortemLungeEffect()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + this.getSpellAbility().setTargetAdjuster(PostmortemLungeAdjuster.instance); } public PostmortemLunge(final PostmortemLunge card) { @@ -44,16 +46,18 @@ public final class PostmortemLunge extends CardImpl { public PostmortemLunge copy() { return new PostmortemLunge(this); } +} + +enum PostmortemLungeAdjuster implements TargetAdjuster { + instance; @Override public void adjustTargets(Ability ability, Game game) { - if (ability.getAbilityType() == AbilityType.SPELL) { // otherwise the target is also added to the delayed triggered ability - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterCard filter = new FilterCreatureCard("creature card with converted mana cost " + xValue + " or less from your graveyard"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue + 1)); - ability.getTargets().add(new TargetCardInYourGraveyard(filter)); - } + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + FilterCard filter = new FilterCreatureCard("creature card with converted mana cost " + xValue + " or less from your graveyard"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue + 1)); + ability.getTargets().add(new TargetCardInYourGraveyard(filter)); } } diff --git a/Mage.Sets/src/mage/cards/p/Probe.java b/Mage.Sets/src/mage/cards/p/Probe.java index e8e4e7a689..6c98d48e93 100644 --- a/Mage.Sets/src/mage/cards/p/Probe.java +++ b/Mage.Sets/src/mage/cards/p/Probe.java @@ -1,9 +1,7 @@ package mage.cards.p; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.common.KickedCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.DrawDiscardControllerEffect; @@ -14,9 +12,11 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.game.Game; import mage.target.TargetPlayer; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author fireshoes */ public final class Probe extends CardImpl { @@ -33,16 +33,7 @@ public final class Probe extends CardImpl { new DiscardTargetEffect(2), KickedCondition.instance, "

if this spell was kicked, target player discards two cards")); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - if (KickedCondition.instance.apply(game, ability)) { - ability.addTarget(new TargetPlayer()); - } - } + this.getSpellAbility().setTargetAdjuster(ProbeAdjuster.instance); } public Probe(final Probe card) { @@ -54,3 +45,15 @@ public final class Probe extends CardImpl { return new Probe(this); } } + +enum ProbeAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + if (KickedCondition.instance.apply(game, ability)) { + ability.addTarget(new TargetPlayer()); + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/ProfaneCommand.java b/Mage.Sets/src/mage/cards/p/ProfaneCommand.java index 6f32b271f7..769dbf2bbf 100644 --- a/Mage.Sets/src/mage/cards/p/ProfaneCommand.java +++ b/Mage.Sets/src/mage/cards/p/ProfaneCommand.java @@ -1,7 +1,6 @@ package mage.cards.p; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.dynamicvalue.DynamicValue; @@ -26,6 +25,9 @@ import mage.game.Game; import mage.target.TargetPlayer; import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** * @author LevelX2 @@ -64,27 +66,8 @@ public final class ProfaneCommand extends CardImpl { mode.addEffect(effect); mode.addTarget(new TargetCreaturePermanent(0, 1)); this.getSpellAbility().addMode(mode); - } - @Override - public void adjustTargets(Ability ability, Game game) { - // adjust targets is called for every selected mode - Mode mode = ability.getModes().getMode(); - for (Effect effect : mode.getEffects()) { - if (effect instanceof ReturnFromGraveyardToBattlefieldTargetEffect) { - mode.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterCard filter = new FilterCreatureCard("creature card with converted mana cost " + xValue + " or less from your graveyard"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue + 1)); - mode.addTarget(new TargetCardInYourGraveyard(filter)); - } - if (effect instanceof GainAbilityTargetEffect) { - mode.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures gain fear until end of turn"); - mode.addTarget(new TargetCreaturePermanent(0, xValue, filter, false)); - } - } + this.getSpellAbility().setTargetAdjuster(ProfaneCommandAdjuster.instance); } public ProfaneCommand(final ProfaneCommand card) { @@ -96,3 +79,27 @@ public final class ProfaneCommand extends CardImpl { return new ProfaneCommand(this); } } + +enum ProfaneCommandAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + // adjust targets is called for every selected mode + Mode mode = ability.getModes().getMode(); + int xValue = ability.getManaCostsToPay().getX(); + for (Effect effect : mode.getEffects()) { + if (effect instanceof ReturnFromGraveyardToBattlefieldTargetEffect) { + mode.getTargets().clear(); + FilterCard filter = new FilterCreatureCard("creature card with converted mana cost " + xValue + " or less from your graveyard"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue + 1)); + mode.addTarget(new TargetCardInYourGraveyard(filter)); + } + if (effect instanceof GainAbilityTargetEffect) { + mode.getTargets().clear(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures gain fear until end of turn"); + mode.addTarget(new TargetCreaturePermanent(0, xValue, filter, false)); + } + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/q/QuarantineField.java b/Mage.Sets/src/mage/cards/q/QuarantineField.java index ee87bc53b4..591e3c8d54 100644 --- a/Mage.Sets/src/mage/cards/q/QuarantineField.java +++ b/Mage.Sets/src/mage/cards/q/QuarantineField.java @@ -1,7 +1,6 @@ package mage.cards.q; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -21,10 +20,12 @@ import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.util.CardUtil; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class QuarantineField extends CardImpl { @@ -35,42 +36,43 @@ public final class QuarantineField extends CardImpl { // Quarantine Field enters the battlefield with X isolation counters on it. this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.ISOLATION.createInstance()))); - // When Quarantine Field enters the battlefield, for each isolation counter on it, exile up to one target nonland permanent an opponenet controls until Quarantine Field leaves the battlefield. + // When Quarantine Field enters the battlefield, for each isolation counter on it, exile up to one target nonland permanent an opponent controls until Quarantine Field leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new QuarantineFieldEffect(), false); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); + ability.setTargetAdjuster(QuarantineFieldAdjuster.instance); this.addAbility(ability); - } public QuarantineField(final QuarantineField card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof EntersBattlefieldTriggeredAbility) { - Permanent sourceObject = game.getPermanent(ability.getSourceId()); - if (sourceObject != null) { - int isolationCounters = sourceObject.getCounters(game).getCount(CounterType.ISOLATION); - FilterNonlandPermanent filter = new FilterNonlandPermanent("up to " + isolationCounters + " nonland permanents controlled by any opponents"); - filter.add(new ControllerPredicate(TargetController.OPPONENT)); - ability.addTarget(new TargetPermanent(0, isolationCounters, filter, false)); - } - - } - } - @Override public QuarantineField copy() { return new QuarantineField(this); } } +enum QuarantineFieldAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + Permanent sourceObject = game.getPermanent(ability.getSourceId()); + if (sourceObject != null) { + int isolationCounters = sourceObject.getCounters(game).getCount(CounterType.ISOLATION); + FilterNonlandPermanent filter = new FilterNonlandPermanent("up to " + isolationCounters + " nonland permanents controlled by an opponent"); + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + ability.addTarget(new TargetPermanent(0, isolationCounters, filter, false)); + } + } +} + class QuarantineFieldEffect extends OneShotEffect { public QuarantineFieldEffect() { super(Outcome.Exile); - this.staticText = "for each isolation counter on it, exile up to one target nonland permanent an opponenet controls until {this} leaves the battlefield"; + this.staticText = "for each isolation counter on it, exile up to one target nonland permanent an opponent controls until {this} leaves the battlefield"; } public QuarantineFieldEffect(final QuarantineFieldEffect effect) { diff --git a/Mage.Sets/src/mage/cards/q/QuicksilverFountain.java b/Mage.Sets/src/mage/cards/q/QuicksilverFountain.java index 418f839664..5782524f16 100644 --- a/Mage.Sets/src/mage/cards/q/QuicksilverFountain.java +++ b/Mage.Sets/src/mage/cards/q/QuicksilverFountain.java @@ -1,6 +1,6 @@ - package mage.cards.q; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -12,19 +12,24 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BecomesBasicLandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.DependencyType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.targetpointer.FixedTarget; - -import java.util.UUID; -import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.common.TargetLandPermanent; +import mage.target.targetadjustment.TargetAdjuster; +import mage.target.targetpointer.FixedTarget; /** * @@ -32,42 +37,22 @@ import mage.target.common.TargetLandPermanent; */ public final class QuicksilverFountain extends CardImpl { - public final UUID originalId; - public QuicksilverFountain(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // At the beginning of each player's upkeep, that player puts a flood counter on target non-Island land he or she controls of their choice. That land is an Island for as long as it has a flood counter on it. Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new QuicksilverFountainEffect(), TargetController.ANY, false, true); ability.addTarget(new TargetLandPermanent()); - originalId = ability.getOriginalId(); + ability.setTargetAdjuster(QuicksilverFountainAdjuster.instance); this.addAbility(ability); // At the beginning of each end step, if all lands on the battlefield are Islands, remove all flood counters from them. Condition condition = new AllLandsAreSubtypeCondition(SubType.ISLAND); this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new QuicksilverFountainEffect2(), TargetController.ANY, condition, false)); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - Player activePlayer = game.getPlayer(game.getActivePlayerId()); - if (activePlayer != null) { - ability.getTargets().clear(); - FilterLandPermanent filter = new FilterLandPermanent(); - filter.add(Predicates.not(new SubtypePredicate(SubType.ISLAND))); - filter.add(new ControllerPredicate(TargetController.ACTIVE)); - TargetLandPermanent target = new TargetLandPermanent(1, 1, filter, false); - target.setTargetController(activePlayer.getId()); - ability.getTargets().add(target); - } - } } public QuicksilverFountain(final QuicksilverFountain card) { super(card); - this.originalId = card.originalId; } @Override @@ -76,11 +61,29 @@ public final class QuicksilverFountain extends CardImpl { } } +enum QuicksilverFountainAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + Player activePlayer = game.getPlayer(game.getActivePlayerId()); + if (activePlayer != null) { + ability.getTargets().clear(); + FilterLandPermanent filter = new FilterLandPermanent(); + filter.add(Predicates.not(new SubtypePredicate(SubType.ISLAND))); + filter.add(new ControllerPredicate(TargetController.ACTIVE)); + TargetLandPermanent target = new TargetLandPermanent(1, 1, filter, false); + target.setTargetController(activePlayer.getId()); + ability.getTargets().add(target); + } + } +} + class QuicksilverFountainEffect extends OneShotEffect { public QuicksilverFountainEffect() { super(Outcome.Neutral); - staticText = "that player puts a flood counter on target non-Island land he or she controls of their choice. That land is an Island for as long as it has a flood counter on it"; + staticText = "that player puts a flood counter on target non-Island land they control of their choice. That land is an Island for as long as it has a flood counter on it"; } public QuicksilverFountainEffect(final QuicksilverFountainEffect effect) { diff --git a/Mage.Sets/src/mage/cards/q/QuillmaneBaku.java b/Mage.Sets/src/mage/cards/q/QuillmaneBaku.java index e98d72f803..5aa3ab8099 100644 --- a/Mage.Sets/src/mage/cards/q/QuillmaneBaku.java +++ b/Mage.Sets/src/mage/cards/q/QuillmaneBaku.java @@ -1,4 +1,3 @@ - package mage.cards.q; import java.util.UUID; @@ -27,16 +26,15 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; /** * @author LevelX2 */ public final class QuillmaneBaku extends CardImpl { - private final UUID originalId; - public QuillmaneBaku(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(3); @@ -45,70 +43,70 @@ public final class QuillmaneBaku extends CardImpl { // Whenever you cast a Spirit or Arcane spell, you may put a ki counter on Skullmane Baku. this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.KI.createInstance()), StaticFilters.SPIRIT_OR_ARCANE_CARD, true)); - //TODO: Make ability properly copiable // {1}, Tap, Remove X ki counters from Quillmane Baku: Return target creature with converted mana cost X or less to its owner's hand. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new QuillmaneBakuReturnEffect(), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.KI.createInstance(1))); ability.addTarget(new TargetCreaturePermanent()); - originalId = ability.getOriginalId(); + ability.setTargetAdjuster(QuillmaneBakuAdjuster.instance); this.addAbility(ability); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - int maxConvManaCost = 0; - for (Cost cost : ability.getCosts()) { - if (cost instanceof RemoveVariableCountersSourceCost) { - maxConvManaCost = ((RemoveVariableCountersSourceCost) cost).getAmount(); - } - } - ability.getTargets().clear(); - FilterCreaturePermanent newFilter = new FilterCreaturePermanent("creature with converted mana cost " + maxConvManaCost + " or less"); - newFilter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, maxConvManaCost + 1)); - TargetCreaturePermanent target = new TargetCreaturePermanent(newFilter); - ability.getTargets().add(target); - } - } - public QuillmaneBaku(final QuillmaneBaku card) { super(card); - this.originalId = card.originalId; } @Override public QuillmaneBaku copy() { return new QuillmaneBaku(this); } +} - static class QuillmaneBakuReturnEffect extends OneShotEffect { +enum QuillmaneBakuAdjuster implements TargetAdjuster { + instance; - public QuillmaneBakuReturnEffect() { - super(Outcome.ReturnToHand); - this.staticText = "Return target creature with converted mana cost X or less to its owner's hand"; - } - - public QuillmaneBakuReturnEffect(final QuillmaneBakuReturnEffect effect) { - super(effect); - } - - @Override - public QuillmaneBakuReturnEffect copy() { - return new QuillmaneBakuReturnEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; + @Override + public void adjustTargets(Ability ability, Game game) { + int maxConvManaCost = 0; + for (Cost cost : ability.getCosts()) { + if (cost instanceof RemoveVariableCountersSourceCost) { + maxConvManaCost = ((RemoveVariableCountersSourceCost) cost).getAmount(); } - Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (permanent != null) { - controller.moveCards(permanent, Zone.HAND, source, game); - } - return true; } + ability.getTargets().clear(); + FilterCreaturePermanent newFilter = new FilterCreaturePermanent("creature with converted mana cost " + maxConvManaCost + " or less"); + newFilter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, maxConvManaCost + 1)); + TargetCreaturePermanent target = new TargetCreaturePermanent(newFilter); + ability.getTargets().add(target); + } +} + +class QuillmaneBakuReturnEffect extends OneShotEffect { + + public QuillmaneBakuReturnEffect() { + super(Outcome.ReturnToHand); + this.staticText = "Return target creature with converted mana cost X or less to its owner's hand"; + } + + public QuillmaneBakuReturnEffect(final QuillmaneBakuReturnEffect effect) { + super(effect); + } + + @Override + public QuillmaneBakuReturnEffect copy() { + return new QuillmaneBakuReturnEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); + if (permanent != null) { + controller.moveCards(permanent, Zone.HAND, source, game); + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/r/RakkaMar.java b/Mage.Sets/src/mage/cards/r/RakkaMar.java index 4e6f41225a..30db7aafab 100644 --- a/Mage.Sets/src/mage/cards/r/RakkaMar.java +++ b/Mage.Sets/src/mage/cards/r/RakkaMar.java @@ -1,7 +1,6 @@ package mage.cards.r; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -17,14 +16,13 @@ import mage.constants.SuperType; import mage.constants.Zone; import mage.game.permanent.token.RakkaMarElementalToken; +import java.util.UUID; + /** - * * @author Loki */ public final class RakkaMar extends CardImpl { - private RakkaMarElementalToken token = new RakkaMarElementalToken(); - public RakkaMar(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); addSuperType(SuperType.LEGENDARY); @@ -34,7 +32,12 @@ public final class RakkaMar extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); this.addAbility(HasteAbility.getInstance()); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(token), new ManaCostsImpl("{R}")); + + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new CreateTokenEffect(new RakkaMarElementalToken()), + new ManaCostsImpl("{R}") + ); ability.addCost(new TapSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/Reap.java b/Mage.Sets/src/mage/cards/r/Reap.java index 36d4d1baf6..f3db1b97ec 100644 --- a/Mage.Sets/src/mage/cards/r/Reap.java +++ b/Mage.Sets/src/mage/cards/r/Reap.java @@ -1,63 +1,40 @@ package mage.cards.r; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.game.Game; import mage.filter.FilterCard; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetOpponent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author L_J */ public final class Reap extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent("black permanents"); - - static { - filter.add(new ColorPredicate(ObjectColor.BLACK)); - } public Reap(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); // Return up to X target cards from your graveyard to your hand, where X is the number of black permanents target opponent controls as you cast Reap. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect().setText("Return up to X target cards from your graveyard to your hand, where X is the number of black permanents target opponent controls as you cast Reap.")); this.getSpellAbility().addTarget(new TargetOpponent()); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 0, new FilterCard("cards from your graveyard"))); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 0)); + this.getSpellAbility().setTargetAdjuster(ReapAdjuster.instance); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - Player controller = game.getPlayer(ability.getControllerId()); - if (controller != null) { - ability.getTargets().clear(); - UUID opponentId = null; - Target target = new TargetOpponent(); - if (controller.chooseTarget(Outcome.ReturnToHand, target, ability, game)) { - opponentId = target.getFirstTarget(); - } - int numbTargets = game.getBattlefield().getAllActivePermanents(filter, opponentId, game).size(); - ability.addTarget(new TargetCardInYourGraveyard(0, numbTargets, new FilterCard("card" + (numbTargets == 1 ? "" : "s") + " from your graveyard"))); - } - } - } - - public Reap(final Reap card) { super(card); } @@ -67,3 +44,27 @@ public final class Reap extends CardImpl { return new Reap(this); } } + +enum ReapAdjuster implements TargetAdjuster { + instance; + private static final FilterPermanent filter = new FilterPermanent("black permanents"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLACK)); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + Player controller = game.getPlayer(ability.getControllerId()); + if (controller != null) { + ability.getTargets().clear(); + UUID opponentId = null; + Target target = new TargetOpponent(); + if (controller.chooseTarget(Outcome.ReturnToHand, target, ability, game)) { + opponentId = target.getFirstTarget(); + } + int numbTargets = game.getBattlefield().getAllActivePermanents(filter, opponentId, game).size(); + ability.addTarget(new TargetCardInYourGraveyard(0, numbTargets, new FilterCard("card" + (numbTargets == 1 ? "" : "s") + " from your graveyard"))); + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java b/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java index d0bc76ed94..a176fbb338 100644 --- a/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java +++ b/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java @@ -1,9 +1,7 @@ package mage.cards.r; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyTargetEffect; @@ -13,9 +11,11 @@ import mage.constants.CardType; import mage.game.Game; import mage.game.permanent.token.GremlinToken; import mage.target.common.TargetArtifactPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author Styxo */ public final class ReleaseTheGremlins extends CardImpl { @@ -30,15 +30,7 @@ public final class ReleaseTheGremlins extends CardImpl { // Create X 2/2 red Gremlin creature tokens. this.getSpellAbility().addEffect(new CreateTokenEffect(new GremlinToken(), new ManacostVariableValue())); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - ability.addTarget(new TargetArtifactPermanent(xValue, xValue)); - } + this.getSpellAbility().setTargetAdjuster(ReleaseTheGremlinsAdjuster.instance); } public ReleaseTheGremlins(final ReleaseTheGremlins card) { @@ -50,3 +42,13 @@ public final class ReleaseTheGremlins extends CardImpl { return new ReleaseTheGremlins(this); } } + +enum ReleaseTheGremlinsAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetArtifactPermanent(ability.getManaCostsToPay().getX())); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/Repeal.java b/Mage.Sets/src/mage/cards/r/Repeal.java index b03390c18d..34851fedca 100644 --- a/Mage.Sets/src/mage/cards/r/Repeal.java +++ b/Mage.Sets/src/mage/cards/r/Repeal.java @@ -1,9 +1,7 @@ - package mage.cards.r; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; @@ -15,6 +13,7 @@ import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.target.TargetPermanent; import mage.target.common.TargetNonlandPermanent; +import mage.target.targetadjustment.TargetAdjuster; /** * @@ -23,29 +22,17 @@ import mage.target.common.TargetNonlandPermanent; public final class Repeal extends CardImpl { public Repeal(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{U}"); // Return target nonland permanent with converted mana cost X to its owner's hand. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); this.getSpellAbility().addTarget(new TargetPermanent(new FilterNonlandPermanent("nonland permanent with converted mana cost X"))); - + this.getSpellAbility().setTargetAdjuster(RepealAdjuster.instance); // Draw a card. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterNonlandPermanent filter = new FilterNonlandPermanent("nonland permanent with converted mana cost " + xValue); - filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); - ability.addTarget(new TargetNonlandPermanent(filter)); - } - } - public Repeal(final Repeal card) { super(card); } @@ -55,3 +42,16 @@ public final class Repeal extends CardImpl { return new Repeal(this); } } + +enum RepealAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + FilterNonlandPermanent filter = new FilterNonlandPermanent("nonland permanent with converted mana cost " + xValue); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); + ability.addTarget(new TargetNonlandPermanent(filter)); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RestlessDreams.java b/Mage.Sets/src/mage/cards/r/RestlessDreams.java index 9bc906e22a..d20f30be5e 100644 --- a/Mage.Sets/src/mage/cards/r/RestlessDreams.java +++ b/Mage.Sets/src/mage/cards/r/RestlessDreams.java @@ -1,23 +1,21 @@ package mage.cards.r; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.common.DiscardXTargetCost; -import mage.abilities.dynamicvalue.common.GetXValue; import mage.abilities.effects.Effect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.FilterCard; import mage.filter.StaticFilters; import mage.game.Game; -import mage.target.Target; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author fireshoes */ public final class RestlessDreams extends CardImpl { @@ -26,7 +24,7 @@ public final class RestlessDreams extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}"); // As an additional cost to cast Restless Dreams, discard X cards. - this.getSpellAbility().addCost(new DiscardXTargetCost(new FilterCard("cards"), true)); + this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true)); // Return X target creature cards from your graveyard to your hand. Effect effect = new ReturnFromGraveyardToHandTargetEffect(); effect.setText("Return X target creature cards from your graveyard to your hand"); @@ -37,15 +35,21 @@ public final class RestlessDreams extends CardImpl { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - int xValue = new GetXValue().calculate(game, ability, null); - Target target = new TargetCardInYourGraveyard(xValue, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD); - ability.addTarget(target); - } - @Override public RestlessDreams copy() { return new RestlessDreams(this); } } + +enum RestlessDreamsAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCardInYourGraveyard( + ability.getManaCostsToPay().getX(), + StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD + )); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/ReturnToDust.java b/Mage.Sets/src/mage/cards/r/ReturnToDust.java index c57d35ac04..2e25ab591f 100644 --- a/Mage.Sets/src/mage/cards/r/ReturnToDust.java +++ b/Mage.Sets/src/mage/cards/r/ReturnToDust.java @@ -2,52 +2,87 @@ package mage.cards.r; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; import mage.filter.StaticFilters; import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.TargetPermanent; import java.util.UUID; /** - * * @author emerald000 */ public final class ReturnToDust extends CardImpl { public ReturnToDust(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{W}{W}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}{W}"); // Exile target artifact or enchantment. If you cast this spell during your main phase, you may exile up to one other target artifact or enchantment. - Effect effect = new ExileTargetEffect(); - effect.setText("Exile target artifact or enchantment. If you cast this spell during your main phase, you may exile up to one other target artifact or enchantment"); - this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addEffect(new ReturnToDustEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(1, 2, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT, false)); } public ReturnToDust(final ReturnToDust card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - if (game.isActivePlayer(ability.getControllerId()) && game.isMainPhase()) { - ability.addTarget(new TargetPermanent(1, 2, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT, false)); - } - else { - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); - } - } - } - @Override public ReturnToDust copy() { return new ReturnToDust(this); } } + +class ReturnToDustEffect extends OneShotEffect { + + ReturnToDustEffect() { + super(Outcome.DestroyPermanent); + staticText = "Exile target artifact or enchantment. If you cast this spell during your main phase, you may exile up to one other target artifact or enchantment"; + } + + private ReturnToDustEffect(final ReturnToDustEffect effect) { + super(effect); + } + + @Override + public Effect copy() { + return new ReturnToDustEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + int targetsCleared = 0; + for (UUID targetId : getTargetPointer().getTargets(game, source)) { + Permanent permanent = game.getPermanent(targetId); + if (permanent == null) { + continue; + } + if (targetsCleared == 0) { + player.moveCards(permanent, Zone.EXILED, source, game); + targetsCleared++; + } else if (targetsCleared == 1) { + if (game.isActivePlayer(source.getControllerId()) && game.isMainPhase() + && player.chooseUse(outcome, "Exile another permanent?", source, game)) { + player.moveCards(permanent, Zone.EXILED, source, game); + targetsCleared++; + } else { + break; + } + } else { + break; + } + } + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/ReturnToTheRanks.java b/Mage.Sets/src/mage/cards/r/ReturnToTheRanks.java index c0b4ec5645..326369bf41 100644 --- a/Mage.Sets/src/mage/cards/r/ReturnToTheRanks.java +++ b/Mage.Sets/src/mage/cards/r/ReturnToTheRanks.java @@ -1,7 +1,6 @@ package mage.cards.r; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.Effect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; @@ -14,41 +13,26 @@ import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class ReturnToTheRanks extends CardImpl { - private static final FilterCreatureCard filter = new FilterCreatureCard("creature cards with converted mana cost 2 or less from your graveyard"); - - static { - filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 3)); - } - public ReturnToTheRanks(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{W}{W}"); // Convoke this.addAbility(new ConvokeAbility()); + // Return X target creature cards with converted mana cost 2 or less from your graveyard to the battlefield. Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect(); effect.setText("Return X target creature cards with converted mana cost 2 or less from your graveyard to the battlefield"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0,Integer.MAX_VALUE, filter)); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - for (Effect effect : ability.getEffects()) { - if (effect instanceof ReturnFromGraveyardToBattlefieldTargetEffect) { - int xValue = ability.getManaCostsToPay().getX(); - ability.getTargets().clear(); - ability.addTarget(new TargetCardInYourGraveyard(xValue,xValue, filter)); - } - } + this.getSpellAbility().setTargetAdjuster(ReturnToTheRanksAdjuster.instance); } public ReturnToTheRanks(final ReturnToTheRanks card) { @@ -60,3 +44,19 @@ public final class ReturnToTheRanks extends CardImpl { return new ReturnToTheRanks(this); } } + +enum ReturnToTheRanksAdjuster implements TargetAdjuster { + instance; + private static final FilterCreatureCard filter = new FilterCreatureCard("creature cards with converted mana cost 2 or less from your graveyard"); + + static { + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 3)); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + int xValue = ability.getManaCostsToPay().getX(); + ability.getTargets().clear(); + ability.addTarget(new TargetCardInYourGraveyard(xValue, xValue, filter)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/RushingRiver.java b/Mage.Sets/src/mage/cards/r/RushingRiver.java index 3f0ac959ed..b521104216 100644 --- a/Mage.Sets/src/mage/cards/r/RushingRiver.java +++ b/Mage.Sets/src/mage/cards/r/RushingRiver.java @@ -1,9 +1,7 @@ package mage.cards.r; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.common.KickedCondition; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.decorator.ConditionalOneShotEffect; @@ -17,23 +15,25 @@ import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetNonlandPermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.SecondTargetPointer; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class RushingRiver extends CardImpl { public RushingRiver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); // Kicker-Sacrifice a land. this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))))); // Return target nonland permanent to its owner's hand. If Rushing River was kicked, return another target nonland permanent to its owner's hand. - this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); Effect effect = new ConditionalOneShotEffect( new ReturnToHandTargetEffect(), KickedCondition.instance, @@ -41,16 +41,7 @@ public final class RushingRiver extends CardImpl { effect.setTargetPointer(new SecondTargetPointer()); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addTarget(new TargetNonlandPermanent()); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility && KickedCondition.instance.apply(game, ability)) { - ability.getTargets().clear(); - ability.addTarget(new TargetNonlandPermanent(2)); - } - + this.getSpellAbility().setTargetAdjuster(RushingRiverAdjuster.instance); } public RushingRiver(final RushingRiver card) { @@ -62,3 +53,15 @@ public final class RushingRiver extends CardImpl { return new RushingRiver(this); } } + +enum RushingRiverAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + if (KickedCondition.instance.apply(game, ability)) { + ability.getTargets().clear(); + ability.addTarget(new TargetNonlandPermanent(2)); + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SatyrFiredancer.java b/Mage.Sets/src/mage/cards/s/SatyrFiredancer.java index 107565da51..19e16e50ca 100644 --- a/Mage.Sets/src/mage/cards/s/SatyrFiredancer.java +++ b/Mage.Sets/src/mage/cards/s/SatyrFiredancer.java @@ -1,10 +1,6 @@ package mage.cards.s; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -14,8 +10,8 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; @@ -26,8 +22,13 @@ import mage.game.permanent.Permanent; import mage.game.stack.StackObject; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.FixedTarget; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + /** * @author LevelX2 */ @@ -48,18 +49,6 @@ public final class SatyrFiredancer extends CardImpl { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SatyrFiredancerTriggeredAbility) { - Player opponent = game.getPlayer(ability.getEffects().get(0).getTargetPointer().getFirst(game, ability)); - if (opponent != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature controlled by " + opponent.getLogName()); - filter.add(new ControllerIdPredicate(opponent.getId())); - ability.getTargets().add(new TargetCreaturePermanent(filter)); - } - } - } - @Override public SatyrFiredancer copy() { return new SatyrFiredancer(this); @@ -72,6 +61,7 @@ class SatyrFiredancerTriggeredAbility extends TriggeredAbilityImpl { public SatyrFiredancerTriggeredAbility() { super(Zone.BATTLEFIELD, new SatyrFiredancerDamageEffect(), false); + targetAdjuster = SatyrFiredancerAdjuster.instance; } public SatyrFiredancerTriggeredAbility(final SatyrFiredancerTriggeredAbility ability) { @@ -154,3 +144,17 @@ class SatyrFiredancerDamageEffect extends OneShotEffect { return false; } } + +enum SatyrFiredancerAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + Player opponent = game.getPlayer(ability.getEffects().get(0).getTargetPointer().getFirst(game, ability)); + if (opponent != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature controlled by " + opponent.getLogName()); + filter.add(new ControllerIdPredicate(opponent.getId())); + ability.getTargets().add(new TargetCreaturePermanent(filter)); + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/ScorchedEarth.java b/Mage.Sets/src/mage/cards/s/ScorchedEarth.java index bc2c406e14..0c578f5129 100644 --- a/Mage.Sets/src/mage/cards/s/ScorchedEarth.java +++ b/Mage.Sets/src/mage/cards/s/ScorchedEarth.java @@ -1,36 +1,36 @@ package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.common.DiscardTargetCost; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.InfoEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.common.FilterLandCard; import mage.filter.common.FilterLandPermanent; import mage.game.Game; import mage.target.common.TargetCardInHand; import mage.target.common.TargetLandPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author fireshoes */ public final class ScorchedEarth extends CardImpl { public ScorchedEarth(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}"); // As an additional cost to cast Scorched Earth, discard X land cards. - Ability ability = new SimpleStaticAbility(Zone.ALL, new ScorchedEarthRuleEffect()); + Ability ability = new SimpleStaticAbility(Zone.ALL, new InfoEffect("as an additional cost to cast this spell, discard X land cards")); ability.setRuleAtTheTop(true); this.addAbility(ability); @@ -39,53 +39,39 @@ public final class ScorchedEarth extends CardImpl { effect.setText("Destroy X target lands"); this.getSpellAbility().addTarget(new TargetLandPermanent()); this.getSpellAbility().addEffect(effect); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - ability.addTarget(new TargetLandPermanent(xValue, xValue, new FilterLandPermanent(), false)); - } + this.getSpellAbility().setTargetAdjuster(ScorchedEarthTargetAdjuster.instance); + this.getSpellAbility().setCostAdjuster(ScorchedEarthCostAdjuster.instance); } public ScorchedEarth(final ScorchedEarth card) { super(card); } - @Override - public void adjustCosts(Ability ability, Game game) { - int xValue = ability.getManaCostsToPay().getX(); - if (xValue > 0) { - ability.addCost(new DiscardTargetCost(new TargetCardInHand(xValue, xValue, new FilterLandCard("land cards")))); - } - } - @Override public ScorchedEarth copy() { return new ScorchedEarth(this); } } -class ScorchedEarthRuleEffect extends OneShotEffect { - - public ScorchedEarthRuleEffect() { - super(Outcome.Benefit); - this.staticText = "as an additional cost to cast this spell, discard X land cards"; - } - - public ScorchedEarthRuleEffect(final ScorchedEarthRuleEffect effect) { - super(effect); - } +enum ScorchedEarthTargetAdjuster implements TargetAdjuster { + instance; @Override - public ScorchedEarthRuleEffect copy() { - return new ScorchedEarthRuleEffect(this); + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + ability.addTarget(new TargetLandPermanent(xValue, xValue, new FilterLandPermanent(), false)); } +} + +enum ScorchedEarthCostAdjuster implements CostAdjuster { + instance; @Override - public boolean apply(Game game, Ability source) { - return true; + public void adjustCosts(Ability ability, Game game) { + int xValue = ability.getManaCostsToPay().getX(); + if (xValue > 0) { + ability.addCost(new DiscardTargetCost(new TargetCardInHand(xValue, xValue, new FilterLandCard("land cards")))); + } } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SentinelOfTheEternalWatch.java b/Mage.Sets/src/mage/cards/s/SentinelOfTheEternalWatch.java index 04acffd490..e3f64e774f 100644 --- a/Mage.Sets/src/mage/cards/s/SentinelOfTheEternalWatch.java +++ b/Mage.Sets/src/mage/cards/s/SentinelOfTheEternalWatch.java @@ -1,11 +1,9 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BeginningOfCombatTriggeredAbility; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; @@ -14,24 +12,26 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; +import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FirstTargetPointer; +import mage.filter.predicate.permanent.ControllerIsActivePlayerPredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class SentinelOfTheEternalWatch extends CardImpl { - private final UUID originalId; + private static final FilterPermanent filter = new FilterCreaturePermanent("creature controlled by the active player"); + + static { + filter.add(new ControllerIsActivePlayerPredicate()); + } public SentinelOfTheEternalWatch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); this.subtype.add(SubType.GIANT); this.subtype.add(SubType.SOLDIER); this.power = new MageInt(4); @@ -39,38 +39,22 @@ public final class SentinelOfTheEternalWatch extends CardImpl { // Vigilance this.addAbility(VigilanceAbility.getInstance()); - // At the beginning of combat on each opponent's turn, tap target creature that player controls. - Ability ability = new BeginningOfCombatTriggeredAbility(Zone.BATTLEFIELD, new TapTargetEffect("target creature that player controls"), TargetController.OPPONENT, false, true); - originalId = ability.getOriginalId(); - this.addAbility(ability); + // At the beginning of combat on each opponent's turn, tap target creature that player controls. + Ability ability = new BeginningOfCombatTriggeredAbility( + Zone.BATTLEFIELD, new TapTargetEffect("target creature that player controls"), + TargetController.OPPONENT, false, false + ); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); } public SentinelOfTheEternalWatch(final SentinelOfTheEternalWatch card) { super(card); - this.originalId = card.originalId; } @Override public SentinelOfTheEternalWatch copy() { return new SentinelOfTheEternalWatch(this); } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - for (Effect effect : ability.getEffects()) { - UUID opponentId = effect.getTargetPointer().getFirst(game, ability); - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - effect.setTargetPointer(new FirstTargetPointer()); - FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature from the active opponent"); - filter.add(new ControllerIdPredicate(opponentId)); - Target target = new TargetCreaturePermanent(filter); - ability.addTarget(target); - } - } - } - } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SepulchralPrimordial.java b/Mage.Sets/src/mage/cards/s/SepulchralPrimordial.java index b0073013b9..614a0252bc 100644 --- a/Mage.Sets/src/mage/cards/s/SepulchralPrimordial.java +++ b/Mage.Sets/src/mage/cards/s/SepulchralPrimordial.java @@ -1,9 +1,6 @@ package mage.cards.s; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -13,8 +10,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; @@ -23,9 +20,13 @@ import mage.game.Game; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInOpponentsGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; /** - * * @author LevelX2 */ public final class SepulchralPrimordial extends CardImpl { @@ -37,28 +38,14 @@ public final class SepulchralPrimordial extends CardImpl { this.power = new MageInt(5); this.toughness = new MageInt(4); - //Vigilance + // Intimidate this.addAbility(IntimidateAbility.getInstance()); // When Sepulchral Primordial enters the battlefield, for each opponent, you may put up to one // target creature card from that player's graveyard onto the battlefield under your control. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SepulchralPrimordialEffect(), false)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof EntersBattlefieldTriggeredAbility) { - ability.getTargets().clear(); - for (UUID opponentId : game.getOpponents(ability.getControllerId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - FilterCard filter = new FilterCreatureCard("creature card from " + opponent.getName() + "'s graveyard"); - filter.add(new OwnerIdPredicate(opponentId)); - TargetCardInOpponentsGraveyard target = new TargetCardInOpponentsGraveyard(0, 1, filter); - ability.addTarget(target); - } - } - } + Ability ability = new EntersBattlefieldTriggeredAbility(new SepulchralPrimordialEffect(), false); + ability.setTargetAdjuster(SepulchralPrimordialAdjuster.instance); + this.addAbility(ability); } public SepulchralPrimordial(final SepulchralPrimordial card) { @@ -71,6 +58,24 @@ public final class SepulchralPrimordial extends CardImpl { } } +enum SepulchralPrimordialAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + for (UUID opponentId : game.getOpponents(ability.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null) { + FilterCard filter = new FilterCreatureCard("creature card from " + opponent.getName() + "'s graveyard"); + filter.add(new OwnerIdPredicate(opponentId)); + TargetCardInOpponentsGraveyard target = new TargetCardInOpponentsGraveyard(0, 1, filter); + ability.addTarget(target); + } + } + } +} + class SepulchralPrimordialEffect extends OneShotEffect { public SepulchralPrimordialEffect() { diff --git a/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java b/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java index 340152cd76..90425abc24 100644 --- a/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java +++ b/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java @@ -1,9 +1,7 @@ package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.effects.Effect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; @@ -15,9 +13,11 @@ import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.target.Target; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class ShatteredCrypt extends CardImpl { @@ -30,17 +30,7 @@ public final class ShatteredCrypt extends CardImpl { effect.setText("Return X target creature cards from your graveyard to your hand"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(new ManacostVariableValue())); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(1, new FilterCreatureCard())); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - Target target = new TargetCardInYourGraveyard(xValue, new FilterCreatureCard((xValue != 1 ? " creature cards" : "creature card") + " from your graveyard")); - ability.addTarget(target); - } + this.getSpellAbility().setTargetAdjuster(ShatteredCryptAdjuster.instance); } public ShatteredCrypt(final ShatteredCrypt card) { @@ -52,3 +42,15 @@ public final class ShatteredCrypt extends CardImpl { return new ShatteredCrypt(this); } } + +enum ShatteredCryptAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + Target target = new TargetCardInYourGraveyard(xValue, new FilterCreatureCard((xValue != 1 ? " creature cards" : "creature card") + " from your graveyard")); + ability.addTarget(target); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SigilOfSleep.java b/Mage.Sets/src/mage/cards/s/SigilOfSleep.java index 2a84a060c0..9e054e1d7f 100644 --- a/Mage.Sets/src/mage/cards/s/SigilOfSleep.java +++ b/Mage.Sets/src/mage/cards/s/SigilOfSleep.java @@ -1,4 +1,3 @@ - package mage.cards.s; import java.util.UUID; @@ -19,6 +18,7 @@ import mage.game.Game; import mage.target.Target; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.FirstTargetPointer; /** @@ -27,10 +27,8 @@ import mage.target.targetpointer.FirstTargetPointer; */ public final class SigilOfSleep extends CardImpl { - private final UUID originalId; - public SigilOfSleep(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -39,34 +37,17 @@ public final class SigilOfSleep extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Whenever enchanted creature deals damage to a player, return target creature that player controls to its owner's hand. Effect effect = new ReturnToHandTargetEffect(); effect.setText("return target creature that player controls to its owner's hand"); ability = new DealsDamageToAPlayerAttachedTriggeredAbility(effect, "enchanted", false, true, false); - originalId = ability.getOriginalId(); + ability.setTargetAdjuster(SigilOfSleepAdjuster.instance); this.addAbility(ability); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - UUID playerId = ability.getEffects().get(0).getTargetPointer().getFirst(game, ability); - if (playerId != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that player controls"); - filter.add(new ControllerIdPredicate(playerId)); - Target target = new TargetCreaturePermanent(filter); - ability.getTargets().clear(); - ability.addTarget(target); - ability.getEffects().get(0).setTargetPointer(new FirstTargetPointer()); - } - - } } public SigilOfSleep(final SigilOfSleep card) { super(card); - this.originalId = card.originalId; } @Override @@ -74,3 +55,20 @@ public final class SigilOfSleep extends CardImpl { return new SigilOfSleep(this); } } + +enum SigilOfSleepAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + UUID playerId = ability.getEffects().get(0).getTargetPointer().getFirst(game, ability); + if (playerId != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that player controls"); + filter.add(new ControllerIdPredicate(playerId)); + Target target = new TargetCreaturePermanent(filter); + ability.getTargets().clear(); + ability.addTarget(target); + ability.getEffects().get(0).setTargetPointer(new FirstTargetPointer()); + } + } +} diff --git a/Mage.Sets/src/mage/cards/s/SkullbriarTheWalkingGrave.java b/Mage.Sets/src/mage/cards/s/SkullbriarTheWalkingGrave.java index 7c21786363..d37ca591ec 100644 --- a/Mage.Sets/src/mage/cards/s/SkullbriarTheWalkingGrave.java +++ b/Mage.Sets/src/mage/cards/s/SkullbriarTheWalkingGrave.java @@ -1,7 +1,6 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.StaticAbility; @@ -22,15 +21,15 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; +import java.util.UUID; + /** - * * @author anonymous */ public final class SkullbriarTheWalkingGrave extends CardImpl { - private Counters counters; public SkullbriarTheWalkingGrave(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{G}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.ELEMENTAL); @@ -46,7 +45,9 @@ public final class SkullbriarTheWalkingGrave extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.ALL, new SkullbriarEffect())); } - public SkullbriarTheWalkingGrave(SkullbriarTheWalkingGrave card) { super(card); } + public SkullbriarTheWalkingGrave(SkullbriarTheWalkingGrave card) { + super(card); + } @Override public SkullbriarTheWalkingGrave copy() { @@ -58,7 +59,7 @@ public final class SkullbriarTheWalkingGrave extends CardImpl { public void updateZoneChangeCounter(Game game, ZoneChangeEvent event) { boolean skullBriarEffectApplied = false; if (event.getToZone() != Zone.HAND && event.getToZone() != Zone.LIBRARY) { - for (StaticAbility ability : getAbilities (game).getStaticAbilities(event.getFromZone())) { + for (StaticAbility ability : getAbilities(game).getStaticAbilities(event.getFromZone())) { for (Effect effect : ability.getEffects(game, EffectType.REPLACEMENT)) { if (effect instanceof SkullbriarEffect && event.getAppliedEffects().contains(effect.getId())) { skullBriarEffectApplied = true; @@ -84,7 +85,7 @@ public final class SkullbriarTheWalkingGrave extends CardImpl { copyTo = this.getCounters(game); } if (copyTo != null && copyFrom != null) { - for(Counter counter : copyFrom.values()) { + for (Counter counter : copyFrom.values()) { copyTo.addCounter(counter); } } diff --git a/Mage.Sets/src/mage/cards/s/SkyfireKirin.java b/Mage.Sets/src/mage/cards/s/SkyfireKirin.java index 03b1241507..899b0aa5aa 100644 --- a/Mage.Sets/src/mage/cards/s/SkyfireKirin.java +++ b/Mage.Sets/src/mage/cards/s/SkyfireKirin.java @@ -1,4 +1,3 @@ - package mage.cards.s; import java.util.UUID; @@ -22,6 +21,7 @@ import mage.game.stack.Spell; import mage.target.Target; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.FixedTarget; /** @@ -29,8 +29,6 @@ import mage.target.targetpointer.FixedTarget; */ public final class SkyfireKirin extends CardImpl { - private final UUID originalId; - public SkyfireKirin(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); addSuperType(SuperType.LEGENDARY); @@ -43,30 +41,17 @@ public final class SkyfireKirin extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); // Whenever you cast a Spirit or Arcane spell, you may gain control of target creature with that spell's converted mana cost until end of turn. - Ability ability = new SpellCastControllerTriggeredAbility(Zone.BATTLEFIELD, new SkyfireKirinEffect(), StaticFilters.SPIRIT_OR_ARCANE_CARD, true, true); + Ability ability = new SpellCastControllerTriggeredAbility( + Zone.BATTLEFIELD, new SkyfireKirinEffect(), + StaticFilters.SPIRIT_OR_ARCANE_CARD, true, true + ); ability.addTarget(new TargetCreaturePermanent()); - originalId = ability.getOriginalId(); + ability.setTargetAdjuster(SkyfireKirinAdjuster.instance); this.addAbility(ability); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - Spell spell = game.getStack().getSpell(ability.getEffects().get(0).getTargetPointer().getFirst(game, ability)); - if (spell != null) { - int cmc = spell.getConvertedManaCost(); - ability.getTargets().clear(); - FilterPermanent filter = new FilterCreaturePermanent("creature with converted mana costs of " + cmc); - filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, cmc)); - Target target = new TargetPermanent(filter); - ability.addTarget(target); - } - } - } - public SkyfireKirin(final SkyfireKirin card) { super(card); - this.originalId = card.originalId; } @Override @@ -75,6 +60,22 @@ public final class SkyfireKirin extends CardImpl { } } +enum SkyfireKirinAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + Spell spell = game.getStack().getSpell(ability.getEffects().get(0).getTargetPointer().getFirst(game, ability)); + if (spell != null) { + int cmc = spell.getConvertedManaCost(); + ability.getTargets().clear(); + FilterPermanent filter = new FilterCreaturePermanent("creature with converted mana cost " + cmc); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, cmc)); + ability.addTarget(new TargetPermanent(filter)); + } + } +} + class SkyfireKirinEffect extends OneShotEffect { public SkyfireKirinEffect() { diff --git a/Mage.Sets/src/mage/cards/s/SpellBlast.java b/Mage.Sets/src/mage/cards/s/SpellBlast.java index c1e3b3c7ef..85337f0ce5 100644 --- a/Mage.Sets/src/mage/cards/s/SpellBlast.java +++ b/Mage.Sets/src/mage/cards/s/SpellBlast.java @@ -1,9 +1,7 @@ package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.CounterTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -12,24 +10,22 @@ import mage.constants.ComparisonType; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; -import mage.target.Target; import mage.target.TargetSpell; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class SpellBlast extends CardImpl { - private static final FilterSpell filter = new FilterSpell("spell with converted mana cost X"); - public SpellBlast(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{U}"); // Counter target spell with converted mana cost X. - this.getSpellAbility().addEffect(new CounterTargetEffect()); - this.getSpellAbility().addTarget(new TargetSpell(filter)); + this.getSpellAbility().addEffect(new CounterTargetEffect().setText("counter target spell with converted mana cost X")); + this.getSpellAbility().setTargetAdjuster(SpellBlastAdjuster.instance); } public SpellBlast(final SpellBlast card) { @@ -40,17 +36,17 @@ public final class SpellBlast extends CardImpl { public SpellBlast copy() { return new SpellBlast(this); } +} + +enum SpellBlastAdjuster implements TargetAdjuster { + instance; @Override public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - int xValue = ability.getManaCostsToPay().getX(); - ability.getTargets().clear(); - FilterSpell newfilter = new FilterSpell("spell with converted mana cost " + xValue); - newfilter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); - Target target = new TargetSpell(newfilter); - ability.addTarget(target); - } - + int xValue = ability.getManaCostsToPay().getX(); + ability.getTargets().clear(); + FilterSpell filter = new FilterSpell("spell with converted mana cost " + xValue); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); + ability.addTarget(new TargetSpell(filter)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SpellBurst.java b/Mage.Sets/src/mage/cards/s/SpellBurst.java index 35d8c2a6cc..7c2cae1ae7 100644 --- a/Mage.Sets/src/mage/cards/s/SpellBurst.java +++ b/Mage.Sets/src/mage/cards/s/SpellBurst.java @@ -1,9 +1,7 @@ package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.CounterTargetEffect; import mage.abilities.keyword.BuybackAbility; import mage.cards.CardImpl; @@ -14,6 +12,9 @@ import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.target.TargetSpell; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** * @author LevelX2 @@ -23,23 +24,12 @@ public final class SpellBurst extends CardImpl { public SpellBurst(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{U}"); - // Buyback {3} this.addAbility(new BuybackAbility("{3}")); // Counter target spell with converted mana cost X. - this.getSpellAbility().addEffect(new CounterTargetEffect()); - this.getSpellAbility().addTarget(new TargetSpell(new FilterSpell("spell with converted mana cost X"))); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - FilterSpell filter = new FilterSpell("spell with converted mana cost X"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, ability.getManaCostsToPay().getX())); - ability.addTarget(new TargetSpell(filter)); - } + this.getSpellAbility().addEffect(new CounterTargetEffect().setText("counter target spell with converted mana cost X")); + this.getSpellAbility().setTargetAdjuster(SpellBurstAdjuster.instance); } public SpellBurst(final SpellBurst card) { @@ -51,3 +41,16 @@ public final class SpellBurst extends CardImpl { return new SpellBurst(this); } } + +enum SpellBurstAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + int xValue = ability.getManaCostsToPay().getX(); + ability.getTargets().clear(); + FilterSpell filter = new FilterSpell("spell with converted mana cost " + xValue); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); + ability.addTarget(new TargetSpell(filter)); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SpellstutterSprite.java b/Mage.Sets/src/mage/cards/s/SpellstutterSprite.java index 9c63519a99..1126c9bcbc 100644 --- a/Mage.Sets/src/mage/cards/s/SpellstutterSprite.java +++ b/Mage.Sets/src/mage/cards/s/SpellstutterSprite.java @@ -1,40 +1,40 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CounterTargetEffect; import mage.abilities.keyword.FlashAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; import mage.filter.FilterPermanent; import mage.filter.FilterSpell; -import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; -import mage.game.stack.StackObject; import mage.target.TargetSpell; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class SpellstutterSprite extends CardImpl { - - static final FilterPermanent filter = new FilterPermanent("number of Faeries you control"); + + private static final FilterSpell filter = new FilterSpell("spell with converted mana cost X or less, where X is the number of Faeries you control"); + static { - filter.add(new ControllerPredicate(TargetController.YOU)); - filter.add(new SubtypePredicate(SubType.FAERIE)); + filter.add(SpellstutterSpritePredicate.instance); } public SpellstutterSprite(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.subtype.add(SubType.FAERIE); this.subtype.add(SubType.WIZARD); @@ -43,71 +43,37 @@ public final class SpellstutterSprite extends CardImpl { // Flash this.addAbility(FlashAbility.getInstance()); + // Flying this.addAbility(FlyingAbility.getInstance()); + // When Spellstutter Sprite enters the battlefield, counter target spell with converted mana cost X or less, where X is the number of Faeries you control. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SpellstutterSpriteCounterTargetEffect())); + Ability ability = new EntersBattlefieldTriggeredAbility(new CounterTargetEffect()); + ability.addTarget(new TargetSpell(filter)); + this.addAbility(ability); } public SpellstutterSprite(final SpellstutterSprite card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof EntersBattlefieldTriggeredAbility) { - int numberFaeries = game.getState().getBattlefield().countAll(filter, ability.getControllerId(), game); - FilterSpell xFilter = new FilterSpell("spell with converted mana cost " + numberFaeries + " or less"); - xFilter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, numberFaeries + 1)); - ability.getTargets().clear(); - ability.addTarget(new TargetSpell(xFilter)); - } - } - @Override public SpellstutterSprite copy() { return new SpellstutterSprite(this); } } -class SpellstutterSpriteCounterTargetEffect extends OneShotEffect { +enum SpellstutterSpritePredicate implements ObjectSourcePlayerPredicate> { + instance; + private static final FilterPermanent filter = new FilterPermanent(); - public SpellstutterSpriteCounterTargetEffect() { - super(Outcome.Detriment); - } - - public SpellstutterSpriteCounterTargetEffect(final SpellstutterSpriteCounterTargetEffect effect) { - super(effect); + static { + filter.add(new SubtypePredicate(SubType.FAERIE)); } @Override - public SpellstutterSpriteCounterTargetEffect copy() { - return new SpellstutterSpriteCounterTargetEffect(this); + public boolean apply(ObjectSourcePlayer input, Game game) { + return input.getObject().getConvertedManaCost() <= + game.getBattlefield().countAll(filter, game.getControllerId(input.getSourceId()), game); } - - @Override - public boolean apply(Game game, Ability source) { - /* - * The value of X needs to be determined both when the ability triggers (so you can choose - * a target) and again when the ability resolves (to check if that target is still legal). - * If the number of Faeries you control has decreased enough in that time to make the target - * illegal, Spellstutter Sprite's ability will be countered (and the targeted spell will - * resolve as normal). - */ - int numberFaeries = game.getState().getBattlefield().countAll(SpellstutterSprite.filter, source.getControllerId(), game); - StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget()); - // If do'nt have any spell targeted - if (stackObject != null && stackObject.getConvertedManaCost() <= numberFaeries) { - if (game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game)) { - return true; - } - } - return false; - } - - @Override - public String getText(Mode mode) { - return "counter target spell with converted mana cost X or less, where X is the number of Faeries you control"; - } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/StirTheGrave.java b/Mage.Sets/src/mage/cards/s/StirTheGrave.java index 39d56a262c..818993060f 100644 --- a/Mage.Sets/src/mage/cards/s/StirTheGrave.java +++ b/Mage.Sets/src/mage/cards/s/StirTheGrave.java @@ -1,7 +1,6 @@ package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.cards.CardImpl; @@ -13,29 +12,21 @@ import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class StirTheGrave extends CardImpl { public StirTheGrave(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}"); // Return target creature card with converted mana cost X or less from your graveyard to the battlefield. - this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card with converted mana cost X or less from your graveyard"))); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - FilterCard filter = new FilterCreatureCard("creature card with converted mana cost " + xValue + " or less from your graveyard"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue + 1)); - ability.getTargets().add(new TargetCardInYourGraveyard(filter)); + this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect().setText("return target creature card with converted mana cost X or less from your graveyard to the battlefield")); + this.getSpellAbility().setTargetAdjuster(StirTheGraveAdjuster.instance); } public StirTheGrave(final StirTheGrave card) { @@ -47,3 +38,16 @@ public final class StirTheGrave extends CardImpl { return new StirTheGrave(this); } } + +enum StirTheGraveAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + FilterCard filter = new FilterCreatureCard("creature card with converted mana cost " + xValue + " or less from your graveyard"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue + 1)); + ability.getTargets().add(new TargetCardInYourGraveyard(filter)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/StrengthOfTheTajuru.java b/Mage.Sets/src/mage/cards/s/StrengthOfTheTajuru.java index 93d7d0d141..48f0586a2b 100644 --- a/Mage.Sets/src/mage/cards/s/StrengthOfTheTajuru.java +++ b/Mage.Sets/src/mage/cards/s/StrengthOfTheTajuru.java @@ -1,9 +1,7 @@ - package mage.cards.s; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.dynamicvalue.common.MultikickerCount; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.MultikickerAbility; @@ -16,7 +14,7 @@ import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; - +import mage.target.targetadjustment.TargetAdjuster; /** * @author noxx @@ -24,7 +22,7 @@ import mage.target.common.TargetCreaturePermanent; public final class StrengthOfTheTajuru extends CardImpl { public StrengthOfTheTajuru(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{G}{G}"); // Multikicker (You may pay an additional {1} any number of times as you cast this spell.) this.addAbility(new MultikickerAbility("{1}")); @@ -32,15 +30,7 @@ public final class StrengthOfTheTajuru extends CardImpl { // Choose target creature, then choose another target creature for each time Strength of the Tajuru was kicked. Put X +1/+1 counters on each of them. this.getSpellAbility().addEffect(new StrengthOfTheTajuruAddCountersTargetEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int numbTargets = new MultikickerCount().calculate(game, ability, null) + 1; - ability.addTarget(new TargetCreaturePermanent(0, numbTargets)); - } + this.getSpellAbility().setTargetAdjuster(StrengthOfTheTajuruAdjuster.instance); } public StrengthOfTheTajuru(final StrengthOfTheTajuru card) { @@ -53,6 +43,17 @@ public final class StrengthOfTheTajuru extends CardImpl { } } +enum StrengthOfTheTajuruAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int numbTargets = new MultikickerCount().calculate(game, ability, null) + 1; + ability.addTarget(new TargetCreaturePermanent(0, numbTargets)); + } +} + class StrengthOfTheTajuruAddCountersTargetEffect extends OneShotEffect { public StrengthOfTheTajuruAddCountersTargetEffect() { @@ -73,7 +74,7 @@ class StrengthOfTheTajuruAddCountersTargetEffect extends OneShotEffect { Permanent permanent = game.getPermanent(uuid); if (permanent != null) { permanent.addCounters(counter.copy(), source, game); - affectedTargets ++; + affectedTargets++; } } return affectedTargets > 0; @@ -84,5 +85,4 @@ class StrengthOfTheTajuruAddCountersTargetEffect extends OneShotEffect { return new StrengthOfTheTajuruAddCountersTargetEffect(this); } - } diff --git a/Mage.Sets/src/mage/cards/s/SupremeLeaderSnoke.java b/Mage.Sets/src/mage/cards/s/SupremeLeaderSnoke.java index f15c2b24a7..4ddba10eb0 100644 --- a/Mage.Sets/src/mage/cards/s/SupremeLeaderSnoke.java +++ b/Mage.Sets/src/mage/cards/s/SupremeLeaderSnoke.java @@ -11,13 +11,16 @@ import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.*; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.abilities.keyword.HasteAbility; -import mage.constants.*; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.*; import mage.counters.Counter; import mage.counters.CounterType; import mage.filter.StaticFilters; @@ -26,19 +29,17 @@ import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; import mage.watchers.common.PlayerLostLifeNonCombatWatcher; /** - * * @author NinthWorld */ public final class SupremeLeaderSnoke extends CardImpl { - UUID ability3Id; - public SupremeLeaderSnoke(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{U}{B}{R}"); - + this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.SNOKE); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3)); @@ -54,35 +55,17 @@ public final class SupremeLeaderSnoke extends CardImpl { // -X: Gain control of target creature with converted mana cost X. Untap that creature. It gains haste. Sacrifice that creature at the beginning of the next end step. Ability ability3 = new LoyaltyAbility(new GainControlTargetEffect(Duration.WhileOnBattlefield) - .setText("Gain control of target creature with converted mana cost X")); + .setText("Gain control of target creature with converted mana cost X")); ability3.addEffect(new UntapTargetEffect().setText("Untap that creature")); ability3.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield).setText("It gains haste")); ability3.addEffect(new GainAbilityTargetEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new SacrificeSourceEffect()), Duration.WhileOnBattlefield) - .setText("Sacrifice that creature at the beginning of the next end step")); - ability3Id = ability3.getOriginalId(); - ability3.addTarget(new TargetCreaturePermanent()); + .setText("Sacrifice that creature at the beginning of the next end step")); + ability3.setTargetAdjuster(SupremeLeaderSnokeAdjuster.instance); this.addAbility(ability3); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(ability3Id)) { - int cmc = 0; - for (Cost cost : ability.getCosts()) { - if (cost instanceof PayVariableLoyaltyCost) { - cmc = ((PayVariableLoyaltyCost) cost).getAmount(); - } - } - FilterCreaturePermanent newFilter = StaticFilters.FILTER_PERMANENT_CREATURE.copy(); - newFilter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, cmc)); - ability.getTargets().clear(); - ability.addTarget(new TargetCreaturePermanent(newFilter)); - } - } - public SupremeLeaderSnoke(final SupremeLeaderSnoke card) { super(card); - this.ability3Id = card.ability3Id; } @Override @@ -91,6 +74,24 @@ public final class SupremeLeaderSnoke extends CardImpl { } } +enum SupremeLeaderSnokeAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + int cmc = 0; + for (Cost cost : ability.getCosts()) { + if (cost instanceof PayVariableLoyaltyCost) { + cmc = ((PayVariableLoyaltyCost) cost).getAmount(); + } + } + FilterCreaturePermanent newFilter = StaticFilters.FILTER_PERMANENT_CREATURE.copy(); + newFilter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, cmc)); + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(newFilter)); + } +} + class OpponentNoncombatLostLifeCount implements DynamicValue { @Override @@ -131,9 +132,9 @@ class SupremeLeaderSnokeCounterEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); - if(permanent != null) { + if (permanent != null) { int amount = new OpponentNoncombatLostLifeCount().calculate(game, source, this); - if(amount > 0) { + if (amount > 0) { Counter counterToAdd = counter.copy(); counterToAdd.add(amount - counter.getCount()); permanent.addCounters(counterToAdd, source, game); diff --git a/Mage.Sets/src/mage/cards/s/SylvanPrimordial.java b/Mage.Sets/src/mage/cards/s/SylvanPrimordial.java index 625bcf609b..b6c63993d5 100644 --- a/Mage.Sets/src/mage/cards/s/SylvanPrimordial.java +++ b/Mage.Sets/src/mage/cards/s/SylvanPrimordial.java @@ -1,7 +1,6 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -25,15 +24,17 @@ import mage.players.Player; import mage.target.Target; import mage.target.TargetPermanent; import mage.target.common.TargetCardInLibrary; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class SylvanPrimordial extends CardImpl { public SylvanPrimordial(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); this.subtype.add(SubType.AVATAR); this.power = new MageInt(6); @@ -43,24 +44,9 @@ public final class SylvanPrimordial extends CardImpl { this.addAbility(ReachAbility.getInstance()); // When Sylvan Primordial enters the battlefield, for each opponent, destroy target noncreature permanent that player controls. For each permanent destroyed this way, search your library for a Forest card and put that card onto the battlefield tapped. Then shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SylvanPrimordialEffect(),false)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof EntersBattlefieldTriggeredAbility) { - ability.getTargets().clear(); - for(UUID opponentId : game.getOpponents(ability.getControllerId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - FilterPermanent filter = new FilterPermanent("noncreature permanent from opponent " + opponent.getLogName()); - filter.add(new ControllerIdPredicate(opponentId)); - filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); - TargetPermanent target = new TargetPermanent(0,1, filter,false); - ability.addTarget(target); - } - } - } + Ability ability = new EntersBattlefieldTriggeredAbility(new SylvanPrimordialEffect(), false); + ability.setTargetAdjuster(SylvanPrimordialAdjuster.instance); + this.addAbility(ability); } public SylvanPrimordial(final SylvanPrimordial card) { @@ -73,10 +59,30 @@ public final class SylvanPrimordial extends CardImpl { } } +enum SylvanPrimordialAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + for (UUID opponentId : game.getOpponents(ability.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null) { + FilterPermanent filter = new FilterPermanent("noncreature permanent from opponent " + opponent.getLogName()); + filter.add(new ControllerIdPredicate(opponentId)); + filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); + TargetPermanent target = new TargetPermanent(0, 1, filter, false); + ability.addTarget(target); + } + } + } +} + class SylvanPrimordialEffect extends OneShotEffect { private static final FilterLandCard filterForest = new FilterLandCard("Forest"); - static{ + + static { filterForest.add(new SubtypePredicate(SubType.FOREST)); } @@ -98,7 +104,7 @@ class SylvanPrimordialEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { boolean result = false; int destroyedCreatures = 0; - for (Target target: source.getTargets()) { + for (Target target : source.getTargets()) { if (target instanceof TargetPermanent) { Permanent targetPermanent = game.getPermanent(target.getFirstTarget()); if (targetPermanent != null) { @@ -109,7 +115,7 @@ class SylvanPrimordialEffect extends OneShotEffect { } } if (destroyedCreatures > 0) { - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(destroyedCreatures,filterForest), true, true).apply(game, source); + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(destroyedCreatures, filterForest), true, true).apply(game, source); } return result; } diff --git a/Mage.Sets/src/mage/cards/t/TaintedSigil.java b/Mage.Sets/src/mage/cards/t/TaintedSigil.java index a2c294ea1b..424a3d3191 100644 --- a/Mage.Sets/src/mage/cards/t/TaintedSigil.java +++ b/Mage.Sets/src/mage/cards/t/TaintedSigil.java @@ -1,7 +1,6 @@ package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; @@ -16,23 +15,22 @@ import mage.constants.Zone; import mage.game.Game; import mage.watchers.common.PlayerLostLifeWatcher; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class TaintedSigil extends CardImpl { - - String rule = "You gain life equal to the total life lost by all players this turn"; + + private static final String rule = "You gain life equal to the total life lost by all players this turn"; public TaintedSigil(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}{W}{B}"); - - - + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{W}{B}"); // {tap}, Sacrifice Tainted Sigil: You gain life equal to the total life lost by all players this turn. - AllPlayersLostLifeCount totalLifeLostThisTurn = new AllPlayersLostLifeCount(); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(totalLifeLostThisTurn, rule), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, new GainLifeEffect(AllPlayersLostLifeCount.instance, rule), new TapSourceCost() + ); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); @@ -48,7 +46,8 @@ public final class TaintedSigil extends CardImpl { } } -class AllPlayersLostLifeCount implements DynamicValue { +enum AllPlayersLostLifeCount implements DynamicValue { + instance; @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { @@ -69,7 +68,7 @@ class AllPlayersLostLifeCount implements DynamicValue { @Override public DynamicValue copy() { - return new AllPlayersLostLifeCount(); + return instance; } @Override diff --git a/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java b/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java index 6945d84d35..75e60e1bf5 100644 --- a/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java +++ b/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java @@ -1,7 +1,6 @@ package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; @@ -13,28 +12,24 @@ import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author Styxo */ public final class TheBattleOfNaboo extends CardImpl { public TheBattleOfNaboo(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{X}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{X}{U}{U}"); // Return X target creatures to their owner's hands. Draw twice that many cards. Effect effect = new ReturnToHandTargetEffect(); effect.setText("Return X target creatures to their owner's hands"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new TheBattleOfNabooEffect()); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - ability.getTargets().clear(); - ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); + this.getSpellAbility().setTargetAdjuster(TheBattleOfNabooAdjuster.instance); } public TheBattleOfNaboo(final TheBattleOfNaboo card) { @@ -47,6 +42,16 @@ public final class TheBattleOfNaboo extends CardImpl { } } +enum TheBattleOfNabooAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); + } +} + class TheBattleOfNabooEffect extends OneShotEffect { public TheBattleOfNabooEffect() { @@ -72,9 +77,7 @@ class TheBattleOfNabooEffect extends OneShotEffect { player.drawCards(2 * x, game); } return true; - } return false; } - } diff --git a/Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java b/Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java index 6a8cc6ccb9..52ad0363c3 100644 --- a/Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java +++ b/Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java @@ -1,9 +1,7 @@ package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.keyword.AssistAbility; @@ -17,9 +15,11 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.CounterPredicate; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class TheCrowdGoesWild extends CardImpl { @@ -41,6 +41,7 @@ public final class TheCrowdGoesWild extends CardImpl { .setText("Support X (Put a +1/+1 counter on each of up to X target creatures.)
") ); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(TheCrowdGoesWildAdjuster.instance); // Each creature with a +1/+1 counter on it gains trample until end of turn. this.getSpellAbility().addEffect(new GainAbilityAllEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, filter)); @@ -50,17 +51,18 @@ public final class TheCrowdGoesWild extends CardImpl { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - ability.addTarget(new TargetCreaturePermanent(0, xValue)); - } - } - @Override public TheCrowdGoesWild copy() { return new TheCrowdGoesWild(this); } } + +enum TheCrowdGoesWildAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(0, ability.getManaCostsToPay().getX())); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/t/Thrive.java b/Mage.Sets/src/mage/cards/t/Thrive.java index 0ef155b6a8..d4d640ab23 100644 --- a/Mage.Sets/src/mage/cards/t/Thrive.java +++ b/Mage.Sets/src/mage/cards/t/Thrive.java @@ -1,9 +1,7 @@ package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.CardImpl; @@ -12,21 +10,23 @@ import mage.constants.CardType; import mage.counters.CounterType; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author emerald000 */ public final class Thrive extends CardImpl { public Thrive(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{G}"); // Put a +1/+1 counter on each of X target creatures. Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); effect.setText("Put a +1/+1 counter on each of X target creatures"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1)); + this.getSpellAbility().setTargetAdjuster(ThriveAdjuster.instance); } public Thrive(final Thrive card) { @@ -37,13 +37,14 @@ public final class Thrive extends CardImpl { public Thrive copy() { return new Thrive(this); } - +} + +enum ThriveAdjuster implements TargetAdjuster { + instance; + @Override public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - ability.addTarget(new TargetCreaturePermanent(xValue)); - } + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/t/TimeToReflect.java b/Mage.Sets/src/mage/cards/t/TimeToReflect.java index 95ac6ecefc..727e2fd5b9 100644 --- a/Mage.Sets/src/mage/cards/t/TimeToReflect.java +++ b/Mage.Sets/src/mage/cards/t/TimeToReflect.java @@ -1,9 +1,7 @@ - package mage.cards.t; import mage.MageObjectReference; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.ExileTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -19,8 +17,8 @@ import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; import mage.watchers.Watcher; - import java.util.*; +import mage.target.targetadjustment.TargetAdjuster; /** * @author jeffwadsworth @@ -34,27 +32,7 @@ public final class TimeToReflect extends CardImpl { this.getSpellAbility().addEffect(new ExileTargetEffect()); this.getSpellAbility().addTarget(new TargetPermanent(new FilterCreaturePermanent("creature that blocked or was blocked by a Zombie this turn."))); this.getSpellAbility().addWatcher(new BlockedOrWasBlockedByAZombieWatcher()); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - List creaturesThatBlockedOrWereBlockedByAZombie = new ArrayList<>(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that blocked or was blocked by a Zombie this turn.").copy(); - BlockedOrWasBlockedByAZombieWatcher watcher = game.getState().getWatcher(BlockedOrWasBlockedByAZombieWatcher.class); - if (watcher != null) { - for (MageObjectReference mor : watcher.getBlockedThisTurnCreatures()) { - Permanent permanent = mor.getPermanent(game); - if (permanent != null) { - creaturesThatBlockedOrWereBlockedByAZombie.add(new PermanentIdPredicate(permanent.getId())); - } - } - } - filter.add(Predicates.or(creaturesThatBlockedOrWereBlockedByAZombie)); - ability.getTargets().clear(); - ability.addTarget(new TargetCreaturePermanent(filter)); - } + this.getSpellAbility().setTargetAdjuster(TimeToReflectAdjuster.instance); } public TimeToReflect(final TimeToReflect card) { @@ -67,6 +45,28 @@ public final class TimeToReflect extends CardImpl { } } +enum TimeToReflectAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + List creaturesThatBlockedOrWereBlockedByAZombie = new ArrayList<>(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that blocked or was blocked by a Zombie this turn.").copy(); + BlockedOrWasBlockedByAZombieWatcher watcher = (BlockedOrWasBlockedByAZombieWatcher) game.getState().getWatchers().get(BlockedOrWasBlockedByAZombieWatcher.class.getSimpleName()); + if (watcher != null) { + for (MageObjectReference mor : watcher.getBlockedThisTurnCreatures()) { + Permanent permanent = mor.getPermanent(game); + if (permanent != null) { + creaturesThatBlockedOrWereBlockedByAZombie.add(new PermanentIdPredicate(permanent.getId())); + } + } + } + filter.add(Predicates.or(creaturesThatBlockedOrWereBlockedByAZombie)); + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(filter)); + } +} + class BlockedOrWasBlockedByAZombieWatcher extends Watcher { private final Set blockedOrWasBlockedByAZombieWatcher; diff --git a/Mage.Sets/src/mage/cards/t/TraceOfAbundance.java b/Mage.Sets/src/mage/cards/t/TraceOfAbundance.java index 3b01224026..361826e348 100644 --- a/Mage.Sets/src/mage/cards/t/TraceOfAbundance.java +++ b/Mage.Sets/src/mage/cards/t/TraceOfAbundance.java @@ -1,23 +1,17 @@ package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.mana.AddManaAnyColorAttachedControllerEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.effects.mana.AddManaAnyColorAttachedControllerEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.ShroudAbility; import mage.abilities.mana.TriggeredManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -25,16 +19,17 @@ import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetLandPermanent; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class TraceOfAbundance extends CardImpl { - private String rule = "Enchanted land has shroud"; + private static final String rule = "Enchanted land has shroud"; public TraceOfAbundance(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R/W}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R/W}{G}"); this.subtype.add(SubType.AURA); // Enchant land diff --git a/Mage.Sets/src/mage/cards/t/TurbulentDreams.java b/Mage.Sets/src/mage/cards/t/TurbulentDreams.java index cd595d460e..6dcdd74d69 100644 --- a/Mage.Sets/src/mage/cards/t/TurbulentDreams.java +++ b/Mage.Sets/src/mage/cards/t/TurbulentDreams.java @@ -1,60 +1,58 @@ package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.common.DiscardXTargetCost; -import mage.abilities.dynamicvalue.common.GetXValue; import mage.abilities.effects.Effect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.FilterCard; import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.StaticFilters; +import mage.filter.common.FilterNonlandPermanent; import mage.game.Game; import mage.target.Target; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author fireshoes */ public final class TurbulentDreams extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent("nonland permanents"); - - static { - filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); - } public TurbulentDreams(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}{U}"); // As an additional cost to cast Turbulent Dreams, discard X cards. - this.getSpellAbility().addCost(new DiscardXTargetCost(new FilterCard("cards"), true)); - + this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true)); + // Return X target nonland permanents to their owners' hands. Effect effect = new ReturnToHandTargetEffect(); effect.setText("Return X target nonland permanents to their owners' hands"); this.getSpellAbility().addEffect(effect); + this.getSpellAbility().setTargetAdjuster(TurbulentDreamsAdjuster.instance); } public TurbulentDreams(final TurbulentDreams card) { super(card); } - - @Override - public void adjustTargets(Ability ability, Game game) { - int xValue = new GetXValue().calculate(game, ability, null); - Target target = new TargetPermanent(0, xValue, filter, false); - ability.addTarget(target); - } @Override public TurbulentDreams copy() { return new TurbulentDreams(this); } } + +enum TurbulentDreamsAdjuster implements TargetAdjuster { + instance; + private static final FilterPermanent filter = new FilterNonlandPermanent("nonland permanents"); + + @Override + public void adjustTargets(Ability ability, Game game) { + Target target = new TargetPermanent(0, ability.getManaCostsToPay().getX(), filter, false); + ability.addTarget(target); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/u/UnstableFooting.java b/Mage.Sets/src/mage/cards/u/UnstableFooting.java index 3682d933e1..898570d5a5 100644 --- a/Mage.Sets/src/mage/cards/u/UnstableFooting.java +++ b/Mage.Sets/src/mage/cards/u/UnstableFooting.java @@ -1,9 +1,7 @@ package mage.cards.u; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.common.KickedCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; @@ -18,9 +16,11 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.target.common.TargetPlayerOrPlaneswalker; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class UnstableFooting extends CardImpl { @@ -36,20 +36,12 @@ public final class UnstableFooting extends CardImpl { this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new DamageTargetEffect(5), KickedCondition.instance, - "If this spell was kicked, it deals 5 damage to target player or planeswalker")); + "If this spell was kicked, it deals 5 damage to target player or planeswalker") + ); + this.getSpellAbility().setTargetAdjuster(UnstableFootingAdjuster.instance); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - if (KickedCondition.instance.apply(game, ability)) { - ability.addTarget(new TargetPlayerOrPlaneswalker()); - } - } - } - public UnstableFooting(final UnstableFooting card) { super(card); } @@ -60,6 +52,18 @@ public final class UnstableFooting extends CardImpl { } } +enum UnstableFootingAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + if (KickedCondition.instance.apply(game, ability)) { + ability.addTarget(new TargetPlayerOrPlaneswalker()); + } + } +} + class UnstableFootingEffect extends ReplacementEffectImpl { public UnstableFootingEffect() { diff --git a/Mage.Sets/src/mage/cards/v/VengefulDreams.java b/Mage.Sets/src/mage/cards/v/VengefulDreams.java index 93f6a61452..55b4b8520d 100644 --- a/Mage.Sets/src/mage/cards/v/VengefulDreams.java +++ b/Mage.Sets/src/mage/cards/v/VengefulDreams.java @@ -1,52 +1,58 @@ package mage.cards.v; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.common.DiscardXTargetCost; -import mage.abilities.dynamicvalue.common.GetXValue; import mage.abilities.effects.Effect; import mage.abilities.effects.common.ExileTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.filter.FilterCard; +import mage.filter.FilterPermanent; import mage.filter.common.FilterAttackingCreature; import mage.game.Game; import mage.target.Target; -import mage.target.common.TargetCreaturePermanent; +import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author fireshoes */ public final class VengefulDreams extends CardImpl { public VengefulDreams(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}{W}"); // As an additional cost to cast Vengeful Dreams, discard X cards. this.getSpellAbility().addCost(new DiscardXTargetCost(new FilterCard("cards"), true)); - + // Exile X target attacking creatures. Effect effect = new ExileTargetEffect(); effect.setText("Exile X target attacking creatures"); this.getSpellAbility().addEffect(effect); + this.getSpellAbility().setTargetAdjuster(VengefulDreamsAdjuster.instance); } public VengefulDreams(final VengefulDreams card) { super(card); } - - @Override - public void adjustTargets(Ability ability, Game game) { - int xValue = new GetXValue().calculate(game, ability, null); - Target target = new TargetCreaturePermanent(0, xValue, new FilterAttackingCreature(), false); - ability.addTarget(target); - } @Override public VengefulDreams copy() { return new VengefulDreams(this); } } + +enum VengefulDreamsAdjuster implements TargetAdjuster { + instance; + private static final FilterPermanent filter = new FilterAttackingCreature(); + + @Override + public void adjustTargets(Ability ability, Game game) { + Target target = new TargetPermanent(0, ability.getManaCostsToPay().getX(), filter, false); + ability.addTarget(target); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java b/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java index 5794410ba0..c0848ff167 100644 --- a/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java +++ b/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java @@ -1,7 +1,6 @@ package mage.cards.v; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -17,12 +16,7 @@ import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.keyword.MorphAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.TargetController; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.AnotherPredicate; @@ -32,14 +26,13 @@ import mage.players.Player; import mage.target.common.TargetCreaturePermanent; import mage.util.functions.ApplyToPermanent; +import java.util.UUID; + /** * @author spjspj */ public final class VesuvanShapeshifter extends CardImpl { - protected Ability turnFaceUpAbility = null; - private static final String effectText = "as a copy of any creature on the battlefield until {this} is turned faced down"; - public VesuvanShapeshifter(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); this.subtype.add(SubType.SHAPESHIFTER); @@ -53,7 +46,7 @@ public final class VesuvanShapeshifter extends CardImpl { // As Vesuvan Shapeshifter etbs, you may choose another creature. If you do, until Vesuvan Shapeshifter is turned face down, it becomes a copy of that creature Effect effect = new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_CREATURE, new VesuvanShapeShifterFaceUpApplier()); - effect.setText(effectText); + effect.setText("as a copy of any creature on the battlefield until {this} is turned faced down"); ability = new EntersBattlefieldAbility(effect, true); ability.setWorksFaceDown(false); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/v/VizierOfDeferment.java b/Mage.Sets/src/mage/cards/v/VizierOfDeferment.java index 377ec9530e..6e24c93d23 100644 --- a/Mage.Sets/src/mage/cards/v/VizierOfDeferment.java +++ b/Mage.Sets/src/mage/cards/v/VizierOfDeferment.java @@ -1,11 +1,7 @@ package mage.cards.v; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.MageInt; -import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; @@ -16,12 +12,9 @@ import mage.abilities.keyword.FlashAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.permanent.PermanentIdPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -30,8 +23,9 @@ import mage.target.targetpointer.FixedTarget; import mage.watchers.common.AttackedThisTurnWatcher; import mage.watchers.common.BlockedThisTurnWatcher; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class VizierOfDeferment extends CardImpl { @@ -49,39 +43,10 @@ public final class VizierOfDeferment extends CardImpl { // When Vizier of Deferment enters the battlefield, you may exile target creature if it attacked or blocked this turn. Return that card to the battlefield under its owner's control at the beginning of the next end step. Ability ability = new EntersBattlefieldTriggeredAbility(new VizierOfDefermentEffect(), true); + ability.addTarget(new TargetCreaturePermanent()); ability.addWatcher(new AttackedThisTurnWatcher()); ability.addWatcher(new BlockedThisTurnWatcher()); this.addAbility(ability); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof EntersBattlefieldTriggeredAbility) { - List creaturesThatCanBeTargeted = new ArrayList<>(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that attacked or blocked this turn."); - AttackedThisTurnWatcher watcherAttacked = game.getState().getWatcher(AttackedThisTurnWatcher.class); - BlockedThisTurnWatcher watcherBlocked = game.getState().getWatcher(BlockedThisTurnWatcher.class); - if (watcherAttacked != null) { - for (MageObjectReference mor : watcherAttacked.getAttackedThisTurnCreatures()) { - Permanent permanent = mor.getPermanent(game); - if (permanent != null) { - creaturesThatCanBeTargeted.add(new PermanentIdPredicate(permanent.getId())); - } - } - if (watcherBlocked != null) { - for (MageObjectReference mor : watcherBlocked.getBlockedThisTurnCreatures()) { - Permanent permanent = mor.getPermanent(game); - if (permanent != null) { - creaturesThatCanBeTargeted.add(new PermanentIdPredicate(permanent.getId())); - } - } - } - filter.add(Predicates.or(creaturesThatCanBeTargeted)); - ability.getTargets().clear(); - ability.addTarget(new TargetCreaturePermanent(filter)); - } - } } public VizierOfDeferment(final VizierOfDeferment card) { @@ -98,7 +63,8 @@ class VizierOfDefermentEffect extends OneShotEffect { public VizierOfDefermentEffect() { super(Outcome.Detriment); - staticText = "you may exile target creature if it attacked or blocked this turn. Return that card to the battlefield under its owner's control at the beginning of the next end step"; + staticText = "you may exile target creature if it attacked or blocked this turn. " + + "Return that card to the battlefield under its owner's control at the beginning of the next end step"; } public VizierOfDefermentEffect(final VizierOfDefermentEffect effect) { @@ -110,8 +76,17 @@ class VizierOfDefermentEffect extends OneShotEffect { Permanent permanent = game.getPermanent(source.getFirstTarget()); Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + AttackedThisTurnWatcher watcherAttacked = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName()); + BlockedThisTurnWatcher watcherBlocked = (BlockedThisTurnWatcher) game.getState().getWatchers().get(BlockedThisTurnWatcher.class.getSimpleName()); + boolean attackedOrBlocked = false; + if (watcherAttacked != null && watcherAttacked.checkIfAttacked(permanent, game)) { + attackedOrBlocked = true; + } + if (watcherBlocked != null && watcherBlocked.checkIfBlocked(permanent, game)) { + attackedOrBlocked = true; + } if (controller != null - && permanent != null + && attackedOrBlocked && sourcePermanent != null) { if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true)) { Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(); diff --git a/Mage.Sets/src/mage/cards/v/VolcanicEruption.java b/Mage.Sets/src/mage/cards/v/VolcanicEruption.java index 8f2514123f..cf6c04bafe 100644 --- a/Mage.Sets/src/mage/cards/v/VolcanicEruption.java +++ b/Mage.Sets/src/mage/cards/v/VolcanicEruption.java @@ -1,10 +1,8 @@ - package mage.cards.v; import java.util.List; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -18,6 +16,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetLandPermanent; +import mage.target.targetadjustment.TargetAdjuster; /** * @@ -25,23 +24,12 @@ import mage.target.common.TargetLandPermanent; */ public final class VolcanicEruption extends CardImpl { - private static final FilterLandPermanent filter = new FilterLandPermanent(SubType.MOUNTAIN, "Mountain"); - public VolcanicEruption(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}{U}{U}"); // Destroy X target Mountains. Volcanic Eruption deals damage to each creature and each player equal to the number of Mountains put into a graveyard this way. - this.getSpellAbility().addTarget(new TargetLandPermanent(filter)); this.getSpellAbility().addEffect(new VolcanicEruptionEffect()); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - ability.addTarget(new TargetLandPermanent(xValue, xValue, filter, false)); - } + this.getSpellAbility().setTargetAdjuster(VolcanicEruptionAdjuster.instance); } public VolcanicEruption(final VolcanicEruption card) { @@ -54,6 +42,19 @@ public final class VolcanicEruption extends CardImpl { } } +enum VolcanicEruptionAdjuster implements TargetAdjuster { + instance; + private static final FilterLandPermanent filter + = new FilterLandPermanent(SubType.MOUNTAIN, "Mountain"); + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + ability.addTarget(new TargetLandPermanent(xValue, xValue, filter, false)); + } +} + class VolcanicEruptionEffect extends OneShotEffect { public VolcanicEruptionEffect() { diff --git a/Mage.Sets/src/mage/cards/v/VolcanicOffering.java b/Mage.Sets/src/mage/cards/v/VolcanicOffering.java index 9037d6ea45..3c9d41e2ee 100644 --- a/Mage.Sets/src/mage/cards/v/VolcanicOffering.java +++ b/Mage.Sets/src/mage/cards/v/VolcanicOffering.java @@ -1,9 +1,7 @@ package mage.cards.v; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -22,30 +20,22 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetOpponentsChoicePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class VolcanicOffering extends CardImpl { - private static final FilterLandPermanent filterLand = new FilterLandPermanent("nonbasic land you don't control"); - private static final FilterCreaturePermanent filterCreature = new FilterCreaturePermanent("creature you don't control"); - static { - filterLand.add(new ControllerPredicate(TargetController.NOT_YOU)); - filterLand.add(Predicates.not(new SupertypePredicate(SuperType.BASIC))); - filterCreature.add(new ControllerPredicate(TargetController.NOT_YOU)); - } public VolcanicOffering(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}"); // Destroy target nonbasic land you don't control and target nonbasic land of an opponent's choice you don't control. // Volcanic Offering deals 7 damage to target creature you don't control and 7 damage to target creature of an opponent's choice you don't control. this.getSpellAbility().addEffect(new VolcanicOfferingEffect()); - this.getSpellAbility().addTarget(new TargetPermanent(filterLand)); - this.getSpellAbility().addTarget(new TargetPermanent(filterCreature)); - + this.getSpellAbility().setTargetAdjuster(VolcanicOfferingAdjuster.instance); } public VolcanicOffering(final VolcanicOffering card) { @@ -53,27 +43,39 @@ public final class VolcanicOffering extends CardImpl { } @Override - public void adjustTargets(Ability ability, Game game) { - Player controller = game.getPlayer(ability.getControllerId()); - if (controller != null && (ability instanceof SpellAbility)) { - ability.getTargets().clear(); - ability.addTarget(new TargetPermanent(filterLand)); - FilterLandPermanent filterLandForOpponent = new FilterLandPermanent("nonbasic land not controlled by " + controller.getLogName()); - filterLandForOpponent.add(Predicates.not(new SupertypePredicate(SuperType.BASIC))); - filterLandForOpponent.add(Predicates.not(new ControllerIdPredicate(controller.getId()))); - ability.addTarget(new TargetOpponentsChoicePermanent(1, 1, filterLandForOpponent, false, true)); + public VolcanicOffering copy() { + return new VolcanicOffering(this); + } +} - ability.addTarget(new TargetPermanent(filterCreature)); - FilterCreaturePermanent filterCreatureForOpponent = new FilterCreaturePermanent("creature not controlled by " + controller.getLogName()); - filterCreatureForOpponent.add(Predicates.not(new ControllerIdPredicate(controller.getId()))); - ability.addTarget(new TargetOpponentsChoicePermanent(1, 1, filterCreatureForOpponent, false, true)); - } +enum VolcanicOfferingAdjuster implements TargetAdjuster { + instance; + private static final FilterLandPermanent filterLand = new FilterLandPermanent("nonbasic land you don't control"); + private static final FilterCreaturePermanent filterCreature = new FilterCreaturePermanent("creature you don't control"); + static { + filterLand.add(new ControllerPredicate(TargetController.NOT_YOU)); + filterLand.add(Predicates.not(new SupertypePredicate(SuperType.BASIC))); + filterCreature.add(new ControllerPredicate(TargetController.NOT_YOU)); } @Override - public VolcanicOffering copy() { - return new VolcanicOffering(this); + public void adjustTargets(Ability ability, Game game) { + Player controller = game.getPlayer(ability.getControllerId()); + if (controller == null) { + return; + } + ability.getTargets().clear(); + ability.addTarget(new TargetPermanent(filterLand)); + FilterLandPermanent filterLandForOpponent = new FilterLandPermanent("nonbasic land not controlled by " + controller.getLogName()); + filterLandForOpponent.add(Predicates.not(new SupertypePredicate(SuperType.BASIC))); + filterLandForOpponent.add(Predicates.not(new ControllerIdPredicate(controller.getId()))); + ability.addTarget(new TargetOpponentsChoicePermanent(1, 1, filterLandForOpponent, false, true)); + + ability.addTarget(new TargetPermanent(filterCreature)); + FilterCreaturePermanent filterCreatureForOpponent = new FilterCreaturePermanent("creature not controlled by " + controller.getLogName()); + filterCreatureForOpponent.add(Predicates.not(new ControllerIdPredicate(controller.getId()))); + ability.addTarget(new TargetOpponentsChoicePermanent(1, 1, filterCreatureForOpponent, false, true)); } } diff --git a/Mage.Sets/src/mage/cards/v/VoyagerDrake.java b/Mage.Sets/src/mage/cards/v/VoyagerDrake.java index 3db5967e0f..afe52717fa 100644 --- a/Mage.Sets/src/mage/cards/v/VoyagerDrake.java +++ b/Mage.Sets/src/mage/cards/v/VoyagerDrake.java @@ -1,12 +1,9 @@ package mage.cards.v; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.condition.common.KickedCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.dynamicvalue.common.MultikickerCount; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.FlyingAbility; @@ -14,21 +11,21 @@ import mage.abilities.keyword.MultikickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author jeffwadsworth */ public final class VoyagerDrake extends CardImpl { - private final UUID originalId; - public VoyagerDrake(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); this.subtype.add(SubType.DRAKE); this.power = new MageInt(3); @@ -41,29 +38,18 @@ public final class VoyagerDrake extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Voyager Drake enters the battlefield, up to X target creatures gain flying until end of turn, where X is the number of times Voyager Drake was kicked. - //TODO this should trigger even if it wasn't kicked at all - Ability ability = new ConditionalInterveningIfTriggeredAbility( - new EntersBattlefieldTriggeredAbility(new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), false), - KickedCondition.instance, - "When {this} enters the battlefield, up to X target creatures gain flying until end of turn, where X is the number of times {this} was kicked."); - originalId = ability.getOriginalId(); + Ability ability = new EntersBattlefieldTriggeredAbility( + new GainAbilityTargetEffect( + FlyingAbility.getInstance(), Duration.EndOfTurn + ).setText("up to X target creatures gain flying until end of turn, " + + "where X is the number of times {this} was kicked.") + ); + ability.setTargetAdjuster(VoyagerDrakeAdjuster.instance); this.addAbility(ability); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability.getOriginalId().equals(originalId)) { - ability.getTargets().clear(); - int numbTargets = new MultikickerCount().calculate(game, ability, null); - if (numbTargets > 0) { - ability.addTarget(new TargetCreaturePermanent(0, numbTargets)); - } - } - } - public VoyagerDrake(final VoyagerDrake card) { super(card); - this.originalId = card.originalId; } @Override @@ -71,3 +57,16 @@ public final class VoyagerDrake extends CardImpl { return new VoyagerDrake(this); } } + +enum VoyagerDrakeAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int numbTargets = new MultikickerCount().calculate(game, ability, null); + if (numbTargets > 0) { + ability.addTarget(new TargetCreaturePermanent(0, numbTargets)); + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/w/WakeTheDead.java b/Mage.Sets/src/mage/cards/w/WakeTheDead.java index 49f0cb0087..b4c6f60a72 100644 --- a/Mage.Sets/src/mage/cards/w/WakeTheDead.java +++ b/Mage.Sets/src/mage/cards/w/WakeTheDead.java @@ -3,7 +3,6 @@ package mage.cards.w; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; -import mage.abilities.SpellAbility; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.condition.common.OnOpponentsTurnCondition; @@ -18,11 +17,13 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TurnPhase; import mage.constants.Zone; +import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetpointer.FixedTargets; import java.util.ArrayList; @@ -30,29 +31,19 @@ import java.util.List; import java.util.UUID; /** - * * @author LevelX2 */ public final class WakeTheDead extends CardImpl { public WakeTheDead(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{B}{B}"); // Cast Wake the Dead only during combat on an opponent's turn. this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(TurnPhase.COMBAT, OnOpponentsTurnCondition.instance)); // Return X target creature cards from your graveyard to the battlefield. Sacrifice those creatures at the beginning of the next end step. this.getSpellAbility().addEffect(new WakeTheDeadReturnFromGraveyardToBattlefieldTargetEffect()); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, Integer.MAX_VALUE, new FilterCreatureCard("creature cards from your graveyard"))); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - int xValue = ability.getManaCostsToPay().getX(); - ability.getTargets().clear(); - ability.addTarget(new TargetCardInYourGraveyard(xValue, xValue, new FilterCreatureCard("creature cards from your graveyard"))); - } + this.getSpellAbility().setTargetAdjuster(WakeTheDeadAdjuster.instance); } public WakeTheDead(final WakeTheDead card) { @@ -65,6 +56,17 @@ public final class WakeTheDead extends CardImpl { } } +enum WakeTheDeadAdjuster implements TargetAdjuster { + instance; + private static final FilterCard filter = new FilterCreatureCard("creature cards from your graveyard"); + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCardInYourGraveyard(ability.getManaCostsToPay().getX(), filter)); + } +} + class WakeTheDeadReturnFromGraveyardToBattlefieldTargetEffect extends OneShotEffect { public WakeTheDeadReturnFromGraveyardToBattlefieldTargetEffect() { diff --git a/Mage.Sets/src/mage/cards/w/WaveOfIndifference.java b/Mage.Sets/src/mage/cards/w/WaveOfIndifference.java index 5ca08c5737..2ba1c6f4aa 100644 --- a/Mage.Sets/src/mage/cards/w/WaveOfIndifference.java +++ b/Mage.Sets/src/mage/cards/w/WaveOfIndifference.java @@ -1,21 +1,20 @@ package mage.cards.w; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.combat.CantBlockTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.filter.StaticFilters; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author emerald000 */ public final class WaveOfIndifference extends CardImpl { @@ -27,23 +26,25 @@ public final class WaveOfIndifference extends CardImpl { Effect effect = new CantBlockTargetEffect(Duration.EndOfTurn); effect.setText("X target creatures can't block this turn"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1, StaticFilters.FILTER_PERMANENT_CREATURE, false)); + this.getSpellAbility().setTargetAdjuster(WaveOfIndifferenceAdjuster.instance); } public WaveOfIndifference(final WaveOfIndifference card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); - } - } - @Override public WaveOfIndifference copy() { return new WaveOfIndifference(this); } } + +enum WaveOfIndifferenceAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/w/WildestDreams.java b/Mage.Sets/src/mage/cards/w/WildestDreams.java index c1623d2fe5..0f3dcf1b93 100644 --- a/Mage.Sets/src/mage/cards/w/WildestDreams.java +++ b/Mage.Sets/src/mage/cards/w/WildestDreams.java @@ -1,9 +1,7 @@ package mage.cards.w; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.ExileSpellEffect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; @@ -13,9 +11,11 @@ import mage.constants.CardType; import mage.filter.StaticFilters; import mage.game.Game; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class WildestDreams extends CardImpl { @@ -28,17 +28,8 @@ public final class WildestDreams extends CardImpl { Effect effect = new ReturnFromGraveyardToHandTargetEffect(); effect.setText("Return X target cards from your graveyard to your hand"); this.getSpellAbility().addEffect(effect); + this.getSpellAbility().setTargetAdjuster(WildestDreamsAdjuster.instance); this.getSpellAbility().addEffect(ExileSpellEffect.getInstance()); - - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - int xValue = ability.getManaCostsToPay().getX(); - ability.getTargets().clear(); - ability.addTarget(new TargetCardInYourGraveyard(xValue, StaticFilters.FILTER_CARD_FROM_YOUR_GRAVEYARD)); - } } public WildestDreams(final WildestDreams card) { @@ -50,3 +41,16 @@ public final class WildestDreams extends CardImpl { return new WildestDreams(this); } } + +enum WildestDreamsAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCardInYourGraveyard( + ability.getManaCostsToPay().getX(), + StaticFilters.FILTER_CARD_FROM_YOUR_GRAVEYARD + )); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/w/WindgracesJudgment.java b/Mage.Sets/src/mage/cards/w/WindgracesJudgment.java index 77067c6f63..006688c784 100644 --- a/Mage.Sets/src/mage/cards/w/WindgracesJudgment.java +++ b/Mage.Sets/src/mage/cards/w/WindgracesJudgment.java @@ -1,8 +1,6 @@ package mage.cards.w; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -12,9 +10,11 @@ import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class WindgracesJudgment extends CardImpl { @@ -29,24 +29,7 @@ public final class WindgracesJudgment extends CardImpl { + "destroy target nonland permanent " + "that player controls") ); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - game.getOpponents(ability.getControllerId()).forEach(playerId -> { - Player player = game.getPlayer(playerId); - if (player != null) { - FilterNonlandPermanent filter = new FilterNonlandPermanent( - "nonland permanent controlled by " - + player.getLogName() - ); - filter.add(new ControllerIdPredicate(playerId)); - ability.addTarget(new TargetPermanent(0, 1, filter, false)); - } - }); - } + this.getSpellAbility().setTargetAdjuster(WindgracesJudgmentAdjuster.instance); } public WindgracesJudgment(final WindgracesJudgment card) { @@ -58,3 +41,23 @@ public final class WindgracesJudgment extends CardImpl { return new WindgracesJudgment(this); } } + +enum WindgracesJudgmentAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + game.getOpponents(ability.getControllerId()).forEach(playerId -> { + Player player = game.getPlayer(playerId); + if (player != null) { + FilterNonlandPermanent filter = new FilterNonlandPermanent( + "nonland permanent controlled by " + + player.getLogName() + ); + filter.add(new ControllerIdPredicate(playerId)); + ability.addTarget(new TargetPermanent(0, 1, filter, false)); + } + }); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/w/WinterBlast.java b/Mage.Sets/src/mage/cards/w/WinterBlast.java index 38eb6606bb..16f67ad957 100644 --- a/Mage.Sets/src/mage/cards/w/WinterBlast.java +++ b/Mage.Sets/src/mage/cards/w/WinterBlast.java @@ -1,9 +1,7 @@ package mage.cards.w; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -13,9 +11,11 @@ import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class WinterBlast extends CardImpl { @@ -26,15 +26,7 @@ public final class WinterBlast extends CardImpl { // Tap X target creatures. Winter Blast deals 2 damage to each of those creatures with flying. this.getSpellAbility().addEffect(new WinterBlastEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int xValue = ability.getManaCostsToPay().getX(); - ability.addTarget(new TargetCreaturePermanent(xValue)); - } + this.getSpellAbility().setTargetAdjuster(WinterBlastAdjuster.instance); } public WinterBlast(final WinterBlast card) { @@ -47,6 +39,16 @@ public final class WinterBlast extends CardImpl { } } +enum WinterBlastAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); + } +} + class WinterBlastEffect extends OneShotEffect { WinterBlastEffect() { diff --git a/Mage.Sets/src/mage/cards/w/WordOfBinding.java b/Mage.Sets/src/mage/cards/w/WordOfBinding.java index 2364364447..9d6782945d 100644 --- a/Mage.Sets/src/mage/cards/w/WordOfBinding.java +++ b/Mage.Sets/src/mage/cards/w/WordOfBinding.java @@ -1,19 +1,18 @@ package mage.cards.w; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.effects.common.TapTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; /** - * * @author fireshoes */ public final class WordOfBinding extends CardImpl { @@ -23,25 +22,25 @@ public final class WordOfBinding extends CardImpl { // Tap X target creatures. this.getSpellAbility().addEffect(new TapTargetEffect("X target creatures")); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1, FILTER_PERMANENT_CREATURES, false)); + this.getSpellAbility().setTargetAdjuster(WordOfBindingAdjuster.instance); } public WordOfBinding(final WordOfBinding card) { super(card); } - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - int numberToTap = ability.getManaCostsToPay().getX(); - numberToTap = Math.min(game.getBattlefield().count(FILTER_PERMANENT_CREATURES, ability.getSourceId(), ability.getControllerId(), game), numberToTap); - ability.addTarget(new TargetCreaturePermanent(numberToTap, numberToTap, FILTER_PERMANENT_CREATURES, false)); - } - } - @Override public WordOfBinding copy() { return new WordOfBinding(this); } } + +enum WordOfBindingAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); + } +} \ No newline at end of file diff --git a/Mage/src/main/java/mage/MageObjectReference.java b/Mage/src/main/java/mage/MageObjectReference.java index ff72668e40..44f63bebc6 100644 --- a/Mage/src/main/java/mage/MageObjectReference.java +++ b/Mage/src/main/java/mage/MageObjectReference.java @@ -1,7 +1,5 @@ package mage; -import java.io.Serializable; -import java.util.UUID; import mage.cards.Card; import mage.constants.Zone; import mage.game.Game; @@ -10,6 +8,9 @@ import mage.game.stack.Spell; import mage.game.stack.StackObject; import org.apache.log4j.Logger; +import java.io.Serializable; +import java.util.UUID; + /** * A object reference that takes zone changes into account. * @@ -145,4 +146,8 @@ public class MageObjectReference implements Comparable, Ser } return null; } + + public boolean zoneCounterIsCurrent(Game game) { + return game.getState().getZoneChangeCounter(sourceId) == zoneChangeCounter; + } } diff --git a/Mage/src/main/java/mage/abilities/Ability.java b/Mage/src/main/java/mage/abilities/Ability.java index 4ef44edad6..e28354a1ba 100644 --- a/Mage/src/main/java/mage/abilities/Ability.java +++ b/Mage/src/main/java/mage/abilities/Ability.java @@ -1,10 +1,8 @@ package mage.abilities; -import java.io.Serializable; -import java.util.List; -import java.util.UUID; import mage.MageObject; import mage.abilities.costs.Cost; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.Costs; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCosts; @@ -24,6 +22,10 @@ import mage.target.Targets; import mage.target.targetadjustment.TargetAdjuster; import mage.watchers.Watcher; +import java.io.Serializable; +import java.util.List; +import java.util.UUID; + /** * Practically everything in the game is started from an Ability. This interface * describes what an Ability is composed of at the highest level. @@ -44,10 +46,8 @@ public interface Ability extends Controllable, Serializable { * * @see mage.players.PlayerImpl#playAbility(mage.abilities.ActivatedAbility, * mage.game.Game) - * @see - * mage.game.GameImpl#addTriggeredAbility(mage.abilities.TriggeredAbility) - * @see - * mage.game.GameImpl#addDelayedTriggeredAbility(mage.abilities.DelayedTriggeredAbility) + * @see mage.game.GameImpl#addTriggeredAbility(mage.abilities.TriggeredAbility) + * @see mage.game.GameImpl#addDelayedTriggeredAbility(mage.abilities.DelayedTriggeredAbility) */ void newId(); @@ -56,10 +56,8 @@ public interface Ability extends Controllable, Serializable { * * @see mage.players.PlayerImpl#playAbility(mage.abilities.ActivatedAbility, * mage.game.Game) - * @see - * mage.game.GameImpl#addTriggeredAbility(mage.abilities.TriggeredAbility) - * @see - * mage.game.GameImpl#addDelayedTriggeredAbility(mage.abilities.DelayedTriggeredAbility) + * @see mage.game.GameImpl#addTriggeredAbility(mage.abilities.TriggeredAbility) + * @see mage.game.GameImpl#addDelayedTriggeredAbility(mage.abilities.DelayedTriggeredAbility) */ void newOriginalId(); @@ -143,7 +141,7 @@ public interface Ability extends Controllable, Serializable { /** * TODO Method is unused, keep it around? - * + *

* Gets all costs that are optional to this ability. These costs can be paid * in addition to other costs to have other effects put into place. * @@ -208,7 +206,6 @@ public interface Ability extends Controllable, Serializable { * * @return The {@link java.util.UUID} of the first target within the targets * list. - * * @see mage.target.Target */ UUID getFirstTarget(); @@ -266,17 +263,15 @@ public interface Ability extends Controllable, Serializable { /** * Activates this ability prompting the controller to pay any mandatory * - * @param game A reference the {@link Game} for which this ability should be - * activated within. + * @param game A reference the {@link Game} for which this ability should be + * activated within. * @param noMana Whether or not {@link ManaCosts} have to be paid. * @return True if this ability was successfully activated. - * * @see mage.players.PlayerImpl#cast(mage.abilities.SpellAbility, * mage.game.Game, boolean) * @see mage.players.PlayerImpl#playAbility(mage.abilities.ActivatedAbility, * mage.game.Game) - * @see - * mage.players.PlayerImpl#triggerAbility(mage.abilities.TriggeredAbility, + * @see mage.players.PlayerImpl#triggerAbility(mage.abilities.TriggeredAbility, * mage.game.Game) */ boolean activate(Game game, boolean noMana); @@ -290,9 +285,7 @@ public interface Ability extends Controllable, Serializable { * * @param game The {@link Game} for which this ability resolves within. * @return Whether or not this ability successfully resolved. - * - * @see - * mage.players.PlayerImpl#playManaAbility(mage.abilities.mana.ManaAbility, + * @see mage.players.PlayerImpl#playManaAbility(mage.abilities.mana.ManaAbility, * mage.game.Game) * @see mage.players.PlayerImpl#specialAction(mage.abilities.SpecialAction, * mage.game.Game) @@ -380,7 +373,7 @@ public interface Ability extends Controllable, Serializable { /** * Sets the value for the ruleAtTheTop attribute - * + *

* true = show the rule at the top position of the rules * * @param ruleAtTheTop @@ -398,7 +391,7 @@ public interface Ability extends Controllable, Serializable { /** * Sets the value for the worksFaceDown flag - * + *

* true = the ability works also if the object is face down * * @param worksFaceDown @@ -414,7 +407,7 @@ public interface Ability extends Controllable, Serializable { /** * Sets the value for the ruleVisible attribute - * + *

* true = rule will be shown for the card / permanent false = rule won't be * shown * @@ -432,7 +425,7 @@ public interface Ability extends Controllable, Serializable { /** * Sets the value for the additional costs rule attribute - * + *

* true = rule will be shown for the card / permanent false = rule won't be * shown * @@ -451,7 +444,7 @@ public interface Ability extends Controllable, Serializable { * Sets the ability word for the given ability. An ability word is a word * that, in essence, groups, and reminds players of, cards that have a * common functionality and does not imply any particular rules. - * + *

* --- Not usable yet for rule text generation of triggered abilities --- * * @param abilityWord @@ -526,4 +519,10 @@ public interface Ability extends Controllable, Serializable { TargetAdjuster getTargetAdjuster(); void adjustTargets(Game game); + + void setCostAdjuster(CostAdjuster costAdjuster); + + CostAdjuster getCostAdjuster(); + + void adjustCosts(Game game); } diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index 481658c507..f38ead41a1 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -1,9 +1,5 @@ package mage.abilities; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.UUID; import mage.MageObject; import mage.Mana; import mage.abilities.costs.*; @@ -37,6 +33,11 @@ import mage.util.ThreadLocalStringBuilder; import mage.watchers.Watcher; import org.apache.log4j.Logger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; + /** * @author BetaSteward_at_googlemail.com */ @@ -71,6 +72,7 @@ public abstract class AbilityImpl implements Ability { protected List subAbilities = null; protected boolean canFizzle = true; protected TargetAdjuster targetAdjuster = null; + protected CostAdjuster costAdjuster = null; public AbilityImpl(AbilityType abilityType, Zone zone) { this.id = UUID.randomUUID(); @@ -1223,4 +1225,21 @@ public abstract class AbilityImpl implements Ability { targetAdjuster.adjustTargets(this, game); } } + + @Override + public void setCostAdjuster(CostAdjuster costAdjuster) { + this.costAdjuster = costAdjuster; + } + + @Override + public CostAdjuster getCostAdjuster() { + return costAdjuster; + } + + @Override + public void adjustCosts(Game game) { + if (costAdjuster != null) { + costAdjuster.adjustCosts(this, game); + } + } } diff --git a/Mage/src/main/java/mage/abilities/costs/CostAdjuster.java b/Mage/src/main/java/mage/abilities/costs/CostAdjuster.java new file mode 100644 index 0000000000..7ac35fe979 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/costs/CostAdjuster.java @@ -0,0 +1,12 @@ +package mage.abilities.costs; + +import mage.abilities.Ability; +import mage.game.Game; + +/** + * @author TheElk801 + */ +public interface CostAdjuster { + + void adjustCosts(Ability ability, Game game); +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/DestroyTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DestroyTargetEffect.java index b9bcf29ba8..e1deaeef67 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DestroyTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DestroyTargetEffect.java @@ -1,6 +1,5 @@ package mage.abilities.effects.common; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; @@ -12,8 +11,9 @@ import mage.target.targetpointer.FirstTargetPointer; import mage.target.targetpointer.SecondTargetPointer; import mage.util.CardUtil; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public class DestroyTargetEffect extends OneShotEffect { @@ -26,14 +26,18 @@ public class DestroyTargetEffect extends OneShotEffect { } public DestroyTargetEffect(String ruleText) { - this(false); - staticText = ruleText; + this(ruleText, false); } public DestroyTargetEffect(boolean noRegen) { this(noRegen, false); } + public DestroyTargetEffect(String ruleText, boolean noRegen) { + this(noRegen, false); + staticText = ruleText; + } + public DestroyTargetEffect(boolean noRegen, boolean multitargetHandling) { super(Outcome.DestroyPermanent); this.noRegen = noRegen; diff --git a/Mage/src/main/java/mage/cards/CardImpl.java b/Mage/src/main/java/mage/cards/CardImpl.java index 56cad1816c..9a473048df 100644 --- a/Mage/src/main/java/mage/cards/CardImpl.java +++ b/Mage/src/main/java/mage/cards/CardImpl.java @@ -327,9 +327,11 @@ public abstract class CardImpl extends MageObjectImpl implements Card { return spellAbility; } - // @Override -// public void adjustCosts(Ability ability, Game game) { -// } + @Override + public void adjustCosts(Ability ability, Game game) { + ability.adjustCosts(game); + } + @Override public void adjustTargets(Ability ability, Game game) { ability.adjustTargets(game); @@ -360,9 +362,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { public List getMana() { List mana = new ArrayList<>(); for (ActivatedManaAbilityImpl ability : this.abilities.getActivatedManaAbilities(Zone.BATTLEFIELD)) { - for (Mana netMana : ability.getNetMana(null)) { - mana.add(netMana); - } + mana.addAll(ability.getNetMana(null)); } return mana; } diff --git a/Mage/src/main/java/mage/game/stack/StackAbility.java b/Mage/src/main/java/mage/game/stack/StackAbility.java index 2fcadf1147..3c0ebac337 100644 --- a/Mage/src/main/java/mage/game/stack/StackAbility.java +++ b/Mage/src/main/java/mage/game/stack/StackAbility.java @@ -5,6 +5,7 @@ import mage.MageObject; import mage.ObjectColor; import mage.abilities.*; import mage.abilities.costs.Cost; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.Costs; import mage.abilities.costs.CostsImpl; import mage.abilities.costs.mana.ManaCost; @@ -52,6 +53,7 @@ public class StackAbility extends StackObjImpl implements Ability { private String name; private String expansionSetCode; private TargetAdjuster targetAdjuster = null; + private CostAdjuster costAdjuster = null; public StackAbility(Ability ability, UUID controllerId) { this.ability = ability; @@ -627,4 +629,21 @@ public class StackAbility extends StackObjImpl implements Ability { targetAdjuster.adjustTargets(this, game); } } + + @Override + public void setCostAdjuster(CostAdjuster costAdjuster) { + this.costAdjuster = costAdjuster; + } + + @Override + public CostAdjuster getCostAdjuster() { + return costAdjuster; + } + + @Override + public void adjustCosts(Game game) { + if (costAdjuster != null) { + costAdjuster.adjustCosts(this, game); + } + } } diff --git a/Mage/src/main/java/mage/watchers/common/AttackedThisTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/AttackedThisTurnWatcher.java index 3254f72abe..f470a6e06a 100644 --- a/Mage/src/main/java/mage/watchers/common/AttackedThisTurnWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/AttackedThisTurnWatcher.java @@ -1,15 +1,17 @@ package mage.watchers.common; +import mage.MageObjectReference; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; + import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import mage.MageObjectReference; -import mage.constants.WatcherScope; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.watchers.Watcher; /** * @author magenoxx_at_gmail.com @@ -47,6 +49,15 @@ public class AttackedThisTurnWatcher extends Watcher { return this.attackedThisTurnCreaturesCounts; } + public boolean checkIfAttacked(Permanent permanent, Game game) { + for (MageObjectReference mor : attackedThisTurnCreatures) { + if (mor.refersTo(permanent, game)) { + return true; + } + } + return false; + } + @Override public AttackedThisTurnWatcher copy() { return new AttackedThisTurnWatcher(this); diff --git a/Mage/src/main/java/mage/watchers/common/BlockedThisTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/BlockedThisTurnWatcher.java index 263f24b8bb..4a7d6133c7 100644 --- a/Mage/src/main/java/mage/watchers/common/BlockedThisTurnWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/BlockedThisTurnWatcher.java @@ -1,17 +1,17 @@ package mage.watchers.common; -import java.util.HashSet; -import java.util.Set; - import mage.MageObjectReference; import mage.constants.WatcherScope; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; import mage.watchers.Watcher; +import java.util.HashSet; +import java.util.Set; + /** - * * @author Quercitron */ public class BlockedThisTurnWatcher extends Watcher { @@ -44,6 +44,15 @@ public class BlockedThisTurnWatcher extends Watcher { return this.blockedThisTurnCreatures; } + public boolean checkIfBlocked(Permanent permanent, Game game) { + for (MageObjectReference mor : blockedThisTurnCreatures) { + if (mor.refersTo(permanent, game)) { + return true; + } + } + return false; + } + @Override public void reset() { super.reset();