From fcc0cb9d0c5f52dbf8d47eeca3c3881961b7584b Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Sat, 9 Jan 2021 20:57:33 +0100 Subject: [PATCH 1/5] Fix multiplayer conceding --- .../java/forge/game/phase/PhaseHandler.java | 4 ++ .../java/forge/match/AbstractGuiGame.java | 47 +++++++++++++++---- .../forge/player/PlayerControllerHuman.java | 8 +++- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java index 8874f974322..f52109c9c84 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -127,6 +127,10 @@ public class PhaseHandler implements java.io.Serializable { game.updatePlayerTurnForView(); setPriority(playerTurn); } + + public final void endPlayerLostTurn() { + setPlayerTurn(handleNextTurn()); + } public final Player getPriorityPlayer() { return pPlayerPriority; diff --git a/forge-gui/src/main/java/forge/match/AbstractGuiGame.java b/forge-gui/src/main/java/forge/match/AbstractGuiGame.java index dd6490bebb3..15f140a0d1d 100644 --- a/forge-gui/src/main/java/forge/match/AbstractGuiGame.java +++ b/forge-gui/src/main/java/forge/match/AbstractGuiGame.java @@ -32,6 +32,7 @@ import forge.interfaces.IGameController; import forge.interfaces.IGuiGame; import forge.interfaces.IMayViewCards; import forge.model.FModel; +import forge.player.PlayerControllerHuman; import forge.properties.ForgeConstants; import forge.properties.ForgePreferences; import forge.trackable.TrackableTypes; @@ -43,7 +44,8 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards { private final Map gameControllers = Maps.newHashMap(); private final Map originalGameControllers = Maps.newHashMap(); private boolean gamePause = false; - + private boolean ignoreConcedeChain = false; + public final boolean hasLocalPlayers() { return !gameControllers.isEmpty(); } @@ -294,23 +296,48 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards { return true; } if (hasLocalPlayers()) { - if (showConfirmDialog(Localizer.getInstance().getMessage("lblConcedeCurrentGame"), Localizer.getInstance().getMessage("lblConcedeTitle"), Localizer.getInstance().getMessage("lblConcede"), Localizer.getInstance().getMessage("lblCancel"))) { - for (final IGameController c : getOriginalGameControllers()) { - // Concede each player on this Gui (except mind-controlled players) - c.concede(); + boolean concedeNeeded = false; + // check if anyone still needs to confirm + for (final IGameController c : getOriginalGameControllers()) { + if (c instanceof PlayerControllerHuman) { + if (((PlayerControllerHuman) c).getPlayer().getOutcome() == null) { + concedeNeeded = true; + } } - } else { - return false; + } + if (concedeNeeded) { + if (showConfirmDialog(Localizer.getInstance().getMessage("lblConcedeCurrentGame"), Localizer.getInstance().getMessage("lblConcedeTitle"), Localizer.getInstance().getMessage("lblConcede"), Localizer.getInstance().getMessage("lblCancel"))) { + for (final IGameController c : getOriginalGameControllers()) { + // Concede each player on this Gui (except mind-controlled players) + c.concede(); + } + } + else { + return false; + } + } + else { + if (ignoreConcedeChain) { + return false; + } + else { + return true; + } + } if (gameView.isGameOver()) { // Don't immediately close, wait for win/lose screen return false; - } else { - for (PlayerView player : getLocalPlayers()){ - if (!player.isAI()){ + } + else { + // since the nextGameDecision might come from somewhere else it will try and concede too + ignoreConcedeChain = true; + for (PlayerView player : getLocalPlayers()) { + if (!player.isAI()) { getGameController(player).nextGameDecision(NextGameDecision.QUIT); } } + ignoreConcedeChain = false; return false; } } diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index b7243562e3a..ddc3135f455 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -2943,7 +2943,13 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont } public void autoPassUntilEndOfTurn() { - getGui().autoPassUntilEndOfTurn(getLocalPlayerView()); + // if we already conceded just skip everything + if (player.getOutcome() != null) { + player.getGame().getPhaseHandler().endPlayerLostTurn(); + } + else { + getGui().autoPassUntilEndOfTurn(getLocalPlayerView()); + } } @Override From e69abf0982e2a49b299e0456f6a027f7f56c6e7f Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Wed, 13 Jan 2021 19:28:58 +0100 Subject: [PATCH 2/5] Code cleanup --- forge-gui/src/main/java/forge/match/AbstractGuiGame.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/forge-gui/src/main/java/forge/match/AbstractGuiGame.java b/forge-gui/src/main/java/forge/match/AbstractGuiGame.java index 15f140a0d1d..d45524871b3 100644 --- a/forge-gui/src/main/java/forge/match/AbstractGuiGame.java +++ b/forge-gui/src/main/java/forge/match/AbstractGuiGame.java @@ -317,12 +317,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards { } } else { - if (ignoreConcedeChain) { - return false; - } - else { - return true; - } + return !ignoreConcedeChain; } if (gameView.isGameOver()) { From afce0b1af49bffd4fcda3df42feed43af2f47845 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Wed, 13 Jan 2021 19:38:05 +0100 Subject: [PATCH 3/5] Partial Rollback --- .../src/main/java/forge/game/phase/PhaseHandler.java | 4 ---- .../src/main/java/forge/player/PlayerControllerHuman.java | 8 +------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java index f52109c9c84..8874f974322 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -127,10 +127,6 @@ public class PhaseHandler implements java.io.Serializable { game.updatePlayerTurnForView(); setPriority(playerTurn); } - - public final void endPlayerLostTurn() { - setPlayerTurn(handleNextTurn()); - } public final Player getPriorityPlayer() { return pPlayerPriority; diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index ddc3135f455..b7243562e3a 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -2943,13 +2943,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont } public void autoPassUntilEndOfTurn() { - // if we already conceded just skip everything - if (player.getOutcome() != null) { - player.getGame().getPhaseHandler().endPlayerLostTurn(); - } - else { - getGui().autoPassUntilEndOfTurn(getLocalPlayerView()); - } + getGui().autoPassUntilEndOfTurn(getLocalPlayerView()); } @Override From 539bfac2807b1f6955682fa0eb574b53aef251e5 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Wed, 13 Jan 2021 21:53:29 +0100 Subject: [PATCH 4/5] Check for lost player right before passing --- forge-game/src/main/java/forge/game/phase/PhaseHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java index 8874f974322..b3fc16544ff 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -1003,6 +1003,9 @@ public class PhaseHandler implements java.io.Serializable { return; } + chosenSa = pPlayerPriority.getController().chooseSpellAbilityToPlay(); + + // this needs to come after chosenSa so it sees you conceding on own turn if (playerTurn.hasLost() && pPlayerPriority.equals(playerTurn) && pFirstPriority.equals(playerTurn)) { // If the active player has lost, and they have priority, set the next player to have priority System.out.println("Active player is no longer in the game..."); @@ -1010,7 +1013,6 @@ public class PhaseHandler implements java.io.Serializable { pFirstPriority = pPlayerPriority; } - chosenSa = pPlayerPriority.getController().chooseSpellAbilityToPlay(); if (chosenSa == null) { break; // that means 'I pass' } From d68c0691f4c0c556622347ccc80a00e3b6012df4 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Wed, 13 Jan 2021 21:55:12 +0100 Subject: [PATCH 5/5] Clean up --- forge-gui/src/main/java/forge/match/AbstractGuiGame.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/forge-gui/src/main/java/forge/match/AbstractGuiGame.java b/forge-gui/src/main/java/forge/match/AbstractGuiGame.java index d45524871b3..225e6ba1fbc 100644 --- a/forge-gui/src/main/java/forge/match/AbstractGuiGame.java +++ b/forge-gui/src/main/java/forge/match/AbstractGuiGame.java @@ -45,7 +45,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards { private final Map originalGameControllers = Maps.newHashMap(); private boolean gamePause = false; private boolean ignoreConcedeChain = false; - + public final boolean hasLocalPlayers() { return !gameControllers.isEmpty(); } @@ -318,7 +318,6 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards { } else { return !ignoreConcedeChain; - } if (gameView.isGameOver()) { // Don't immediately close, wait for win/lose screen