diff --git a/Mage.Sets/src/mage/cards/r/RadiantEpicure.java b/Mage.Sets/src/mage/cards/r/RadiantEpicure.java index d4b76ca0c60..89498e54248 100644 --- a/Mage.Sets/src/mage/cards/r/RadiantEpicure.java +++ b/Mage.Sets/src/mage/cards/r/RadiantEpicure.java @@ -11,6 +11,7 @@ import mage.cards.CardSetInfo; import mage.constants.*; import mage.game.Game; import mage.players.Player; +import mage.util.CardUtil; import mage.watchers.common.ManaSpentToCastWatcher; import java.util.UUID; @@ -69,7 +70,7 @@ class RadiantEpicureEffect extends OneShotEffect { if (player == null || watcher == null) { return false; } - Mana payment = watcher.getLastManaPayment(source.getSourceId()); + Mana payment = watcher.getManaPayment(CardUtil.getSourceStackMomentReference(game, source)); if (payment == null) { return false; } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/conditional/ManaWasSpentToCastTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/ManaWasSpentToCastTest.java index 6613e20793a..d5f9514a067 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/conditional/ManaWasSpentToCastTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/ManaWasSpentToCastTest.java @@ -25,7 +25,9 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Abzan Banner"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tin Street Hooligan"); - // Abzan Banner is auto-chosen since only possible target + addTarget(playerA, "Abzan Banner"); + + setStrictChooseMode(true); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); @@ -42,16 +44,43 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Abzan Banner"); - setStrictChooseMode(true); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tin Street Hooligan"); // {G} was not spent, so no target is chosen + setStrictChooseMode(true); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); assertPermanentCount(playerA, "Tin Street Hooligan", 1); } + //ManaWasSpentCondition gives false negative after permanent leaves battlefield + //Fixed by using MageObjectReference instead of UUID + @Test + public void testArtifactWillBeDestroyedAfterDeath() { + // Tin Street Hooligan - Creature 2/1 {1}{R} + // When Tin Street Hooligan enters the battlefield, if {G} was spent to cast Tin Street Hooligan, destroy target artifact. + addCard(Zone.HAND, playerA, "Tin Street Hooligan"); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); + + addCard(Zone.HAND, playerB, "Lightning Bolt"); + addCard(Zone.BATTLEFIELD, playerB, "Abzan Banner"); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tin Street Hooligan"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN,true); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB,"Lightning Bolt","Tin Street Hooligan"); + addTarget(playerA, "Abzan Banner"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Tin Street Hooligan", 0); + assertPermanentCount(playerB, "Abzan Banner", 0); + assertGraveyardCount(playerA, 1); + assertGraveyardCount(playerB, 2); + } @Test public void testSnowMana() { @@ -59,9 +88,12 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Boreal Druid"); addCard(Zone.BATTLEFIELD, playerA, "Plains"); addCard(Zone.HAND, playerA, "Search for Glory"); + addCard(Zone.LIBRARY, playerA, "Snow-Covered Plains"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Search for Glory"); + addTarget(playerA, "Snow-Covered Plains"); + setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -78,12 +110,15 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Vodalian Arcanist"); addCard(Zone.BATTLEFIELD, playerA, "Rimefeather Owl"); addCard(Zone.HAND, playerA, "Search for Glory"); + addCard(Zone.LIBRARY, playerA, "Snow-Covered Plains"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {U}"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{S}", "Vodalian Arcanist"); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Search for Glory"); + addTarget(playerA, "Snow-Covered Plains"); + setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -99,7 +134,9 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Berg Strider"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Berg Strider"); + addTarget(playerA, "Silvercoat Lion"); + setStrictChooseMode(true); setStopAt(2, PhaseStep.PRECOMBAT_MAIN); execute(); @@ -113,8 +150,11 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Strike It Rich", 1); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Strike It Rich", true); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Sacrifice"); + setChoice(playerA, "Red"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Jaded Sell-Sword"); + setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -129,6 +169,7 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Jaded Sell-Sword"); + setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -145,6 +186,7 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase { setChoice(playerA, "X=2"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Verazol, the Split Current"); + setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -163,6 +205,7 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Prossh, Skyraider of Kher"); + setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -226,6 +269,7 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase { waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN); // Let the Mana Drain delayed triggered ability resolve castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Sliver Construct"); + setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); execute(); diff --git a/Mage/src/main/java/mage/abilities/condition/common/AdamantCondition.java b/Mage/src/main/java/mage/abilities/condition/common/AdamantCondition.java index 030f8b6e949..aefb7c3e6d1 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/AdamantCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/AdamantCondition.java @@ -6,6 +6,7 @@ import mage.abilities.condition.Condition; import mage.constants.AbilityType; import mage.constants.ColoredManaSymbol; import mage.game.Game; +import mage.util.CardUtil; import mage.watchers.common.ManaSpentToCastWatcher; import java.util.Arrays; @@ -53,7 +54,7 @@ public enum AdamantCondition implements Condition { if (watcher == null) { return false; } - Mana payment = watcher.getLastManaPayment(source.getSourceId()); + Mana payment = watcher.getManaPayment(CardUtil.getSourceStackMomentReference(game, source)); if (payment == null) { return false; } diff --git a/Mage/src/main/java/mage/abilities/condition/common/ManaWasSpentCondition.java b/Mage/src/main/java/mage/abilities/condition/common/ManaWasSpentCondition.java index 413e4bfb862..b88e145a779 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/ManaWasSpentCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/ManaWasSpentCondition.java @@ -6,6 +6,7 @@ import mage.abilities.condition.Condition; import mage.constants.AbilityType; import mage.constants.ColoredManaSymbol; import mage.game.Game; +import mage.util.CardUtil; import mage.watchers.common.ManaSpentToCastWatcher; /** @@ -33,7 +34,7 @@ public enum ManaWasSpentCondition implements Condition { } ManaSpentToCastWatcher watcher = game.getState().getWatcher(ManaSpentToCastWatcher.class); if (watcher != null) { - Mana payment = watcher.getLastManaPayment(source.getSourceId()); + Mana payment = watcher.getManaPayment(CardUtil.getSourceStackMomentReference(game, source)); if (payment != null) { return payment.getColor(coloredManaSymbol) > 0; } diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/EachTwoManaSpentToCastValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/EachTwoManaSpentToCastValue.java index 4620fbb9795..128edaed565 100644 --- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/EachTwoManaSpentToCastValue.java +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/EachTwoManaSpentToCastValue.java @@ -7,6 +7,7 @@ import mage.abilities.effects.Effect; import mage.constants.AbilityType; import mage.constants.ColoredManaSymbol; import mage.game.Game; +import mage.util.CardUtil; import mage.watchers.common.ManaSpentToCastWatcher; /** @@ -32,7 +33,7 @@ public enum EachTwoManaSpentToCastValue implements DynamicValue { Mana payment = game .getState() .getWatcher(ManaSpentToCastWatcher.class) - .getLastManaPayment(sourceAbility.getSourceId()); + .getManaPayment(CardUtil.getSourceStackMomentReference(game, sourceAbility)); if (payment == null) { return 0; } diff --git a/Mage/src/main/java/mage/watchers/common/ManaSpentToCastWatcher.java b/Mage/src/main/java/mage/watchers/common/ManaSpentToCastWatcher.java index 85de7e05964..28fc4350146 100644 --- a/Mage/src/main/java/mage/watchers/common/ManaSpentToCastWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/ManaSpentToCastWatcher.java @@ -1,18 +1,16 @@ package mage.watchers.common; +import mage.MageObjectReference; import mage.Mana; -import mage.abilities.Ability; import mage.constants.WatcherScope; -import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.game.stack.Spell; import mage.watchers.Watcher; import java.util.HashMap; import java.util.Map; -import java.util.UUID; + /** * Watcher saves the mana that was spent to cast a spell @@ -24,7 +22,7 @@ import java.util.UUID; */ public class ManaSpentToCastWatcher extends Watcher { - private final Map manaMap = new HashMap<>(); + private final Map manaMap = new HashMap<>(); public ManaSpentToCastWatcher() { super(WatcherScope.GAME); @@ -33,22 +31,17 @@ public class ManaSpentToCastWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { // There was a check for the from zone being the hand, but that should not matter - switch (event.getType()) { - case SPELL_CAST: + if (event.getType() == GameEvent.EventType.SPELL_CAST){ Spell spell = (Spell) game.getObject(event.getTargetId()); if (spell != null) { - manaMap.put(spell.getSourceId(), spell.getSpellAbility().getManaCostsToPay().getUsedManaToPay()); - } - return; - case ZONE_CHANGE: - if (((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { - manaMap.remove(event.getTargetId()); + manaMap.put(new MageObjectReference(spell.getSpellAbility()), + spell.getSpellAbility().getManaCostsToPay().getUsedManaToPay()); } } } - public Mana getLastManaPayment(UUID sourceId) { - return manaMap.getOrDefault(sourceId, null); + public Mana getManaPayment(MageObjectReference source) { + return manaMap.getOrDefault(source, null); } @Override