From 2941487219b9b6fd0d38841554f896b3525222e6 Mon Sep 17 00:00:00 2001 From: "Alex W. Jackson" Date: Fri, 28 Jan 2022 13:43:46 -0500 Subject: [PATCH] Improve DiscardCardYouChooseTargetEffect and use it for many cards that were using custom effects --- .../src/mage/cards/a/AcquisitionsExpert.java | 2 +- Mage.Sets/src/mage/cards/b/BalaGedThief.java | 89 +++------------- Mage.Sets/src/mage/cards/b/Brainbite.java | 2 +- .../src/mage/cards/c/CabalInterrogator.java | 88 ++------------- .../src/mage/cards/d/DiscipleOfPhenax.java | 80 +------------- Mage.Sets/src/mage/cards/d/Distress.java | 11 +- Mage.Sets/src/mage/cards/d/Divest.java | 15 +-- Mage.Sets/src/mage/cards/d/DreadFugue.java | 55 +--------- Mage.Sets/src/mage/cards/e/Encroach.java | 7 +- .../src/mage/cards/e/EntomberExarch.java | 51 ++------- .../src/mage/cards/g/GruesomeDiscovery.java | 44 +------- Mage.Sets/src/mage/cards/h/HarshScrutiny.java | 4 +- Mage.Sets/src/mage/cards/h/HollowSpecter.java | 48 +-------- .../src/mage/cards/l/LayBareTheHeart.java | 7 +- Mage.Sets/src/mage/cards/n/NogginWhack.java | 70 +----------- Mage.Sets/src/mage/cards/o/Ostracize.java | 4 +- .../src/mage/cards/p/PelakkaPredation.java | 10 +- Mage.Sets/src/mage/cards/p/PsychicSpear.java | 2 +- Mage.Sets/src/mage/cards/r/RiversGrasp.java | 62 ++--------- .../src/mage/cards/s/ShatteredDreams.java | 9 +- .../src/mage/cards/s/SplittingHeadache.java | 55 ++-------- .../src/mage/cards/t/ThievingSprite.java | 100 +++--------------- .../src/mage/cards/t/ThoughtErasure.java | 8 +- .../src/mage/cards/t/TollOfTheInvasion.java | 7 +- .../src/mage/cards/t/TourachsCanticle.java | 4 +- .../DiscardCardYouChooseTargetEffect.java | 100 ++++++++++-------- 26 files changed, 168 insertions(+), 766 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AcquisitionsExpert.java b/Mage.Sets/src/mage/cards/a/AcquisitionsExpert.java index bc1faa331d..85f7fe6757 100644 --- a/Mage.Sets/src/mage/cards/a/AcquisitionsExpert.java +++ b/Mage.Sets/src/mage/cards/a/AcquisitionsExpert.java @@ -30,7 +30,7 @@ public final class AcquisitionsExpert extends CardImpl { // When Acquisitions Expert enters the battlefield, target opponent reveals a number of cards from their hand equal to the number of creatures in your party. You choose one of those cards. That player discards that card. Ability ability = new EntersBattlefieldTriggeredAbility( - new DiscardCardYouChooseTargetEffect(TargetController.ANY, PartyCount.instance) + new DiscardCardYouChooseTargetEffect(TargetController.OPPONENT, PartyCount.instance) .setText("target opponent reveals a number of cards from their hand " + "equal to the number of creatures in your party. You choose one of those cards. " + "That player discards that card. " + PartyCount.getReminder()) diff --git a/Mage.Sets/src/mage/cards/b/BalaGedThief.java b/Mage.Sets/src/mage/cards/b/BalaGedThief.java index a8c92dfa37..f27ca9a854 100644 --- a/Mage.Sets/src/mage/cards/b/BalaGedThief.java +++ b/Mage.Sets/src/mage/cards/b/BalaGedThief.java @@ -1,22 +1,19 @@ - package mage.cards.b; -import java.util.List; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AllyEntersBattlefieldTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.cards.*; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +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.SubType; -import mage.constants.Zone; -import mage.filter.FilterCard; +import mage.constants.TargetController; import mage.filter.common.FilterControlledPermanent; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; import mage.target.TargetPlayer; /** @@ -25,6 +22,8 @@ import mage.target.TargetPlayer; */ public final class BalaGedThief extends CardImpl { + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.ALLY, "Allies you control"), null); + public BalaGedThief(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); this.subtype.add(SubType.HUMAN, SubType.ROGUE, SubType.ALLY); @@ -32,8 +31,10 @@ public final class BalaGedThief extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); - // Whenever Bala Ged Thief or another Ally enters the battlefield under your control, target player reveals a number of cards from their hand equal to the number of Allies you control. You choose one of them. That player discards that card. - Ability ability = new AllyEntersBattlefieldTriggeredAbility(new BalaGedThiefEffect(), false); + // Whenever Bala Ged Thief or another Ally enters the battlefield under your control, + // target player reveals a number of cards from their hand equal to the number of Allies you control. + // You choose one of them. That player discards that card. + Ability ability = new AllyEntersBattlefieldTriggeredAbility(new DiscardCardYouChooseTargetEffect(TargetController.ANY, xValue), false); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } @@ -47,67 +48,3 @@ public final class BalaGedThief extends CardImpl { return new BalaGedThief(this); } } - -class BalaGedThiefEffect extends OneShotEffect { - - public BalaGedThiefEffect() { - super(Outcome.Discard); - this.staticText = "target player reveals a number of cards from their hand equal to the number of Allies you control. You choose one of them. That player discards that card"; - } - - public BalaGedThiefEffect(final BalaGedThiefEffect effect) { - super(effect); - } - - @Override - public BalaGedThiefEffect copy() { - return new BalaGedThiefEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player targetPlayer = game.getPlayer(source.getFirstTarget()); - - if (targetPlayer == null) { - return false; - } - - Player you = game.getPlayer(source.getControllerId()); - - FilterControlledPermanent filter = new FilterControlledPermanent(); - filter.add(SubType.ALLY.getPredicate()); - - int numberOfAllies = game.getBattlefield().countAll(filter, you.getId(), game); - - Cards cardsInHand = new CardsImpl(); - cardsInHand.addAll(targetPlayer.getHand()); - - int count = Math.min(cardsInHand.size(), numberOfAllies); - - TargetCard target = new TargetCard(count, Zone.HAND, new FilterCard()); - Cards revealedCards = new CardsImpl(); - - if (targetPlayer.choose(Outcome.DrawCard, cardsInHand, target, game)) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card card = game.getCard(targetId); - if (card != null) { - revealedCards.add(card); - } - } - } - - TargetCard targetInHand = new TargetCard(Zone.HAND, new FilterCard("card to discard")); - - if (!revealedCards.isEmpty()) { - targetPlayer.revealCards("Bala Ged Thief", revealedCards, game); - you.choose(Outcome.Neutral, revealedCards, targetInHand, game); - Card card = revealedCards.get(targetInHand.getFirstTarget(), game); - if (card != null) { - targetPlayer.discard(card, false, source, game); - game.informPlayers("Bala Ged Thief: " + targetPlayer.getLogName() + " discarded " + card.getName()); - } - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/b/Brainbite.java b/Mage.Sets/src/mage/cards/b/Brainbite.java index ca85112a55..ce767dff89 100644 --- a/Mage.Sets/src/mage/cards/b/Brainbite.java +++ b/Mage.Sets/src/mage/cards/b/Brainbite.java @@ -21,7 +21,7 @@ public final class Brainbite extends CardImpl { // Target opponent reveals their hand. You choose a card from it. That player discards that card. this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect()); // Draw a card. - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("
")); this.getSpellAbility().addTarget(new TargetOpponent()); } diff --git a/Mage.Sets/src/mage/cards/c/CabalInterrogator.java b/Mage.Sets/src/mage/cards/c/CabalInterrogator.java index 3b44ee4082..fb4ab265fa 100644 --- a/Mage.Sets/src/mage/cards/c/CabalInterrogator.java +++ b/Mage.Sets/src/mage/cards/c/CabalInterrogator.java @@ -1,4 +1,3 @@ - package mage.cards.c; import mage.MageInt; @@ -7,19 +6,14 @@ import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.ManacostVariableValue; -import mage.abilities.effects.OneShotEffect; -import mage.cards.*; +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.SubType; -import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; +import mage.constants.TargetController; import mage.target.TargetPlayer; -import java.util.List; import java.util.UUID; /** @@ -36,8 +30,10 @@ public final class CabalInterrogator extends CardImpl { this.toughness = new MageInt(1); // {X}{B}, {tap}: Target player reveals X cards from their hand and you choose one of them. That player discards that card. - // Activate this ability only any time you could cast a sorcery. - Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new CabalInterrogatorEffect(), new ManaCostsImpl("{X}{B}")); + // Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + new DiscardCardYouChooseTargetEffect(TargetController.ANY, ManacostVariableValue.REGULAR), + new ManaCostsImpl("{X}{B}")); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetPlayer()); this.addAbility(ability); @@ -52,71 +48,3 @@ public final class CabalInterrogator extends CardImpl { return new CabalInterrogator(this); } } - -class CabalInterrogatorEffect extends OneShotEffect { - - public CabalInterrogatorEffect() { - super(Outcome.Discard); - this.staticText = "Target player reveals X cards from their hand and you choose one of them. That player discards that card"; - } - - public CabalInterrogatorEffect(final CabalInterrogatorEffect effect) { - super(effect); - } - - @Override - public CabalInterrogatorEffect copy() { - return new CabalInterrogatorEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - - Player targetPlayer = game.getPlayer(source.getFirstTarget()); - Player controller = game.getPlayer(source.getControllerId()); - if (targetPlayer == null || controller == null) { - return false; - } - - int amountToReveal = (ManacostVariableValue.REGULAR).calculate(game, source, this); - - if (amountToReveal < 1) { - return true; - } - Cards revealedCards = new CardsImpl(); - if (targetPlayer.getHand().size() > amountToReveal) { - Cards cardsInHand = new CardsImpl(); - cardsInHand.addAll(targetPlayer.getHand()); - - TargetCard target = new TargetCard(amountToReveal, Zone.HAND, new FilterCard()); - - if (targetPlayer.choose(Outcome.Discard, cardsInHand, target, game)) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card card = game.getCard(targetId); - if (card != null) { - revealedCards.add(card); - } - } - } - } else { - revealedCards.addAll(targetPlayer.getHand()); - } - - TargetCard targetInHand = new TargetCard(Zone.HAND, new FilterCard("card to discard")); - - if (!revealedCards.isEmpty()) { - targetPlayer.revealCards("Cabal Interrogator", revealedCards, game); - Card card = null; - if (revealedCards.size() > 1) { - controller.choose(Outcome.Discard, revealedCards, targetInHand, game); - card = revealedCards.get(targetInHand.getFirstTarget(), game); - } else { - card = revealedCards.getRandom(game); - } - - targetPlayer.discard(card, false, source, game); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/d/DiscipleOfPhenax.java b/Mage.Sets/src/mage/cards/d/DiscipleOfPhenax.java index 75c5cf1658..fa3d079d89 100644 --- a/Mage.Sets/src/mage/cards/d/DiscipleOfPhenax.java +++ b/Mage.Sets/src/mage/cards/d/DiscipleOfPhenax.java @@ -4,19 +4,14 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.dynamicvalue.common.DevotionCount; -import mage.abilities.effects.OneShotEffect; -import mage.cards.*; +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.SubType; -import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; +import mage.constants.TargetController; import mage.target.TargetPlayer; -import java.util.List; import java.util.UUID; /** @@ -34,7 +29,7 @@ public final class DiscipleOfPhenax extends CardImpl { // When Disciple of Phenax enters the battlefield, target player reveals a number of cards // from their hand equal to your devotion to black. You choose one of them. That player discards that card. - Ability ability = new EntersBattlefieldTriggeredAbility(new DiscipleOfPhenaxEffect(), false); + Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardCardYouChooseTargetEffect(TargetController.ANY, DevotionCount.B)); ability.addTarget(new TargetPlayer()); ability.addHint(DevotionCount.B.getHint()); this.addAbility(ability); @@ -50,68 +45,3 @@ public final class DiscipleOfPhenax extends CardImpl { return new DiscipleOfPhenax(this); } } - -class DiscipleOfPhenaxEffect extends OneShotEffect { - - DiscipleOfPhenaxEffect() { - super(Outcome.Discard); - staticText = "target player reveals a number of cards from their hand " - + "equal to your devotion to black. You choose one of " - + "them. That player discards that card"; - } - - private DiscipleOfPhenaxEffect(final DiscipleOfPhenaxEffect effect) { - super(effect); - } - - @Override - public DiscipleOfPhenaxEffect copy() { - return new DiscipleOfPhenaxEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - int devotion = DevotionCount.B.calculate(game, source, this); - Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); - if (devotion <= 0 || targetPlayer == null) { - return false; - } - Cards revealedCards = new CardsImpl(); - int amount = Math.min(targetPlayer.getHand().size(), devotion); - if (targetPlayer.getHand().size() > amount) { - FilterCard filter = new FilterCard("card in target player's hand"); - TargetCard chosenCards = new TargetCard(amount, amount, Zone.HAND, filter); - chosenCards.setNotTarget(true); - if (chosenCards.canChoose(source.getSourceId(), targetPlayer.getId(), game) - && targetPlayer.choose(Outcome.Discard, targetPlayer.getHand(), chosenCards, game)) { - if (!chosenCards.getTargets().isEmpty()) { - List targets = chosenCards.getTargets(); - for (UUID targetid : targets) { - Card card = game.getCard(targetid); - if (card != null) { - revealedCards.add(card); - } - } - } - } - } else { - revealedCards.addAll(targetPlayer.getHand()); - } - if (revealedCards.isEmpty()) { - return true; - } - targetPlayer.revealCards("Disciple of Phenax", revealedCards, game); - Player you = game.getPlayer(source.getControllerId()); - if (you == null) { - return false; - } - TargetCard yourChoice = new TargetCard(Zone.HAND, new FilterCard()); - yourChoice.setNotTarget(true); - if (you.choose(Outcome.Benefit, revealedCards, yourChoice, game)) { - Card card = targetPlayer.getHand().get(yourChoice.getFirstTarget(), game); - return targetPlayer.discard(card, false, source, game); - - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/d/Distress.java b/Mage.Sets/src/mage/cards/d/Distress.java index d4869558a7..5d2eda3040 100644 --- a/Mage.Sets/src/mage/cards/d/Distress.java +++ b/Mage.Sets/src/mage/cards/d/Distress.java @@ -7,8 +7,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.TargetController; -import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; +import mage.filter.StaticFilters; import mage.target.TargetPlayer; /** @@ -16,19 +15,13 @@ import mage.target.TargetPlayer; */ public final class Distress extends CardImpl { - private static final FilterCard filter = new FilterCard("nonland card"); - - static { - filter.add(Predicates.not(CardType.LAND.getPredicate())); - } - public Distress(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}{B}"); // Target player reveals their hand. You choose a nonland card from it. That player discards that card. this.getSpellAbility().addTarget(new TargetPlayer()); - this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.ANY)); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND, TargetController.ANY)); } private Distress(final Distress card) { diff --git a/Mage.Sets/src/mage/cards/d/Divest.java b/Mage.Sets/src/mage/cards/d/Divest.java index 5419018b70..5ca23291fe 100644 --- a/Mage.Sets/src/mage/cards/d/Divest.java +++ b/Mage.Sets/src/mage/cards/d/Divest.java @@ -1,4 +1,3 @@ - package mage.cards.d; import java.util.UUID; @@ -7,8 +6,7 @@ import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; +import mage.filter.StaticFilters; import mage.constants.TargetController; import mage.target.TargetPlayer; @@ -19,19 +17,12 @@ import mage.target.TargetPlayer; */ public final class Divest extends CardImpl { - private static final FilterCard filter = new FilterCard("an artifact or creature card"); - - static { - filter.add(Predicates.or(CardType.ARTIFACT.getPredicate(), - CardType.CREATURE.getPredicate())); - } - public Divest(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}"); // Target player reveals their hand. You choose an artifact or creature card from it. That player discards that card. this.getSpellAbility().addTarget(new TargetPlayer()); - this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.ANY)); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_ARTIFACT_OR_CREATURE, TargetController.ANY)); } private Divest(final Divest card) { @@ -42,4 +33,4 @@ public final class Divest extends CardImpl { public Divest copy() { return new Divest(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/d/DreadFugue.java b/Mage.Sets/src/mage/cards/d/DreadFugue.java index 345b121c28..1ef552f24f 100644 --- a/Mage.Sets/src/mage/cards/d/DreadFugue.java +++ b/Mage.Sets/src/mage/cards/d/DreadFugue.java @@ -3,19 +3,14 @@ package mage.cards.d; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.abilities.keyword.CleaveAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.filter.FilterCard; import mage.filter.StaticFilters; import mage.filter.common.FilterNonlandCard; import mage.filter.predicate.mageobject.ManaValuePredicate; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; import mage.target.TargetPlayer; /** @@ -24,7 +19,7 @@ import mage.target.TargetPlayer; */ public final class DreadFugue extends CardImpl { - private static final FilterNonlandCard filter = new FilterNonlandCard("nonland card [with mana value 2 or less]"); + private static final FilterNonlandCard filter = new FilterNonlandCard("nonland card from it [with mana value 2 or less]"); static { filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 3)); @@ -34,13 +29,13 @@ public final class DreadFugue extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}"); // Cleave {2}{B} - Ability ability = new CleaveAbility(this, new DreadFugueEffect(StaticFilters.FILTER_CARD_NON_LAND), "{2}{B}"); + Ability ability = new CleaveAbility(this, new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND, TargetController.ANY), "{2}{B}"); ability.addTarget(new TargetPlayer()); this.addAbility(ability); - // Target player reveals their hand. You may choose a nonland card from it [with mana value 2 or less]. That player discards that card. + // Target player reveals their hand. Choose a nonland card from it [with mana value 2 or less]. That player discards that card. this.getSpellAbility().addTarget(new TargetPlayer()); - this.getSpellAbility().addEffect(new DreadFugueEffect(filter)); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.ANY)); } private DreadFugue(final DreadFugue card) { @@ -52,43 +47,3 @@ public final class DreadFugue extends CardImpl { return new DreadFugue(this); } } - -class DreadFugueEffect extends OneShotEffect { - - private final FilterCard filter; - - public DreadFugueEffect(FilterCard filter) { - super(Outcome.Discard); - this.filter = filter; - staticText = "Target player reveals their hand. You choose a nonland card from it [with mana value 2 or less]. That player discards that card"; - } - - private DreadFugueEffect(final DreadFugueEffect effect) { - super(effect); - this.filter = effect.filter; - } - - @Override - public DreadFugueEffect copy() { - return new DreadFugueEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player targetPlayer = game.getPlayer(source.getFirstTarget()); - Player controller = game.getPlayer(source.getControllerId()); - if (targetPlayer == null || controller == null) { - return false; - } - Card sourceCard = game.getCard(source.getSourceId()); - targetPlayer.revealCards(sourceCard != null ? sourceCard.getIdName() + " (" - + sourceCard.getZoneChangeCounter(game) + ')' : "Discard", targetPlayer.getHand(), game); - TargetCard target = new TargetCard(0, 1, Zone.HAND, filter); - controller.choose(Outcome.Benefit, targetPlayer.getHand(), target, game); - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - targetPlayer.discard(card, false, source, game); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/e/Encroach.java b/Mage.Sets/src/mage/cards/e/Encroach.java index fdaebefef3..b15c28dfdb 100644 --- a/Mage.Sets/src/mage/cards/e/Encroach.java +++ b/Mage.Sets/src/mage/cards/e/Encroach.java @@ -7,9 +7,10 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SuperType; +import mage.constants.TargetController; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; -import mage.target.common.TargetOpponent; +import mage.target.TargetPlayer; /** * @@ -28,8 +29,8 @@ public final class Encroach extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}"); // Target player reveals their hand. You choose a nonbasic land card from it. That player discards that card. - this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter)); - this.getSpellAbility().addTarget(new TargetOpponent()); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.ANY)); + this.getSpellAbility().addTarget(new TargetPlayer()); } private Encroach(final Encroach card) { diff --git a/Mage.Sets/src/mage/cards/e/EntomberExarch.java b/Mage.Sets/src/mage/cards/e/EntomberExarch.java index e7cec5acdf..c616dec979 100644 --- a/Mage.Sets/src/mage/cards/e/EntomberExarch.java +++ b/Mage.Sets/src/mage/cards/e/EntomberExarch.java @@ -1,23 +1,16 @@ - package mage.cards.e; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.cards.Card; +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.SubType; -import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetOpponent; @@ -36,11 +29,14 @@ public final class EntomberExarch extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); - // When Entomber Exarch enters the battlefield, choose one - Return target creature card from your graveyard to your hand; or target opponent reveals their hand, you choose a noncreature card from it, then that player discards that card. + // When Entomber Exarch enters the battlefield, choose one — + // • Return target creature card from your graveyard to your hand Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), false); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + + // • Target opponent reveals their hand. You choose a noncreature card from it. That player discards that card. Mode mode = new Mode(); - mode.addEffect(new EntomberExarchEffect()); + mode.addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_CREATURE)); mode.addTarget(new TargetOpponent()); ability.addMode(mode); this.addAbility(ability); @@ -55,38 +51,3 @@ public final class EntomberExarch extends CardImpl { return new EntomberExarch(this); } } - -class EntomberExarchEffect extends OneShotEffect { - - EntomberExarchEffect() { - super(Outcome.Discard); - staticText = "target opponent reveals their hand, you choose a noncreature card from it, then that player discards that card"; - } - - EntomberExarchEffect(final EntomberExarchEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getFirstTarget()); - if (player != null) { - player.revealCards("Entomber Exarch", player.getHand(), game); - Player you = game.getPlayer(source.getControllerId()); - if (you != null) { - TargetCard target = new TargetCard(Zone.HAND, StaticFilters.FILTER_CARD_A_NON_CREATURE); - if (you.choose(Outcome.Benefit, player.getHand(), target, game)) { - Card card = player.getHand().get(target.getFirstTarget(), game); - return player.discard(card, false, source, game); - - } - } - } - return false; - } - - @Override - public EntomberExarchEffect copy() { - return new EntomberExarchEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java b/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java index 87b6f5fcfb..7358a24381 100644 --- a/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java +++ b/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java @@ -3,20 +3,15 @@ package mage.cards.g; import mage.abilities.Ability; import mage.abilities.condition.common.MorbidCondition; import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.hint.common.MorbidHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.Outcome; +import mage.constants.TargetController; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; import mage.target.TargetPlayer; -import mage.target.common.TargetCardInHand; import java.util.UUID; @@ -31,7 +26,7 @@ public final class GruesomeDiscovery extends CardImpl { // Target player discards two cards. // Morbid — If a creature died this turn, instead that player reveals their hand, you choose two cards from it, then that player discards those cards. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new GruesomeDiscoveryEffect(), new DiscardTargetEffect(2), + new DiscardCardYouChooseTargetEffect(2, TargetController.ANY), new DiscardTargetEffect(2), MorbidCondition.instance, "Target player discards two cards. " + "
Morbid — If a creature died this turn, instead that player reveals their hand, " + "you choose two cards from it, then that player discards those cards" @@ -49,36 +44,3 @@ public final class GruesomeDiscovery extends CardImpl { return new GruesomeDiscovery(this); } } - -class GruesomeDiscoveryEffect extends OneShotEffect { - - GruesomeDiscoveryEffect() { - super(Outcome.Discard); - } - - private GruesomeDiscoveryEffect(final GruesomeDiscoveryEffect effect) { - super(effect); - } - - @Override - public GruesomeDiscoveryEffect copy() { - return new GruesomeDiscoveryEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Player targetPlayer = game.getPlayer(source.getFirstTarget()); - if (player == null || targetPlayer == null) { - return false; - } - targetPlayer.revealCards(source, targetPlayer.getHand(), game); - if (targetPlayer.getHand().size() <= 2) { - targetPlayer.discard(2, false, false, source, game); - } - TargetCard target = new TargetCardInHand(2, StaticFilters.FILTER_CARD_CARDS); - player.choose(Outcome.Discard, targetPlayer.getHand(), target, game); - targetPlayer.discard(new CardsImpl(target.getTargets()), false, source, game); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/h/HarshScrutiny.java b/Mage.Sets/src/mage/cards/h/HarshScrutiny.java index 3a75731ac9..b337645e8a 100644 --- a/Mage.Sets/src/mage/cards/h/HarshScrutiny.java +++ b/Mage.Sets/src/mage/cards/h/HarshScrutiny.java @@ -7,7 +7,7 @@ import mage.abilities.effects.keyword.ScryEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.common.FilterCreatureCard; +import mage.filter.StaticFilters; import mage.target.common.TargetOpponent; /** @@ -21,7 +21,7 @@ public final class HarshScrutiny extends CardImpl { // Target opponent reveals their hand. You choose a creature card from it. That player discards that card. Scry 1. this.getSpellAbility().addTarget(new TargetOpponent()); - this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(new FilterCreatureCard("a creature card"))); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_CREATURE)); this.getSpellAbility().addEffect(new ScryEffect(1, false)); } diff --git a/Mage.Sets/src/mage/cards/h/HollowSpecter.java b/Mage.Sets/src/mage/cards/h/HollowSpecter.java index 3e7a9300cd..418cfcee0a 100644 --- a/Mage.Sets/src/mage/cards/h/HollowSpecter.java +++ b/Mage.Sets/src/mage/cards/h/HollowSpecter.java @@ -4,16 +4,15 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.*; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.FilterCard; +import mage.constants.TargetController; import mage.game.Game; import mage.players.Player; -import mage.target.TargetCard; import mage.util.ManaUtil; import java.util.List; @@ -70,50 +69,13 @@ class HollowSpecterEffect extends OneShotEffect { Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); - if (targetPlayer != null && controller != null && controller.chooseUse(Outcome.Benefit, "Do you want to to pay {X}?", source, game)) { + if (targetPlayer != null && controller != null && controller.chooseUse(Outcome.Benefit, "Pay {X}?", source, game)) { int payCount = ManaUtil.playerPaysXGenericMana(true, "Hollow Specter", controller, source, game); if (payCount > 0) { - // find to reveal - Cards revealedCards = new CardsImpl(); - if (targetPlayer.getHand().size() > payCount) { - Cards cardsInHand = new CardsImpl(); - cardsInHand.addAll(targetPlayer.getHand()); - TargetCard target = new TargetCard(payCount, Zone.HAND, new FilterCard()); - if (targetPlayer.choose(Outcome.Discard, cardsInHand, target, game)) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card card = game.getCard(targetId); - if (card != null) { - revealedCards.add(card); - } - } - } else { - // take any cards on disconnect - targetPlayer.getHand().stream().limit(payCount).forEach(revealedCards::add); - } - } else { - revealedCards.addAll(targetPlayer.getHand()); - } - - // select to discard - TargetCard targetInHand = new TargetCard(Zone.HAND, new FilterCard("card to discard")); - if (!revealedCards.isEmpty()) { - targetPlayer.revealCards("Hollow Specter", revealedCards, game); - Card card; - if (revealedCards.size() > 1) { - controller.choose(Outcome.Discard, revealedCards, targetInHand, game); - card = revealedCards.get(targetInHand.getFirstTarget(), game); - } else { - card = revealedCards.getRandom(game); - } - - targetPlayer.discard(card, false, source, game); - - } + return new DiscardCardYouChooseTargetEffect(TargetController.ANY, payCount).setTargetPointer(targetPointer).apply(game, source); } - return true; } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/l/LayBareTheHeart.java b/Mage.Sets/src/mage/cards/l/LayBareTheHeart.java index 1e0c52bedc..7e6248399c 100644 --- a/Mage.Sets/src/mage/cards/l/LayBareTheHeart.java +++ b/Mage.Sets/src/mage/cards/l/LayBareTheHeart.java @@ -1,4 +1,3 @@ - package mage.cards.l; import java.util.UUID; @@ -10,7 +9,7 @@ import mage.constants.SuperType; import mage.constants.TargetController; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; -import mage.target.TargetPlayer; +import mage.target.common.TargetOpponent; /** * @@ -29,8 +28,8 @@ public final class LayBareTheHeart extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); // Target opponent reveals their hand. You choose a nonlegendary, nonland card from it. That player discards that card. - this.getSpellAbility().addTarget(new TargetPlayer()); - this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.ANY)); + this.getSpellAbility().addTarget(new TargetOpponent()); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter)); } private LayBareTheHeart(final LayBareTheHeart card) { diff --git a/Mage.Sets/src/mage/cards/n/NogginWhack.java b/Mage.Sets/src/mage/cards/n/NogginWhack.java index 929f19feef..2753905ff2 100644 --- a/Mage.Sets/src/mage/cards/n/NogginWhack.java +++ b/Mage.Sets/src/mage/cards/n/NogginWhack.java @@ -1,17 +1,13 @@ package mage.cards.n; import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.abilities.keyword.ProwlAbility; -import mage.cards.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; +import mage.constants.TargetController; import mage.target.TargetPlayer; import java.util.List; @@ -26,13 +22,11 @@ public final class NogginWhack extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.SORCERY}, "{2}{B}{B}"); this.subtype.add(SubType.ROGUE); - // Prowl {1}{B} this.addAbility(new ProwlAbility(this, "{1}{B}")); // Target player reveals three cards from their hand. You choose two of them. That player discards those cards. - this.getSpellAbility().addEffect(new NogginWhackEffect()); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(2, TargetController.ANY, 3)); this.getSpellAbility().addTarget(new TargetPlayer()); - } private NogginWhack(final NogginWhack card) { @@ -44,57 +38,3 @@ public final class NogginWhack extends CardImpl { return new NogginWhack(this); } } - -class NogginWhackEffect extends OneShotEffect { - - NogginWhackEffect() { - super(Outcome.Benefit); - this.staticText = "Target player reveals three cards from their hand. You choose two of them. That player discards those cards"; - } - - private NogginWhackEffect(final NogginWhackEffect effect) { - super(effect); - } - - @Override - public NogginWhackEffect copy() { - return new NogginWhackEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Player targetPlayer = game.getPlayer(source.getFirstTarget()); - Card sourceCard = game.getCard(source.getSourceId()); - if (controller == null || targetPlayer == null || sourceCard == null) { - return false; - } - Cards cardsInHand = new CardsImpl(); - cardsInHand.addAll(targetPlayer.getHand()); - - int count = Math.min(cardsInHand.size(), 3); - - TargetCard target = new TargetCard(count, Zone.HAND, new FilterCard()); - Cards revealedCards = new CardsImpl(); - - if (targetPlayer.chooseTarget(Outcome.Discard, cardsInHand, target, source, game)) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card card = game.getCard(targetId); - if (card != null) { - revealedCards.add(card); - } - } - } - - int cardsToDiscard = Math.min(revealedCards.size(), 2); - TargetCard targetInHand = new TargetCard(cardsToDiscard, cardsToDiscard, Zone.HAND, new FilterCard("card to discard")); - - if (!revealedCards.isEmpty()) { - targetPlayer.revealCards(source, revealedCards, game); - controller.chooseTarget(Outcome.Exile, revealedCards, targetInHand, source, game); - targetPlayer.discard(new CardsImpl(targetInHand.getTargets()), false, source, game); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/o/Ostracize.java b/Mage.Sets/src/mage/cards/o/Ostracize.java index 944baa651f..b183fea9d1 100644 --- a/Mage.Sets/src/mage/cards/o/Ostracize.java +++ b/Mage.Sets/src/mage/cards/o/Ostracize.java @@ -6,7 +6,7 @@ import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.common.FilterCreatureCard; +import mage.filter.StaticFilters; import mage.target.common.TargetOpponent; /** @@ -21,7 +21,7 @@ public final class Ostracize extends CardImpl { // Target opponent reveals their hand. You choose a creature card from it. That player discards that card. this.getSpellAbility().addTarget(new TargetOpponent()); - this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(new FilterCreatureCard("a creature card"))); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_CREATURE_A)); } private Ostracize(final Ostracize card) { diff --git a/Mage.Sets/src/mage/cards/p/PelakkaPredation.java b/Mage.Sets/src/mage/cards/p/PelakkaPredation.java index 22beb21b40..8c7d186c49 100644 --- a/Mage.Sets/src/mage/cards/p/PelakkaPredation.java +++ b/Mage.Sets/src/mage/cards/p/PelakkaPredation.java @@ -8,7 +8,6 @@ import mage.cards.ModalDoubleFacesCard; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.SubType; -import mage.constants.TargetController; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.ManaValuePredicate; import mage.target.common.TargetOpponent; @@ -36,13 +35,8 @@ public final class PelakkaPredation extends ModalDoubleFacesCard { // Pelakka Predation // Sorcery - // Target opponent reveals their hand. You may choose a card from it with converted mana cost 3 or greater. That player discards that card. - this.getLeftHalfCard().getSpellAbility().addEffect( - new DiscardCardYouChooseTargetEffect(filter, TargetController.OPPONENT).setText( - "Target opponent reveals their hand. " + - "You choose a card from it with converted mana cost 3 or greater. " + - "That player discards that card" - )); + // Target opponent reveals their hand. You may choose a card from it with mana value 3 or greater. That player discards that card. + this.getLeftHalfCard().getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter)); this.getLeftHalfCard().getSpellAbility().addTarget(new TargetOpponent()); // 2. diff --git a/Mage.Sets/src/mage/cards/p/PsychicSpear.java b/Mage.Sets/src/mage/cards/p/PsychicSpear.java index 6a127e9733..8b0bea766a 100644 --- a/Mage.Sets/src/mage/cards/p/PsychicSpear.java +++ b/Mage.Sets/src/mage/cards/p/PsychicSpear.java @@ -18,7 +18,7 @@ import mage.target.TargetPlayer; */ public final class PsychicSpear extends CardImpl { - private static final FilterCard filter = new FilterCard("a Spirit or Arcane card to discard"); + private static final FilterCard filter = new FilterCard("Spirit or Arcane card"); static { filter.add(Predicates.or(SubType.SPIRIT.getPredicate(),SubType.ARCANE.getPredicate())); diff --git a/Mage.Sets/src/mage/cards/r/RiversGrasp.java b/Mage.Sets/src/mage/cards/r/RiversGrasp.java index d6bdf5b16c..95b3fb8426 100644 --- a/Mage.Sets/src/mage/cards/r/RiversGrasp.java +++ b/Mage.Sets/src/mage/cards/r/RiversGrasp.java @@ -1,26 +1,20 @@ - package mage.cards.r; import mage.abilities.Ability; import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.cards.Card; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ColoredManaSymbol; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.TargetController; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.Target; -import mage.target.TargetCard; import mage.target.TargetPlayer; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.SecondTargetPointer; import java.util.UUID; @@ -33,17 +27,18 @@ public final class RiversGrasp extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U/B}"); // If {U} was spent to cast River's Grasp, return up to one target creature to its owner's hand. If {B} was spent to cast River's Grasp, target player reveals their hand, you choose a nonland card from it, then that player discards that card. - Target targetCreature = new TargetCreaturePermanent(0, 1); - Target targetPlayer = new TargetPlayer(); this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new ReturnToHandTargetEffect(), - new ManaWasSpentCondition(ColoredManaSymbol.U), "If {U} was spent to cast this spell, return up to one target creature to its owner's hand")); + new ManaWasSpentCondition(ColoredManaSymbol.U), + "If {U} was spent to cast this spell, return up to one target creature to its owner's hand")); this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new RiversGraspEffect(), - new ManaWasSpentCondition(ColoredManaSymbol.B), " If {B} was spent to cast this spell, target player reveals their hand, you choose a nonland card from it, then that player discards that card")); + new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND, TargetController.ANY), + new ManaWasSpentCondition(ColoredManaSymbol.B), + " If {B} was spent to cast this spell, target player reveals their hand, you choose a nonland card from it, then that player discards that card") + .setTargetPointer(new SecondTargetPointer())); - this.getSpellAbility().addTarget(targetCreature); - this.getSpellAbility().addTarget(targetPlayer); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1)); + this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addEffect(new InfoEffect("(Do both if {U}{B} was spent.)")); } @@ -57,38 +52,3 @@ public final class RiversGrasp extends CardImpl { return new RiversGrasp(this); } } - -class RiversGraspEffect extends OneShotEffect { - - public RiversGraspEffect() { - super(Outcome.Discard); - this.staticText = "Target player reveals their hand, you choose a card from it, then that player discards that card."; - } - - public RiversGraspEffect(final RiversGraspEffect effect) { - super(effect); - } - - @Override - public RiversGraspEffect copy() { - return new RiversGraspEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getTargets().get(1).getFirstTarget()); - if (player != null) { - player.revealCards("River's Grasp", player.getHand(), game); - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - TargetCard target = new TargetCard(Zone.HAND, StaticFilters.FILTER_CARD_A_NON_LAND); - if (controller.choose(Outcome.Benefit, player.getHand(), target, game)) { - Card card = player.getHand().get(target.getFirstTarget(), game); - return player.discard(card, false, source, game); - - } - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/s/ShatteredDreams.java b/Mage.Sets/src/mage/cards/s/ShatteredDreams.java index 9ca10425d5..e799faae24 100644 --- a/Mage.Sets/src/mage/cards/s/ShatteredDreams.java +++ b/Mage.Sets/src/mage/cards/s/ShatteredDreams.java @@ -6,7 +6,7 @@ import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.target.common.TargetOpponent; /** @@ -15,18 +15,13 @@ import mage.target.common.TargetOpponent; */ public final class ShatteredDreams extends CardImpl { - private static final FilterCard filter = new FilterCard("an artifact card from it"); - static { - filter.add(CardType.ARTIFACT.getPredicate()); - } - public ShatteredDreams(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}"); // Target opponent reveals their hand. You choose an artifact card from it. That player discards that card. this.getSpellAbility().addTarget(new TargetOpponent()); - this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter)); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_ARTIFACT_AN)); } private ShatteredDreams(final ShatteredDreams card) { diff --git a/Mage.Sets/src/mage/cards/s/SplittingHeadache.java b/Mage.Sets/src/mage/cards/s/SplittingHeadache.java index 457341276a..fff7ab904a 100644 --- a/Mage.Sets/src/mage/cards/s/SplittingHeadache.java +++ b/Mage.Sets/src/mage/cards/s/SplittingHeadache.java @@ -1,20 +1,12 @@ - package mage.cards.s; -import mage.abilities.Ability; import mage.abilities.Mode; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; +import mage.constants.TargetController; import mage.target.TargetPlayer; import java.util.UUID; @@ -28,14 +20,16 @@ public final class SplittingHeadache extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}"); - // Choose one - Target player discards two cards; or target player reveals their hand, you choose a card from it, then that player discards that card. + // Choose one — + // • Target player discards two cards. this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addEffect(new DiscardTargetEffect(2)); + + // • Target player reveals their hand. You choose a card from it. That player discards that card. Mode mode = new Mode(); - mode.addEffect(new SplittingHeadacheEffect()); + mode.addEffect(new DiscardCardYouChooseTargetEffect(TargetController.ANY)); mode.addTarget(new TargetPlayer()); this.getSpellAbility().addMode(mode); - } private SplittingHeadache(final SplittingHeadache card) { @@ -47,38 +41,3 @@ public final class SplittingHeadache extends CardImpl { return new SplittingHeadache(this); } } - -class SplittingHeadacheEffect extends OneShotEffect { - - public SplittingHeadacheEffect() { - super(Outcome.Discard); - this.staticText = "Target player reveals their hand, you choose a card from it, then that player discards that card."; - } - - public SplittingHeadacheEffect(final SplittingHeadacheEffect effect) { - super(effect); - } - - @Override - public SplittingHeadacheEffect copy() { - return new SplittingHeadacheEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getFirstTarget()); - if (player != null) { - player.revealCards("Splitting Headache", player.getHand(), game); - Player you = game.getPlayer(source.getControllerId()); - if (you != null) { - TargetCard target = new TargetCard(Zone.HAND, new FilterCard()); - if (you.choose(Outcome.Benefit, player.getHand(), target, game)) { - Card card = player.getHand().get(target.getFirstTarget(), game); - return player.discard(card, false, source, game); - - } - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/t/ThievingSprite.java b/Mage.Sets/src/mage/cards/t/ThievingSprite.java index e8ec4a22ce..f10d870695 100644 --- a/Mage.Sets/src/mage/cards/t/ThievingSprite.java +++ b/Mage.Sets/src/mage/cards/t/ThievingSprite.java @@ -1,24 +1,20 @@ - package mage.cards.t; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.abilities.keyword.FlyingAbility; -import mage.cards.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.FilterCard; +import mage.constants.TargetController; import mage.filter.common.FilterControlledPermanent; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; import mage.target.TargetPlayer; -import java.util.List; import java.util.UUID; /** @@ -26,6 +22,11 @@ import java.util.UUID; */ public final class ThievingSprite extends CardImpl { + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.FAERIE, "Faeries you control"), null); + + private static final String rule = "target player reveals X cards from their hand, where X is " + + xValue.getMessage() + ". You choose one of those cards. That player discards that card"; + public ThievingSprite(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); this.subtype.add(SubType.FAERIE); @@ -37,11 +38,11 @@ public final class ThievingSprite extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); - // When Thieving Sprite enters the battlefield, target player reveals X cards from their hand, where X is the number of Faeries you control. - // You choose one of those cards. That player discards that card. - Ability ability = new EntersBattlefieldTriggeredAbility(new ThievingSpriteEffect(), false); - TargetPlayer target = new TargetPlayer(); - ability.addTarget(target); + // When Thieving Sprite enters the battlefield, target player reveals X cards from their hand, + // where X is the number of Faeries you control. You choose one of those cards. + // That player discards that card. + Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardCardYouChooseTargetEffect(TargetController.ANY, xValue).setText(rule)); + ability.addTarget(new TargetPlayer()); this.addAbility(ability); } @@ -55,72 +56,3 @@ public final class ThievingSprite extends CardImpl { return new ThievingSprite(this); } } - -class ThievingSpriteEffect extends OneShotEffect { - - public ThievingSpriteEffect() { - super(Outcome.Discard); - this.staticText = "target player reveals X cards from their hand, where X is the number of Faeries you control. You choose one of those cards. " - + "That player discards that card"; - } - - public ThievingSpriteEffect(final ThievingSpriteEffect effect) { - super(effect); - } - - @Override - public ThievingSpriteEffect copy() { - return new ThievingSpriteEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player targetPlayer = game.getPlayer(source.getFirstTarget()); - Player controller = game.getPlayer(source.getControllerId()); - if (targetPlayer == null || controller == null) { - return false; - } - - FilterControlledPermanent filter = new FilterControlledPermanent(); - filter.add(SubType.FAERIE.getPredicate()); - int numberOfFaeries = game.getBattlefield().countAll(filter, controller.getId(), game); - if (numberOfFaeries < 1) { - return true; - } - - Cards revealedCards = new CardsImpl(); - if (targetPlayer.getHand().size() > numberOfFaeries) { - Cards cardsInHand = new CardsImpl(); - cardsInHand.addAll(targetPlayer.getHand()); - - TargetCard target = new TargetCard(numberOfFaeries, Zone.HAND, new FilterCard()); - - if (targetPlayer.choose(Outcome.Discard, cardsInHand, target, game)) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card card = game.getCard(targetId); - if (card != null) { - revealedCards.add(card); - } - } - } - } else { - revealedCards.addAll(targetPlayer.getHand()); - } - - TargetCard targetInHand = new TargetCard(Zone.HAND, new FilterCard("card to discard")); - - if (!revealedCards.isEmpty()) { - targetPlayer.revealCards("Thieving Sprite", revealedCards, game); - Card card = null; - if (revealedCards.size() > 1) { - controller.choose(Outcome.Discard, revealedCards, targetInHand, game); - card = revealedCards.get(targetInHand.getFirstTarget(), game); - } else { - card = revealedCards.getRandom(game); - } - targetPlayer.discard(card, false, source, game); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/t/ThoughtErasure.java b/Mage.Sets/src/mage/cards/t/ThoughtErasure.java index ac228a10d8..8553da5463 100644 --- a/Mage.Sets/src/mage/cards/t/ThoughtErasure.java +++ b/Mage.Sets/src/mage/cards/t/ThoughtErasure.java @@ -5,9 +5,7 @@ import mage.abilities.effects.keyword.SurveilEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.TargetController; -import mage.filter.FilterCard; -import mage.filter.common.FilterNonlandCard; +import mage.filter.StaticFilters; import mage.target.common.TargetOpponent; import java.util.UUID; @@ -17,13 +15,11 @@ import java.util.UUID; */ public final class ThoughtErasure extends CardImpl { - private static final FilterCard filter = new FilterNonlandCard(); - public ThoughtErasure(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}{B}"); // Target opponent reveals their hand. You choose a nonland card from it. That player discards that card. - this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.OPPONENT)); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND)); this.getSpellAbility().addTarget(new TargetOpponent()); // Surveil 1. diff --git a/Mage.Sets/src/mage/cards/t/TollOfTheInvasion.java b/Mage.Sets/src/mage/cards/t/TollOfTheInvasion.java index 88a1bf0e13..6f738ed570 100644 --- a/Mage.Sets/src/mage/cards/t/TollOfTheInvasion.java +++ b/Mage.Sets/src/mage/cards/t/TollOfTheInvasion.java @@ -5,7 +5,6 @@ import mage.abilities.effects.keyword.AmassEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.TargetController; import mage.filter.StaticFilters; import mage.target.common.TargetOpponent; @@ -20,13 +19,11 @@ public final class TollOfTheInvasion extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); // Target opponent reveals their hand. You choose a nonland card from it. That player discards that card. - this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect( - StaticFilters.FILTER_CARD_NON_LAND, TargetController.OPPONENT - )); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND)); this.getSpellAbility().addTarget(new TargetOpponent()); // Amass 1. - this.getSpellAbility().addEffect(new AmassEffect(1)); + this.getSpellAbility().addEffect(new AmassEffect(1).concatBy("
")); } private TollOfTheInvasion(final TollOfTheInvasion card) { diff --git a/Mage.Sets/src/mage/cards/t/TourachsCanticle.java b/Mage.Sets/src/mage/cards/t/TourachsCanticle.java index b2a6e752ea..117ddff379 100644 --- a/Mage.Sets/src/mage/cards/t/TourachsCanticle.java +++ b/Mage.Sets/src/mage/cards/t/TourachsCanticle.java @@ -20,9 +20,7 @@ public final class TourachsCanticle extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}"); // Target opponent reveals their hand. You choose a card from it. That player discards that card, then discards a card at random. - this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect( - StaticFilters.FILTER_CARD, TargetController.OPPONENT - )); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect()); this.getSpellAbility().addEffect(new DiscardTargetEffect(1, true) .setText(", then discards a card at random")); this.getSpellAbility().addTarget(new TargetOpponent()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java index f70a044d8c..02432352ab 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java @@ -31,8 +31,6 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { private final DynamicValue numberCardsToDiscard; private boolean revealAllCards; - private static final FilterCard filterOneCard = new FilterCard("one card"); - public DiscardCardYouChooseTargetEffect() { this(StaticFilters.FILTER_CARD_A); } @@ -41,38 +39,22 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { this(StaticFilters.FILTER_CARD_A, targetController); } - public DiscardCardYouChooseTargetEffect(DynamicValue numberCardsToDiscard, TargetController targetController) { - this(numberCardsToDiscard, StaticFilters.FILTER_CARD_CARDS, targetController); - } - public DiscardCardYouChooseTargetEffect(FilterCard filter) { this(filter, TargetController.OPPONENT); } - public DiscardCardYouChooseTargetEffect(TargetController targetController, int numberCardsToReveal) { - this(filterOneCard, targetController, StaticValue.get(numberCardsToReveal)); - } - - public DiscardCardYouChooseTargetEffect(TargetController targetController, DynamicValue numberCardsToReveal) { - this(filterOneCard, targetController, numberCardsToReveal); - } - - public DiscardCardYouChooseTargetEffect(FilterCard filter, TargetController targetController, DynamicValue numberCardsToReveal) { - super(Outcome.Discard); - this.targetController = targetController; - this.filter = filter; - - this.revealAllCards = false; - this.numberCardsToReveal = numberCardsToReveal; - this.numberCardsToDiscard = StaticValue.get(1); - - staticText = this.setText(); - } - public DiscardCardYouChooseTargetEffect(FilterCard filter, TargetController targetController) { this(StaticValue.get(1), filter, targetController); } + public DiscardCardYouChooseTargetEffect(int numberCardsToDiscard, TargetController targetController) { + this(StaticValue.get(numberCardsToDiscard), targetController); + } + + public DiscardCardYouChooseTargetEffect(DynamicValue numberCardsToDiscard, TargetController targetController) { + this(numberCardsToDiscard, StaticFilters.FILTER_CARD_CARDS, targetController); + } + public DiscardCardYouChooseTargetEffect(DynamicValue numberCardsToDiscard, FilterCard filter, TargetController targetController) { super(Outcome.Discard); @@ -86,6 +68,30 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { staticText = this.setText(); } + public DiscardCardYouChooseTargetEffect(TargetController targetController, int numberCardsToReveal) { + this(targetController, StaticValue.get(numberCardsToReveal)); + } + + public DiscardCardYouChooseTargetEffect(TargetController targetController, DynamicValue numberCardsToReveal) { + this(StaticValue.get(1), StaticFilters.FILTER_CARD_A, targetController, numberCardsToReveal); + } + + public DiscardCardYouChooseTargetEffect(int numberCardsToDiscard, TargetController targetController, int numberCardsToReveal) { + this(StaticValue.get(numberCardsToDiscard), StaticFilters.FILTER_CARD_CARDS, targetController, StaticValue.get(numberCardsToReveal)); + } + + public DiscardCardYouChooseTargetEffect(DynamicValue numberCardsToDiscard, FilterCard filter, TargetController targetController, DynamicValue numberCardsToReveal) { + super(Outcome.Discard); + this.targetController = targetController; + this.filter = filter; + + this.revealAllCards = false; + this.numberCardsToReveal = numberCardsToReveal; + this.numberCardsToDiscard = numberCardsToDiscard; + + staticText = this.setText(); + } + public DiscardCardYouChooseTargetEffect(final DiscardCardYouChooseTargetEffect effect) { super(effect); this.filter = effect.filter; @@ -155,6 +161,7 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { } private String setText() { + boolean discardMultipleCards = !numberCardsToDiscard.toString().equals("1"); StringBuilder sb = new StringBuilder("target "); switch (targetController) { case OPPONENT: @@ -166,32 +173,37 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { default: throw new UnsupportedOperationException("target controller not supported"); } + sb.append(" reveals "); if (revealAllCards) { - sb.append(" reveals their hand"); + sb.append("their hand. You choose "); + if (discardMultipleCards) { + sb.append(numberCardsToDiscard).append(' ').append(filter.getMessage()); + } else { + sb.append(CardUtil.addArticle(filter.getMessage())); + } + if (!filter.getMessage().contains("from it")) { + sb.append(" from it"); + } } else { if (numberCardsToReveal instanceof StaticValue) { - sb.append(" reveals "); - sb.append(CardUtil.numberToText(((StaticValue) numberCardsToReveal).getValue())).append(" cards"); - sb.append(" from their hand"); + sb.append(CardUtil.numberToText(((StaticValue) numberCardsToReveal).getValue())); + sb.append(" cards from their hand"); + } else if (numberCardsToReveal.getMessage().isEmpty()) { + sb.append("X cards from their hand"); } else { - sb.append(" reveals a number of cards from their hand equal to "); + sb.append("a number of cards from their hand equal to "); sb.append(numberCardsToReveal.getMessage()); } - } - sb.append(". You choose "); - boolean discardMultipleCards = !numberCardsToDiscard.toString().equals("1"); - if (discardMultipleCards) { - sb.append(numberCardsToDiscard).append(' ').append(filter.getMessage()); - } else { - sb.append(CardUtil.addArticle(filter.getMessage())); - } - if (revealAllCards) { - sb.append(filter.getMessage().contains("from it") ? "." : " from it."); - } else { - sb.append(" of them."); + sb.append(". You choose "); + if (numberCardsToDiscard instanceof StaticValue) { + sb.append(CardUtil.numberToText(((StaticValue) numberCardsToDiscard).getValue())); + } else { + sb.append(numberCardsToDiscard); + } + sb.append(" of them"); } - sb.append(" That player discards ").append(discardMultipleCards ? "those cards" : "that card"); + sb.append(". That player discards ").append(discardMultipleCards ? "those cards" : "that card"); return sb.toString(); } }