From 8d9cf6a8d29211bbe5bc4cecd71f4c6ea6f5aef0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 24 Sep 2018 14:56:03 -0400 Subject: [PATCH] so many cards to refactor... --- .../mage/cards/c/ChampionOfStraySouls.java | 41 ++++----- .../src/mage/cards/c/ConfusionInTheRanks.java | 91 ++++++++++--------- .../src/mage/cards/c/CovetedPeacock.java | 32 +++---- .../src/mage/cards/c/CuombajjWitches.java | 62 ++++++------- .../src/mage/cards/c/CurseOfTheSwine.java | 31 ++++--- .../src/mage/cards/c/CustodiSoulcaller.java | 58 ++++++------ 6 files changed, 154 insertions(+), 161 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java b/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java index 24434b01b7f..9bfb91786ed 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/ConfusionInTheRanks.java b/Mage.Sets/src/mage/cards/c/ConfusionInTheRanks.java index 388e46d2bc9..fe65023e65f 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 9b748f40682..97502d3bee6 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/CuombajjWitches.java b/Mage.Sets/src/mage/cards/c/CuombajjWitches.java index 2bb7d7a7772..5d58744bdbb 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 cc40d560843..0414cd2ef06 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 ae27d4bddab..1f19992beca 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 = (CustodiSoulcallerWatcher) game.getState().getWatchers().get(CustodiSoulcallerWatcher.class.getSimpleName()); - 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);