From 3e91a56ced44d6d4617df5ed42fb5e787e8676dd Mon Sep 17 00:00:00 2001 From: Myrd Date: Thu, 22 Dec 2016 20:31:41 +0000 Subject: [PATCH] Fix NPE in CardUtil.getLKICopy() that would happen when Thespian's Stage would copy itself. The problem would happen when executing: newCopy.getCurrentState().copyFrom(in, in.getState(in.getCurrentStateName())); Because the clone code was clearing the cloned state without updating currentStateName. Also added a test for this in the context of simulated AI, although the actual bug was not in simulation code - it's just simulation code would run into it since it tries all possible targets to copy (while humans would likely not try it). --- .../src/main/java/forge/game/card/Card.java | 9 +++++++-- .../ai/simulation/GameSimulatorTest.java | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 1a1c39854ba..74207c3f38a 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -356,7 +356,6 @@ public class Card extends GameEntity implements Comparable { return states.get(state); } public boolean setState(final CardStateName state, boolean updateView) { - if (!states.containsKey(state)) { System.out.println(getName() + " tried to switch to non-existant state \"" + state + "\"!"); return false; // Nonexistant state. @@ -427,7 +426,13 @@ public class Card extends GameEntity implements Comparable { } public void clearStates(final CardStateName state, boolean updateView) { - if (states.remove(state) != null && updateView) { + if (states.remove(state) == null) { + return; + } + if (state == currentStateName) { + currentStateName = CardStateName.Original; + } + if (updateView) { view.updateState(this); } } diff --git a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java index 46c76bc793a..79a76d029db 100644 --- a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java +++ b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java @@ -561,4 +561,23 @@ public class GameSimulatorTest extends TestCase { assertNull(strSimGame, findCardWithName(simGame, "Thespian's Stage")); assertNotNull(strSimGame, findCardWithName(simGame, "Marit Lage")); } + + public void testThespianStageSelfCopy() { + Game game = initAndCreateGame(); + Player p = game.getPlayers().get(1); + addCard("Swamp", p); + addCard("Swamp", p); + Card thespian = addCard("Thespian's Stage", p); + game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); + game.getAction().checkStateEffects(true); + + SpellAbility sa = findSAWithPrefix(thespian, "{2}, {T}: CARDNAME becomes a copy of target land and gains this ability."); + assertNotNull(sa); + sa.getTargets().add(thespian); + + GameSimulator sim = createSimulator(game, p); + sim.simulateSpellAbility(sa); + Game simGame = sim.getSimulatedGameState(); + assertNotNull(gameStateToString(simGame), findCardWithName(simGame, "Thespian's Stage")); + } }