From aeb2d31d47de7cef51a41f2d5647c494f8334e7c Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 20 Nov 2020 12:53:13 +0400 Subject: [PATCH] [CMR] fixed Gilanra, Caller of Wirewood - duplicated triggers on unused mana (#7191); --- .../mage/cards/g/GilanraCallerOfWirewood.java | 17 +++ .../cmr/GilanraCallerOfWirewoodTest.java | 132 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/cmr/GilanraCallerOfWirewoodTest.java diff --git a/Mage.Sets/src/mage/cards/g/GilanraCallerOfWirewood.java b/Mage.Sets/src/mage/cards/g/GilanraCallerOfWirewood.java index 836622c7a8..4f3bdc208c 100644 --- a/Mage.Sets/src/mage/cards/g/GilanraCallerOfWirewood.java +++ b/Mage.Sets/src/mage/cards/g/GilanraCallerOfWirewood.java @@ -18,6 +18,7 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.game.stack.Spell; +import mage.players.Player; import java.util.UUID; @@ -95,6 +96,22 @@ class GilanraCallerOfWirewoodTriggeredAbility extends DelayedTriggeredAbility { return spell != null && spell.getConvertedManaCost() >= 6; } + @Override + public boolean isInactive(Game game) { + if (super.isInactive(game)) { + return true; + } + + // must remove effect on empty mana pool to fix accumulate bug + Player player = game.getPlayer(this.getControllerId()); + if (player == null) { + return true; + } + + // if no mana in pool then it can be discarded + return player.getManaPool().getManaItems().stream().noneMatch(m -> m.getSourceId().equals(getSourceId())); + } + @Override public String getRule() { return "When you spend this mana to cast a spell with converted mana cost 6 or greater, draw a card."; diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/cmr/GilanraCallerOfWirewoodTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/cmr/GilanraCallerOfWirewoodTest.java new file mode 100644 index 0000000000..95c508dd6f --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/cmr/GilanraCallerOfWirewoodTest.java @@ -0,0 +1,132 @@ +package org.mage.test.cards.single.cmr; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author JayDi85 + */ + +public class GilanraCallerOfWirewoodTest extends CardTestPlayerBase { + + @Test + public void test_EffectMustBeDiscardedOnNextTurn_SinglePlay_FromPool() { + // https://github.com/magefree/mage/issues/7191 + removeAllCardsFromHand(playerA); + + // {T}: Add {G}. When you spend this mana to cast a spell with converted mana cost 6 or greater, draw a card. + addCard(Zone.BATTLEFIELD, playerA, "Gilanra, Caller of Wirewood", 1); + // + // Angel of Deliverance + addCard(Zone.HAND, playerA, "Angel of Deliverance", 1); // {6}{W}{W} + addCard(Zone.BATTLEFIELD, playerA, "Plains", 8 - 1); + + // play and use 1 trigger + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}. When"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Deliverance"); + checkStackSize("must have one trigger", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 1 + 1); // card + trigger + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Angel of Deliverance", 1); + assertHandCount(playerA, 1); // draw from trigger + } + + @Test + public void test_EffectMustBeDiscardedOnNextTurn_SinglePlay_FromAutoPay() { + // https://github.com/magefree/mage/issues/7191 + removeAllCardsFromHand(playerA); + + // {T}: Add {G}. When you spend this mana to cast a spell with converted mana cost 6 or greater, draw a card. + addCard(Zone.BATTLEFIELD, playerA, "Gilanra, Caller of Wirewood", 1); + // + // Angel of Deliverance + addCard(Zone.HAND, playerA, "Angel of Deliverance", 1); // {6}{W}{W} + addCard(Zone.BATTLEFIELD, playerA, "Plains", 8 - 1); + + // play and use 1 trigger (auto-pay must work) + //activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}. When"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Deliverance"); + checkStackSize("must have one trigger", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 1 + 1); // card + trigger + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Angel of Deliverance", 1); + assertHandCount(playerA, 1); // draw from trigger + } + + @Test + public void test_EffectMustBeDiscardedOnNextTurn_DoublePlay_ByTurns() { + // https://github.com/magefree/mage/issues/7191 + removeAllCardsFromHand(playerA); + + // {T}: Add {G}. When you spend this mana to cast a spell with converted mana cost 6 or greater, draw a card. + addCard(Zone.BATTLEFIELD, playerA, "Gilanra, Caller of Wirewood", 1); + // + // Angel of Deliverance + addCard(Zone.HAND, playerA, "Angel of Deliverance", 1); // {6}{W}{W} + addCard(Zone.BATTLEFIELD, playerA, "Plains", 8 - 1); + + // turn 1 - activate mana, but don't use + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}. When"); + + // turn 3 - activate mana and use it to cast card + // possible bug: draw 2 cards intead 1 + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}. When"); + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Deliverance"); + checkStackSize("must have one trigger", 3, PhaseStep.PRECOMBAT_MAIN, playerA, 1 + 1); // card + trigger + + setStrictChooseMode(true); + setStopAt(3, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Angel of Deliverance", 1); + assertHandCount(playerA, 1 + 1); // draw from turn 3 and draw from trigger + } + + @Test + public void test_EffectMustBeDiscardedOnNextTurn_DoublePlay_ByUntap() { + // https://github.com/magefree/mage/issues/7191 + removeAllCardsFromHand(playerA); + + // {T}: Add {G}. When you spend this mana to cast a spell with converted mana cost 6 or greater, draw a card. + addCard(Zone.BATTLEFIELD, playerA, "Gilanra, Caller of Wirewood", 1); + // + // Angel of Deliverance + addCard(Zone.HAND, playerA, "Angel of Deliverance", 1); // {6}{W}{W} + addCard(Zone.BATTLEFIELD, playerA, "Plains", 8 - 2); + // + addCard(Zone.HAND, playerA, "Burst of Energy", 1); // {W} + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + + // activate mana two times (by untap - cast untap first to use normal mana) + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {W}"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Burst of Energy", "Gilanra, Caller of Wirewood"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}. When"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}. When"); + checkManaPool("must have 2 green", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "G", 2); + + // cast card and use 2 green mana -- must triggers two times + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Deliverance"); + checkStackSize("must have two trigger", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 1 + 2); // card + 2 trigger + setChoice(playerA, "When you spend this mana"); // two triggers order + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Angel of Deliverance", 1); + assertHandCount(playerA, 2); // 2 draws from 2 triggers + } +}