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).
This commit is contained in:
Myrd
2016-12-22 20:31:41 +00:00
parent 4b14c9d943
commit 3e91a56ced
2 changed files with 26 additions and 2 deletions

View File

@@ -356,7 +356,6 @@ public class Card extends GameEntity implements Comparable<Card> {
return states.get(state); return states.get(state);
} }
public boolean setState(final CardStateName state, boolean updateView) { public boolean setState(final CardStateName state, boolean updateView) {
if (!states.containsKey(state)) { if (!states.containsKey(state)) {
System.out.println(getName() + " tried to switch to non-existant state \"" + state + "\"!"); System.out.println(getName() + " tried to switch to non-existant state \"" + state + "\"!");
return false; // Nonexistant state. return false; // Nonexistant state.
@@ -427,7 +426,13 @@ public class Card extends GameEntity implements Comparable<Card> {
} }
public void clearStates(final CardStateName state, boolean updateView) { 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); view.updateState(this);
} }
} }

View File

@@ -561,4 +561,23 @@ public class GameSimulatorTest extends TestCase {
assertNull(strSimGame, findCardWithName(simGame, "Thespian's Stage")); assertNull(strSimGame, findCardWithName(simGame, "Thespian's Stage"));
assertNotNull(strSimGame, findCardWithName(simGame, "Marit Lage")); 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"));
}
} }