From 278e44667e110f742bc0768fadfcafb18a30c5ac Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Fri, 25 Jan 2013 23:42:49 +0000 Subject: [PATCH] passPriority is called from PlayerController, to avoid priority being passed by players who don't have it. --- .../java/forge/control/input/InputBlock.java | 3 +- .../forge/control/input/InputCleanup.java | 18 ++--- .../forge/control/input/InputControl.java | 19 +++--- .../control/input/InputPassPriority.java | 3 +- src/main/java/forge/game/GameState.java | 35 ++++++++++ src/main/java/forge/game/ai/AiController.java | 9 +++ .../java/forge/game/ai/AiInputCommon.java | 7 +- .../java/forge/game/phase/PhaseHandler.java | 67 ++----------------- src/main/java/forge/game/player/AIPlayer.java | 8 ++- .../java/forge/game/player/HumanPlayer.java | 4 +- src/main/java/forge/game/player/Player.java | 35 ++++++++-- .../forge/game/player/PlayerController.java | 35 +++++++++- 12 files changed, 143 insertions(+), 100 deletions(-) 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 list = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES); - - for (int i = 0; i < list.size(); i++) { - final Card c = list.get(i); - if (c.getDamageHistory().getCreatureAttackedThisCombat()) { - c.getDamageHistory().setCreatureAttackedThisCombat(false); - } - if (c.getDamageHistory().getCreatureBlockedThisCombat()) { - c.getDamageHistory().setCreatureBlockedThisCombat(false); - } - - if (c.getDamageHistory().getCreatureGotBlockedThisCombat()) { - c.getDamageHistory().setCreatureGotBlockedThisCombat(false); - } - } - } - /** *

* 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 { game.getAction().discardMadness(c, this); - boolean hasPutIntoPlayInsteadOfDiscard = c.hasKeyword("If a spell or ability an opponent controls causes you " - + "to discard CARDNAME, put it onto the battlefield instead of putting it into your graveyard."); - boolean hasPutIntoPlayWith2xP1P1InsteadOfDiscard = c.hasKeyword("If a spell or ability an opponent controls causes you to discard CARDNAME, " - + "put it onto the battlefield with two +1/+1 counters on it instead of putting it into your graveyard."); + boolean hasPutIntoPlayInsteadOfDiscard = c.hasKeyword("If a spell or ability an opponent controls causes you to discard CARDNAME, put it onto the battlefield instead of putting it into your graveyard."); + boolean hasPutIntoPlayWith2xP1P1InsteadOfDiscard = c.hasKeyword("If a spell or ability an opponent controls causes you to discard CARDNAME, put it onto the battlefield with two +1/+1 counters on it instead of putting it into your graveyard."); if ((hasPutIntoPlayInsteadOfDiscard || hasPutIntoPlayWith2xP1P1InsteadOfDiscard) && null != sa && sa.getSourceCard().getController().isHostileTo(c.getController())) { @@ -1722,7 +1720,7 @@ public abstract class Player extends GameEntity implements Comparable { game.getAction().moveToGraveyard(c); // Play the Discard sound - Singletons.getModel().getGame().getEvents().post(new CardDiscardedEvent()); + game.getEvents().post(new CardDiscardedEvent()); } // Run triggers @@ -3245,4 +3243,31 @@ public abstract class Player extends GameEntity implements Comparable { game.setActivePlane(currentPlane); } + /** + *

+ * resetAttackedThisCombat. + *

+ * + * @param player + * a {@link forge.game.player.Player} object. + */ + public final void resetAttackedThisCombat() { + // resets the status of attacked/blocked this phase + List list = CardLists.filter(getCardsIn(ZoneType.Battlefield), Presets.CREATURES); + + for (int i = 0; i < list.size(); i++) { + final Card c = list.get(i); + if (c.getDamageHistory().getCreatureAttackedThisCombat()) { + c.getDamageHistory().setCreatureAttackedThisCombat(false); + } + if (c.getDamageHistory().getCreatureBlockedThisCombat()) { + c.getDamageHistory().setCreatureBlockedThisCombat(false); + } + + if (c.getDamageHistory().getCreatureGotBlockedThisCombat()) { + c.getDamageHistory().setCreatureGotBlockedThisCombat(false); + } + } + } + } diff --git a/src/main/java/forge/game/player/PlayerController.java b/src/main/java/forge/game/player/PlayerController.java index 8e86f8135e6..0d712aa7b7c 100644 --- a/src/main/java/forge/game/player/PlayerController.java +++ b/src/main/java/forge/game/player/PlayerController.java @@ -5,6 +5,8 @@ import java.util.List; import forge.Singletons; import forge.card.spellability.SpellAbility; import forge.control.input.Input; +import forge.game.GameState; +import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.gui.GuiChoose; import forge.gui.match.CMatchUI; @@ -25,12 +27,18 @@ public class PlayerController { private Input defaultInput; private Input blockInput; + private Input cleanupInput; + + private final GameState game; + public final Input getDefaultInput() { return defaultInput; } - public PlayerController() {} + public PlayerController(GameState game0) { + game = game0; + } void setPlayer(Player p) { player = p; } @@ -62,6 +70,12 @@ public class PlayerController { defaultInput = input; } + + void setCleanupInput(Input input) { + // TODO Auto-generated method stub + cleanupInput = input; + } + /** * Uses GUI to learn which spell the player (human in our case) would like to play */ @@ -84,4 +98,23 @@ public class PlayerController { this.blockInput = blockInput0; } + /** + * TODO: Write javadoc for this method. + */ + public void passPriority() { + PhaseHandler handler = game.getPhaseHandler(); + // may pass only priority is has + if ( handler.getPriorityPlayer() == player ) + game.getPhaseHandler().passPriority(); + } + + /** + * @return the cleanupInput + */ + public Input getCleanupInput() { + return cleanupInput; + } + + + }