mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
passPriority is called from PlayerController, to avoid priority being passed by players who don't have it.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
* </p>
|
||||
*/
|
||||
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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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} */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* resetAttackedThisCombat.
|
||||
* </p>
|
||||
*
|
||||
* @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<Card> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
// //////////////
|
||||
|
||||
@@ -1704,10 +1704,8 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
||||
|
||||
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<Player> {
|
||||
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<Player> {
|
||||
game.setActivePlane(currentPlane);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* resetAttackedThisCombat.
|
||||
* </p>
|
||||
*
|
||||
* @param player
|
||||
* a {@link forge.game.player.Player} object.
|
||||
*/
|
||||
public final void resetAttackedThisCombat() {
|
||||
// resets the status of attacked/blocked this phase
|
||||
List<Card> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user