mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
Turn counting removed from GameState (cause phaseHandler already did it)
Inlined some static methods called from phaseHandler PhaseType: index is not a field, yet the order is set by a list initialized statically GetLabelForPhase - moved to VField from PhaseUtil Game has a method to determine the next player who takes turn/priority after the given one.
This commit is contained in:
@@ -70,7 +70,6 @@ public class GameState {
|
||||
private final Zone stackZone = new Zone(ZoneType.Stack);
|
||||
|
||||
private long timestamp = 0;
|
||||
private int nTurn = 0;
|
||||
private final GameAction action;
|
||||
|
||||
/**
|
||||
@@ -269,21 +268,6 @@ public class GameState {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @return
|
||||
*/
|
||||
public int getTurnNumber() {
|
||||
return nTurn;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
*/
|
||||
public void notifyNextTurn() {
|
||||
nTurn++;
|
||||
}
|
||||
|
||||
|
||||
// THESE WERE MOVED HERE FROM AllZoneUtil
|
||||
// They must once become non-static members of this class
|
||||
@@ -441,4 +425,19 @@ public class GameState {
|
||||
public GameAction getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param playerTurn
|
||||
* @return
|
||||
*/
|
||||
public Player getNextPlayerAfter(Player playerTurn) {
|
||||
int iPlayer = roPlayers.indexOf(playerTurn);
|
||||
if( iPlayer == roPlayers.size() - 1)
|
||||
iPlayer = -1;
|
||||
iPlayer++;
|
||||
// should also check that he has not lost yet.
|
||||
return roPlayers.get(iPlayer);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public class MatchController {
|
||||
throw new RuntimeException("Game is not over yet.");
|
||||
|
||||
GameOutcome result = new GameOutcome(reason, game.getPlayers());
|
||||
result.setTurnsPlayed(game.getTurnNumber());
|
||||
result.setTurnsPlayed(game.getPhaseHandler().getTurn());
|
||||
gamesPlayed.add(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
/** Constant <code>serialVersionUID=5207222278370963197L</code>. */
|
||||
private static final long serialVersionUID = 5207222278370963197L;
|
||||
|
||||
private int phaseIndex = 0;
|
||||
private PhaseType phase = PhaseType.UNTAP;
|
||||
private int turn = 1;
|
||||
|
||||
private final Stack<ExtraTurn> extraTurns = new Stack<ExtraTurn>();
|
||||
@@ -286,27 +286,37 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
public final void handleBeginPhase() {
|
||||
this.setPhaseEffects(false);
|
||||
// Handle effects that happen at the beginning of phases
|
||||
final PhaseType phase = this.getPhase();
|
||||
final Player turn = this.getPlayerTurn();
|
||||
this.setSkipPhase(true);
|
||||
game.getAction().checkStateEffects();
|
||||
|
||||
if (this.isAutoPassedPhase(turn, phase)) {
|
||||
if (this.isAutoPassedPhase(this.getPlayerTurn(), this.getPhase())) {
|
||||
this.setAutoPass(false);
|
||||
}
|
||||
|
||||
switch(phase) {
|
||||
switch(this.getPhase()) {
|
||||
case UNTAP:
|
||||
//SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
|
||||
PhaseUtil.handleUntap();
|
||||
PhaseUtil.handleUntap(game);
|
||||
break;
|
||||
|
||||
case UPKEEP:
|
||||
PhaseUtil.handleUpkeep();
|
||||
if (PhaseUtil.skipUpkeep()) {
|
||||
// Slowtrips all say "on the next turn's upkeep" if there is no
|
||||
// upkeep next turn, the trigger will never occur.
|
||||
for( Player p : game.getPlayers() )
|
||||
p.clearSlowtripList();
|
||||
game.getPhaseHandler().setNeedToNextPhase(true);
|
||||
} else {
|
||||
game.getUpkeep().executeUntil(this.getPlayerTurn());
|
||||
game.getUpkeep().executeAt();
|
||||
}
|
||||
break;
|
||||
|
||||
case DRAW:
|
||||
PhaseUtil.handleDraw();
|
||||
if (getTurn() == 1 || PhaseUtil.skipDraw(this.getPlayerTurn()))
|
||||
game.getPhaseHandler().setNeedToNextPhase(true);
|
||||
else
|
||||
this.getPlayerTurn().drawCards(1, true);
|
||||
break;
|
||||
|
||||
case COMBAT_BEGIN:
|
||||
@@ -329,7 +339,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
// we can skip AfterBlockers and AfterAttackers if necessary
|
||||
case COMBAT_DECLARE_BLOCKERS:
|
||||
if (this.inCombat()) {
|
||||
PhaseUtil.verifyCombat();
|
||||
Singletons.getModel().getGame().getCombat().verifyCreaturesInPlay();
|
||||
CombatUtil.showCombat();
|
||||
} else {
|
||||
this.setNeedToNextPhase(true);
|
||||
@@ -340,7 +350,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
// After declare blockers are finished being declared mark them
|
||||
// blocked and trigger blocking things
|
||||
if (this.inCombat()) {
|
||||
PhaseUtil.handleDeclareBlockers();
|
||||
PhaseUtil.handleDeclareBlockers(game);
|
||||
CombatUtil.showCombat();
|
||||
} else {
|
||||
this.setNeedToNextPhase(true);
|
||||
@@ -440,8 +450,8 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
if (!this.isNeedToNextPhase()) {
|
||||
// Run triggers if phase isn't being skipped
|
||||
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||
runParams.put("Phase", phase.Name);
|
||||
runParams.put("Player", turn);
|
||||
runParams.put("Phase", this.getPhase().Name);
|
||||
runParams.put("Player", this.getPlayerTurn());
|
||||
game.getTriggerHandler().runTrigger(TriggerType.Phase, runParams);
|
||||
|
||||
}
|
||||
@@ -450,7 +460,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
game.getStack().unfreezeStack();
|
||||
|
||||
// UNTAP
|
||||
if (phase != PhaseType.UNTAP) {
|
||||
if (this.getPhase() != PhaseType.UNTAP) {
|
||||
// during untap
|
||||
this.resetPriority();
|
||||
}
|
||||
@@ -502,7 +512,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
this.bCombat = false;
|
||||
}
|
||||
|
||||
if (this.phaseIndex == PhaseType.CLEANUP.Index) {
|
||||
if (this.phase == PhaseType.CLEANUP) {
|
||||
this.bPreventCombatDamageThisTurn = false;
|
||||
if (!this.bRepeat) {
|
||||
this.setPlayerTurn(this.handleNextTurn());
|
||||
@@ -526,11 +536,10 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
game.getCombat().reset();
|
||||
game.getCombat().setAttackingPlayer(player);
|
||||
game.getCombat().setDefendingPlayer(opp);
|
||||
this.phaseIndex = PhaseType.COMBAT_DECLARE_ATTACKERS.Index;
|
||||
this.phase = PhaseType.COMBAT_DECLARE_ATTACKERS;
|
||||
} else {
|
||||
if (!this.bRepeat) { // for when Cleanup needs to repeat itself
|
||||
this.phaseIndex++;
|
||||
this.phaseIndex %= PhaseType.values().length;
|
||||
this.phase = phase.getNextPhase();
|
||||
} else {
|
||||
this.bRepeat = false;
|
||||
}
|
||||
@@ -594,7 +603,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
* @return a {@link forge.game.player.Player} object.
|
||||
*/
|
||||
private Player getNextActivePlayer() {
|
||||
Player nextTurn = this.getPlayerTurn().getOpponent();
|
||||
Player nextTurn = game.getNextPlayerAfter(this.getPlayerTurn());
|
||||
if (!this.extraTurns.isEmpty()) {
|
||||
ExtraTurn extraTurn = this.extraTurns.pop();
|
||||
nextTurn = extraTurn.getPlayer();
|
||||
@@ -669,8 +678,8 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
* a {@link java.lang.String} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final synchronized boolean is(final PhaseType phase) {
|
||||
return this.getPhase() == phase;
|
||||
public final synchronized boolean is(final PhaseType phase0) {
|
||||
return this.getPhase() == phase0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -681,7 +690,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public final PhaseType getPhase() {
|
||||
return PhaseType.getByIndex(this.phaseIndex);
|
||||
return phase;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -704,7 +713,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
*/
|
||||
public final Player getNextTurn() {
|
||||
if (this.extraTurns.isEmpty()) {
|
||||
return this.getPlayerTurn().getOpponent();
|
||||
return game.getNextPlayerAfter(this.getPlayerTurn());
|
||||
}
|
||||
|
||||
return this.extraTurns.peek().getPlayer();
|
||||
@@ -736,35 +745,12 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
// use a stack to handle extra turns, make sure the bottom of the stack
|
||||
// restores original turn order
|
||||
if (this.extraTurns.isEmpty()) {
|
||||
this.extraTurns.push(new ExtraTurn(this.getPlayerTurn().getOpponent()));
|
||||
this.extraTurns.push(new ExtraTurn(game.getNextPlayerAfter(this.getPlayerTurn())));
|
||||
}
|
||||
|
||||
return this.extraTurns.push(new ExtraTurn(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* skipTurn.
|
||||
* </p>
|
||||
*
|
||||
* @param player
|
||||
* a {@link forge.game.player.Player} object.
|
||||
*/
|
||||
public final void skipTurn(final Player player) {
|
||||
// skipping turn without having extras is equivalent to giving your
|
||||
// opponent an extra turn
|
||||
boolean skipped = false;
|
||||
for (ExtraTurn turn : this.extraTurns) {
|
||||
if (turn.getPlayer().equals(player)) {
|
||||
this.extraTurns.remove(turn);
|
||||
skipped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!skipped) {
|
||||
this.addExtraTurn(player.getOpponent());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -831,7 +817,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
|
||||
if (firstAction.equals(actingPlayer)) {
|
||||
// pass the priority to other player
|
||||
this.setPriorityPlayer(actingPlayer.getOpponent());
|
||||
this.setPriorityPlayer(game.getNextPlayerAfter(actingPlayer));
|
||||
Singletons.getModel().getMatch().getInput().resetInput();
|
||||
game.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
||||
} else {
|
||||
@@ -929,8 +915,8 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
* @param phase
|
||||
* a {@link java.forge.game.phase.PhaseType} object.
|
||||
*/
|
||||
public final void setDevPhaseState(final PhaseType phase) {
|
||||
this.phaseIndex = phase.Index;
|
||||
public final void setDevPhaseState(final PhaseType phase0) {
|
||||
this.phase = phase0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -938,8 +924,8 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
*
|
||||
* @param phaseID the new phase state
|
||||
*/
|
||||
public final void setPhaseState(final PhaseType phaseID) {
|
||||
this.phaseIndex = phaseID.Index;
|
||||
public final void setPhaseState(final PhaseType phase0) {
|
||||
this.phase = phase0;
|
||||
this.handleBeginPhase();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,57 +1,55 @@
|
||||
package forge.game.phase;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
||||
public enum PhaseType {
|
||||
UNTAP("Untap", 0),
|
||||
UPKEEP("Upkeep", 1),
|
||||
DRAW("Draw", 2),
|
||||
MAIN1("Main1", 3),
|
||||
COMBAT_BEGIN("BeginCombat", 4),
|
||||
COMBAT_DECLARE_ATTACKERS("Declare Attackers", 5),
|
||||
COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY("Declare Attackers - Play Instants and Abilities", 6),
|
||||
COMBAT_DECLARE_BLOCKERS("Declare Blockers", 7),
|
||||
COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY("Declare Blockers - Play Instants and Abilities", 8),
|
||||
COMBAT_FIRST_STRIKE_DAMAGE("First Strike Damage", 9),
|
||||
COMBAT_DAMAGE("Combat Damage", 10),
|
||||
COMBAT_END("EndCombat", 11),
|
||||
MAIN2("Main2", 12),
|
||||
END_OF_TURN("End of Turn", 13),
|
||||
CLEANUP("Cleanup", 14);
|
||||
UNTAP("Untap"),
|
||||
UPKEEP("Upkeep"),
|
||||
DRAW("Draw"),
|
||||
MAIN1("Main1"),
|
||||
COMBAT_BEGIN("BeginCombat"),
|
||||
COMBAT_DECLARE_ATTACKERS("Declare Attackers"),
|
||||
COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY("Declare Attackers - Play Instants and Abilities"),
|
||||
COMBAT_DECLARE_BLOCKERS("Declare Blockers"),
|
||||
COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY("Declare Blockers - Play Instants and Abilities"),
|
||||
COMBAT_FIRST_STRIKE_DAMAGE("First Strike Damage"),
|
||||
COMBAT_DAMAGE("Combat Damage"),
|
||||
COMBAT_END("EndCombat"),
|
||||
MAIN2("Main2"),
|
||||
END_OF_TURN("End of Turn"),
|
||||
CLEANUP("Cleanup");
|
||||
|
||||
public static final List<PhaseType> ALL_PHASES = Collections.unmodifiableList(
|
||||
Arrays.asList(
|
||||
UNTAP, UPKEEP, DRAW, MAIN1,
|
||||
COMBAT_BEGIN, COMBAT_DECLARE_ATTACKERS, COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY,
|
||||
COMBAT_DECLARE_BLOCKERS, COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY,
|
||||
COMBAT_FIRST_STRIKE_DAMAGE, COMBAT_DAMAGE, COMBAT_END,
|
||||
MAIN2, END_OF_TURN, CLEANUP
|
||||
)
|
||||
);
|
||||
|
||||
public final String Name;
|
||||
public final int Index;
|
||||
private PhaseType(String name, int index) {
|
||||
private PhaseType(String name) {
|
||||
Name = name;
|
||||
Index = index;
|
||||
}
|
||||
|
||||
public static PhaseType getByIndex(int idx) {
|
||||
for (PhaseType ph : PhaseType.values()) {
|
||||
|
||||
if (ph.Index == idx) {
|
||||
return ph;
|
||||
}
|
||||
}
|
||||
throw new InvalidParameterException("No PhaseType found with index " + idx);
|
||||
}
|
||||
|
||||
public final boolean isAfter(final PhaseType phase) {
|
||||
return this.Index > phase.Index;
|
||||
return ALL_PHASES.indexOf(this) > ALL_PHASES.indexOf(phase);
|
||||
}
|
||||
|
||||
public final boolean isMain() {
|
||||
return this == MAIN1 || this == MAIN2;
|
||||
}
|
||||
|
||||
|
||||
public final boolean isBefore(final PhaseType phase) {
|
||||
return this.Index < phase.Index;
|
||||
return ALL_PHASES.indexOf(this) < ALL_PHASES.indexOf(phase);
|
||||
}
|
||||
|
||||
public static PhaseType smartValueOf(final String value) {
|
||||
@@ -91,8 +89,10 @@ public enum PhaseType {
|
||||
PhaseType from = PhaseType.smartValueOf(s.substring(0, idxArrow));
|
||||
String sTo = s.substring(idxArrow + 2);
|
||||
PhaseType to = StringUtils.isBlank(sTo) ? PhaseType.CLEANUP : PhaseType.smartValueOf(sTo);
|
||||
for (int i = from.Index; i <= to.Index; i++) {
|
||||
result.add(PhaseType.getByIndex(i));
|
||||
int iFrom = ALL_PHASES.indexOf(from);
|
||||
int iTo = ALL_PHASES.indexOf(to);
|
||||
for (int i = iFrom; i <= iTo; i++) {
|
||||
result.add(ALL_PHASES.get(i));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -101,4 +101,15 @@ public enum PhaseType {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @return
|
||||
*/
|
||||
public PhaseType getNextPhase() {
|
||||
int iNext = ALL_PHASES.indexOf(this) + 1;
|
||||
while ( iNext >= ALL_PHASES.size() )
|
||||
iNext = 0;
|
||||
return ALL_PHASES.get(iNext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,13 @@ import forge.CardLists;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.Singletons;
|
||||
import forge.card.trigger.TriggerType;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.match.CMatchUI;
|
||||
import forge.gui.match.controllers.CMessage;
|
||||
import forge.gui.match.nonsingleton.VField.PhaseLabel;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* PhaseUtil class.
|
||||
@@ -64,7 +64,8 @@ public class PhaseUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Singletons.getModel().getGame().isCardInPlay("Sands of Time") || Singletons.getModel().getGame().isCardInPlay("Stasis")) {
|
||||
if (Singletons.getModel().getGame().isCardInPlay("Sands of Time")
|
||||
|| Singletons.getModel().getGame().isCardInPlay("Stasis")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -81,18 +82,18 @@ public class PhaseUtil {
|
||||
* handleUntap.
|
||||
* </p>
|
||||
*/
|
||||
public static void handleUntap() {
|
||||
final PhaseHandler ph = Singletons.getModel().getGame().getPhaseHandler();
|
||||
public static void handleUntap(GameState game) {
|
||||
final PhaseHandler ph = game.getPhaseHandler();
|
||||
final Player turn = ph.getPlayerTurn();
|
||||
|
||||
Singletons.getModel().getGame().notifyNextTurn();
|
||||
CMessage.SINGLETON_INSTANCE.updateGameInfo(Singletons.getModel().getMatch());
|
||||
|
||||
Singletons.getModel().getGame().getCombat().reset();
|
||||
Singletons.getModel().getGame().getCombat().setAttackingPlayer(turn);
|
||||
Singletons.getModel().getGame().getCombat().setDefendingPlayer(turn.getOpponent());
|
||||
game.getCombat().reset();
|
||||
game.getCombat().setAttackingPlayer(turn);
|
||||
game.getCombat().setDefendingPlayer(turn.getOpponent());
|
||||
|
||||
// Tokens starting game in play now actually suffer from Sum. Sickness again
|
||||
// Tokens starting game in play now actually suffer from Sum. Sickness
|
||||
// again
|
||||
final List<Card> list = turn.getCardsIncludePhasingIn(ZoneType.Battlefield);
|
||||
for (final Card c : list) {
|
||||
if (turn.getTurn() > 0 || !c.isStartsGameInPlay()) {
|
||||
@@ -101,7 +102,7 @@ public class PhaseUtil {
|
||||
}
|
||||
turn.incrementTurn();
|
||||
|
||||
Singletons.getModel().getGame().getAction().resetActivationsPerTurn();
|
||||
game.getAction().resetActivationsPerTurn();
|
||||
|
||||
final List<Card> lands = CardLists.filter(turn.getLandsInPlay(), Presets.UNTAPPED);
|
||||
turn.setNumPowerSurgeLands(lands.size());
|
||||
@@ -110,39 +111,17 @@ public class PhaseUtil {
|
||||
// phase is skipped
|
||||
|
||||
if (PhaseUtil.skipUntap(turn)) {
|
||||
Singletons.getModel().getGame().getPhaseHandler().setNeedToNextPhase(true);
|
||||
game.getPhaseHandler().setNeedToNextPhase(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Singletons.getModel().getGame().getUntap().executeUntil(turn);
|
||||
Singletons.getModel().getGame().getUntap().executeAt();
|
||||
game.getUntap().executeUntil(turn);
|
||||
game.getUntap().executeAt();
|
||||
|
||||
// otherwise land seems to stay tapped when it is really untapped
|
||||
// AllZone.getHumanPlayer().getZone(ZoneType.Battlefield).updateObservers();
|
||||
|
||||
Singletons.getModel().getGame().getPhaseHandler().setNeedToNextPhase(true);
|
||||
}
|
||||
|
||||
// ******* UPKEEP PHASE *****
|
||||
/**
|
||||
* <p>
|
||||
* handleUpkeep.
|
||||
* </p>
|
||||
*/
|
||||
public static void handleUpkeep() {
|
||||
final Player turn = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
|
||||
if (PhaseUtil.skipUpkeep()) {
|
||||
// Slowtrips all say "on the next turn's upkeep" if there is no
|
||||
// upkeep next turn, the trigger will never occur.
|
||||
turn.clearSlowtripList();
|
||||
turn.getOpponent().clearSlowtripList();
|
||||
Singletons.getModel().getGame().getPhaseHandler().setNeedToNextPhase(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Singletons.getModel().getGame().getUpkeep().executeUntil(turn);
|
||||
Singletons.getModel().getGame().getUpkeep().executeAt();
|
||||
game.getPhaseHandler().setNeedToNextPhase(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,23 +145,6 @@ public class PhaseUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ******* DRAW PHASE *****
|
||||
/**
|
||||
* <p>
|
||||
* handleDraw.
|
||||
* </p>
|
||||
*/
|
||||
public static void handleDraw() {
|
||||
final Player playerTurn = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
|
||||
if (PhaseUtil.skipDraw(playerTurn)) {
|
||||
Singletons.getModel().getGame().getPhaseHandler().setNeedToNextPhase(true);
|
||||
return;
|
||||
}
|
||||
|
||||
playerTurn.drawCards(1, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* skipDraw.
|
||||
@@ -192,11 +154,7 @@ public class PhaseUtil {
|
||||
* a {@link forge.game.player.Player} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
private static boolean skipDraw(final Player player) {
|
||||
// starting player skips his draw
|
||||
if (Singletons.getModel().getGame().getPhaseHandler().getTurn() == 1) {
|
||||
return true;
|
||||
}
|
||||
public static boolean skipDraw(final Player player) {
|
||||
|
||||
if (player.hasKeyword("Skip your next draw step.")) {
|
||||
player.removeKeyword("Skip your next draw step.");
|
||||
@@ -212,15 +170,6 @@ public class PhaseUtil {
|
||||
|
||||
// ********* Declare Attackers ***********
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* verifyCombat.
|
||||
* </p>
|
||||
*/
|
||||
public static void verifyCombat() {
|
||||
Singletons.getModel().getGame().getCombat().verifyCreaturesInPlay();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* handleCombatBegin.
|
||||
@@ -259,7 +208,7 @@ public class PhaseUtil {
|
||||
* a {@link forge.game.player.Player} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
private static boolean skipCombat(final Player player) {
|
||||
public static boolean skipCombat(final Player player) {
|
||||
|
||||
if (player.hasKeyword("Skip your next combat phase.")) {
|
||||
return true;
|
||||
@@ -285,9 +234,10 @@ public class PhaseUtil {
|
||||
* </p>
|
||||
*/
|
||||
public static void handleDeclareAttackers() {
|
||||
PhaseUtil.verifyCombat();
|
||||
Singletons.getModel().getGame().getCombat().verifyCreaturesInPlay();
|
||||
|
||||
// Handles removing cards like Mogg Flunkies from combat if group attack didn't occur
|
||||
// Handles removing cards like Mogg Flunkies from combat if group attack
|
||||
// didn't occur
|
||||
final List<Card> filterList = Singletons.getModel().getGame().getCombat().getAttackerList();
|
||||
for (Card c : filterList) {
|
||||
if (c.hasKeyword("CARDNAME can't attack or block alone.") && c.isAttacking()) {
|
||||
@@ -351,26 +301,29 @@ public class PhaseUtil {
|
||||
* <p>
|
||||
* handleDeclareBlockers.
|
||||
* </p>
|
||||
*
|
||||
* @param game
|
||||
*/
|
||||
public static void handleDeclareBlockers() {
|
||||
PhaseUtil.verifyCombat();
|
||||
public static void handleDeclareBlockers(GameState game) {
|
||||
game.getCombat().verifyCreaturesInPlay();
|
||||
|
||||
// Handles removing cards like Mogg Flunkies from combat if group block didn't occur
|
||||
final List<Card> filterList = Singletons.getModel().getGame().getCombat().getAllBlockers();
|
||||
// Handles removing cards like Mogg Flunkies from combat if group block
|
||||
// didn't occur
|
||||
final List<Card> filterList = game.getCombat().getAllBlockers();
|
||||
for (Card c : filterList) {
|
||||
if (c.hasKeyword("CARDNAME can't attack or block alone.") && c.isBlocking()) {
|
||||
if (Singletons.getModel().getGame().getCombat().getAllBlockers().size() < 2) {
|
||||
Singletons.getModel().getGame().getCombat().undoBlockingAssignment(c);
|
||||
if (game.getCombat().getAllBlockers().size() < 2) {
|
||||
game.getCombat().undoBlockingAssignment(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Singletons.getModel().getGame().getStack().freezeStack();
|
||||
game.getStack().freezeStack();
|
||||
|
||||
Singletons.getModel().getGame().getCombat().setUnblocked();
|
||||
game.getCombat().setUnblocked();
|
||||
|
||||
List<Card> list = new ArrayList<Card>();
|
||||
list.addAll(Singletons.getModel().getGame().getCombat().getAllBlockers());
|
||||
list.addAll(game.getCombat().getAllBlockers());
|
||||
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
@@ -379,20 +332,20 @@ public class PhaseUtil {
|
||||
}
|
||||
});
|
||||
|
||||
final List<Card> attList = Singletons.getModel().getGame().getCombat().getAttackerList();
|
||||
final List<Card> attList = game.getCombat().getAttackerList();
|
||||
|
||||
CombatUtil.checkDeclareBlockers(list);
|
||||
|
||||
for (final Card a : attList) {
|
||||
final List<Card> blockList = Singletons.getModel().getGame().getCombat().getBlockers(a);
|
||||
final List<Card> blockList = game.getCombat().getBlockers(a);
|
||||
for (final Card b : blockList) {
|
||||
CombatUtil.checkBlockedAttackers(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
Singletons.getModel().getGame().getStack().unfreezeStack();
|
||||
game.getStack().unfreezeStack();
|
||||
|
||||
Singletons.getModel().getGame().getGameLog().add("Combat", CombatUtil.getCombatBlockForLog(), 1);
|
||||
game.getGameLog().add("Combat", CombatUtil.getCombatBlockForLog(), 1);
|
||||
}
|
||||
|
||||
// ***** Combat Utility **********
|
||||
@@ -415,59 +368,20 @@ public class PhaseUtil {
|
||||
* Retrieves and visually activates phase label for appropriate phase and
|
||||
* player.
|
||||
*
|
||||
* @param s
|
||||
* @param phase
|
||||
*   Phase state
|
||||
*/
|
||||
public static void visuallyActivatePhase(final PhaseType s) {
|
||||
PhaseLabel lbl = null;
|
||||
public static void visuallyActivatePhase(final PhaseType phase) {
|
||||
final Player p = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
final CMatchUI t = CMatchUI.SINGLETON_INSTANCE;
|
||||
final CMatchUI matchUi = CMatchUI.SINGLETON_INSTANCE;
|
||||
|
||||
// Index of field; computer is 1, human is 0
|
||||
int i = p.isComputer() ? 1 : 0;
|
||||
|
||||
switch(s) {
|
||||
case UPKEEP:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblUpkeep();
|
||||
break;
|
||||
case DRAW:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblDraw();
|
||||
break;
|
||||
case MAIN1:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblMain1();
|
||||
break;
|
||||
case COMBAT_BEGIN:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblBeginCombat();
|
||||
break;
|
||||
case COMBAT_DECLARE_ATTACKERS:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblDeclareAttackers();
|
||||
break;
|
||||
case COMBAT_DECLARE_BLOCKERS:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblDeclareBlockers();
|
||||
break;
|
||||
case COMBAT_DAMAGE:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblCombatDamage();
|
||||
break;
|
||||
case COMBAT_FIRST_STRIKE_DAMAGE:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblFirstStrike();
|
||||
break;
|
||||
case COMBAT_END:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblEndCombat();
|
||||
break;
|
||||
case MAIN2:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblMain2();
|
||||
break;
|
||||
case END_OF_TURN:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblEndTurn();
|
||||
break;
|
||||
case CLEANUP:
|
||||
lbl = t.getFieldControls().get(i).getView().getLblCleanup();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
PhaseLabel lbl = matchUi.getFieldControls().get(i).getView().getLabelFor(phase);
|
||||
|
||||
t.resetAllPhaseButtons();
|
||||
matchUi.resetAllPhaseButtons();
|
||||
if (lbl != null)
|
||||
lbl.setActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public enum CMessage implements ICDoc {
|
||||
match.getGameType().toString() + ": Game #"
|
||||
+ (match.getPlayedGames().size() + 1)
|
||||
+ " of " + match.getGamesPerMatch()
|
||||
+ ", turn " + match.getCurrentGame().getTurnNumber());
|
||||
+ ", turn " + match.getCurrentGame().getPhaseHandler().getTurn());
|
||||
}
|
||||
|
||||
/** Flashes animation on input panel if play is currently waiting on input. */
|
||||
|
||||
@@ -35,6 +35,7 @@ import javax.swing.border.MatteBorder;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.mana.ManaPool;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.framework.DragCell;
|
||||
@@ -538,6 +539,37 @@ public class VField implements IVDoc {
|
||||
|
||||
//========== Custom class handling
|
||||
|
||||
public PhaseLabel getLabelFor(final PhaseType s) {
|
||||
switch (s) {
|
||||
case UPKEEP:
|
||||
return this.getLblUpkeep();
|
||||
case DRAW:
|
||||
return this.getLblDraw();
|
||||
case MAIN1:
|
||||
return this.getLblMain1();
|
||||
case COMBAT_BEGIN:
|
||||
return this.getLblBeginCombat();
|
||||
case COMBAT_DECLARE_ATTACKERS:
|
||||
return this.getLblDeclareAttackers();
|
||||
case COMBAT_DECLARE_BLOCKERS:
|
||||
return this.getLblDeclareBlockers();
|
||||
case COMBAT_DAMAGE:
|
||||
return this.getLblCombatDamage();
|
||||
case COMBAT_FIRST_STRIKE_DAMAGE:
|
||||
return this.getLblFirstStrike();
|
||||
case COMBAT_END:
|
||||
return this.getLblEndCombat();
|
||||
case MAIN2:
|
||||
return this.getLblMain2();
|
||||
case END_OF_TURN:
|
||||
return this.getLblEndTurn();
|
||||
case CLEANUP:
|
||||
return this.getLblCleanup();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows phase labels, handles repainting and on/off states. A PhaseLabel
|
||||
* has "skip" and "active" states, meaning "this phase is (not) skipped" and
|
||||
|
||||
Reference in New Issue
Block a user