Fix restoration referencing the wrong game when restoring game entities

This commit is contained in:
Chris H
2024-04-04 22:38:07 -04:00
parent 6d5579c4b8
commit 1a2de095db

View File

@@ -20,6 +20,7 @@ import forge.game.zone.ZoneType;
public class GameSnapshot { public class GameSnapshot {
private final Game origGame; private final Game origGame;
private Game newGame = null; private Game newGame = null;
private boolean restore = false;
private final SnapshotEntityMap gameObjectMap = new SnapshotEntityMap(); private final SnapshotEntityMap gameObjectMap = new SnapshotEntityMap();
@@ -45,7 +46,8 @@ public class GameSnapshot {
GameRules currentRules = origGame.getRules(); GameRules currentRules = origGame.getRules();
Match newMatch = new Match(currentRules, newPlayers, origGame.getView().getTitle()); Match newMatch = new Match(currentRules, newPlayers, origGame.getView().getTitle());
newGame = new Game(newPlayers, currentRules, newMatch); newGame = new Game(newPlayers, currentRules, newMatch);
assignGameState(origGame, newGame, includeStack, false); restore = false;
assignGameState(origGame, newGame, includeStack);
//System.out.println("Storing game state with timestamp of :" + origGame.getTimestamp()); //System.out.println("Storing game state with timestamp of :" + origGame.getTimestamp());
return newGame; return newGame;
@@ -53,15 +55,15 @@ public class GameSnapshot {
public void restoreGameState(Game currentGame) { public void restoreGameState(Game currentGame) {
System.out.println("Restoring game state with timestamp of :" + newGame.getTimestamp()); System.out.println("Restoring game state with timestamp of :" + newGame.getTimestamp());
restore = true;
assignGameState(newGame, currentGame, true, true); assignGameState(newGame, currentGame, true);
} }
public void assignGameState(Game fromGame, Game toGame, boolean includeStack, boolean restore) { public void assignGameState(Game fromGame, Game toGame, boolean includeStack) {
for (int i = 0; i < fromGame.getPlayers().size(); i++) { for (int i = 0; i < fromGame.getPlayers().size(); i++) {
Player origPlayer = fromGame.getPlayers().get(i); Player origPlayer = fromGame.getPlayers().get(i);
Player newPlayer = findBy(toGame, origPlayer); Player newPlayer = findBy(toGame, origPlayer);
assignPlayerState(origPlayer, newPlayer, restore); assignPlayerState(origPlayer, newPlayer);
} }
PhaseHandler origPhaseHandler = fromGame.getPhaseHandler(); PhaseHandler origPhaseHandler = fromGame.getPhaseHandler();
@@ -72,7 +74,7 @@ public class GameSnapshot {
((PlayerZoneBattlefield) p.getZone(ZoneType.Battlefield)).setTriggers(false); ((PlayerZoneBattlefield) p.getZone(ZoneType.Battlefield)).setTriggers(false);
} }
copyGameState(fromGame, toGame, restore); copyGameState(fromGame, toGame);
for (Player p : fromGame.getPlayers()) { for (Player p : fromGame.getPlayers()) {
Player toPlayer = findBy(toGame, p); Player toPlayer = findBy(toGame, p);
@@ -138,7 +140,9 @@ public class GameSnapshot {
// } // }
if (origPhaseHandler.getCombat() != null) { if (origPhaseHandler.getCombat() != null) {
toGame.getPhaseHandler().setCombat(new Combat(origPhaseHandler.getCombat(), gameObjectMap)); Combat combat = new Combat(origPhaseHandler.getCombat(), gameObjectMap);
toGame.getPhaseHandler().setCombat(combat);
//System.out.println(origPhaseHandler.getCombat().toString());
} }
// I think re-assigning this is killing something? // I think re-assigning this is killing something?
@@ -146,7 +150,7 @@ public class GameSnapshot {
// toGame.getTriggerHandler().resetActiveTriggers(); // toGame.getTriggerHandler().resetActiveTriggers();
if (includeStack) { if (includeStack) {
copyStack(fromGame, toGame, restore); copyStack(fromGame, toGame);
} }
if (restore) { if (restore) {
@@ -154,14 +158,20 @@ public class GameSnapshot {
p.updateAllZonesForView(); p.updateAllZonesForView();
} }
System.out.println("RESTORED"); Combat combat = toGame.getPhaseHandler().getCombat();
if (combat != null) {
//System.out.println(combat.toString());
toGame.updateCombatForView();
}
//System.out.println("RESTORED");
} }
// TODO update thisTurnCast // TODO update thisTurnCast
} }
public void assignPlayerState(Player origPlayer, Player newPlayer, boolean restore) { public void assignPlayerState(Player origPlayer, Player newPlayer) {
if (restore) { if (restore) {
// Player controller of the original player isn't associated with the GUI at this point?
origPlayer.dangerouslySetController(newPlayer.getController()); origPlayer.dangerouslySetController(newPlayer.getController());
} }
newPlayer.setLife(origPlayer.getLife(), null); newPlayer.setLife(origPlayer.getLife(), null);
@@ -177,6 +187,7 @@ public class GameSnapshot {
newPlayer.setRevolt(origPlayer.hasRevolt()); newPlayer.setRevolt(origPlayer.hasRevolt());
newPlayer.setLibrarySearched(origPlayer.getLibrarySearched()); newPlayer.setLibrarySearched(origPlayer.getLibrarySearched());
newPlayer.setSpellsCastLastTurn(origPlayer.getSpellsCastLastTurn()); newPlayer.setSpellsCastLastTurn(origPlayer.getSpellsCastLastTurn());
newPlayer.setCommitedCrimeThisTurn(origPlayer.getCommitedCrimeThisTurn());
for (int j = 0; j < origPlayer.getSpellsCastThisTurn(); j++) { for (int j = 0; j < origPlayer.getSpellsCastThisTurn(); j++) {
newPlayer.addSpellCastThisTurn(); newPlayer.addSpellCastThisTurn();
} }
@@ -211,12 +222,12 @@ public class GameSnapshot {
return newMana; return newMana;
} }
private void copyStack(Game fromGame, Game toGame, boolean restore) { private void copyStack(Game fromGame, Game toGame) {
// Try to match the StackInstance ID. If we don't find it, generate a new stack instance that matches // Try to match the StackInstance ID. If we don't find it, generate a new stack instance that matches
// If we do find it, we may need to alter the existing stack instance // If we do find it, we may need to alter the existing stack instance
// If we find it and we're restoring, we dont need to do anything // If we find it and we're restoring, we dont need to do anything
Map<Integer, SpellAbilityStackInstance> stackIds = new HashMap(); Map<Integer, SpellAbilityStackInstance> stackIds = new HashMap<>();
for (SpellAbilityStackInstance toEntry : toGame.getStack()) { for (SpellAbilityStackInstance toEntry : toGame.getStack()) {
stackIds.put(toEntry.getId(), toEntry); stackIds.put(toEntry.getId(), toEntry);
} }
@@ -249,8 +260,6 @@ public class GameSnapshot {
SpellAbility newSa = null; SpellAbility newSa = null;
if (origSa.isSpell()) { if (origSa.isSpell()) {
newSa = findSAInCard(origSa, newCard); newSa = findSAInCard(origSa, newCard);
} else {
} }
// Is the SA on the stack? // Is the SA on the stack?
@@ -272,7 +281,7 @@ public class GameSnapshot {
} }
} }
public void copyGameState(Game fromGame, Game toGame, boolean restore) { public void copyGameState(Game fromGame, Game toGame) {
toGame.setAge(fromGame.getAge()); toGame.setAge(fromGame.getAge());
toGame.dangerouslySetTimestamp(fromGame.getTimestamp()); toGame.dangerouslySetTimestamp(fromGame.getTimestamp());
@@ -315,14 +324,15 @@ public class GameSnapshot {
if (fromType.equals(ZoneType.Stack)) { if (fromType.equals(ZoneType.Stack)) {
toGame.getStackZone().add(newCard); toGame.getStackZone().add(newCard);
newCard.setZone(toGame.getStackZone());
} else { } else {
toPlayer.getZone(fromType).add(newCard); toPlayer.getZone(fromType).add(newCard);
newCard.setZone(toPlayer.getZone(fromType));
} }
// TODO: This is a bit of a mess. We should probably have a method to copy a card's state. // TODO: This is a bit of a mess. We should probably have a method to copy a card's state.
newCard.setGameTimestamp(fromCard.getGameTimestamp()); newCard.setGameTimestamp(fromCard.getGameTimestamp());
newCard.setLayerTimestamp(fromCard.getLayerTimestamp()); newCard.setLayerTimestamp(fromCard.getLayerTimestamp());
newCard.setZone(fromCard.getZone());
newCard.setTapped(fromCard.isTapped()); newCard.setTapped(fromCard.isTapped());
newCard.setFaceDown(fromCard.isFaceDown()); newCard.setFaceDown(fromCard.isFaceDown());
newCard.setManifested(fromCard.isManifested()); newCard.setManifested(fromCard.isManifested());
@@ -389,40 +399,33 @@ public class GameSnapshot {
public class SnapshotEntityMap implements IEntityMap { public class SnapshotEntityMap implements IEntityMap {
@Override @Override
public Game getGame() { public Game getGame() {
if (restore) {
return origGame;
}
return newGame; return newGame;
} }
@Override @Override
public GameObject map(GameObject o) { public GameObject map(GameObject o) {
if (o instanceof Player) { if (o instanceof Player) {
return findBy(newGame, (Player) o); return findBy(getGame(), (Player) o);
} else if (o instanceof Card) { } else if (o instanceof Card) {
return findBy(newGame, (Card) o); return findBy(getGame(), (Card) o);
} }
return null; return null;
} }
@Override @Override
public Card map(final Card c) { public Card map(final Card c) {
return findBy(newGame, c); return findBy(getGame(), c);
} }
@Override @Override
public Player map(final Player p) { public Player map(final Player p) {
return findBy(newGame, p); return findBy(getGame(), p);
} }
} }
private GameEntity findBy(Game toGame, GameEntity fromEntity) {
if (fromEntity instanceof Card) {
return toGame.findById(fromEntity.getId());
} else if (fromEntity instanceof Player) {
return toGame.getPlayer(fromEntity.getId());
}
return null;
}
private Card findBy(Game toGame, Card fromCard) { private Card findBy(Game toGame, Card fromCard) {
return toGame.findById(fromCard.getId()); return toGame.findById(fromCard.getId());
} }