mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28: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/ControlBazaarUI.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/Lobby.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.WindowConstants;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import forge.Card;
|
||||
import forge.FThreads;
|
||||
import forge.Constant.Preferences;
|
||||
import forge.Singletons;
|
||||
import forge.control.KeyboardShortcuts.Shortcut;
|
||||
import forge.control.input.InputQueue;
|
||||
import forge.game.GameState;
|
||||
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.Player;
|
||||
import forge.gui.GuiDialog;
|
||||
import forge.gui.SOverlayUtils;
|
||||
import forge.gui.deckeditor.CDeckEditorUI;
|
||||
import forge.gui.deckeditor.VDeckEditorUI;
|
||||
@@ -64,14 +53,12 @@ import forge.gui.home.CHomeUI;
|
||||
import forge.gui.home.VHomeUI;
|
||||
import forge.gui.match.CMatchUI;
|
||||
import forge.gui.match.VMatchUI;
|
||||
import forge.gui.match.ViewWinLose;
|
||||
import forge.gui.match.controllers.CCombat;
|
||||
import forge.gui.match.controllers.CDock;
|
||||
import forge.gui.match.controllers.CLog;
|
||||
import forge.gui.match.controllers.CMessage;
|
||||
import forge.gui.match.controllers.CStack;
|
||||
import forge.gui.match.nonsingleton.VField;
|
||||
import forge.gui.match.nonsingleton.VHand;
|
||||
import forge.gui.match.views.VAntes;
|
||||
import forge.gui.toolbox.CardFaceSymbols;
|
||||
import forge.gui.toolbox.FSkin;
|
||||
@@ -371,6 +358,7 @@ public enum FControl {
|
||||
}
|
||||
|
||||
|
||||
private final FControlGameEventHandler fcVisitor = new FControlGameEventHandler(this);
|
||||
public void attachToGame(GameState game0) {
|
||||
// TODO: Detach from other game we might be looking at
|
||||
|
||||
@@ -401,7 +389,7 @@ public enum FControl {
|
||||
// some observers were set in CMatchUI.initMatch
|
||||
|
||||
// Listen to DuelOutcome event to show ViewWinLose
|
||||
game.subscribeToEvents(this);
|
||||
game.subscribeToEvents(fcVisitor);
|
||||
|
||||
|
||||
VAntes.SINGLETON_INSTANCE.setModel(game.getRegisteredPlayers());
|
||||
@@ -416,37 +404,6 @@ public enum FControl {
|
||||
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.GameEventCardRegenerated;
|
||||
import forge.game.event.GameEventCardSacrificed;
|
||||
import forge.game.event.GameEventDuelFinished;
|
||||
import forge.game.player.GameLossReason;
|
||||
import forge.game.player.HumanPlay;
|
||||
import forge.game.player.Player;
|
||||
@@ -1506,7 +1507,8 @@ public class GameAction {
|
||||
first = game.getPhaseHandler().getPlayerTurn(); // needed only for restart
|
||||
} 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) {
|
||||
|
||||
@@ -89,9 +89,6 @@ public class MatchState {
|
||||
|
||||
// The log shall listen to events and generate text internally
|
||||
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();
|
||||
updateObservers();
|
||||
// don't even offer priority, because it's untap of 1st turn now
|
||||
givePriorityToPlayer = false;
|
||||
|
||||
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
|
||||
// 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;
|
||||
|
||||
boolean givePriority = givePriorityToPlayer ;
|
||||
if ( phase == PhaseType.COMBAT_DECLARE_BLOCKERS)
|
||||
givePriority = game.getCombat().isPlayerAttacked(pPlayerPriority);
|
||||
|
||||
@@ -755,6 +714,46 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
import forge.Card;
|
||||
import forge.Singletons;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
|
||||
Reference in New Issue
Block a user