Game starts with phase = NULL and turn = 0. This lets us log turn 1 beginning properly.

Some effects may not work during turn 0 (leylines/chancellors) - if they do, convert them to T:Phase Upkeep | Turn$ 1
This commit is contained in:
Maxmtg
2013-05-26 21:36:58 +00:00
parent 3eb9aed797
commit f9f0a77cd9
7 changed files with 85 additions and 102 deletions

View File

@@ -43,14 +43,10 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
private static final long serialVersionUID = 3955194449319994301L;
private final BlockingDeque<Input> inputStack = new LinkedBlockingDeque<Input>();
private final GameState game;
private final InputLockUI inputLock;
public InputQueue(GameState game0) {
game = game0;
public InputQueue() {
inputLock = new InputLockUI(this);
}
@@ -80,17 +76,6 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
return inputStack.isEmpty() ? null : this.inputStack.peek();
}
/**
* <p>
* clearInput.
* </p>
*/
public final void clearInput() {
this.inputStack.clear();
this.updateObservers();
}
/**
* <p>
* resetInput.
@@ -101,16 +86,8 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
*/
final void removeInput(Input inp) {
FThreads.assertExecutedByEdt(false);
Input topMostInput = inputStack.isEmpty() ? null : inputStack.pop();
// StackTraceElement[] trace = Thread.currentThread().getStackTrace();
// System.out.printf("%s > Remove input %s -- called from %s%n", FThreads.isEDT() ? "EDT" : "TRD", topMostInput, trace[2].toString());
// if( trace[2].toString().contains("InputBase.stop"))
// for(StackTraceElement se : trace) {
// System.out.println(se.toString());
// }
if( topMostInput != inp )
throw new RuntimeException("Inputs adding/removal into stack is imbalanced! Check your code again!");
@@ -128,7 +105,7 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
*
* @return a {@link forge.control.input.InputBase} object.
*/
public final Input getActualInput() {
public final Input getActualInput(GameState game) {
GameAge age = game.getAge();
if ( game.isGameOver() )
@@ -142,7 +119,7 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
return inputLock;
final PhaseHandler handler = game.getPhaseHandler();
final PhaseType phase = handler.getPhase();
final Player playerTurn = handler.getPlayerTurn();
final Player priority = handler.getPriorityPlayer();
if (priority == null)
@@ -155,6 +132,7 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
}
// Special Inputs needed for the following phases:
final PhaseType phase = handler.getPhase();
final MagicStack stack = game.getStack();
switch (phase) {
case COMBAT_DECLARE_ATTACKERS:
@@ -168,12 +146,8 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
case COMBAT_DECLARE_BLOCKERS:
stack.freezeStack();
if (game.getCombat().isPlayerAttacked(priority)) {
return pc.getBlockInput();
}
// noone attacks you
return pc.getAutoPassPriorityInput();
boolean isAttacked = game.getCombat().isPlayerAttacked(priority);
return isAttacked ? pc.getBlockInput() : pc.getAutoPassPriorityInput();
case CLEANUP:
// discard

View File

@@ -1476,12 +1476,16 @@ public class GameAction {
public void mulligan(final Player firstPlayer) {
performMulligans(firstPlayer, game.getType() == GameType.Commander);
game.setAge(GameAge.Play);
// THIS CODE WILL WORK WITH PHASE = NULL {
handleLeylinesAndChancellors();
// Run Trigger beginning of the game
final HashMap<String, Object> runParams = new HashMap<String, Object>();
game.getTriggerHandler().runTrigger(TriggerType.NewGame, runParams, false);
game.setAge(GameAge.Play);
game.getInputQueue().clearInput();
// }
game.getPhaseHandler().startFirstTurn(firstPlayer);
}
private void performMulligans(final Player firstPlayer, final boolean isCommander) {

View File

@@ -89,7 +89,7 @@ public class GameState {
private final MatchController match;
private GameAge age = GameAge.BeforeMulligan;
private final InputQueue inputQueue;
private final InputQueue inputQueue = new InputQueue();
/**
* Constructor.
@@ -128,8 +128,6 @@ public class GameState {
endOfTurn = new EndOfTurn(this);
endOfCombat = new EndOfCombat(this);
inputQueue = new InputQueue(this);
if ( match0.getGameType() == GameType.Quest)
events.register(Singletons.getModel().getQuest()); // this one listens to player's mulligans ATM

View File

@@ -132,7 +132,6 @@ public class MatchController {
currentGame.getInputQueue().invokeGameAction(new Runnable() {
@Override
public void run() {
currentGame.getInputQueue().clearInput();
if(currentGame.getType() == GameType.Planechase)
firstPlayer.initPlane();
@@ -266,7 +265,6 @@ public class MatchController {
boolean willPlay = goesFirst.getController().getWillPlayOnFirstTurn(message);
goesFirst = willPlay ? goesFirst : goesFirst.getOpponent();
game.getPhaseHandler().setPlayerTurn(goesFirst);
return goesFirst;
}

View File

@@ -56,9 +56,10 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
/** Constant <code>serialVersionUID=5207222278370963197L</code>. */
private static final long serialVersionUID = 5207222278370963197L;
private PhaseType phase = PhaseType.UNTAP;
private int turn = 1;
// Start turn at 1, since first untap is where we start
// Start turn at 0, since we start even before first untap
private PhaseType phase = null;
private int turn = 0;
private final transient Stack<ExtraTurn> extraTurns = new Stack<ExtraTurn>();
private final transient Map<PhaseType, Stack<PhaseType>> extraPhases = new HashMap<PhaseType, Stack<PhaseType>>();
@@ -232,6 +233,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
p.updateObservers();
}
if( phase != null ) {
switch (this.phase) {
case UNTAP:
this.nCombatsThisTurn = 0;
@@ -247,7 +249,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
break;
case COMBAT_END:
//SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
game.getCombat().reset(playerTurn);
this.getPlayerTurn().resetAttackedThisCombat();
this.bCombat.set(false);
@@ -265,6 +266,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
break;
default: // no action
}
}
String phaseType = "";
if (this.bRepeatCleanup) { // for when Cleanup needs to repeat itself
@@ -283,7 +285,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.phase = nextPhase;
phaseType = "Additional ";
} else {
this.phase = phase.getNextPhase();
this.phase = PhaseType.getNext(phase);
}
}
@@ -712,15 +714,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
// 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
setPlayersPriorityPermission(true);
nextPhase();
// When consecutively skipping phases (like in combat) this section
// pushes through that block
handleBeginPhase();
// it no longer does.
updateObservers();
advancePhase();
} else if (!game.getStack().hasSimultaneousStackEntries()) {
game.getStack().resolveStack();
game.getStack().chooseOrderOfSimultaneousStackEntryAll();
@@ -734,6 +728,26 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
}
public void startFirstTurn(Player goesFirst) {
if(phase != null)
throw new IllegalStateException("Turns already started, call this only once per game");
setPlayerTurn(goesFirst);
advancePhase();
}
private void advancePhase() { // may be called externally only from gameAction after mulligans
this.setPriority(this.getPlayerTurn()); // this needs to be set early as we exit the phase
// end phase
setPlayersPriorityPermission(true);
nextPhase();
// When consecutively skipping phases (like in combat) this section
// pushes through that block
handleBeginPhase();
// it no longer does.
updateObservers();
}
/**
* <p>
* Setter for the field <code>needToNextPhase</code>.

View File

@@ -106,9 +106,9 @@ public enum PhaseType {
* Get the next PhaseType in turn order.
* @return
*/
public PhaseType getNextPhase() {
int iNext = ALL_PHASES.indexOf(this) + 1;
while (iNext >= ALL_PHASES.size()) {
public static PhaseType getNext(PhaseType current) {
int iNext = ALL_PHASES.indexOf(current) + 1;
if (iNext >= ALL_PHASES.size()) {
iNext = 0;
}
return ALL_PHASES.get(iNext);

View File

@@ -43,11 +43,10 @@ public class InputProxy implements Observer {
private AtomicReference<Input> input = new AtomicReference<Input>();
private GameState game = null;
private static final boolean INPUT_DEBUG = false;
private static final boolean DEBUG_INPUT = false;
public void setGame(GameState game0) {
game = game0;
// game.getStack().addObserver(this);
game.getPhaseHandler().addObserver(this);
game.getInputQueue().addObserver(this);
}
@@ -58,18 +57,14 @@ public class InputProxy implements Observer {
FThreads.assertExecutedByEdt(false);
final PhaseHandler ph = game.getPhaseHandler();
final Input nextInput = game.getInputQueue().getActualInput();
final Input nextInput = game.getInputQueue().getActualInput(game);
if(INPUT_DEBUG) {
System.out.print(FThreads.debugGetStackTraceItem(6, true) + " ... ");
System.out.printf("\t%s on %s, \tstack = %s%n", nextInput == null ? "null" : nextInput.getClass().getSimpleName(), ph.debugPrintState(), game.getInputQueue().printInputStack());
}
if(DEBUG_INPUT)
System.out.printf("%s ... \t%s on %s, \tstack = %s%n", FThreads.debugGetStackTraceItem(6, true), nextInput == null ? "null" : nextInput.getClass().getSimpleName(), ph.debugPrintState(), game.getInputQueue().printInputStack());
this.input.set(nextInput);
Runnable showMessage = new Runnable() {
@Override public void run() {
//if(INPUT_DEBUG)
// System.out.printf("%s > showMessage @ %s/%s during %s%n%n", FThreads.debugGetCurrThreadId(), nextInput.getClass().getSimpleName(), getInput().getClass().getSimpleName(), ph.debugPrintState());
getInput().showMessage(game.getInputQueue());
}