From 5b2e8480654795300aaebbb05d9319a5d4aec8c7 Mon Sep 17 00:00:00 2001 From: "Alex W. Jackson" Date: Tue, 27 Sep 2022 22:07:22 -0400 Subject: [PATCH] Add test for flickering Animate Dead --- Mage.Sets/src/mage/cards/a/AnimateDead.java | 4 ++ .../src/mage/cards/d/DanceOfTheDead.java | 4 ++ Mage.Sets/src/mage/cards/n/Necromancy.java | 9 ++- .../cards/enchantments/AnimateDeadTest.java | 63 +++++++++++++++++++ 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AnimateDead.java b/Mage.Sets/src/mage/cards/a/AnimateDead.java index e0252542f5..421a431c98 100644 --- a/Mage.Sets/src/mage/cards/a/AnimateDead.java +++ b/Mage.Sets/src/mage/cards/a/AnimateDead.java @@ -31,6 +31,10 @@ public final class AnimateDead extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.PutCreatureInPlay)); this.addAbility(new EnchantAbility(auraTarget.getTargetName())); + // When Animate Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature + // card in a graveyard" and gains "enchant creature put onto the battlefield with Animate Dead." + // Return enchanted creature card to the battlefield under your control and attach Animate Dead + // to it. When Animate Dead leaves the battlefield, that creature's controller sacrifices it. this.addAbility(new AnimateDeadTriggeredAbility()); // Enchanted creature gets -1/-0. diff --git a/Mage.Sets/src/mage/cards/d/DanceOfTheDead.java b/Mage.Sets/src/mage/cards/d/DanceOfTheDead.java index e7b9fd8297..7fed4a82d3 100644 --- a/Mage.Sets/src/mage/cards/d/DanceOfTheDead.java +++ b/Mage.Sets/src/mage/cards/d/DanceOfTheDead.java @@ -44,6 +44,10 @@ public final class DanceOfTheDead extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.PutCreatureInPlay)); this.addAbility(new EnchantAbility(auraTarget.getTargetName())); + // When Dance of the Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature + // card in a graveyard" and gains "enchant creature put onto the battlefield with Dance of the Dead." + // Put enchanted creature card onto the battlefield tapped under your control and attach Dance of the Dead + // to it. When Dance of the Dead leaves the battlefield, that creature's controller sacrifices it. this.addAbility(new AnimateDeadTriggeredAbility(false, true)); // Enchanted creature gets +1/+1 and doesn't untap during its controller's untap step. diff --git a/Mage.Sets/src/mage/cards/n/Necromancy.java b/Mage.Sets/src/mage/cards/n/Necromancy.java index 7b8a655c6d..1460a6639c 100644 --- a/Mage.Sets/src/mage/cards/n/Necromancy.java +++ b/Mage.Sets/src/mage/cards/n/Necromancy.java @@ -20,15 +20,20 @@ import java.util.UUID; */ public final class Necromancy extends CardImpl { - private static final FilterCreatureCard filter = new FilterCreatureCard("creature card in a graveyard"); + private static final FilterCreatureCard filter = new FilterCreatureCard("creature card from a graveyard"); public Necromancy(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); - // You may cast Necromancy as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. + // You may cast Necromancy as though it had flash. If you cast it any time a sorcery couldn't have been cast, + // the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame))); this.addAbility(new SacrificeIfCastAtInstantTimeTriggeredAbility()); + // When Necromancy enters the battlefield, if it's on the battlefield, it becomes an Aura with + // "enchant creature put onto the battlefield with Necromancy." Put target creature card from + // a graveyard onto the battlefield under your control and attach Necromancy to it. When Necromancy + // leaves the battlefield, that creature's controller sacrifices it. Ability ability = new AnimateDeadTriggeredAbility(true); ability.addTarget(new TargetCardInGraveyard(filter)); this.addAbility(ability); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/AnimateDeadTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/AnimateDeadTest.java index 4df2b00c8a..3aaa6ead77 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/AnimateDeadTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/AnimateDeadTest.java @@ -217,4 +217,67 @@ public class AnimateDeadTest extends CardTestPlayerBase { assertPowerToughness(playerA, "Blackbloom Rogue", 1, 3); assertPermanentCount(playerA, "Animate Dead", 1); } + + /** + * Flickering Animate Dead, resolving enters trigger first + * https://github.com/magefree/mage/issues/5250 + */ + @Test + public void testFlickerAnimateDeadEnterTriggerFirst() { + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Walking Corpse"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + addCard(Zone.HAND, playerA, "Animate Dead"); + addCard(Zone.HAND, playerA, "Flicker of Fate"); + + setStrictChooseMode(true); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Animate Dead", "Silvercoat Lion"); + + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Flicker of Fate", "Animate Dead"); + setChoice(playerA, "Walking Corpse"); // card to attach reentering aura to + setChoice(playerA, "When {this} leaves"); // resolve leaves trigger last + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Animate Dead", 1); + assertPermanentCount(playerA, "Walking Corpse", 1); + assertPermanentCount(playerA, "Silvercoat Lion", 0); + assertGraveyardCount(playerA, "Silvercoat Lion", 1); + assertGraveyardCount(playerA, "Walking Corpse", 0); + assertGraveyardCount(playerA, "Flicker of Fate", 1); + } + + /** + * Flickering Animate Dead, resolving leaves trigger first + */ + @Test + public void testFlickerAnimateDeadLeaveTriggerFirst() { + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Walking Corpse"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + addCard(Zone.HAND, playerA, "Animate Dead"); + addCard(Zone.HAND, playerA, "Flicker of Fate"); + + setStrictChooseMode(true); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Animate Dead", "Silvercoat Lion"); + + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Flicker of Fate", "Animate Dead"); + setChoice(playerA, "Walking Corpse"); // card to attach reentering aura to + setChoice(playerA, "When {this} enters"); // resolve enters trigger last + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Animate Dead", 1); + assertPermanentCount(playerA, "Walking Corpse", 1); + assertPermanentCount(playerA, "Silvercoat Lion", 0); + assertGraveyardCount(playerA, "Silvercoat Lion", 1); + assertGraveyardCount(playerA, "Walking Corpse", 0); + assertGraveyardCount(playerA, "Flicker of Fate", 1); + } }