diff --git a/src/main/java/forge/control/input/InputBlock.java b/src/main/java/forge/control/input/InputBlock.java index ce609e6ae80..60526233b66 100644 --- a/src/main/java/forge/control/input/InputBlock.java +++ b/src/main/java/forge/control/input/InputBlock.java @@ -24,6 +24,7 @@ import java.util.List; import forge.Card; import forge.Singletons; +import forge.control.FControl; import forge.game.GameState; import forge.game.phase.CombatUtil; import forge.game.player.Player; @@ -103,7 +104,7 @@ public class InputBlock extends Input { ButtonUtil.reset(); CombatUtil.orderMultipleCombatants(game.getCombat()); - game.getPhaseHandler().passPriority(); + FControl.SINGLETON_INSTANCE.getPlayer().getController().passPriority(); } } diff --git a/src/main/java/forge/control/input/InputCleanup.java b/src/main/java/forge/control/input/InputCleanup.java index e131fd29771..cf8ba745882 100644 --- a/src/main/java/forge/control/input/InputCleanup.java +++ b/src/main/java/forge/control/input/InputCleanup.java @@ -40,18 +40,15 @@ public class InputCleanup extends Input { /** {@inheritDoc} */ @Override public final void showMessage() { - final Player active = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn(); - if (active.isComputer()) { - this.aiCleanupDiscard(active); - Singletons.getModel().getGame().getPhaseHandler().passPriority(); - return; - } + final Player active = Singletons.getModel().getGame().getPhaseHandler().getPriorityPlayer(); final int n = active.getCardsIn(ZoneType.Hand).size(); final int max = active.getMaxHandSize(); // goes to the next phase if (active.isUnlimitedHandSize() || n <= max || n <= 0) { - Singletons.getModel().getGame().getPhaseHandler().passPriority(); + active.getController().passPriority(); + + return; } ButtonUtil.disableAll(); @@ -81,14 +78,7 @@ public class InputCleanup extends Input { * AI_CleanupDiscard. *
*/ - public void aiCleanupDiscard(final Player ai) { - final int size = ai.getCardsIn(ZoneType.Hand).size(); - if (!ai.isUnlimitedHandSize()) { - final int numDiscards = size - ai.getMaxHandSize(); - ai.discard(numDiscards, null); - } - } /* (non-Javadoc) * @see forge.control.input.Input#isClassUpdated() diff --git a/src/main/java/forge/control/input/InputControl.java b/src/main/java/forge/control/input/InputControl.java index ed77e526e64..83a3def162e 100644 --- a/src/main/java/forge/control/input/InputControl.java +++ b/src/main/java/forge/control/input/InputControl.java @@ -194,6 +194,10 @@ public class InputControl extends MyObservable implements java.io.Serializable { return null; } + if (priority == null) + return null; + PlayerController pc = priority.getController(); + // Special Inputs needed for the following phases: switch (phase) { case COMBAT_DECLARE_ATTACKERS: @@ -208,19 +212,18 @@ public class InputControl extends MyObservable implements java.io.Serializable { stack.freezeStack(); if (game.getCombat().isPlayerAttacked(priority)) { - return priority.getController().getBlockInput(); + return pc.getBlockInput(); } // noone attacks you - handler.passPriority(); + pc.passPriority(); return null; case CLEANUP: // discard if (stack.isEmpty()) { - // resolve things - // like Madness - return new InputCleanup(); + // resolve things like Madness + return pc.getCleanupInput(); } break; default: @@ -230,14 +233,10 @@ public class InputControl extends MyObservable implements java.io.Serializable { // ********************* // Special phases handled above, everything else is handled simply by // priority - if (priority == null) - return null; - - PlayerController pc = priority.getController(); boolean prioritySkip = pc.mayAutoPass(phase) || pc.isUiSetToSkipPhase(playerTurn, phase); if (this.game.getStack().isEmpty() && prioritySkip) { - handler.passPriority(); + pc.passPriority(); return null; } else pc.autoPassCancel(); // probably cancel, since something has happened diff --git a/src/main/java/forge/control/input/InputPassPriority.java b/src/main/java/forge/control/input/InputPassPriority.java index 42d7378cbc8..a54307c934e 100644 --- a/src/main/java/forge/control/input/InputPassPriority.java +++ b/src/main/java/forge/control/input/InputPassPriority.java @@ -20,6 +20,7 @@ package forge.control.input; import forge.Card; import forge.Singletons; import forge.card.spellability.SpellAbility; +import forge.control.FControl; import forge.game.GameState; import forge.game.phase.PhaseType; import forge.game.player.Player; @@ -73,7 +74,7 @@ public class InputPassPriority extends Input { /** {@inheritDoc} */ @Override public final void selectButtonOK() { - Singletons.getModel().getGame().getPhaseHandler().passPriority(); + FControl.SINGLETON_INSTANCE.getPlayer().getController().passPriority(); } /** {@inheritDoc} */ diff --git a/src/main/java/forge/game/GameState.java b/src/main/java/forge/game/GameState.java index 39bc8832398..f8ae8c2acd5 100644 --- a/src/main/java/forge/game/GameState.java +++ b/src/main/java/forge/game/GameState.java @@ -37,6 +37,7 @@ import forge.StaticEffects; import forge.card.replacement.ReplacementHandler; import forge.card.spellability.Ability; import forge.card.spellability.SpellAbility; +import forge.card.spellability.SpellAbilityStackInstance; import forge.card.trigger.TriggerHandler; import forge.card.trigger.TriggerType; import forge.game.phase.Cleanup; @@ -623,4 +624,38 @@ public class GameState { getTriggerHandler().clearSuppression(TriggerType.PlaneswalkedTo); } + + public void archenemy904_10() { + //904.10. If a non-ongoing scheme card is face up in the + //command zone, and it isn't the source of a triggered ability + //that has triggered but not yet left the stack, that scheme card + //is turned face down and put on the bottom of its owner's scheme + //deck the next time a player would receive priority. + //(This is a state-based action. See rule 704.) + + for (int i = 0; i < getCardsIn(ZoneType.Command).size(); i++) { + Card c = getCardsIn(ZoneType.Command).get(i); + if (c.isScheme() && !c.isType("Ongoing")) { + + boolean foundonstack = false; + for (SpellAbilityStackInstance si : getStack().getStack()) { + if (si.getSourceCard().equals(c)) { + + foundonstack = true; + break; + } + } + if (!foundonstack) { + + getTriggerHandler().suppressMode(TriggerType.ChangesZone); + c.getController().getZone(ZoneType.Command).remove(c); + i--; + getTriggerHandler().clearSuppression(TriggerType.ChangesZone); + + c.getController().getSchemeDeck().add(c); + } + } + + } + } } diff --git a/src/main/java/forge/game/ai/AiController.java b/src/main/java/forge/game/ai/AiController.java index 0d6478703d5..a0e6c2b16f6 100644 --- a/src/main/java/forge/game/ai/AiController.java +++ b/src/main/java/forge/game/ai/AiController.java @@ -480,5 +480,14 @@ public class AiController { return p; } }; // Comparator + + public void cleanupDiscard() { + final int size = player.getCardsIn(ZoneType.Hand).size(); + + if (!player.isUnlimitedHandSize()) { + final int numDiscards = size - player.getMaxHandSize(); + player.discard(numDiscards, null); + } + } } diff --git a/src/main/java/forge/game/ai/AiInputCommon.java b/src/main/java/forge/game/ai/AiInputCommon.java index 85e9dfd663b..d38213c784a 100644 --- a/src/main/java/forge/game/ai/AiInputCommon.java +++ b/src/main/java/forge/game/ai/AiInputCommon.java @@ -81,6 +81,10 @@ public class AiInputCommon extends Input { playSpellAbilities(game); } else { switch(phase) { + case CLEANUP: + computer.cleanupDiscard(); + break; + case COMBAT_DECLARE_ATTACKERS: declareAttackers(); break; @@ -95,7 +99,7 @@ public class AiInputCommon extends Input { break; } } - game.getPhaseHandler().passPriority(); + player.getController().passPriority(); } // getMessage(); /** @@ -147,6 +151,7 @@ public class AiInputCommon extends Input { do { sa = computer.getSpellAbilityToPlay(); if ( sa == null ) break; + //System.out.println("Playing sa: " + sa); ComputerUtil.handlePlayingSpellAbility(player, sa, game); } while ( sa != null ); } diff --git a/src/main/java/forge/game/phase/PhaseHandler.java b/src/main/java/forge/game/phase/PhaseHandler.java index afe9d5b6276..97281b57b7a 100644 --- a/src/main/java/forge/game/phase/PhaseHandler.java +++ b/src/main/java/forge/game/phase/PhaseHandler.java @@ -18,17 +18,13 @@ package forge.game.phase; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Stack; import com.esotericsoftware.minlog.Log; import forge.Card; -import forge.CardLists; -import forge.CardPredicates; import forge.Singletons; -import forge.card.spellability.SpellAbilityStackInstance; import forge.card.trigger.TriggerType; import forge.game.GameState; import forge.game.GameType; @@ -464,7 +460,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { case COMBAT_END: //SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc()); game.getCombat().reset(); - this.resetAttackedThisCombat(this.getPlayerTurn()); + this.getPlayerTurn().resetAttackedThisCombat(); this.bCombat = false; break; @@ -704,33 +700,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { return (this.nCombatsThisTurn == 1); } - /** - *- * resetAttackedThisCombat. - *
- * - * @param player - * a {@link forge.game.player.Player} object. - */ - public final void resetAttackedThisCombat(final Player player) { - // resets the status of attacked/blocked this phase - List
* passPriority.
@@ -742,38 +711,8 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
return;
}
- //904.10. If a non-ongoing scheme card is face up in the
- //command zone, and it isn't the source of a triggered ability
- //that has triggered but not yet left the stack, that scheme card
- //is turned face down and put on the bottom of its owner's scheme
- //deck the next time a player would receive priority.
- //(This is a state-based action. See rule 704.)
if(game.getType() == GameType.Archenemy)
- {
- for (int i = 0; i < game.getCardsIn(ZoneType.Command).size(); i++) {
- Card c = game.getCardsIn(ZoneType.Command).get(i);
- if (c.isScheme() && !c.isType("Ongoing")) {
-
- boolean foundonstack = false;
- for (SpellAbilityStackInstance si : game.getStack().getStack()) {
- if (si.getSourceCard().equals(c)) {
-
- foundonstack = true;
- break;
- }
- }
- if (!foundonstack) {
-
- game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
- c.getController().getZone(ZoneType.Command).remove(c);
- i--;
- game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
-
- c.getController().getSchemeDeck().add(c);
- }
- }
- }
- }
+ game.archenemy904_10();
final Player actingPlayer = this.getPriorityPlayer();
final Player firstAction = this.getFirstPriority();
@@ -783,6 +722,8 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
// 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
diff --git a/src/main/java/forge/game/player/AIPlayer.java b/src/main/java/forge/game/player/AIPlayer.java
index 610bdb103bd..20f904f8698 100644
--- a/src/main/java/forge/game/player/AIPlayer.java
+++ b/src/main/java/forge/game/player/AIPlayer.java
@@ -57,10 +57,12 @@ public class AIPlayer extends Player {
* a {@link java.lang.String} object.
*/
public AIPlayer(final LobbyPlayer player, final GameState game) {
- super(player, game, new PlayerController());
+ super(player, game, new PlayerController(game));
brains = new AiController(this, game);
- getController().setDefaultInput(new AiInputCommon(brains));
- getController().setBlockInput(new AiInputBlock(game, this));
+ PlayerController pc = getController();
+ pc.setDefaultInput(new AiInputCommon(brains));
+ pc.setBlockInput(new AiInputBlock(game, this));
+ pc.setCleanupInput(pc.getDefaultInput());
}
diff --git a/src/main/java/forge/game/player/HumanPlayer.java b/src/main/java/forge/game/player/HumanPlayer.java
index ed7e53d1ec4..8e387f3fc0c 100644
--- a/src/main/java/forge/game/player/HumanPlayer.java
+++ b/src/main/java/forge/game/player/HumanPlayer.java
@@ -25,6 +25,7 @@ import forge.Singletons;
import forge.card.spellability.SpellAbility;
import forge.control.input.Input;
import forge.control.input.InputBlock;
+import forge.control.input.InputCleanup;
import forge.control.input.InputPassPriority;
import forge.game.GameType;
import forge.game.GameState;
@@ -53,9 +54,10 @@ public class HumanPlayer extends Player {
* a {@link java.lang.String} object.
*/
public HumanPlayer(final LobbyPlayer player, GameState game) {
- super(player, game, new PlayerController());
+ super(player, game, new PlayerController(game));
getController().setDefaultInput(new InputPassPriority());
getController().setBlockInput(new InputBlock(this));
+ getController().setCleanupInput(new InputCleanup());
}
// //////////////
diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java
index 793df5f4133..8013238ecc6 100644
--- a/src/main/java/forge/game/player/Player.java
+++ b/src/main/java/forge/game/player/Player.java
@@ -1704,10 +1704,8 @@ public abstract class Player extends GameEntity implements Comparable
+ * resetAttackedThisCombat.
+ *