diff --git a/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java b/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java index aa51649a5a4..be82f5ad2cd 100644 --- a/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java +++ b/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java @@ -108,7 +108,18 @@ public class GameCopier { ((PlayerZoneBattlefield) p.getZone(ZoneType.Battlefield)).setTriggers(true); } newGame.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); - + + for (Card c : newGame.getCardsInGame()) { + for (SpellAbility sa : c.getSpellAbilities()) { + Player activatingPlayer = sa.getActivatingPlayer(); + if (activatingPlayer != null && activatingPlayer.getGame() != newGame) { + sa.setActivatingPlayer(gameObjectMap.map(activatingPlayer)); + } + } + } + origGame.validateSpabCache(); + newGame.validateSpabCache(); + // Undo effects first before calculating them below, to avoid them applying twice. for (StaticEffect effect : origGame.getStaticEffects().getEffects()) { effect.removeMapped(gameObjectMap); diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index 6b6c548cf12..4efd5bdb017 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -199,6 +199,16 @@ public class Game { public void removeSpellAbility(SpellAbility spellAbility) { spabCache.remove(spellAbility.getId()); } + public void validateSpabCache() { + for (SpellAbility sa : spabCache.getValues()) { + if (sa.getHostCard() != null && sa.getHostCard().getGame() != this) { + throw new RuntimeException(); + } + if (sa.getActivatingPlayer() != null && sa.getActivatingPlayer().getGame() != this) { + throw new RuntimeException(); + } + } + } public Game(List players0, GameRules rules0, Match match0) { /* no more zones to map here */ rules = rules0; diff --git a/forge-game/src/main/java/forge/game/GameEntityCache.java b/forge-game/src/main/java/forge/game/GameEntityCache.java index 182568341cf..aeb3145f9c8 100644 --- a/forge-game/src/main/java/forge/game/GameEntityCache.java +++ b/forge-game/src/main/java/forge/game/GameEntityCache.java @@ -1,6 +1,7 @@ package forge.game; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -40,4 +41,8 @@ public class GameEntityCache getValues() { + return entityCache.values(); + } } diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 684dff7092c..e3d6efeb3f9 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -203,9 +203,9 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit @Override public void setHostCard(final Card c) { if (hostCard == c) { return; } - super.setHostCard(c); Game oldGame = hostCard != null ? hostCard.getGame() : null; Game newGame = c != null ? c.getGame() : null; + super.setHostCard(c); if (oldGame != newGame) { if (oldGame != null) { oldGame.removeSpellAbility(this); } if (newGame != null) { newGame.addSpellAbility(this); }