mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
Applied visitor to FControl loop.
put 'give priority' on top of game loop, so that we never give anyone priority if game is over
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -14162,6 +14162,7 @@ src/main/java/forge/card/trigger/package-info.java svneol=native#text/plain
|
|||||||
src/main/java/forge/control/ChatArea.java -text
|
src/main/java/forge/control/ChatArea.java -text
|
||||||
src/main/java/forge/control/ControlBazaarUI.java -text
|
src/main/java/forge/control/ControlBazaarUI.java -text
|
||||||
src/main/java/forge/control/FControl.java -text
|
src/main/java/forge/control/FControl.java -text
|
||||||
|
src/main/java/forge/control/FControlGameEventHandler.java -text
|
||||||
src/main/java/forge/control/KeyboardShortcuts.java -text
|
src/main/java/forge/control/KeyboardShortcuts.java -text
|
||||||
src/main/java/forge/control/Lobby.java -text
|
src/main/java/forge/control/Lobby.java -text
|
||||||
src/main/java/forge/control/RestartUtil.java -text
|
src/main/java/forge/control/RestartUtil.java -text
|
||||||
|
|||||||
@@ -31,28 +31,17 @@ import javax.swing.SwingUtilities;
|
|||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.WindowConstants;
|
import javax.swing.WindowConstants;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.FThreads;
|
|
||||||
import forge.Constant.Preferences;
|
import forge.Constant.Preferences;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.control.KeyboardShortcuts.Shortcut;
|
import forge.control.KeyboardShortcuts.Shortcut;
|
||||||
import forge.control.input.InputQueue;
|
import forge.control.input.InputQueue;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.ai.AiProfileUtil;
|
import forge.game.ai.AiProfileUtil;
|
||||||
import forge.game.event.GameEventAnteCardsSelected;
|
|
||||||
import forge.game.event.GameEventDuelFinished;
|
|
||||||
import forge.game.event.GameEvent;
|
|
||||||
import forge.game.event.GameEventTurnPhase;
|
|
||||||
import forge.game.event.GameEventPlayerControl;
|
|
||||||
import forge.game.phase.PhaseType;
|
|
||||||
import forge.game.phase.PhaseUtil;
|
|
||||||
import forge.game.player.LobbyPlayer;
|
import forge.game.player.LobbyPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.gui.GuiDialog;
|
|
||||||
import forge.gui.SOverlayUtils;
|
import forge.gui.SOverlayUtils;
|
||||||
import forge.gui.deckeditor.CDeckEditorUI;
|
import forge.gui.deckeditor.CDeckEditorUI;
|
||||||
import forge.gui.deckeditor.VDeckEditorUI;
|
import forge.gui.deckeditor.VDeckEditorUI;
|
||||||
@@ -64,14 +53,12 @@ import forge.gui.home.CHomeUI;
|
|||||||
import forge.gui.home.VHomeUI;
|
import forge.gui.home.VHomeUI;
|
||||||
import forge.gui.match.CMatchUI;
|
import forge.gui.match.CMatchUI;
|
||||||
import forge.gui.match.VMatchUI;
|
import forge.gui.match.VMatchUI;
|
||||||
import forge.gui.match.ViewWinLose;
|
|
||||||
import forge.gui.match.controllers.CCombat;
|
import forge.gui.match.controllers.CCombat;
|
||||||
import forge.gui.match.controllers.CDock;
|
import forge.gui.match.controllers.CDock;
|
||||||
import forge.gui.match.controllers.CLog;
|
import forge.gui.match.controllers.CLog;
|
||||||
import forge.gui.match.controllers.CMessage;
|
import forge.gui.match.controllers.CMessage;
|
||||||
import forge.gui.match.controllers.CStack;
|
import forge.gui.match.controllers.CStack;
|
||||||
import forge.gui.match.nonsingleton.VField;
|
import forge.gui.match.nonsingleton.VField;
|
||||||
import forge.gui.match.nonsingleton.VHand;
|
|
||||||
import forge.gui.match.views.VAntes;
|
import forge.gui.match.views.VAntes;
|
||||||
import forge.gui.toolbox.CardFaceSymbols;
|
import forge.gui.toolbox.CardFaceSymbols;
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
@@ -371,6 +358,7 @@ public enum FControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final FControlGameEventHandler fcVisitor = new FControlGameEventHandler(this);
|
||||||
public void attachToGame(GameState game0) {
|
public void attachToGame(GameState game0) {
|
||||||
// TODO: Detach from other game we might be looking at
|
// TODO: Detach from other game we might be looking at
|
||||||
|
|
||||||
@@ -401,7 +389,7 @@ public enum FControl {
|
|||||||
// some observers were set in CMatchUI.initMatch
|
// some observers were set in CMatchUI.initMatch
|
||||||
|
|
||||||
// Listen to DuelOutcome event to show ViewWinLose
|
// Listen to DuelOutcome event to show ViewWinLose
|
||||||
game.subscribeToEvents(this);
|
game.subscribeToEvents(fcVisitor);
|
||||||
|
|
||||||
|
|
||||||
VAntes.SINGLETON_INSTANCE.setModel(game.getRegisteredPlayers());
|
VAntes.SINGLETON_INSTANCE.setModel(game.getRegisteredPlayers());
|
||||||
@@ -416,37 +404,6 @@ public enum FControl {
|
|||||||
SDisplayUtil.showTab(nextField);
|
SDisplayUtil.showTab(nextField);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void receiveGameEvent(final GameEvent ev) {
|
|
||||||
|
|
||||||
if( ev instanceof GameEventDuelFinished ) {
|
|
||||||
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
|
|
||||||
getInputQueue().onGameOver();
|
|
||||||
new ViewWinLose(game.getMatch());
|
|
||||||
SOverlayUtils.showOverlay();
|
|
||||||
} });
|
|
||||||
} else if ( ev instanceof GameEventAnteCardsSelected ) {
|
|
||||||
// Require EDT here?
|
|
||||||
final String nl = System.getProperty("line.separator");
|
|
||||||
final StringBuilder msg = new StringBuilder();
|
|
||||||
for (final Pair<Player, Card> kv : ((GameEventAnteCardsSelected) ev).cards) {
|
|
||||||
msg.append(kv.getKey().getName()).append(" ante: ").append(kv.getValue()).append(nl);
|
|
||||||
}
|
|
||||||
GuiDialog.message(msg.toString(), "Ante");
|
|
||||||
} else if ( ev instanceof GameEventPlayerControl ) {
|
|
||||||
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
|
|
||||||
CMatchUI.SINGLETON_INSTANCE.initHandViews(getLobby().getGuiPlayer());
|
|
||||||
VMatchUI.SINGLETON_INSTANCE.populate();
|
|
||||||
for(VHand h : VMatchUI.SINGLETON_INSTANCE.getHands()) {
|
|
||||||
h.getLayoutControl().updateHand();
|
|
||||||
}
|
|
||||||
} });
|
|
||||||
} else if ( ev instanceof GameEventTurnPhase ) {
|
|
||||||
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
|
|
||||||
Player p = ((GameEventTurnPhase) ev).playerTurn;
|
|
||||||
PhaseType ph = ((GameEventTurnPhase) ev).phase;
|
|
||||||
PhaseUtil.visuallyActivatePhase(p, ph);
|
|
||||||
} });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
84
src/main/java/forge/control/FControlGameEventHandler.java
Normal file
84
src/main/java/forge/control/FControlGameEventHandler.java
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package forge.control;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
|
||||||
|
import forge.Card;
|
||||||
|
import forge.FThreads;
|
||||||
|
import forge.game.event.GameEvent;
|
||||||
|
import forge.game.event.GameEventAnteCardsSelected;
|
||||||
|
import forge.game.event.GameEventDuelFinished;
|
||||||
|
import forge.game.event.GameEventDuelOutcome;
|
||||||
|
import forge.game.event.GameEventPlayerControl;
|
||||||
|
import forge.game.event.GameEventTurnPhase;
|
||||||
|
import forge.game.event.IGameEventVisitor;
|
||||||
|
import forge.game.phase.PhaseUtil;
|
||||||
|
import forge.game.player.Player;
|
||||||
|
import forge.gui.GuiDialog;
|
||||||
|
import forge.gui.SOverlayUtils;
|
||||||
|
import forge.gui.match.CMatchUI;
|
||||||
|
import forge.gui.match.VMatchUI;
|
||||||
|
import forge.gui.match.ViewWinLose;
|
||||||
|
import forge.gui.match.nonsingleton.VHand;
|
||||||
|
|
||||||
|
public class FControlGameEventHandler extends IGameEventVisitor.Base<Void, Void> {
|
||||||
|
public final FControl fc;
|
||||||
|
public FControlGameEventHandler(FControl fc ) {
|
||||||
|
this.fc = fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void receiveGameEvent(final GameEvent ev) { ev.visit(this, null); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(final GameEventTurnPhase ev, Void params) {
|
||||||
|
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
|
||||||
|
PhaseUtil.visuallyActivatePhase(ev.playerTurn, ev.phase);
|
||||||
|
} });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(GameEventAnteCardsSelected ev, Void params) {
|
||||||
|
// Require EDT here?
|
||||||
|
final String nl = System.getProperty("line.separator");
|
||||||
|
final StringBuilder msg = new StringBuilder();
|
||||||
|
for (final Pair<Player, Card> kv : ((GameEventAnteCardsSelected) ev).cards) {
|
||||||
|
msg.append(kv.getKey().getName()).append(" ante: ").append(kv.getValue()).append(nl);
|
||||||
|
}
|
||||||
|
GuiDialog.message(msg.toString(), "Ante");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(GameEventPlayerControl ev, Void params) {
|
||||||
|
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
|
||||||
|
CMatchUI.SINGLETON_INSTANCE.initHandViews(fc.getLobby().getGuiPlayer());
|
||||||
|
VMatchUI.SINGLETON_INSTANCE.populate();
|
||||||
|
for(VHand h : VMatchUI.SINGLETON_INSTANCE.getHands()) {
|
||||||
|
h.getLayoutControl().updateHand();
|
||||||
|
}
|
||||||
|
} });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(GameEventDuelOutcome ev, Void params) {
|
||||||
|
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
|
||||||
|
fc.getInputQueue().onGameOver();
|
||||||
|
} });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(GameEventDuelFinished ev, Void params) {
|
||||||
|
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
|
||||||
|
new ViewWinLose(fc.getObservedGame().getMatch());
|
||||||
|
SOverlayUtils.showOverlay();
|
||||||
|
} });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -62,6 +62,7 @@ import forge.game.ai.ComputerUtilCost;
|
|||||||
import forge.game.event.GameEventCardDestroyed;
|
import forge.game.event.GameEventCardDestroyed;
|
||||||
import forge.game.event.GameEventCardRegenerated;
|
import forge.game.event.GameEventCardRegenerated;
|
||||||
import forge.game.event.GameEventCardSacrificed;
|
import forge.game.event.GameEventCardSacrificed;
|
||||||
|
import forge.game.event.GameEventDuelFinished;
|
||||||
import forge.game.player.GameLossReason;
|
import forge.game.player.GameLossReason;
|
||||||
import forge.game.player.HumanPlay;
|
import forge.game.player.HumanPlay;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -1506,7 +1507,8 @@ public class GameAction {
|
|||||||
first = game.getPhaseHandler().getPlayerTurn(); // needed only for restart
|
first = game.getPhaseHandler().getPlayerTurn(); // needed only for restart
|
||||||
} while( game.getAge() == GameAge.RestartedByKarn );
|
} while( game.getAge() == GameAge.RestartedByKarn );
|
||||||
|
|
||||||
System.out.println(FThreads.prependThreadId("Thread exited game loop due to ... " + ( game.isGameOver() ? "game over" : "interrupt" )));
|
// will pull UI
|
||||||
|
game.fireEvent(new GameEventDuelFinished());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performMulligans(final Player firstPlayer, final boolean isCommander) {
|
private void performMulligans(final Player firstPlayer, final boolean isCommander) {
|
||||||
|
|||||||
@@ -89,9 +89,6 @@ public class MatchState {
|
|||||||
|
|
||||||
// The log shall listen to events and generate text internally
|
// The log shall listen to events and generate text internally
|
||||||
game.fireEvent(new GameEventDuelOutcome(result, gamesPlayedRo));
|
game.fireEvent(new GameEventDuelOutcome(result, gamesPlayedRo));
|
||||||
|
|
||||||
// will pull UI
|
|
||||||
game.fireEvent(new GameEventDuelFinished());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -681,52 +681,11 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
onPhaseBegin();
|
onPhaseBegin();
|
||||||
updateObservers();
|
updateObservers();
|
||||||
// don't even offer priority, because it's untap of 1st turn now
|
// don't even offer priority, because it's untap of 1st turn now
|
||||||
|
givePriorityToPlayer = false;
|
||||||
|
|
||||||
while (!game.isGameOver()) { // loop only while is playing
|
while (!game.isGameOver()) { // loop only while is playing
|
||||||
final Player actingPlayer = this.getPriorityPlayer();
|
|
||||||
final Player firstAction = this.getFirstPriority();
|
|
||||||
|
|
||||||
// actingPlayer is the player who may act
|
boolean givePriority = givePriorityToPlayer ;
|
||||||
// the firstAction is the player who gained Priority First in this segment
|
|
||||||
// of Priority
|
|
||||||
|
|
||||||
Player nextPlayer = game.getNextPlayerAfter(actingPlayer);
|
|
||||||
|
|
||||||
// System.out.println(String.format("%s %s: %s passes priority to %s", playerTurn, phase, actingPlayer, nextPlayer));
|
|
||||||
if (firstAction.equals(nextPlayer)) {
|
|
||||||
if (game.getStack().isEmpty()) {
|
|
||||||
this.setPriority(this.getPlayerTurn()); // this needs to be set early as we exit the phase
|
|
||||||
// end phase
|
|
||||||
this.givePriorityToPlayer = true;
|
|
||||||
|
|
||||||
onPhaseEnd();
|
|
||||||
advanceToNextPhase();
|
|
||||||
onPhaseBegin();
|
|
||||||
} else if (!game.getStack().hasSimultaneousStackEntries()) {
|
|
||||||
game.getStack().resolveStack();
|
|
||||||
game.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// pass the priority to other player
|
|
||||||
this.pPlayerPriority = nextPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateObservers();
|
|
||||||
|
|
||||||
// If ever the karn's ultimate resolved
|
|
||||||
if( game.getAge() == GameAge.RestartedByKarn) {
|
|
||||||
phase = null;
|
|
||||||
game.fireEvent(new GameEventGameRestarted(playerTurn));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Time to handle priority to next player.
|
|
||||||
if ( phase == PhaseType.COMBAT_DECLARE_ATTACKERS || phase == PhaseType.COMBAT_DECLARE_BLOCKERS)
|
|
||||||
game.getStack().freezeStack();
|
|
||||||
|
|
||||||
boolean givePriority = givePriorityToPlayer;
|
|
||||||
|
|
||||||
if ( phase == PhaseType.COMBAT_DECLARE_BLOCKERS)
|
if ( phase == PhaseType.COMBAT_DECLARE_BLOCKERS)
|
||||||
givePriority = game.getCombat().isPlayerAttacked(pPlayerPriority);
|
givePriority = game.getCombat().isPlayerAttacked(pPlayerPriority);
|
||||||
|
|
||||||
@@ -755,6 +714,46 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
System.out.print(" >>\n");
|
System.out.print(" >>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// actingPlayer is the player who may act
|
||||||
|
// the firstAction is the player who gained Priority First in this segment
|
||||||
|
// of Priority
|
||||||
|
|
||||||
|
Player nextPlayer = game.getNextPlayerAfter(this.getPriorityPlayer());
|
||||||
|
|
||||||
|
// System.out.println(String.format("%s %s: %s passes priority to %s", playerTurn, phase, actingPlayer, nextPlayer));
|
||||||
|
if (this.getFirstPriority().equals(nextPlayer)) {
|
||||||
|
if (game.getStack().isEmpty()) {
|
||||||
|
this.setPriority(this.getPlayerTurn()); // this needs to be set early as we exit the phase
|
||||||
|
|
||||||
|
// end phase
|
||||||
|
this.givePriorityToPlayer = true;
|
||||||
|
onPhaseEnd();
|
||||||
|
advanceToNextPhase();
|
||||||
|
onPhaseBegin();
|
||||||
|
} else if (!game.getStack().hasSimultaneousStackEntries()) {
|
||||||
|
game.getStack().resolveStack();
|
||||||
|
game.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// pass the priority to other player
|
||||||
|
this.pPlayerPriority = nextPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateObservers();
|
||||||
|
|
||||||
|
// If ever the karn's ultimate resolved
|
||||||
|
if( game.getAge() == GameAge.RestartedByKarn) {
|
||||||
|
phase = null;
|
||||||
|
game.fireEvent(new GameEventGameRestarted(playerTurn));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Time to handle priority to next player.
|
||||||
|
if ( phase == PhaseType.COMBAT_DECLARE_ATTACKERS || phase == PhaseType.COMBAT_DECLARE_BLOCKERS)
|
||||||
|
game.getStack().freezeStack();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package forge.sound;
|
package forge.sound;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
|
|||||||
Reference in New Issue
Block a user