mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
PhaseHandler cleanup, solving problems with delayed triggers already added to simultaneous stack but not yet ordered
This commit is contained in:
@@ -5,7 +5,6 @@ import forge.Card;
|
|||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.phase.PhaseType;
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
|
||||||
public class EndTurnEffect extends SpellAbilityEffect {
|
public class EndTurnEffect extends SpellAbilityEffect {
|
||||||
@@ -39,7 +38,7 @@ public class EndTurnEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
// 4) The current phase and/or step ends. The game skips straight to the
|
// 4) The current phase and/or step ends. The game skips straight to the
|
||||||
// cleanup step. The cleanup step happens in its entirety.
|
// cleanup step. The cleanup step happens in its entirety.
|
||||||
game.getPhaseHandler().setPhaseState(PhaseType.CLEANUP);
|
game.getPhaseHandler().endTurnByEffect();
|
||||||
|
|
||||||
// Update observers
|
// Update observers
|
||||||
game.getStack().updateObservers();
|
game.getStack().updateObservers();
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ public class RestartGameEffect extends SpellAbilityEffect {
|
|||||||
trigHandler.clearSuppression(TriggerType.ChangesZone);
|
trigHandler.clearSuppression(TriggerType.ChangesZone);
|
||||||
|
|
||||||
game.setAge(GameAge.RestartedByKarn);
|
game.setAge(GameAge.RestartedByKarn);
|
||||||
game.getPhaseHandler().setPlayerTurn(sa.getActivatingPlayer());
|
// Do not need this because ability will resolve only during that player's turn
|
||||||
|
//game.getPhaseHandler().setPlayerTurn(sa.getActivatingPlayer());
|
||||||
|
|
||||||
// Set turn number?
|
// Set turn number?
|
||||||
|
|
||||||
|
|||||||
@@ -282,4 +282,9 @@ public class SpellAbilityStackInstance {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%s->%s", getSourceCard(), stackDescription);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,8 +96,6 @@ public class InputAttack extends InputSyncronizedBase {
|
|||||||
protected final void onOk() {
|
protected final void onOk() {
|
||||||
// Propaganda costs could have been paid here.
|
// Propaganda costs could have been paid here.
|
||||||
setCurrentDefender(null); // remove highlights
|
setCurrentDefender(null); // remove highlights
|
||||||
game.getPhaseHandler().setCombat(!game.getCombat().getAttackers().isEmpty());
|
|
||||||
|
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1065,6 +1065,7 @@ public class GameAction {
|
|||||||
if (game.getTriggerHandler().runWaitingTriggers()) {
|
if (game.getTriggerHandler().runWaitingTriggers()) {
|
||||||
checkAgain = true;
|
checkAgain = true;
|
||||||
// Place triggers on stack
|
// Place triggers on stack
|
||||||
|
game.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.handleLegendRule()) {
|
if (this.handleLegendRule()) {
|
||||||
@@ -1085,10 +1086,6 @@ public class GameAction {
|
|||||||
// Clear Simultaneous triggers at the end of the game
|
// Clear Simultaneous triggers at the end of the game
|
||||||
game.setGameOver(endGame);
|
game.setGameOver(endGame);
|
||||||
game.getStack().clearSimultaneousStack();
|
game.getStack().clearSimultaneousStack();
|
||||||
if (!refreeze) {
|
|
||||||
game.getStack().unfreezeStack();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!refreeze) {
|
if (!refreeze) {
|
||||||
|
|||||||
@@ -845,11 +845,7 @@ public class AiController {
|
|||||||
// 12/2/10(sol) the decision making here has moved to getAttackers()
|
// 12/2/10(sol) the decision making here has moved to getAttackers()
|
||||||
game.setCombat(new AiAttackController(player, player.getOpponent()).getAttackers());
|
game.setCombat(new AiAttackController(player, player.getOpponent()).getAttackers());
|
||||||
|
|
||||||
final List<Card> att = game.getCombat().getAttackers();
|
for (final Card element : game.getCombat().getAttackers()) {
|
||||||
game.getPhaseHandler().setCombat(!att.isEmpty());
|
|
||||||
|
|
||||||
|
|
||||||
for (final Card element : att) {
|
|
||||||
// tapping of attackers happens after Propaganda is paid for
|
// tapping of attackers happens after Propaganda is paid for
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("Computer just assigned ").append(element.getName()).append(" as an attacker.");
|
sb.append("Computer just assigned ").append(element.getName()).append(" as an attacker.");
|
||||||
|
|||||||
@@ -21,12 +21,8 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.time.StopWatch;
|
import org.apache.commons.lang.time.StopWatch;
|
||||||
|
|
||||||
import com.esotericsoftware.minlog.Log;
|
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.FThreads;
|
import forge.FThreads;
|
||||||
@@ -82,11 +78,11 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
|
|
||||||
private Player pPlayerPriority = null;
|
private Player pPlayerPriority = null;
|
||||||
private Player pFirstPriority = null;
|
private Player pFirstPriority = null;
|
||||||
private AtomicBoolean bCombat = new AtomicBoolean(false);
|
private boolean bCombat = false;
|
||||||
private boolean bRepeatCleanup = false;
|
private boolean bRepeatCleanup = false;
|
||||||
|
|
||||||
/** The need to next phase. */
|
/** The need to next phase. */
|
||||||
private boolean isPlayerPriorityAllowed = false;
|
private boolean givePriorityToPlayer = false;
|
||||||
|
|
||||||
private final transient GameState game;
|
private final transient GameState game;
|
||||||
|
|
||||||
@@ -95,28 +91,12 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
game = game0;
|
game = game0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* isPlayerTurn.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* a {@link forge.game.player.Player} object.
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public final boolean isPlayerTurn(final Player player) {
|
public final boolean isPlayerTurn(final Player player) {
|
||||||
return player.equals(this.playerTurn);
|
return player.equals(this.playerTurn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private final void setPlayerTurn(final Player s) {
|
||||||
* <p>
|
|
||||||
* Setter for the field <code>playerTurn</code>.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param s
|
|
||||||
* a {@link forge.game.player.Player} object.
|
|
||||||
*/
|
|
||||||
public final void setPlayerTurn(final Player s) {
|
|
||||||
this.playerTurn = s;
|
this.playerTurn = s;
|
||||||
this.setPriority(s);
|
this.setPriority(s);
|
||||||
}
|
}
|
||||||
@@ -166,9 +146,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
* a {@link forge.game.player.Player} object.
|
* a {@link forge.game.player.Player} object.
|
||||||
*/
|
*/
|
||||||
public final void setPriority(final Player p) {
|
public final void setPriority(final Player p) {
|
||||||
if (game.getStack() != null) {
|
game.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
||||||
game.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.pFirstPriority = p;
|
this.pFirstPriority = p;
|
||||||
this.pPlayerPriority = p;
|
this.pPlayerPriority = p;
|
||||||
@@ -191,19 +169,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public final boolean inCombat() {
|
public final boolean inCombat() {
|
||||||
return this.bCombat.get();
|
return this.bCombat;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* setCombat.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param b
|
|
||||||
* a boolean.
|
|
||||||
*/
|
|
||||||
public final void setCombat(boolean value) {
|
|
||||||
this.bCombat.set(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -215,18 +181,42 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
this.bRepeatCleanup = true;
|
this.bRepeatCleanup = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void advanceToNextPhase() {
|
||||||
* <p>
|
PhaseType oldPhase = phase;
|
||||||
* nextPhase.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
private final void nextPhase() {
|
|
||||||
this.setPlayersPriorityPermission(true); // PlayerPriorityAllowed = false;
|
|
||||||
|
|
||||||
|
if (this.bRepeatCleanup) { // for when Cleanup needs to repeat itself
|
||||||
|
this.bRepeatCleanup = false;
|
||||||
|
} else {
|
||||||
|
// If the phase that's ending has a stack of additional phases
|
||||||
|
// Take the LIFO one and move to that instead of the normal one
|
||||||
|
if (this.extraPhases.containsKey(phase)) {
|
||||||
|
PhaseType nextPhase = this.extraPhases.get(phase).pop();
|
||||||
|
// If no more additional phases are available, remove it from the map
|
||||||
|
// and let the next add, reput the key
|
||||||
|
if (this.extraPhases.get(phase).isEmpty()) {
|
||||||
|
this.extraPhases.remove(phase);
|
||||||
|
}
|
||||||
|
this.phase = nextPhase;
|
||||||
|
} else {
|
||||||
|
this.phase = PhaseType.getNext(phase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String phaseType = oldPhase == phase ? "Repeat" : phase == PhaseType.getNext(oldPhase) ? "" : "Additional";
|
||||||
|
|
||||||
|
if (this.phase == PhaseType.UNTAP) {
|
||||||
|
this.turn++;
|
||||||
|
game.getGameLog().add(GameEventType.TURN, "Turn " + this.turn + " (" + this.getPlayerTurn() + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
game.getEvents().post(new PhaseEvent(this.getPlayerTurn(), this.getPhase(), phaseType));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onPhaseEnd() {
|
||||||
// If the Stack isn't empty why is nextPhase being called?
|
// If the Stack isn't empty why is nextPhase being called?
|
||||||
if (!game.getStack().isEmpty()) {
|
if (!game.getStack().isEmpty()) {
|
||||||
Log.debug("Phase.nextPhase() is called, but Stack isn't empty.");
|
throw new IllegalStateException("Phase.nextPhase() is called, but Stack isn't empty.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Player p : game.getPlayers()) {
|
for (Player p : game.getPlayers()) {
|
||||||
@@ -240,252 +230,210 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
p.updateObservers();
|
p.updateObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( phase != null ) {
|
switch (this.phase) {
|
||||||
switch (this.phase) {
|
case UNTAP:
|
||||||
|
this.nCombatsThisTurn = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMBAT_DECLARE_ATTACKERS:
|
||||||
|
this.bCombat = !game.getCombat().getAttackers().isEmpty();
|
||||||
|
game.getStack().unfreezeStack();
|
||||||
|
this.nCombatsThisTurn++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMBAT_DECLARE_BLOCKERS:
|
||||||
|
game.getStack().unfreezeStack();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMBAT_END:
|
||||||
|
game.getCombat().reset(playerTurn);
|
||||||
|
this.getPlayerTurn().resetAttackedThisCombat();
|
||||||
|
this.bCombat = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLEANUP:
|
||||||
|
this.bPreventCombatDamageThisTurn = false;
|
||||||
|
if (!this.bRepeatCleanup) {
|
||||||
|
this.setPlayerTurn(this.handleNextTurn());
|
||||||
|
}
|
||||||
|
this.planarDiceRolledthisTurn = 0;
|
||||||
|
// Play the End Turn sound
|
||||||
|
game.getEvents().post(new EndOfTurnEvent());
|
||||||
|
break;
|
||||||
|
default: // no action
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSkippingPhase(PhaseType phase) {
|
||||||
|
switch(phase) {
|
||||||
|
case UPKEEP:
|
||||||
|
return getPlayerTurn().hasKeyword("Skip your upkeep step.");
|
||||||
|
|
||||||
|
case DRAW:
|
||||||
|
return getPlayerTurn().isSkippingDraw() || getTurn() == 1 && game.getPlayers().size() == 2;
|
||||||
|
|
||||||
|
case COMBAT_BEGIN:
|
||||||
|
case COMBAT_DECLARE_ATTACKERS:
|
||||||
|
return playerTurn.isSkippingCombat();
|
||||||
|
|
||||||
|
case COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY:
|
||||||
|
case COMBAT_DECLARE_BLOCKERS:
|
||||||
|
case COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY:
|
||||||
|
case COMBAT_FIRST_STRIKE_DAMAGE:
|
||||||
|
case COMBAT_DAMAGE:
|
||||||
|
return !this.inCombat();
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void onPhaseBegin() {
|
||||||
|
|
||||||
|
if ( isSkippingPhase(phase) ) {
|
||||||
|
givePriorityToPlayer = false;
|
||||||
|
if( phase == PhaseType.COMBAT_DECLARE_ATTACKERS )
|
||||||
|
playerTurn.removeKeyword("Skip your next combat phase.");
|
||||||
|
} else {
|
||||||
|
// Perform turn-based actions
|
||||||
|
switch(this.getPhase()) {
|
||||||
case UNTAP:
|
case UNTAP:
|
||||||
this.nCombatsThisTurn = 0;
|
//SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
|
||||||
|
givePriorityToPlayer = false;
|
||||||
|
|
||||||
|
game.getCombat().reset(playerTurn);
|
||||||
|
|
||||||
|
// Tokens starting game in play should suffer from Sum. Sickness
|
||||||
|
final List<Card> list = playerTurn.getCardsIncludePhasingIn(ZoneType.Battlefield);
|
||||||
|
for (final Card c : list) {
|
||||||
|
if (playerTurn.getTurn() > 0 || !c.isStartsGameInPlay()) {
|
||||||
|
c.setSickness(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
playerTurn.incrementTurn();
|
||||||
|
|
||||||
|
game.getAction().resetActivationsPerTurn();
|
||||||
|
|
||||||
|
final List<Card> lands = CardLists.filter(playerTurn.getLandsInPlay(), Presets.UNTAPPED);
|
||||||
|
playerTurn.setNumPowerSurgeLands(lands.size());
|
||||||
|
|
||||||
|
// anything before this point happens regardless of whether the Untap
|
||||||
|
// phase is skipped
|
||||||
|
|
||||||
|
if (!PhaseUtil.isSkipUntap(playerTurn)) {
|
||||||
|
game.getUntap().executeUntil(playerTurn);
|
||||||
|
game.getUntap().executeAt();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UPKEEP:
|
||||||
|
this.nUpkeepsThisTurn++;
|
||||||
|
game.getUpkeep().executeUntil(this.getPlayerTurn());
|
||||||
|
game.getUpkeep().executeAt();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRAW:
|
||||||
|
this.getPlayerTurn().drawCard();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAIN1:
|
||||||
|
if (this.getPlayerTurn().isArchenemy()) {
|
||||||
|
this.getPlayerTurn().setSchemeInMotion();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMBAT_BEGIN:
|
||||||
|
//PhaseUtil.verifyCombat();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMBAT_DECLARE_ATTACKERS:
|
case COMBAT_DECLARE_ATTACKERS:
|
||||||
game.getStack().unfreezeStack();
|
break;
|
||||||
this.nCombatsThisTurn++;
|
|
||||||
|
case COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY:
|
||||||
|
PhaseUtil.handleDeclareAttackers(game);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMBAT_DECLARE_BLOCKERS:
|
case COMBAT_DECLARE_BLOCKERS:
|
||||||
game.getStack().unfreezeStack();
|
game.getCombat().verifyCreaturesInPlay();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY:
|
||||||
|
PhaseUtil.handleDeclareBlockers(game);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMBAT_FIRST_STRIKE_DAMAGE:
|
||||||
|
game.getCombat().verifyCreaturesInPlay();
|
||||||
|
|
||||||
|
// no first strikers, skip this step
|
||||||
|
if (!game.getCombat().assignCombatDamage(true)) {
|
||||||
|
this.givePriorityToPlayer = false;
|
||||||
|
} else {
|
||||||
|
game.getCombat().dealAssignedDamage();
|
||||||
|
game.getAction().checkStateEffects();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMBAT_DAMAGE:
|
||||||
|
game.getCombat().verifyCreaturesInPlay();
|
||||||
|
|
||||||
|
if (!game.getCombat().assignCombatDamage(false)) {
|
||||||
|
this.givePriorityToPlayer = false;
|
||||||
|
} else {
|
||||||
|
game.getCombat().dealAssignedDamage();
|
||||||
|
game.getAction().checkStateEffects();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMBAT_END:
|
case COMBAT_END:
|
||||||
game.getCombat().reset(playerTurn);
|
// End Combat always happens
|
||||||
this.getPlayerTurn().resetAttackedThisCombat();
|
game.getEndOfCombat().executeUntil();
|
||||||
this.bCombat.set(false);
|
game.getEndOfCombat().executeAt();
|
||||||
|
|
||||||
|
//SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAIN2:
|
||||||
|
//SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case END_OF_TURN:
|
||||||
|
game.getEndOfTurn().executeAt();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLEANUP:
|
case CLEANUP:
|
||||||
this.bPreventCombatDamageThisTurn = false;
|
// Reset Damage received map
|
||||||
if (!this.bRepeatCleanup) {
|
for (final Card c : game.getCardsIn(ZoneType.Battlefield)) {
|
||||||
this.setPlayerTurn(this.handleNextTurn());
|
c.onCleanupPhase(playerTurn);
|
||||||
}
|
}
|
||||||
this.planarDiceRolledthisTurn = 0;
|
|
||||||
// Play the End Turn sound
|
game.getEndOfCombat().executeUntil(); //Repeat here in case Time Stop et. al. ends combat early
|
||||||
game.getEvents().post(new EndOfTurnEvent());
|
game.getEndOfTurn().executeUntil();
|
||||||
|
|
||||||
|
for (Player player : game.getPlayers()) {
|
||||||
|
player.onCleanupPhase();
|
||||||
|
player.getController().autoPassCancel(); // autopass won't wrap to next turn
|
||||||
|
}
|
||||||
|
this.getPlayerTurn().removeKeyword("Skip all combat phases of this turn.");
|
||||||
|
game.getCleanup().executeUntil(this.getNextTurn());
|
||||||
|
this.nUpkeepsThisTurn = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
default: // no action
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
String phaseType = "";
|
if (inCombat()) {
|
||||||
if (this.bRepeatCleanup) { // for when Cleanup needs to repeat itself
|
CombatUtil.showCombat(game);
|
||||||
this.bRepeatCleanup = false;
|
|
||||||
phaseType = "Repeat ";
|
|
||||||
} else {
|
|
||||||
// If the phase that's ending has a stack of additional phases
|
|
||||||
// Take the LIFO one and move to that instead of the normal one
|
|
||||||
if (this.extraPhases.containsKey(phase)) {
|
|
||||||
PhaseType nextPhase = this.extraPhases.get(phase).pop();
|
|
||||||
// If no more additional phases are available, remove it from the map
|
|
||||||
// and let the next add, reput the key
|
|
||||||
if (this.extraPhases.get(phase).isEmpty()) {
|
|
||||||
this.extraPhases.remove(phase);
|
|
||||||
}
|
|
||||||
this.phase = nextPhase;
|
|
||||||
phaseType = "Additional ";
|
|
||||||
} else {
|
|
||||||
this.phase = PhaseType.getNext(phase);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// **** Anything BELOW Here is actually in the next phase. Maybe move
|
|
||||||
// this to handleBeginPhase
|
|
||||||
if (this.phase == PhaseType.UNTAP) {
|
|
||||||
this.turn++;
|
|
||||||
game.getGameLog().add(GameEventType.TURN, "Turn " + this.turn + " (" + this.getPlayerTurn() + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
game.getEvents().post(new PhaseEvent(this.getPlayerTurn(), this.getPhase(), phaseType));
|
|
||||||
}
|
|
||||||
|
|
||||||
private final void handleBeginPhase() {
|
|
||||||
if (null == playerTurn) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle effects that happen at the beginning of phases
|
// Handle effects that happen at the beginning of phases
|
||||||
game.getAction().checkStateEffects();
|
game.getAction().checkStateEffects();
|
||||||
|
|
||||||
|
if (this.givePriorityToPlayer) {
|
||||||
switch(this.getPhase()) {
|
|
||||||
case UNTAP:
|
|
||||||
//SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
|
|
||||||
game.getPhaseHandler().setPlayersPriorityPermission(false);
|
|
||||||
|
|
||||||
game.getCombat().reset(playerTurn);
|
|
||||||
|
|
||||||
// Tokens starting game in play should suffer from Sum. Sickness
|
|
||||||
final List<Card> list = playerTurn.getCardsIncludePhasingIn(ZoneType.Battlefield);
|
|
||||||
for (final Card c : list) {
|
|
||||||
if (playerTurn.getTurn() > 0 || !c.isStartsGameInPlay()) {
|
|
||||||
c.setSickness(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
playerTurn.incrementTurn();
|
|
||||||
|
|
||||||
game.getAction().resetActivationsPerTurn();
|
|
||||||
|
|
||||||
final List<Card> lands = CardLists.filter(playerTurn.getLandsInPlay(), Presets.UNTAPPED);
|
|
||||||
playerTurn.setNumPowerSurgeLands(lands.size());
|
|
||||||
|
|
||||||
// anything before this point happens regardless of whether the Untap
|
|
||||||
// phase is skipped
|
|
||||||
|
|
||||||
if (!PhaseUtil.isSkipUntap(playerTurn)) {
|
|
||||||
game.getUntap().executeUntil(playerTurn);
|
|
||||||
game.getUntap().executeAt();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UPKEEP:
|
|
||||||
if (this.getPlayerTurn().hasKeyword("Skip your upkeep step.")) {
|
|
||||||
this.setPlayersPriorityPermission(false);
|
|
||||||
} else {
|
|
||||||
this.nUpkeepsThisTurn++;
|
|
||||||
game.getUpkeep().executeUntil(this.getPlayerTurn());
|
|
||||||
game.getUpkeep().executeAt();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DRAW:
|
|
||||||
if (getTurn() == 1 || this.getPlayerTurn().isSkippingDraw()) {
|
|
||||||
this.setPlayersPriorityPermission(false);
|
|
||||||
} else {
|
|
||||||
this.getPlayerTurn().drawCard();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAIN1:
|
|
||||||
if (this.getPlayerTurn().isArchenemy()) {
|
|
||||||
this.getPlayerTurn().setSchemeInMotion();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COMBAT_BEGIN:
|
|
||||||
//PhaseUtil.verifyCombat();
|
|
||||||
if (playerTurn.isSkippingCombat()) {
|
|
||||||
this.setPlayersPriorityPermission(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COMBAT_DECLARE_ATTACKERS:
|
|
||||||
if (playerTurn.isSkippingCombat()) {
|
|
||||||
this.setPlayersPriorityPermission(false);
|
|
||||||
playerTurn.removeKeyword("Skip your next combat phase.");
|
|
||||||
} /* else game.getInputQueue().setInput(playerTurn.getController().getAttackInput());*/
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY:
|
|
||||||
if (this.inCombat()) {
|
|
||||||
PhaseUtil.handleDeclareAttackers(game);
|
|
||||||
CombatUtil.showCombat(game);
|
|
||||||
} else {
|
|
||||||
this.setPlayersPriorityPermission(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
// we can skip AfterBlockers and AfterAttackers if necessary
|
|
||||||
case COMBAT_DECLARE_BLOCKERS:
|
|
||||||
if (this.inCombat()) {
|
|
||||||
game.getCombat().verifyCreaturesInPlay();
|
|
||||||
CombatUtil.showCombat(game);
|
|
||||||
} else {
|
|
||||||
this.setPlayersPriorityPermission(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY:
|
|
||||||
// After declare blockers are finished being declared mark them
|
|
||||||
// blocked and trigger blocking things
|
|
||||||
if (this.inCombat()) {
|
|
||||||
PhaseUtil.handleDeclareBlockers(game);
|
|
||||||
CombatUtil.showCombat(game);
|
|
||||||
} else {
|
|
||||||
this.setPlayersPriorityPermission(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COMBAT_FIRST_STRIKE_DAMAGE:
|
|
||||||
if (!this.inCombat()) {
|
|
||||||
this.setPlayersPriorityPermission(false);
|
|
||||||
} else {
|
|
||||||
game.getCombat().verifyCreaturesInPlay();
|
|
||||||
|
|
||||||
// no first strikers, skip this step
|
|
||||||
if (!game.getCombat().assignCombatDamage(true)) {
|
|
||||||
this.setPlayersPriorityPermission(false);
|
|
||||||
} else {
|
|
||||||
game.getCombat().dealAssignedDamage();
|
|
||||||
game.getAction().checkStateEffects();
|
|
||||||
CombatUtil.showCombat(game);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COMBAT_DAMAGE:
|
|
||||||
if (!this.inCombat()) {
|
|
||||||
this.setPlayersPriorityPermission(false);
|
|
||||||
} else {
|
|
||||||
game.getCombat().verifyCreaturesInPlay();
|
|
||||||
|
|
||||||
if (!game.getCombat().assignCombatDamage(false)) {
|
|
||||||
this.setPlayersPriorityPermission(false);
|
|
||||||
} else {
|
|
||||||
game.getCombat().dealAssignedDamage();
|
|
||||||
game.getAction().checkStateEffects();
|
|
||||||
CombatUtil.showCombat(game);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COMBAT_END:
|
|
||||||
// End Combat always happens
|
|
||||||
game.getEndOfCombat().executeUntil();
|
|
||||||
game.getEndOfCombat().executeAt();
|
|
||||||
CombatUtil.showCombat(game);
|
|
||||||
//SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAIN2:
|
|
||||||
CombatUtil.showCombat(game);
|
|
||||||
//SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case END_OF_TURN:
|
|
||||||
game.getEndOfTurn().executeAt();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLEANUP:
|
|
||||||
// Reset Damage received map
|
|
||||||
for (final Card c : game.getCardsIn(ZoneType.Battlefield)) {
|
|
||||||
c.onCleanupPhase(playerTurn);
|
|
||||||
}
|
|
||||||
|
|
||||||
game.getEndOfCombat().executeUntil(); //Repeat here in case Time Stop et. al. ends combat early
|
|
||||||
game.getEndOfTurn().executeUntil();
|
|
||||||
|
|
||||||
for (Player player : game.getPlayers()) {
|
|
||||||
player.onCleanupPhase();
|
|
||||||
player.getController().autoPassCancel(); // autopass won't wrap to next turn
|
|
||||||
}
|
|
||||||
this.getPlayerTurn().removeKeyword("Skip all combat phases of this turn.");
|
|
||||||
game.getCleanup().executeUntil(this.getNextTurn());
|
|
||||||
this.nUpkeepsThisTurn = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isPlayerPriorityAllowed()) {
|
|
||||||
// Run triggers if phase isn't being skipped
|
// Run triggers if phase isn't being skipped
|
||||||
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||||
runParams.put("Phase", this.getPhase().NameForScripts);
|
runParams.put("Phase", this.getPhase().NameForScripts);
|
||||||
@@ -495,7 +443,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
|
|
||||||
// This line fixes Combat Damage triggers not going off when they should
|
// This line fixes Combat Damage triggers not going off when they should
|
||||||
game.getStack().unfreezeStack();
|
game.getStack().unfreezeStack();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -715,8 +662,11 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
|
|
||||||
if(phase != null)
|
if(phase != null)
|
||||||
throw new IllegalStateException("Turns already started, call this only once per game");
|
throw new IllegalStateException("Turns already started, call this only once per game");
|
||||||
|
|
||||||
setPlayerTurn(goesFirst);
|
setPlayerTurn(goesFirst);
|
||||||
advancePhase();
|
advanceToNextPhase();
|
||||||
|
onPhaseBegin();
|
||||||
|
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
|
||||||
|
|
||||||
while (!game.isGameOver()) { // loop only while is playing
|
while (!game.isGameOver()) { // loop only while is playing
|
||||||
@@ -732,18 +682,24 @@ 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));
|
// System.out.println(String.format("%s %s: %s passes priority to %s", playerTurn, phase, actingPlayer, nextPlayer));
|
||||||
if (firstAction.equals(nextPlayer)) {
|
if (firstAction.equals(nextPlayer)) {
|
||||||
if (game.getStack().isEmpty()) {
|
if (game.getStack().isEmpty()) {
|
||||||
advancePhase();
|
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()) {
|
} else if (!game.getStack().hasSimultaneousStackEntries()) {
|
||||||
game.getStack().resolveStack();
|
game.getStack().resolveStack();
|
||||||
game.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
game.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
||||||
updateObservers();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// pass the priority to other player
|
// pass the priority to other player
|
||||||
this.pPlayerPriority = nextPlayer;
|
this.pPlayerPriority = nextPlayer;
|
||||||
updateObservers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateObservers();
|
||||||
|
|
||||||
// If ever the karn's ultimate resolved
|
// If ever the karn's ultimate resolved
|
||||||
if( game.getAge() == GameAge.RestartedByKarn) {
|
if( game.getAge() == GameAge.RestartedByKarn) {
|
||||||
phase = null;
|
phase = null;
|
||||||
@@ -756,16 +712,18 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
if ( phase == PhaseType.COMBAT_DECLARE_ATTACKERS || phase == PhaseType.COMBAT_DECLARE_BLOCKERS)
|
if ( phase == PhaseType.COMBAT_DECLARE_ATTACKERS || phase == PhaseType.COMBAT_DECLARE_BLOCKERS)
|
||||||
game.getStack().freezeStack();
|
game.getStack().freezeStack();
|
||||||
|
|
||||||
boolean givePriority = isPlayerPriorityAllowed;
|
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);
|
||||||
}
|
|
||||||
if ( phase == PhaseType.COMBAT_DECLARE_ATTACKERS && playerTurn != pPlayerPriority )
|
if ( phase == PhaseType.COMBAT_DECLARE_ATTACKERS && playerTurn != pPlayerPriority )
|
||||||
givePriority = false;
|
givePriority = false;
|
||||||
|
|
||||||
if( DEBUG_PHASES )
|
if( DEBUG_PHASES ) {
|
||||||
|
System.out.println("\t\tStack: " + game.getStack());
|
||||||
System.out.print(FThreads.prependThreadId(debugPrintState(givePriority)));
|
System.out.print(FThreads.prependThreadId(debugPrintState(givePriority)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if( givePriority ) {
|
if( givePriority ) {
|
||||||
@@ -776,66 +734,24 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
|
|
||||||
if( DEBUG_PHASES ) {
|
if( DEBUG_PHASES ) {
|
||||||
sw.stop();
|
sw.stop();
|
||||||
System.out.print("... passed in " + sw.getTime()/1000f + " ms\n");
|
System.out.print("... passed in " + sw.getTime()/1000f + " s\n");
|
||||||
|
System.out.println("\t\tStack: " + game.getStack());
|
||||||
sw.reset();
|
sw.reset();
|
||||||
}
|
}
|
||||||
} else if( DEBUG_PHASES ){
|
} else if( DEBUG_PHASES ){
|
||||||
System.out.print(" >>\n");
|
System.out.print(" >>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void advancePhase() { // may be called externally only from gameAction after mulligans
|
// this is a hack for the setup game state mode, do not use outside of devSetupGameState code
|
||||||
|
// as it avoids calling any of the phase effects that may be necessary in a less enforced context
|
||||||
this.setPriority(this.getPlayerTurn()); // this needs to be set early as we exit the phase
|
public final void devModeSet(final PhaseType phase0, final Player player0) {
|
||||||
// end phase
|
if (null != phase0) this.phase = phase0;
|
||||||
setPlayersPriorityPermission(true);
|
if (null != player0 )
|
||||||
nextPhase();
|
setPlayerTurn(player0);
|
||||||
// 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>.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param needToNextPhase
|
|
||||||
* a boolean.
|
|
||||||
*/
|
|
||||||
public final void setPlayersPriorityPermission(final boolean mayHavePriority) {
|
|
||||||
this.isPlayerPriorityAllowed = mayHavePriority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* isNeedToNextPhase.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public final boolean isPlayerPriorityAllowed() {
|
|
||||||
return this.isPlayerPriorityAllowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is a hack for the setup game state mode, do not use outside of
|
|
||||||
// devSetupGameState code
|
|
||||||
// as it avoids calling any of the phase effects that may be necessary in a
|
|
||||||
// less enforced context
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* setDevPhaseState.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param phase
|
|
||||||
* a {@link java.forge.game.phase.PhaseType} object.
|
|
||||||
*/
|
|
||||||
public final void setDevPhaseState(final PhaseType phase0) {
|
|
||||||
this.phase = phase0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -843,18 +759,12 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
*
|
*
|
||||||
* @param phaseID the new phase state
|
* @param phaseID the new phase state
|
||||||
*/
|
*/
|
||||||
public final void setPhaseState(final PhaseType phase0) {
|
public final void endTurnByEffect() {
|
||||||
this.phase = phase0;
|
this.phase = PhaseType.CLEANUP;
|
||||||
this.handleBeginPhase();
|
this.onPhaseBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* TODO Write javadoc for this method.
|
|
||||||
*
|
|
||||||
* @param b
|
|
||||||
* a boolean
|
|
||||||
*/
|
|
||||||
public final void setPreventCombatDamageThisTurn(final boolean b) {
|
public final void setPreventCombatDamageThisTurn(final boolean b) {
|
||||||
this.bPreventCombatDamageThisTurn = true;
|
this.bPreventCombatDamageThisTurn = true;
|
||||||
}
|
}
|
||||||
@@ -876,4 +786,10 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// just to avoid exposing variable to oute classes
|
||||||
|
public void onStackResolved() {
|
||||||
|
givePriorityToPlayer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,9 +101,8 @@ public class PhaseUtil {
|
|||||||
// TODO move propaganda to happen as the Attacker is Declared
|
// TODO move propaganda to happen as the Attacker is Declared
|
||||||
// Remove illegal Propaganda attacks first only for attacking the Player
|
// Remove illegal Propaganda attacks first only for attacking the Player
|
||||||
|
|
||||||
final int size = list.size();
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (final Card c : list) {
|
||||||
final Card c = list.get(i);
|
|
||||||
CombatUtil.checkPropagandaEffects(game, c);
|
CombatUtil.checkPropagandaEffects(game, c);
|
||||||
}
|
}
|
||||||
PhaseUtil.handleAttackingTriggers(game);
|
PhaseUtil.handleAttackingTriggers(game);
|
||||||
|
|||||||
@@ -198,15 +198,16 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
*/
|
*/
|
||||||
public final void unfreezeStack() {
|
public final void unfreezeStack() {
|
||||||
this.frozen = false;
|
this.frozen = false;
|
||||||
boolean checkState = !this.getFrozenStack().isEmpty();
|
|
||||||
// Add all Frozen Abilities onto the stack
|
// Add all Frozen Abilities onto the stack
|
||||||
while (!this.getFrozenStack().isEmpty()) {
|
while (!this.getFrozenStack().isEmpty()) {
|
||||||
final SpellAbility sa = this.getFrozenStack().pop().getSpellAbility();
|
final SpellAbility sa = this.getFrozenStack().pop().getSpellAbility();
|
||||||
this.add(sa);
|
this.add(sa);
|
||||||
}
|
}
|
||||||
// Add all waiting triggers onto the stack
|
// Add all waiting triggers onto the stack
|
||||||
checkState |= game.getTriggerHandler().runWaitingTriggers();
|
game.getTriggerHandler().runWaitingTriggers();
|
||||||
if (checkState) {
|
|
||||||
|
if (!simultaneousStackEntryList.isEmpty()) {
|
||||||
this.chooseOrderOfSimultaneousStackEntryAll();
|
this.chooseOrderOfSimultaneousStackEntryAll();
|
||||||
game.getAction().checkStateEffects();
|
game.getAction().checkStateEffects();
|
||||||
}
|
}
|
||||||
@@ -738,7 +739,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
|
|
||||||
game.getAction().checkStateEffects();
|
game.getAction().checkStateEffects();
|
||||||
|
|
||||||
game.getPhaseHandler().setPlayersPriorityPermission(true);
|
game.getPhaseHandler().onStackResolved();
|
||||||
|
|
||||||
this.curResolvingCard = null;
|
this.curResolvingCard = null;
|
||||||
|
|
||||||
@@ -1108,4 +1109,10 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
public void clear() {
|
public void clear() {
|
||||||
stack.clear();
|
stack.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%s==%s==%s", simultaneousStackEntryList, frozenStack.toString(), stack.toString());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import forge.control.input.InputSelectCardsFromList;
|
|||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.GameType;
|
import forge.game.GameType;
|
||||||
import forge.game.PlanarDice;
|
import forge.game.PlanarDice;
|
||||||
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.HumanPlay;
|
import forge.game.player.HumanPlay;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.PlayerZone;
|
import forge.game.zone.PlayerZone;
|
||||||
@@ -146,15 +147,10 @@ public final class GuiDisplayUtil {
|
|||||||
final Player human = game.getPlayers().get(0);
|
final Player human = game.getPlayers().get(0);
|
||||||
final Player ai = game.getPlayers().get(1);
|
final Player ai = game.getPlayers().get(1);
|
||||||
|
|
||||||
if (tChangePlayer.equals("human")) {
|
Player newPlayerTurn = tChangePlayer.equals("human") ? newPlayerTurn = human : tChangePlayer.equals("ai") ? newPlayerTurn = ai : null;
|
||||||
game.getPhaseHandler().setPlayerTurn(human);
|
PhaseType newPhase = tChangePhase.trim().equalsIgnoreCase("none") ? null : PhaseType.smartValueOf(tChangePhase);
|
||||||
} else if (tChangePlayer.equals("ai")) {
|
|
||||||
game.getPhaseHandler().setPlayerTurn(ai);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tChangePhase.trim().equalsIgnoreCase("none")) {
|
game.getPhaseHandler().devModeSet(newPhase, newPlayerTurn);
|
||||||
game.getPhaseHandler().setDevPhaseState(forge.game.phase.PhaseType.smartValueOf(tChangePhase));
|
|
||||||
}
|
|
||||||
|
|
||||||
game.getCombat().reset(game.getPhaseHandler().getPlayerTurn());
|
game.getCombat().reset(game.getPhaseHandler().getPlayerTurn());
|
||||||
game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
|
game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
|
||||||
|
|||||||
Reference in New Issue
Block a user