mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Added another class to indicate auto-pass of priority and keep the passPriority call in right thread (that is non-edt)
InputBase has player field and that passPriority method,
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -13820,6 +13820,7 @@ src/main/java/forge/control/bazaar/ControlStall.java -text
|
||||
src/main/java/forge/control/bazaar/package-info.java svneol=native#text/plain
|
||||
src/main/java/forge/control/input/Input.java -text
|
||||
src/main/java/forge/control/input/InputAttack.java svneol=native#text/plain
|
||||
src/main/java/forge/control/input/InputAutoPassPriority.java -text
|
||||
src/main/java/forge/control/input/InputBase.java svneol=native#text/plain
|
||||
src/main/java/forge/control/input/InputBlock.java svneol=native#text/plain
|
||||
src/main/java/forge/control/input/InputCleanup.java svneol=native#text/plain
|
||||
|
||||
@@ -124,4 +124,8 @@ public class FThreads {
|
||||
getScheduledPool().schedule(inputUpdater, milliseconds, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public static String debugGetCurrThreadId() {
|
||||
return isEDT() ? "EDT" : Long.toString(Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ public class CostPartMana extends CostPart {
|
||||
}
|
||||
if (this.getAmountOfX() > 0) {
|
||||
source.setXManaCostPaid(0);
|
||||
InputPayment inpPayment = new InputPayManaX(game, ability, this.getAmountOfX(), this.canXbe0());
|
||||
InputPayment inpPayment = new InputPayManaX(ability, this.getAmountOfX(), this.canXbe0());
|
||||
FThreads.setInputAndWait(inpPayment);
|
||||
if(!inpPayment.isPaid())
|
||||
return false;
|
||||
|
||||
@@ -23,83 +23,21 @@ import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.FThreads;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.InputPayment;
|
||||
import forge.control.input.InputSelectCards;
|
||||
import forge.control.input.InputSelectCardsFromList;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.view.ButtonUtil;
|
||||
|
||||
/**
|
||||
* The Class CostTapType.
|
||||
*/
|
||||
public class CostTapType extends CostPartWithList {
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public static final class InputPayCostTapType extends InputPayCostBase {
|
||||
private final CostTapType tapType;
|
||||
private final int nCards;
|
||||
private final List<Card> cardList;
|
||||
private static final long serialVersionUID = 6438988130447851042L;
|
||||
private int nTapped = 0;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
* @param sa
|
||||
* @param tapType
|
||||
* @param nCards
|
||||
* @param cardList
|
||||
* @param payment
|
||||
*/
|
||||
public InputPayCostTapType(CostTapType tapType, int nCards, List<Card> cardList) {
|
||||
this.tapType = tapType;
|
||||
this.nCards = nCards;
|
||||
this.cardList = cardList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessage() {
|
||||
|
||||
final int left = nCards - this.nTapped;
|
||||
showMessage("Select a " + tapType.getDescription() + " to tap (" + left + " left)");
|
||||
ButtonUtil.enableOnlyCancel();
|
||||
if (nCards == 0) {
|
||||
this.done();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void selectCard(final Card card) {
|
||||
Zone zone = Singletons.getModel().getGame().getZoneOf(card);
|
||||
if (zone.is(ZoneType.Battlefield) && cardList.contains(card) && card.isUntapped()) {
|
||||
// send in List<Card> for Typing
|
||||
tapType.executePayment(null, card);
|
||||
cardList.remove(card);
|
||||
|
||||
this.nTapped++;
|
||||
|
||||
if (this.nTapped == nCards) {
|
||||
this.done();
|
||||
} else if (cardList.size() == 0) {
|
||||
// happen
|
||||
this.cancel();
|
||||
} else {
|
||||
this.showMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final boolean canTapSource;
|
||||
|
||||
/**
|
||||
@@ -214,9 +152,15 @@ public class CostTapType extends CostPartWithList {
|
||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
||||
}
|
||||
}
|
||||
InputPayment inp = new InputPayCostTapType(this, c, typeList);
|
||||
|
||||
|
||||
InputSelectCards inp = new InputSelectCardsFromList(c, c, typeList);
|
||||
inp.setMessage("Select a " + getDescription() + " to tap (%d left)");
|
||||
FThreads.setInputAndWait(inp);
|
||||
return inp.isPaid();
|
||||
if ( inp.hasCancelled() )
|
||||
return false;
|
||||
|
||||
return executePayment(ability, inp.getSelected());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package forge.card.cost;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.control.input.InputPayment;
|
||||
import forge.control.input.InputSyncronizedBase;
|
||||
|
||||
@@ -8,6 +9,14 @@ import forge.control.input.InputSyncronizedBase;
|
||||
*
|
||||
*/
|
||||
abstract class InputPayCostBase extends InputSyncronizedBase implements InputPayment {
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
* @param player
|
||||
*/
|
||||
public InputPayCostBase() {
|
||||
super(Singletons.getControl().getPlayer());
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -2967434867139585579L;
|
||||
boolean bPaid = false;
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ public class TargetSelection {
|
||||
* @param mandatory
|
||||
*/
|
||||
public InputSelectTargets(TargetSelection select, List<Card> choices, ArrayList<Object> alreadyTargeted, boolean targeted, Target tgt, SpellAbility sa, boolean mandatory) {
|
||||
super(sa.getActivatingPlayer());
|
||||
this.select = select;
|
||||
this.choices = choices;
|
||||
this.alreadyTargeted = alreadyTargeted;
|
||||
|
||||
@@ -47,8 +47,9 @@ public class InputAttack extends InputBase {
|
||||
private static final long serialVersionUID = 7849903731842214245L;
|
||||
|
||||
private final GameState game;
|
||||
public InputAttack(GameState game0) {
|
||||
game = game0;
|
||||
public InputAttack(Player human) {
|
||||
super(human);
|
||||
game = human.getGame();
|
||||
}
|
||||
|
||||
|
||||
|
||||
21
src/main/java/forge/control/input/InputAutoPassPriority.java
Normal file
21
src/main/java/forge/control/input/InputAutoPassPriority.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package forge.control.input;
|
||||
|
||||
import forge.game.player.Player;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public class InputAutoPassPriority extends InputBase {
|
||||
private static final long serialVersionUID = -7520803307255234647L;
|
||||
|
||||
public InputAutoPassPriority(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessage() {
|
||||
passPriority();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
package forge.control.input;
|
||||
|
||||
import forge.Card;
|
||||
import forge.FThreads;
|
||||
import forge.Singletons;
|
||||
import forge.game.player.Player;
|
||||
import forge.gui.match.CMatchUI;
|
||||
@@ -33,6 +34,10 @@ import forge.gui.match.CMatchUI;
|
||||
public abstract class InputBase implements java.io.Serializable, Input {
|
||||
/** Constant <code>serialVersionUID=-6539552513871194081L</code>. */
|
||||
private static final long serialVersionUID = -6539552513871194081L;
|
||||
protected final Player player;
|
||||
public InputBase(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
// showMessage() is always the first method called
|
||||
@Override
|
||||
@@ -64,4 +69,18 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
||||
}
|
||||
|
||||
protected void afterStop() { }
|
||||
|
||||
|
||||
|
||||
protected void passPriority() {
|
||||
final Runnable pass = new Runnable() {
|
||||
@Override public void run() {
|
||||
player.getController().passPriority();
|
||||
}
|
||||
};
|
||||
if( FThreads.isEDT() )
|
||||
FThreads.invokeInNewThread(pass, true);
|
||||
else
|
||||
pass.run();
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,6 @@ 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;
|
||||
@@ -48,14 +47,13 @@ public class InputBlock extends InputBase {
|
||||
|
||||
private Card currentAttacker = null;
|
||||
private final HashMap<Card, List<Card>> allBlocking = new HashMap<Card, List<Card>>();
|
||||
private final Player defender;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
* @param priority
|
||||
*/
|
||||
public InputBlock(Player priority) {
|
||||
defender = priority;
|
||||
public InputBlock(Player human) {
|
||||
super(human);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,14 +96,14 @@ public class InputBlock extends InputBase {
|
||||
@Override
|
||||
public final void selectButtonOK() {
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
if (CombatUtil.finishedMandatoryBlocks(game.getCombat(), defender)) {
|
||||
if (CombatUtil.finishedMandatoryBlocks(game.getCombat(), player)) {
|
||||
// Done blocking
|
||||
ButtonUtil.reset();
|
||||
CombatUtil.orderMultipleCombatants(game.getCombat());
|
||||
currentAttacker = null;
|
||||
allBlocking.clear();
|
||||
|
||||
FControl.SINGLETON_INSTANCE.getPlayer().getController().passPriority();
|
||||
passPriority();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,8 +119,8 @@ public class InputBlock extends InputBase {
|
||||
} else {
|
||||
Zone zone = Singletons.getModel().getGame().getZoneOf(card);
|
||||
// Make sure this card is valid to even be a blocker
|
||||
if (this.currentAttacker != null && card.isCreature() && card.getController().equals(defender)
|
||||
&& zone.is(ZoneType.Battlefield, defender)) {
|
||||
if (this.currentAttacker != null && card.isCreature() && card.getController().equals(player)
|
||||
&& zone.is(ZoneType.Battlefield, player)) {
|
||||
// Create a new blockedBy list if it doesn't exist
|
||||
if (!this.allBlocking.containsKey(card)) {
|
||||
this.allBlocking.put(card, new ArrayList<Card>());
|
||||
|
||||
@@ -24,7 +24,6 @@ import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.match.CMatchUI;
|
||||
import forge.view.ButtonUtil;
|
||||
|
||||
/**
|
||||
@@ -44,9 +43,9 @@ public class InputCleanup extends InputBase {
|
||||
* TODO: Write javadoc for Constructor.
|
||||
* @param game
|
||||
*/
|
||||
public InputCleanup(GameState game) {
|
||||
super();
|
||||
this.game = game;
|
||||
public InputCleanup(Player player) {
|
||||
super(player);
|
||||
this.game = player.getGame();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@@ -59,7 +58,7 @@ public class InputCleanup extends InputBase {
|
||||
final int max = active.getMaxHandSize();
|
||||
// goes to the next phase
|
||||
if (active.isUnlimitedHandSize() || n <= max || n <= 0 || active != turnOwner) {
|
||||
active.getController().passPriority();
|
||||
passPriority();
|
||||
return;
|
||||
}
|
||||
ButtonUtil.disableAll();
|
||||
@@ -69,7 +68,7 @@ public class InputCleanup extends InputBase {
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
sb.append("Cleanup Phase: You can only have a maximum of ").append(max);
|
||||
sb.append(" cards, you currently have ").append(n).append(" cards in your hand - select a card to discard");
|
||||
CMatchUI.SINGLETON_INSTANCE.showMessage(sb.toString());
|
||||
showMessage(sb.toString());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
|
||||
@@ -19,6 +19,7 @@ package forge.control.input;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.game.GameState;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -115,38 +116,37 @@ public class InputControl extends MyObservable implements java.io.Serializable {
|
||||
*/
|
||||
public final Input getActualInput(GameState game) {
|
||||
if ( !game.hasMulliganned() )
|
||||
return new InputMulligan();
|
||||
return new InputMulligan(Singletons.getModel().getMatch(), Singletons.getControl().getPlayer());
|
||||
|
||||
final PhaseHandler handler = game.getPhaseHandler();
|
||||
final PhaseType phase = handler.getPhase();
|
||||
final Player playerTurn = handler.getPlayerTurn();
|
||||
final Player priority = handler.getPriorityPlayer();
|
||||
final MagicStack stack = game.getStack();
|
||||
if (priority == null)
|
||||
throw new RuntimeException("No player has priority!");
|
||||
PlayerController pc = priority.getController();
|
||||
|
||||
|
||||
|
||||
// TODO this resolving portion needs more work, but fixes Death Cloud
|
||||
// issues
|
||||
if (!this.inputStack.isEmpty()) { // incoming input to Control
|
||||
return this.inputStack.peek();
|
||||
}
|
||||
|
||||
// If the Phase we're in doesn't allow for Priority, return null to move
|
||||
// to next phase
|
||||
|
||||
|
||||
// If the Phase we're in doesn't allow for Priority, move to next phase
|
||||
if (!handler.isPlayerPriorityAllowed()) {
|
||||
return null;
|
||||
return pc.getAutoPassPriorityInput();
|
||||
}
|
||||
|
||||
if (priority == null)
|
||||
return null;
|
||||
PlayerController pc = priority.getController();
|
||||
|
||||
// Special Inputs needed for the following phases:
|
||||
final MagicStack stack = game.getStack();
|
||||
switch (phase) {
|
||||
case COMBAT_DECLARE_ATTACKERS:
|
||||
stack.freezeStack();
|
||||
if (playerTurn.isHuman() && !playerTurn.getController().mayAutoPass(phase)) {
|
||||
game.getCombat().initiatePossibleDefenders(playerTurn.getOpponents());
|
||||
return new InputAttack(game);
|
||||
return new InputAttack(playerTurn);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -158,8 +158,7 @@ public class InputControl extends MyObservable implements java.io.Serializable {
|
||||
}
|
||||
|
||||
// noone attacks you
|
||||
pc.passPriority();
|
||||
return null;
|
||||
return pc.getAutoPassPriorityInput();
|
||||
|
||||
case CLEANUP:
|
||||
// discard
|
||||
@@ -176,10 +175,9 @@ public class InputControl extends MyObservable implements java.io.Serializable {
|
||||
// Special phases handled above, everything else is handled simply by
|
||||
// priority
|
||||
|
||||
boolean prioritySkip = pc.mayAutoPass(phase) || pc.isUiSetToSkipPhase(playerTurn, phase);
|
||||
if (game.getStack().isEmpty() && prioritySkip) {
|
||||
pc.passPriority();
|
||||
return null;
|
||||
boolean maySkipPriority = pc.mayAutoPass(phase) || pc.isUiSetToSkipPhase(playerTurn, phase);
|
||||
if (game.getStack().isEmpty() && maySkipPriority) {
|
||||
return pc.getAutoPassPriorityInput();
|
||||
} else
|
||||
pc.autoPassCancel(); // probably cancel, since something has happened
|
||||
|
||||
|
||||
@@ -2,16 +2,18 @@ package forge.control.input;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import forge.Card;
|
||||
import forge.FThreads;
|
||||
import forge.Singletons;
|
||||
import forge.game.player.Player;
|
||||
import forge.gui.match.CMatchUI;
|
||||
import forge.view.ButtonUtil;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public class InputLockUI extends InputBase {
|
||||
private static final long serialVersionUID = 5777143577098597374L;
|
||||
|
||||
public class InputLockUI implements Input {
|
||||
private final AtomicInteger iCall = new AtomicInteger();
|
||||
|
||||
public void showMessage() {
|
||||
@@ -48,4 +50,17 @@ public class InputLockUI extends InputBase {
|
||||
}
|
||||
};
|
||||
|
||||
protected final boolean isActive() {
|
||||
return Singletons.getModel().getMatch().getInput().getInput() == this;
|
||||
}
|
||||
|
||||
protected void showMessage(String message) {
|
||||
CMatchUI.SINGLETON_INSTANCE.showMessage(message);
|
||||
}
|
||||
|
||||
@Override public void selectCard(Card c) {}
|
||||
@Override public void selectPlayer(Player player) {}
|
||||
@Override public void selectButtonOK() {}
|
||||
@Override public void selectButtonCancel() {}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,12 +24,13 @@ import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardPredicates;
|
||||
import forge.Singletons;
|
||||
import forge.FThreads;
|
||||
import forge.card.ability.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameAction;
|
||||
import forge.game.GameState;
|
||||
import forge.game.GameType;
|
||||
import forge.game.MatchController;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
@@ -53,21 +54,27 @@ public class InputMulligan extends InputBase {
|
||||
/** Constant <code>serialVersionUID=-8112954303001155622L</code>. */
|
||||
private static final long serialVersionUID = -8112954303001155622L;
|
||||
|
||||
private final MatchController match;
|
||||
|
||||
public InputMulligan(MatchController match0, Player humanPlayer) {
|
||||
super(humanPlayer);
|
||||
match = match0;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void showMessage() {
|
||||
ButtonUtil.setButtonText("No", "Yes");
|
||||
ButtonUtil.enableAllFocusOk();
|
||||
|
||||
GameState game = Singletons.getModel().getGame();
|
||||
GameState game = match.getCurrentGame();
|
||||
Player startingPlayer = game.getPhaseHandler().getPlayerTurn();
|
||||
Player localPlayer = Singletons.getControl().getPlayer();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(startingPlayer.getName()).append(" is going first. ");
|
||||
|
||||
if (!startingPlayer.equals(localPlayer)) {
|
||||
sb.append("You are going ").append(game.getOrdinalPosition(localPlayer, startingPlayer)).append(". ");
|
||||
if (!startingPlayer.equals(player)) {
|
||||
sb.append("You are going ").append(game.getOrdinalPosition(player, startingPlayer)).append(". ");
|
||||
}
|
||||
|
||||
sb.append("Do you want to Mulligan?");
|
||||
@@ -83,10 +90,9 @@ public class InputMulligan extends InputBase {
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void selectButtonCancel() {
|
||||
final Player humanPlayer = Singletons.getControl().getPlayer();
|
||||
humanPlayer.doMulligan();
|
||||
player.doMulligan();
|
||||
|
||||
if (humanPlayer.getCardsIn(ZoneType.Hand).isEmpty()) {
|
||||
if (player.getCardsIn(ZoneType.Hand).isEmpty()) {
|
||||
this.end();
|
||||
} else {
|
||||
ButtonUtil.enableAllFocusOk();
|
||||
@@ -94,9 +100,9 @@ public class InputMulligan extends InputBase {
|
||||
}
|
||||
|
||||
final void end() {
|
||||
GameState game = Singletons.getModel().getGame();
|
||||
|
||||
// Computer mulligan
|
||||
final GameState game = match.getCurrentGame();
|
||||
for (Player p : game.getPlayers()) {
|
||||
if (!(p instanceof AIPlayer)) {
|
||||
continue;
|
||||
@@ -173,17 +179,22 @@ public class InputMulligan extends InputBase {
|
||||
SDisplayUtil.showTab(nextField);
|
||||
|
||||
game.setMulliganned(true);
|
||||
Singletons.getModel().getMatch().getInput().clearInput();
|
||||
FThreads.invokeInNewThread( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
match.getInput().clearInput();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectCard(Card c0) {
|
||||
Zone z0 = Singletons.getModel().getGame().getZoneOf(c0);
|
||||
Zone z0 = match.getCurrentGame().getZoneOf(c0);
|
||||
if (c0.getName().equals("Serum Powder") && z0.is(ZoneType.Hand)) {
|
||||
if (GuiDialog.confirm(c0, "Use " + c0.getName() + "'s ability?")) {
|
||||
List<Card> hand = new ArrayList<Card>(c0.getController().getCardsIn(ZoneType.Hand));
|
||||
for (Card c : hand) {
|
||||
Singletons.getModel().getGame().getAction().exile(c);
|
||||
match.getCurrentGame().getAction().exile(c);
|
||||
}
|
||||
c0.getController().drawCards(hand.size());
|
||||
}
|
||||
|
||||
@@ -19,11 +19,9 @@ package forge.control.input;
|
||||
|
||||
import forge.Card;
|
||||
import forge.FThreads;
|
||||
import forge.Singletons;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.FControl;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.player.HumanPlayer;
|
||||
import forge.gui.GuiDisplayUtil;
|
||||
import forge.gui.framework.SDisplayUtil;
|
||||
import forge.gui.match.CMatchUI;
|
||||
@@ -42,26 +40,28 @@ public class InputPassPriority extends InputBase {
|
||||
/** Constant <code>serialVersionUID=-581477682214137181L</code>. */
|
||||
private static final long serialVersionUID = -581477682214137181L;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
* @param player
|
||||
*/
|
||||
public InputPassPriority(HumanPlayer human) {
|
||||
super(human);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void showMessage() {
|
||||
GuiDisplayUtil.updateGUI();
|
||||
ButtonUtil.enableOnlyOk();
|
||||
|
||||
final PhaseType phase = Singletons.getModel().getGame().getPhaseHandler().getPhase();
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPriorityPlayer();
|
||||
|
||||
if (player.isComputer()) {
|
||||
System.err.println(phase + ": Computer in passpriority");
|
||||
}
|
||||
|
||||
final PhaseHandler ph = player.getGame().getPhaseHandler();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("Turn : ").append(Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn()).append("\n");
|
||||
sb.append("Phase: ").append(phase.Name).append("\n");
|
||||
sb.append("Turn : ").append(ph.getPlayerTurn()).append("\n");
|
||||
sb.append("Phase: ").append(ph.getPhase().Name).append("\n");
|
||||
sb.append("Stack: ");
|
||||
if (Singletons.getModel().getGame().getStack().size() != 0) {
|
||||
sb.append(Singletons.getModel().getGame().getStack().size()).append(" to Resolve.");
|
||||
if (player.getGame().getStack().size() != 0) {
|
||||
sb.append(player.getGame().getStack().size()).append(" to Resolve.");
|
||||
} else {
|
||||
sb.append("Empty");
|
||||
}
|
||||
@@ -71,16 +71,17 @@ public class InputPassPriority extends InputBase {
|
||||
CMatchUI.SINGLETON_INSTANCE.showMessage(sb.toString());
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void selectButtonOK() {
|
||||
FControl.SINGLETON_INSTANCE.getPlayer().getController().passPriority();
|
||||
ButtonUtil.disableAll();
|
||||
passPriority();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void selectCard(final Card card) {
|
||||
final Player player = Singletons.getControl().getPlayer();
|
||||
final SpellAbility ab = player.getController().getAbilityToPlay(player.getGame().getAbilitesOfCard(card, player));
|
||||
if ( null != ab) {
|
||||
Runnable execAbility = new Runnable() {
|
||||
|
||||
@@ -30,16 +30,15 @@ public abstract class InputPayManaBase extends InputSyncronizedBase implements I
|
||||
|
||||
protected int phyLifeToLose = 0;
|
||||
|
||||
protected final Player whoPays;
|
||||
protected final GameState game;
|
||||
protected ManaCostBeingPaid manaCost;
|
||||
protected final SpellAbility saPaidFor;
|
||||
|
||||
boolean bPaid = false;
|
||||
|
||||
protected InputPayManaBase(final GameState game, SpellAbility saToPayFor) {
|
||||
this.game = game;
|
||||
this.whoPays = saToPayFor.getActivatingPlayer();
|
||||
protected InputPayManaBase(SpellAbility saToPayFor) {
|
||||
super(saToPayFor.getActivatingPlayer());
|
||||
this.game = player.getGame();
|
||||
this.saPaidFor = saToPayFor;
|
||||
}
|
||||
|
||||
@@ -115,7 +114,7 @@ public abstract class InputPayManaBase extends InputSyncronizedBase implements I
|
||||
* @return ManaCost the amount of mana remaining to be paid after the mana is activated
|
||||
*/
|
||||
protected void useManaFromPool(String color, ManaCostBeingPaid manaCost) {
|
||||
ManaPool mp = whoPays.getManaPool();
|
||||
ManaPool mp = player.getManaPool();
|
||||
|
||||
// Convert Color to short String
|
||||
String manaStr = "1";
|
||||
@@ -144,7 +143,7 @@ public abstract class InputPayManaBase extends InputSyncronizedBase implements I
|
||||
*/
|
||||
protected void activateManaAbility(final Card card, ManaCostBeingPaid manaCost) {
|
||||
// make sure computer's lands aren't selected
|
||||
if (card.getController() != whoPays) {
|
||||
if (card.getController() != player) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -168,7 +167,7 @@ public abstract class InputPayManaBase extends InputSyncronizedBase implements I
|
||||
// you can't remove unneeded abilities inside a for(am:abilities) loop :(
|
||||
|
||||
for (SpellAbility ma : card.getManaAbility()) {
|
||||
ma.setActivatingPlayer(whoPays);
|
||||
ma.setActivatingPlayer(player);
|
||||
AbilityManaPart m = null;
|
||||
SpellAbility tail = ma;
|
||||
while(m == null && tail != null)
|
||||
@@ -303,11 +302,11 @@ public abstract class InputPayManaBase extends InputSyncronizedBase implements I
|
||||
|
||||
public void onManaAbilityPlayed(final SpellAbility saPaymentSrc) {
|
||||
if ( saPaymentSrc != null) // null comes when they've paid from pool
|
||||
this.manaCost = whoPays.getManaPool().payManaFromAbility(saPaidFor, manaCost, saPaymentSrc);
|
||||
this.manaCost = player.getManaPool().payManaFromAbility(saPaidFor, manaCost, saPaymentSrc);
|
||||
|
||||
onManaAbilityPaid();
|
||||
if ( saPaymentSrc != null )
|
||||
whoPays.getZone(ZoneType.Battlefield).updateObservers();
|
||||
player.getZone(ZoneType.Battlefield).updateObservers();
|
||||
}
|
||||
|
||||
protected final void checkIfAlredyPaid() {
|
||||
|
||||
@@ -62,7 +62,7 @@ public class InputPayManaExecuteCommands extends InputPayManaBase implements Inp
|
||||
* a {@link forge.Command} object.
|
||||
*/
|
||||
public InputPayManaExecuteCommands(final Player p, final String prompt, final ManaCost manaCost2) {
|
||||
super(p.getGame(), new SpellAbility(null) {
|
||||
super(new SpellAbility(null) {
|
||||
@Override
|
||||
public void resolve() {}
|
||||
|
||||
@@ -90,8 +90,8 @@ public class InputPayManaExecuteCommands extends InputPayManaBase implements Inp
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectPlayer(final Player player) {
|
||||
if (player == whoPays) {
|
||||
public void selectPlayer(final Player selectedPlayer) {
|
||||
if (player == selectedPlayer) {
|
||||
if (player.canPayLife(this.phyLifeToLose + 2) && manaCost.payPhyrexian()) {
|
||||
this.phyLifeToLose += 2;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import forge.view.ButtonUtil;
|
||||
public class InputPayManaOfCostPayment extends InputPayManaBase {
|
||||
|
||||
public InputPayManaOfCostPayment(final GameState game, CostPartMana costMana, SpellAbility spellAbility, int toAdd) {
|
||||
super(game, spellAbility);
|
||||
super(spellAbility);
|
||||
manaCost = new ManaCostBeingPaid(costMana.getManaToPay());
|
||||
manaCost.increaseColorlessMana(toAdd);
|
||||
}
|
||||
@@ -21,8 +21,8 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
|
||||
private int phyLifeToLose = 0;
|
||||
|
||||
@Override
|
||||
public void selectPlayer(final Player player) {
|
||||
if (player == whoPays) {
|
||||
public void selectPlayer(final Player selectedPlayer) {
|
||||
if (player == selectedPlayer) {
|
||||
if (player.canPayLife(this.phyLifeToLose + 2) && manaCost.payPhyrexian()) {
|
||||
this.phyLifeToLose += 2;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class InputPayManaSimple extends InputPayManaBase {
|
||||
private final String originalManaCost;
|
||||
|
||||
public InputPayManaSimple(final GameState game, final SpellAbility sa, final ManaCostBeingPaid manaCostToPay) {
|
||||
super(game, sa);
|
||||
super(sa);
|
||||
this.originalManaCost = manaCostToPay.toString(); // Change
|
||||
this.originalCard = sa.getSourceCard();
|
||||
|
||||
@@ -68,9 +68,9 @@ public class InputPayManaSimple extends InputPayManaBase {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void selectPlayer(final Player player) {
|
||||
public final void selectPlayer(final Player selectedPlayer) {
|
||||
|
||||
if (player == whoPays) {
|
||||
if (player == selectedPlayer) {
|
||||
if (player.canPayLife(this.phyLifeToLose + 2) && manaCost.payPhyrexian()) {
|
||||
this.phyLifeToLose += 2;
|
||||
}
|
||||
@@ -88,10 +88,10 @@ public class InputPayManaSimple extends InputPayManaBase {
|
||||
@Override
|
||||
protected void done() {
|
||||
if (this.phyLifeToLose > 0) {
|
||||
whoPays.payLife(this.phyLifeToLose, this.originalCard);
|
||||
player.payLife(this.phyLifeToLose, this.originalCard);
|
||||
}
|
||||
if (!this.saPaidFor.getSourceCard().isCopiedSpell()) {
|
||||
whoPays.getManaPool().clearManaPaid(this.saPaidFor, false);
|
||||
player.getManaPool().clearManaPaid(this.saPaidFor, false);
|
||||
this.resetManaCost();
|
||||
|
||||
if (this.saPaidFor.isSpell()) {
|
||||
@@ -110,8 +110,8 @@ public class InputPayManaSimple extends InputPayManaBase {
|
||||
handleConvokedCards(true);
|
||||
this.resetManaCost();
|
||||
|
||||
whoPays.getManaPool().refundManaPaid(this.saPaidFor, true);
|
||||
whoPays.getZone(ZoneType.Battlefield).updateObservers(); // DO
|
||||
player.getManaPool().refundManaPaid(this.saPaidFor, true);
|
||||
player.getZone(ZoneType.Battlefield).updateObservers(); // DO
|
||||
|
||||
this.stop();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package forge.control.input;
|
||||
import forge.Card;
|
||||
import forge.card.mana.ManaCostBeingPaid;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.view.ButtonUtil;
|
||||
|
||||
public class InputPayManaX extends InputPayManaBase {
|
||||
@@ -15,9 +14,9 @@ public class InputPayManaX extends InputPayManaBase {
|
||||
private final boolean xCanBe0;
|
||||
|
||||
|
||||
public InputPayManaX(final GameState game, final SpellAbility sa0, final int amountX, final boolean xCanBe0)
|
||||
public InputPayManaX(final SpellAbility sa0, final int amountX, final boolean xCanBe0)
|
||||
{
|
||||
super(game, sa0);
|
||||
super(sa0);
|
||||
|
||||
xPaid = 0;
|
||||
colorX = saPaidFor.hasParam("XColor") ? saPaidFor.getParam("XColor") : "";
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.List;
|
||||
|
||||
import forge.Card;
|
||||
import forge.GameEntity;
|
||||
import forge.Singletons;
|
||||
import forge.view.ButtonUtil;
|
||||
|
||||
public abstract class InputSelectManyBase<T extends GameEntity> extends InputSyncronizedBase implements InputSelectMany<T> {
|
||||
@@ -23,6 +24,7 @@ public abstract class InputSelectManyBase<T extends GameEntity> extends InputSyn
|
||||
|
||||
|
||||
protected InputSelectManyBase(int min, int max) {
|
||||
super(Singletons.getControl().getPlayer());
|
||||
selected = new ArrayList<T>();
|
||||
if (min > max) {
|
||||
throw new IllegalArgumentException("Min must not be greater than Max");
|
||||
|
||||
@@ -4,13 +4,15 @@ import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.error.BugReporter;
|
||||
import forge.game.player.Player;
|
||||
|
||||
public abstract class InputSyncronizedBase extends InputBase implements InputSynchronized {
|
||||
private static final long serialVersionUID = 8756177361251703052L;
|
||||
|
||||
private final CountDownLatch cdlDone;
|
||||
|
||||
public InputSyncronizedBase() {
|
||||
public InputSyncronizedBase(Player player) {
|
||||
super(player);
|
||||
cdlDone = new CountDownLatch(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,21 +14,17 @@ import forge.game.player.Player;
|
||||
*
|
||||
*/
|
||||
public class AiInputBlock extends InputBase {
|
||||
|
||||
private final GameState game;
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
* @param game
|
||||
* @param player
|
||||
*/
|
||||
public AiInputBlock(GameState game, Player player) {
|
||||
super();
|
||||
this.game = game;
|
||||
this.player = player;
|
||||
public AiInputBlock(Player human) {
|
||||
super(human);
|
||||
this.game = human.getGame();
|
||||
}
|
||||
|
||||
private final Player player;
|
||||
|
||||
private static final long serialVersionUID = -2253562658069995572L;
|
||||
|
||||
@Override
|
||||
|
||||
@@ -43,6 +43,7 @@ public class AiInputCommon extends InputBase implements AiInput {
|
||||
* a {@link forge.game.player.Computer} object.
|
||||
*/
|
||||
public AiInputCommon(final AiController iComputer) {
|
||||
super(iComputer.getPlayer());
|
||||
this.computer = iComputer;
|
||||
}
|
||||
|
||||
|
||||
@@ -709,6 +709,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
* </p>
|
||||
*/
|
||||
public final void passPriority() {
|
||||
FThreads.checkEDT("PhaseHandler.passPriority", false);
|
||||
// stop game if it's outcome is clear
|
||||
if (game.isGameOver()) {
|
||||
return;
|
||||
|
||||
@@ -29,13 +29,15 @@ public abstract class PlayerController {
|
||||
|
||||
private PhaseType autoPassUntil = null;
|
||||
|
||||
|
||||
public PlayerController(GameState game0) {
|
||||
game = game0;
|
||||
|
||||
}
|
||||
|
||||
public abstract Input getDefaultInput();
|
||||
public abstract Input getBlockInput();
|
||||
public abstract Input getCleanupInput();
|
||||
public abstract Input getAutoPassPriorityInput();
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,7 @@ import forge.GameEntity;
|
||||
import forge.card.spellability.Spell;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.control.input.InputAutoPassPriority;
|
||||
import forge.deck.Deck;
|
||||
import forge.game.GameState;
|
||||
import forge.game.GameType;
|
||||
@@ -36,6 +37,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
private Input defaultInput;
|
||||
private Input blockInput;
|
||||
private Input cleanupInput;
|
||||
private Input autoPassPriorityInput;
|
||||
|
||||
private final AiController brains;
|
||||
private final AIPlayer player;
|
||||
@@ -52,9 +54,9 @@ public class PlayerControllerAi extends PlayerController {
|
||||
brains = new AiController(p, game);
|
||||
|
||||
defaultInput = new AiInputCommon(brains);
|
||||
blockInput = new AiInputBlock(game, getPlayer());
|
||||
blockInput = new AiInputBlock(getPlayer());
|
||||
cleanupInput = getDefaultInput();
|
||||
|
||||
autoPassPriorityInput = new InputAutoPassPriority(getPlayer());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,6 +77,11 @@ public class PlayerControllerAi extends PlayerController {
|
||||
return blockInput;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Input getAutoPassPriorityInput() {
|
||||
return autoPassPriorityInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cleanupInput
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@ import forge.FThreads;
|
||||
import forge.GameEntity;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.control.input.InputAutoPassPriority;
|
||||
import forge.control.input.InputBlock;
|
||||
import forge.control.input.InputCleanup;
|
||||
import forge.control.input.InputPassPriority;
|
||||
@@ -45,6 +46,7 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
private final Input defaultInput;
|
||||
private final Input blockInput;
|
||||
private final Input cleanupInput;
|
||||
private final Input autoPassPriorityInput;
|
||||
private final HumanPlayer player;
|
||||
|
||||
public final Input getDefaultInput() {
|
||||
@@ -55,9 +57,10 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
super(game0);
|
||||
player = p;
|
||||
|
||||
defaultInput = new InputPassPriority();
|
||||
defaultInput = new InputPassPriority(player);
|
||||
blockInput = new InputBlock(getPlayer());
|
||||
cleanupInput = new InputCleanup(game);
|
||||
cleanupInput = new InputCleanup(getPlayer());
|
||||
autoPassPriorityInput = new InputAutoPassPriority(getPlayer());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,6 +86,11 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
return blockInput;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Input getAutoPassPriorityInput() {
|
||||
return autoPassPriorityInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cleanupInput
|
||||
*/
|
||||
|
||||
@@ -391,7 +391,7 @@ public class MagicStack extends MyObservable {
|
||||
final int xCost = sa.getXManaCost();
|
||||
Player player = sp.getSourceCard().getController();
|
||||
if (player.isHuman()) {
|
||||
InputSynchronized inp = new InputPayManaX(game, sa, xCost, true);
|
||||
InputSynchronized inp = new InputPayManaX(sa, xCost, true);
|
||||
FThreads.setInputAndWait(inp);
|
||||
MagicStack.this.push(sa);
|
||||
} else {
|
||||
|
||||
@@ -26,7 +26,6 @@ import forge.FThreads;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.MatchController;
|
||||
import forge.game.ai.AiInput;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.player.Player;
|
||||
|
||||
@@ -50,35 +49,37 @@ public class InputProxy implements Observer {
|
||||
|
||||
@Override
|
||||
public final synchronized void update(final Observable observable, final Object obj) {
|
||||
this.input.set(null);
|
||||
final GameState game = match.getCurrentGame();
|
||||
final PhaseHandler ph = game.getPhaseHandler();
|
||||
//System.out.printf("%s > InputProxy.update() =>%n", FThreads.debugGetCurrThreadId());
|
||||
|
||||
//System.out.print((FThreads.isEDT() ? "EDT > " : "TRD > ") + ph.debugPrintState());
|
||||
if ( match.getInput().isEmpty() && ph.hasPhaseEffects()) {
|
||||
//System.out.println(" handle begin phase");
|
||||
FThreads.invokeInNewThread(new Runnable() {
|
||||
@Override public void run() {
|
||||
Runnable rPhase = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//System.out.printf("\t%s > handle begin phase during %s%n", FThreads.debugGetCurrThreadId(), ph.debugPrintState());
|
||||
ph.handleBeginPhase();
|
||||
update(observable, obj);
|
||||
update(null, null);
|
||||
}
|
||||
}, true);
|
||||
};
|
||||
FThreads.invokeInNewThread(rPhase);
|
||||
return;
|
||||
}
|
||||
|
||||
final Input nextInput = match.getInput().getActualInput(game);
|
||||
//System.out.printf(" input is %s \t stack = %s%n", nextInput == null ? "null" : nextInput.getClass().getSimpleName(), match.getInput().printInputStack());
|
||||
//System.out.printf("\tinput is %s during %s, \tstack = %s%n", nextInput == null ? "null" : nextInput.getClass().getSimpleName(), ph.debugPrintState(), match.getInput().printInputStack());
|
||||
|
||||
if (nextInput != null) {
|
||||
this.input.set(nextInput);
|
||||
Runnable showMessage = new Runnable() { @Override public void run() { nextInput.showMessage(); } };
|
||||
this.input.set(nextInput);
|
||||
Runnable showMessage = new Runnable() {
|
||||
@Override public void run() {
|
||||
//System.out.printf("%s > showMessage @ %s during %s%n", FThreads.debugGetCurrThreadId(), nextInput.getClass().getSimpleName(), ph.debugPrintState());
|
||||
nextInput.showMessage();
|
||||
}
|
||||
};
|
||||
// if( nextInput instanceof AiInput )
|
||||
// FThreads.invokeInNewThread(showMessage, true);
|
||||
// else
|
||||
FThreads.invokeInEDT(showMessage);
|
||||
} else if (!ph.isPlayerPriorityAllowed()) {
|
||||
ph.getPriorityPlayer().getController().passPriority();
|
||||
}
|
||||
FThreads.invokeInEDT(showMessage);
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
|
||||
Reference in New Issue
Block a user