From 31c772d3683e6f33a6a15d628e7d4a4ec3ebe8bd Mon Sep 17 00:00:00 2001 From: Susucre <34709007+Susucre@users.noreply.github.com> Date: Sat, 1 Jun 2024 13:07:21 +0200 Subject: [PATCH] clean EmergeAbility and Doom Foretold --- Mage.Sets/src/mage/cards/c/Crabomination.java | 11 +--- Mage.Sets/src/mage/cards/d/DoomForetold.java | 8 +-- .../cards/single/eld/DoomForetoldTest.java | 64 +++++++++++++++++++ .../mage/abilities/keyword/EmergeAbility.java | 12 +--- 4 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/eld/DoomForetoldTest.java diff --git a/Mage.Sets/src/mage/cards/c/Crabomination.java b/Mage.Sets/src/mage/cards/c/Crabomination.java index 74158b09d64..c6513842be0 100644 --- a/Mage.Sets/src/mage/cards/c/Crabomination.java +++ b/Mage.Sets/src/mage/cards/c/Crabomination.java @@ -10,10 +10,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.FilterPermanent; import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledArtifactPermanent; -import mage.filter.predicate.permanent.CanBeSacrificedPredicate; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetOpponent; @@ -26,12 +23,6 @@ import java.util.UUID; */ public final class Crabomination extends CardImpl { - private static final FilterPermanent filter = new FilterControlledArtifactPermanent(); - - static { - filter.add(CanBeSacrificedPredicate.instance); - } - public Crabomination(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); @@ -41,7 +32,7 @@ public final class Crabomination extends CardImpl { this.toughness = new MageInt(5); // Emerge from artifact {5}{B}{B} - this.addAbility(new EmergeAbility(this, "{5}{B}{B}", filter, "from artifact")); + this.addAbility(new EmergeAbility(this, "{5}{B}{B}", StaticFilters.FILTER_PERMANENT_ARTIFACT, "from artifact")); // When Crabomination enters the battlefield, target opponent exiles the top card of their library, a card at random from their graveyard, and a card at random from their hand. You may cast a spell from among cards exiled this way without paying its mana cost. Ability ability = new EntersBattlefieldTriggeredAbility(new CrabominationEffect()); diff --git a/Mage.Sets/src/mage/cards/d/DoomForetold.java b/Mage.Sets/src/mage/cards/d/DoomForetold.java index 4db07ecd344..2264f51dbd6 100644 --- a/Mage.Sets/src/mage/cards/d/DoomForetold.java +++ b/Mage.Sets/src/mage/cards/d/DoomForetold.java @@ -13,14 +13,11 @@ import mage.constants.Outcome; import mage.constants.TargetController; import mage.filter.FilterPermanent; import mage.filter.common.FilterNonlandPermanent; -import mage.filter.predicate.permanent.CanBeSacrificedPredicate; -import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.filter.predicate.permanent.TokenPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.KnightToken; import mage.players.Player; -import mage.target.TargetPermanent; import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -55,7 +52,6 @@ class DoomForetoldEffect extends OneShotEffect { static { filter.add(TokenPredicate.FALSE); - filter.add(CanBeSacrificedPredicate.instance); } private static final Effect effect1 = new CreateTokenEffect(new KnightToken()); @@ -84,8 +80,8 @@ class DoomForetoldEffect extends OneShotEffect { if (controller == null || player == null) { return false; } - if (game.getBattlefield().countAll(filter, player.getId(), game) > 0) { - TargetSacrifice target = new TargetSacrifice(filter); + TargetSacrifice target = new TargetSacrifice(filter); + if (target.canChoose(player.getId(), source, game)) { if (player.choose(Outcome.Sacrifice, target, source, game)) { Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null && permanent.sacrifice(source, game)) { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/DoomForetoldTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/DoomForetoldTest.java new file mode 100644 index 00000000000..e1f1973e651 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/DoomForetoldTest.java @@ -0,0 +1,64 @@ +package org.mage.test.cards.single.eld; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class DoomForetoldTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.d.DoomForetold Doom Foretold} {2}{W}{B} + * Enchantment + * At the beginning of each player’s upkeep, that player sacrifices a nonland, nontoken permanent. If that player can’t, they discard a card, they lose 2 life, you draw a card, you gain 2 life, you create a 2/2 white Knight creature token with vigilance, then you sacrifice Doom Foretold. + */ + private static final String doom = "Doom Foretold"; + + @Test + public void test_Simple_Sac_It() { + setStrictChooseMode(true); + + addCard(Zone.BATTLEFIELD, playerA, "Memnite"); // for sac turn 1 + addCard(Zone.BATTLEFIELD, playerA, doom); + addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears"); + + setChoice(playerA, "Memnite"); + setChoice(playerB, "Grizzly Bears"); + setChoice(playerA, doom); + + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, doom, 1); + assertPermanentCount(playerA, 0); + assertGraveyardCount(playerB, "Grizzly Bears", 1); + assertPermanentCount(playerB, 0); + } + + @Test + public void test_Simple_OpponentCantSacrifice() { + setStrictChooseMode(true); + + addCard(Zone.BATTLEFIELD, playerA, "Memnite"); // for sac turn 1 + addCard(Zone.BATTLEFIELD, playerA, doom); + addCard(Zone.HAND, playerB, "Grizzly Bears"); + + setChoice(playerA, "Memnite"); + + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertLife(playerA, 20 + 2); + assertLife(playerB, 20 - 2); + assertHandCount(playerA, 1); + assertHandCount(playerB, 1); // drawn for the turn + assertGraveyardCount(playerA, doom, 1); + assertPermanentCount(playerA, 1); + assertPermanentCount(playerA, "Knight Token", 1); + assertGraveyardCount(playerB, "Grizzly Bears", 1); + assertPermanentCount(playerB, 0); + } +} diff --git a/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java b/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java index 3c06cccbd34..1f64cb7e010 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java @@ -13,8 +13,8 @@ import mage.constants.Outcome; import mage.constants.SpellAbilityType; import mage.constants.Zone; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.predicate.permanent.CanBeSacrificedPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -31,23 +31,17 @@ public class EmergeAbility extends SpellAbility { private final ManaCosts emergeCost; public static final String EMERGE_ACTIVATION_CREATURE_REFERENCE = "emergeActivationMOR"; - private static final FilterPermanent SAC_FILTER = new FilterControlledCreaturePermanent(); - - static { - SAC_FILTER.add(CanBeSacrificedPredicate.instance); - } - private final String emergeFromText; private final FilterPermanent filter; public EmergeAbility(Card card, String emergeManaString) { - this(card, emergeManaString, SAC_FILTER, ""); + this(card, emergeManaString, StaticFilters.FILTER_PERMANENT_CREATURE, ""); } public EmergeAbility(Card card, String emergeManaString, FilterPermanent filter, String emergeFromText) { super(card.getSpellAbility()); - this.filter = filter; + this.filter = TargetSacrifice.makeFilter(filter); this.emergeFromText = emergeFromText; this.emergeCost = new ManaCostsImpl<>(emergeManaString);