Repository: magefree/mage (Java)

Issue:
`ManaWasSpentCondition` gives false negative after permanent leaves battlefield
Example: Kill [[Tin-Street Hooligan]] in response to its trigger

This is happening because [`ManaSpentToCastWatcher` clears its map entry upon the permanent leaving the battlefield](https://github.com/magefree/mage/blob/1f261d722cf098484241d618285e194c64cc7abf/Mage/src/main/java/mage/watchers/common/ManaSpentToCastWatcher.java#L48C1-L48C1), but that can't just be removed as presumably then the mana spent would be remembered across things like flickers and reanimation.


Discussion: **[Tin Street Hooligan](https://cards.scryfall.io/normal/front/a/d/ad525bb3-15fd-4887-a3e7-0a036258dcc7.jpg?1593272393)** - [(Gatherer)](https://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=96960) [(Scryfall)](https://scryfall.com/card/gpt/78/tin-street-hooligan?utm_source=api) [(EDHREC)](https://edhrec.com/route/?cc=Tin+Street+Hooligan)
> {1}{R}
> Creature — Goblin Rogue
> 2/1
> When Tin Street Hooligan enters the battlefield, if {G} was spent to cast it, destroy target artifact.



Fix (patch):
diff --git a/Mage.Sets/src/mage/cards/r/RadiantEpicure.java b/Mage.Sets/src/mage/cards/r/RadiantEpicure.java
index d4b76ca0c60e..89498e542482 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.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 @@ public boolean apply(Game game, Ability source) {
         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/src/main/java/mage/abilities/condition/common/AdamantCondition.java b/Mage/src/main/java/mage/abilities/condition/common/AdamantCondition.java
index 030f8b6e949a..aefb7c3e6d11 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.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 boolean apply(Game game, Ability source) {
         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 413e4bfb862a..b88e145a779b 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.constants.AbilityType;
 import mage.constants.ColoredManaSymbol;
 import mage.game.Game;
+import mage.util.CardUtil;
 import mage.watchers.common.ManaSpentToCastWatcher;
 
 /**
@@ -33,7 +34,7 @@ public boolean apply(Game game, Ability source) {
         }
         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 4620fbb9795b..128edaed5658 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.constants.AbilityType;
 import mage.constants.ColoredManaSymbol;
 import mage.game.Game;
+import mage.util.CardUtil;
 import mage.watchers.common.ManaSpentToCastWatcher;
 
 /**
@@ -32,7 +33,7 @@ public int calculate(Game game, Ability sourceAbility, Effect effect) {
         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 85de7e059646..28fc4350146a 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 @@
  */
 public class ManaSpentToCastWatcher extends Watcher {
 
-    private final Map<UUID, Mana> manaMap = new HashMap<>();
+    private final Map<MageObjectReference, Mana> manaMap = new HashMap<>();
 
     public ManaSpentToCastWatcher() {
         super(WatcherScope.GAME);
@@ -33,22 +31,17 @@ public ManaSpentToCastWatcher() {
     @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