From f68e435fc4c5961dde2ec3c860a3863b935d9029 Mon Sep 17 00:00:00 2001 From: Susucre <34709007+Susucre@users.noreply.github.com> Date: Sun, 14 Apr 2024 12:33:26 +0200 Subject: [PATCH] rework and test Phyrexian Ingester --- .../src/mage/cards/p/PhyrexianIngester.java | 47 +++++--- .../single/nph/PhyrexianIngesterTest.java | 110 ++++++++++++++++++ 2 files changed, 139 insertions(+), 18 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/nph/PhyrexianIngesterTest.java diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianIngester.java b/Mage.Sets/src/mage/cards/p/PhyrexianIngester.java index 79e06338515..a87d0520b24 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianIngester.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianIngester.java @@ -1,7 +1,6 @@ package mage.cards.p; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -19,10 +18,12 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; +import mage.util.CardUtil; + +import java.util.UUID; /** - * - * @author North + * @author North, Susucr */ public final class PhyrexianIngester extends CardImpl { @@ -33,7 +34,7 @@ public final class PhyrexianIngester extends CardImpl { } public PhyrexianIngester(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{6}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{U}"); this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); @@ -78,16 +79,25 @@ class PhyrexianIngesterImprintEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); - if (controller != null && sourceObject != null) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - Permanent targetPermanent = game.getPermanent(source.getFirstTarget()); - if (sourcePermanent != null && targetPermanent != null) { - controller.moveCardToExileWithInfo(targetPermanent, getId(), sourceObject.getIdName() + " (Imprint)", source, game, Zone.BATTLEFIELD, true); - sourcePermanent.imprint(targetPermanent.getId(), game); - return true; - } + if (controller == null && sourceObject == null) { + return false; } - return false; + Permanent targetPermanent = game.getPermanent(source.getFirstTarget()); + if (targetPermanent == null) { + return false; + } + Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game); + if (sourcePermanent != null) { + UUID exileZoneId = CardUtil.getCardExileZoneId(game, source); + String exileZoneName = sourceObject.getIdName() + " (Imprint)"; + controller.moveCardsToExile(targetPermanent, source, game, true, exileZoneId, exileZoneName); + sourcePermanent.imprint(targetPermanent.getId(), game); + } else { + // Ingester is no longer on the battlefield, but the target still needs to be exiled. + // no need for specific exile zone + controller.moveCardsToExile(targetPermanent, source, game, true, null, ""); + } + return true; } } @@ -110,15 +120,16 @@ class PhyrexianIngesterBoostEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null && !permanent.getImprinted().isEmpty()) { - Card card = game.getCard(permanent.getImprinted().get(0)); + if (permanent == null) { + return false; + } + for (UUID cardId : permanent.getImprinted()) { + Card card = game.getCard(cardId); if (card != null) { permanent.addPower(card.getPower().getValue()); permanent.addToughness(card.getToughness().getValue()); - return true; } - return true; } - return false; + return true; } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/nph/PhyrexianIngesterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/nph/PhyrexianIngesterTest.java new file mode 100644 index 00000000000..c33a209749c --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/nph/PhyrexianIngesterTest.java @@ -0,0 +1,110 @@ +package org.mage.test.cards.single.nph; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class PhyrexianIngesterTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.p.PhyrexianIngester Phyrexian Ingester} {6}{U} + * Creature — Phyrexian Beast + * Imprint — When Phyrexian Ingester enters the battlefield, you may exile target nontoken creature. + * Phyrexian Ingester gets +X/+Y, where X is the exiled creature card’s power and Y is its toughness. + * 3/3 + */ + private static final String ingester = "Phyrexian Ingester"; + + @Test + public void test_Ingest() { + setStrictChooseMode(true); + + addCard(Zone.HAND, playerA, ingester); + addCard(Zone.BATTLEFIELD, playerA, "Island", 7); + addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard"); // 2/1 + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ingester); + addTarget(playerA, "Elite Vanguard"); // target for trigger + setChoice(playerA, true); // yes to "you may" + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertExileCount(playerA, "Elite Vanguard", 1); + assertPowerToughness(playerA, ingester, 3 + 2, 3 + 1); + } + + @Test + public void test_Panharmonicon() { + setStrictChooseMode(true); + + addCard(Zone.HAND, playerA, ingester); + addCard(Zone.BATTLEFIELD, playerA, "Island", 7); + addCard(Zone.BATTLEFIELD, playerA, "Panharmonicon"); + addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard"); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); // 2/2 + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ingester); + setChoice(playerA, "Imprint"); // stack triggers + addTarget(playerA, "Elite Vanguard"); // target for trigger + setChoice(playerA, true); // yes to "you may" + addTarget(playerA, "Grizzly Bears"); // target for trigger + setChoice(playerA, true); // yes to "you may" + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertExileCount(playerA, "Elite Vanguard", 1); + assertExileCount(playerA, "Grizzly Bears", 1); + assertPowerToughness(playerA, ingester, 3 + 2 + 2, 3 + 1 + 2); + } + + @Test + public void test_DestroyInResponse() { + setStrictChooseMode(true); + + addCard(Zone.HAND, playerA, ingester); + addCard(Zone.BATTLEFIELD, playerA, "Underground Sea", 7 + 2); + addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard"); // 2/1 + addCard(Zone.HAND, playerA, "Doom Blade"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ingester, true); + addTarget(playerA, "Elite Vanguard"); // target for trigger + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Doom Blade", ingester); + setChoice(playerA, true); // yes to "you may" + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertExileCount(playerA, "Elite Vanguard", 1); + assertGraveyardCount(playerA, ingester, 1); + } + + @Test + public void test_BlinkInResponse() { + setStrictChooseMode(true); + + addCard(Zone.HAND, playerA, ingester); + addCard(Zone.BATTLEFIELD, playerA, "Tundra", 7 + 1); + addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard"); // 2/1 + addCard(Zone.HAND, playerA, "Ephemerate"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ingester); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA, true); + addTarget(playerA, "Elite Vanguard"); // target for oldest trigger + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ephemerate", ingester); + addTarget(playerA, "Elite Vanguard"); // target for latest trigger + setChoice(playerA, false); // no to "you may" of latest ingester trigger + setChoice(playerA, true); // yes to "you may" of oldest ingester trigger + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertExileCount(playerA, "Elite Vanguard", 1); + assertPowerToughness(playerA, ingester, 3, 3); + } +}