mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
Don't prompt to declare blockers if no creatures can block
This commit is contained in:
@@ -35,21 +35,18 @@ import forge.gui.input.InputSynchronized;
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class InputQueue extends Observable {
|
public class InputQueue extends Observable {
|
||||||
|
|
||||||
private final BlockingDeque<InputSynchronized> inputStack = new LinkedBlockingDeque<InputSynchronized>();
|
private final BlockingDeque<InputSynchronized> inputStack = new LinkedBlockingDeque<InputSynchronized>();
|
||||||
private final InputLockUI inputLock;
|
private final InputLockUI inputLock;
|
||||||
|
|
||||||
|
|
||||||
public InputQueue() {
|
public InputQueue() {
|
||||||
inputLock = new InputLockUI(this);
|
inputLock = new InputLockUI(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final void updateObservers() {
|
public final void updateObservers() {
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Input getInput() {
|
public final Input getInput() {
|
||||||
return inputStack.isEmpty() ? null : this.inputStack.peek();
|
return inputStack.isEmpty() ? null : this.inputStack.peek();
|
||||||
}
|
}
|
||||||
@@ -81,25 +78,24 @@ public class InputQueue extends Observable {
|
|||||||
public String printInputStack() {
|
public String printInputStack() {
|
||||||
return inputStack.toString();
|
return inputStack.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInputAndWait(InputSynchronized input) {
|
public void setInputAndWait(InputSynchronized input) {
|
||||||
this.inputStack.push(input);
|
this.inputStack.push(input);
|
||||||
syncPoint();
|
syncPoint();
|
||||||
this.updateObservers();
|
this.updateObservers();
|
||||||
|
|
||||||
input.awaitLatchRelease();
|
input.awaitLatchRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setInput(InputSynchronized input) {
|
void setInput(InputSynchronized input) {
|
||||||
this.inputStack.push(input);
|
this.inputStack.push(input);
|
||||||
syncPoint();
|
syncPoint();
|
||||||
this.updateObservers();
|
this.updateObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void syncPoint() {
|
public void syncPoint() {
|
||||||
synchronized (inputLock) {
|
synchronized (inputLock) {
|
||||||
// acquire and release lock, so that actions from Game thread happen before EDT reads their results
|
// acquire and release lock, so that actions from Game thread happen before EDT reads their results
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,5 +109,4 @@ public class InputQueue extends Observable {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // InputControl
|
} // InputControl
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ public class CombatUtil {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean canBlock(final Card blocker, final Combat combat) {
|
public static boolean canBlock(final Card blocker, final Combat combat) {
|
||||||
|
|
||||||
if (blocker == null) {
|
if (blocker == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -131,7 +130,6 @@ public class CombatUtil {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean canBlock(final Card blocker, final boolean nextTurn) {
|
public static boolean canBlock(final Card blocker, final boolean nextTurn) {
|
||||||
|
|
||||||
if (blocker == null) {
|
if (blocker == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -176,7 +174,6 @@ public class CombatUtil {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean canBeBlocked(final Card attacker, final Combat combat, Player defendingPlayer) {
|
public static boolean canBeBlocked(final Card attacker, final Combat combat, Player defendingPlayer) {
|
||||||
|
|
||||||
if (attacker == null) {
|
if (attacker == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -206,7 +203,6 @@ public class CombatUtil {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean canBeBlocked(final Card attacker, Player defender) {
|
public static boolean canBeBlocked(final Card attacker, Player defender) {
|
||||||
|
|
||||||
if (attacker == null) {
|
if (attacker == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -366,7 +362,6 @@ public class CombatUtil {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static String validateBlocks(final Combat combat, final Player defending) {
|
public static String validateBlocks(final Combat combat, final Player defending) {
|
||||||
|
|
||||||
final List<Card> defendersArmy = defending.getCreaturesInPlay();
|
final List<Card> defendersArmy = defending.getCreaturesInPlay();
|
||||||
final List<Card> attackers = combat.getAttackers();
|
final List<Card> attackers = combat.getAttackers();
|
||||||
final List<Card> blockers = CardLists.filterControlledBy(combat.getAllBlockers(), defending);
|
final List<Card> blockers = CardLists.filterControlledBy(combat.getAllBlockers(), defending);
|
||||||
@@ -494,6 +489,35 @@ public class CombatUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// can a player block with one or more creatures at the moment?
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* canAttack.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param p
|
||||||
|
* a {@link forge.game.player} object.
|
||||||
|
* @param combat
|
||||||
|
* a {@link forge.game.combat.Combat} object.
|
||||||
|
* @return a boolean.
|
||||||
|
*/
|
||||||
|
public static boolean canBlock(Player p, Combat combat) {
|
||||||
|
List<Card> creatures = p.getCreaturesInPlay();
|
||||||
|
if (creatures.isEmpty()) { return false; }
|
||||||
|
|
||||||
|
List<Card> attackers = combat.getAttackers();
|
||||||
|
if (attackers.isEmpty()) { return false; }
|
||||||
|
|
||||||
|
for (Card c : creatures) {
|
||||||
|
for (Card a : attackers) {
|
||||||
|
if (CombatUtil.canBlock(a, c, combat)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// can the blocker block the attacker given the combat state?
|
// can the blocker block the attacker given the combat state?
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -509,7 +533,6 @@ public class CombatUtil {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean canBlock(final Card attacker, final Card blocker, final Combat combat) {
|
public static boolean canBlock(final Card attacker, final Card blocker, final Combat combat) {
|
||||||
|
|
||||||
if (attacker == null || blocker == null) {
|
if (attacker == null || blocker == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -614,7 +637,6 @@ public class CombatUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (attacker.hasStartOfKeyword("CantBeBlockedBy ")) {
|
if (attacker.hasStartOfKeyword("CantBeBlockedBy ")) {
|
||||||
final int keywordPosition = attacker.getKeywordPosition("CantBeBlockedBy ");
|
final int keywordPosition = attacker.getKeywordPosition("CantBeBlockedBy ");
|
||||||
final String parse = attacker.getKeyword().get(keywordPosition).toString();
|
final String parse = attacker.getKeyword().get(keywordPosition).toString();
|
||||||
|
|||||||
@@ -555,13 +555,16 @@ public class PhaseHandler implements java.io.Serializable {
|
|||||||
if (game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.attackerChoosesBlockers)) {
|
if (game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.attackerChoosesBlockers)) {
|
||||||
whoDeclaresBlockers = combat.getAttackingPlayer();
|
whoDeclaresBlockers = combat.getAttackingPlayer();
|
||||||
}
|
}
|
||||||
if ( combat.isPlayerAttacked(p) ) {
|
if (combat.isPlayerAttacked(p)) {
|
||||||
whoDeclaresBlockers.getController().declareBlockers(p, combat);
|
if (CombatUtil.canBlock(p, combat)) {
|
||||||
} else
|
whoDeclaresBlockers.getController().declareBlockers(p, combat);
|
||||||
continue;
|
}
|
||||||
|
}
|
||||||
|
else { continue; }
|
||||||
|
|
||||||
if ( game.isGameOver() ) // they just like to close window at any moment
|
if (game.isGameOver()) { // they just like to close window at any moment
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Handles removing cards like Mogg Flunkies from combat if group block
|
// Handles removing cards like Mogg Flunkies from combat if group block
|
||||||
// didn't occur
|
// didn't occur
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
public boolean isUiSetToSkipPhase(final Player turn, final PhaseType phase) {
|
public boolean isUiSetToSkipPhase(final Player turn, final PhaseType phase) {
|
||||||
return !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase);
|
return !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses GUI to learn which spell the player (human in our case) would like to play
|
* Uses GUI to learn which spell the player (human in our case) would like to play
|
||||||
*/
|
*/
|
||||||
@@ -145,7 +145,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
});
|
});
|
||||||
menu.show(triggerEvent.getComponent(), triggerEvent.getX(), triggerEvent.getY());
|
menu.show(triggerEvent.getComponent(), triggerEvent.getX(), triggerEvent.getY());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; //delay ability until choice made
|
return null; //delay ability until choice made
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
|
|
||||||
CardPool newSb = new CardPool();
|
CardPool newSb = new CardPool();
|
||||||
List<PaperCard> newMain = null;
|
List<PaperCard> newMain = null;
|
||||||
|
|
||||||
if (sbSize == 0 && mainSize == deckMinSize) {
|
if (sbSize == 0 && mainSize == deckMinSize) {
|
||||||
// Skip sideboard loop if there are no sideboarding opportunities
|
// Skip sideboard loop if there are no sideboarding opportunities
|
||||||
newMain = main.toFlatList();
|
newMain = main.toFlatList();
|
||||||
@@ -223,7 +223,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
for(PaperCard c : newMain) {
|
for(PaperCard c : newMain) {
|
||||||
newSb.remove(c);
|
newSb.remove(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
Deck res = (Deck)deck.copyTo(deck.getName());
|
Deck res = (Deck)deck.copyTo(deck.getName());
|
||||||
res.getMain().clear();
|
res.getMain().clear();
|
||||||
res.getMain().add(newMain);
|
res.getMain().add(newMain);
|
||||||
@@ -239,7 +239,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
@Override
|
@Override
|
||||||
public Map<Card, Integer> assignCombatDamage(Card attacker, List<Card> blockers, int damageDealt, GameEntity defender, boolean overrideOrder) {
|
public Map<Card, Integer> assignCombatDamage(Card attacker, List<Card> blockers, int damageDealt, GameEntity defender, boolean overrideOrder) {
|
||||||
// Attacker is a poor name here, since the creature assigning damage
|
// Attacker is a poor name here, since the creature assigning damage
|
||||||
// could just as easily be the blocker.
|
// could just as easily be the blocker.
|
||||||
Map<Card, Integer> map;
|
Map<Card, Integer> map;
|
||||||
if (defender != null && assignDamageAsIfNotBlocked(attacker)) {
|
if (defender != null && assignDamageAsIfNotBlocked(attacker)) {
|
||||||
map = new HashMap<Card, Integer>();
|
map = new HashMap<Card, Integer>();
|
||||||
@@ -254,7 +254,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final boolean assignDamageAsIfNotBlocked(Card attacker) {
|
private final boolean assignDamageAsIfNotBlocked(Card attacker) {
|
||||||
return attacker.hasKeyword("CARDNAME assigns its combat damage as though it weren't blocked.")
|
return attacker.hasKeyword("CARDNAME assigns its combat damage as though it weren't blocked.")
|
||||||
|| (attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")
|
|| (attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")
|
||||||
@@ -270,8 +270,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
for(int i = canChooseZero ? 0 : 1; i < 10; i++)
|
for(int i = canChooseZero ? 0 : 1; i < 10; i++)
|
||||||
options.add(Integer.valueOf(i));
|
options.add(Integer.valueOf(i));
|
||||||
options.add("Other amount");
|
options.add("Other amount");
|
||||||
|
|
||||||
|
|
||||||
Object chosen = GuiChoose.oneOrNone("Choose " + announce + " for " + ability.getSourceCard().getName(), options);
|
Object chosen = GuiChoose.oneOrNone("Choose " + announce + " for " + ability.getSourceCard().getName(), options);
|
||||||
if (chosen instanceof Integer || chosen == null)
|
if (chosen instanceof Integer || chosen == null)
|
||||||
return (Integer)chosen;
|
return (Integer)chosen;
|
||||||
@@ -280,27 +279,26 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
while(true){
|
while(true){
|
||||||
String str = JOptionPane.showInputDialog(JOptionPane.getRootFrame(), message, ability.getSourceCard().getName(), JOptionPane.QUESTION_MESSAGE);
|
String str = JOptionPane.showInputDialog(JOptionPane.getRootFrame(), message, ability.getSourceCard().getName(), JOptionPane.QUESTION_MESSAGE);
|
||||||
if (null == str) return null; // that is 'cancel'
|
if (null == str) return null; // that is 'cancel'
|
||||||
|
|
||||||
if(StringUtils.isNumeric(str)) {
|
if(StringUtils.isNumeric(str)) {
|
||||||
Integer val = Integer.valueOf(str);
|
Integer val = Integer.valueOf(str);
|
||||||
if (val == 0 && canChooseZero || val > 0)
|
if (val == 0 && canChooseZero || val > 0)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
GuiDialog.message("You have to enter a valid number", "Announce value");
|
GuiDialog.message("You have to enter a valid number", "Announce value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Card> choosePermanentsToSacrifice(SpellAbility sa, int min, int max, List<Card> valid, String message) {
|
public List<Card> choosePermanentsToSacrifice(SpellAbility sa, int min, int max, List<Card> valid, String message) {
|
||||||
String outerMessage = "Select %d " + message + "(s) to sacrifice";
|
String outerMessage = "Select %d " + message + "(s) to sacrifice";
|
||||||
return choosePermanentsTo(min, max, valid, outerMessage);
|
return choosePermanentsTo(min, max, valid, outerMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Card> choosePermanentsToDestroy(SpellAbility sa, int min, int max, List<Card> valid, String message) {
|
public List<Card> choosePermanentsToDestroy(SpellAbility sa, int min, int max, List<Card> valid, String message) {
|
||||||
String outerMessage = "Select %d " + message + "(s) to be destroyed";
|
String outerMessage = "Select %d " + message + "(s) to be destroyed";
|
||||||
return choosePermanentsTo(min, max, valid, outerMessage);
|
return choosePermanentsTo(min, max, valid, outerMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Card> choosePermanentsTo(int min, int max, List<Card> valid, String outerMessage) {
|
private List<Card> choosePermanentsTo(int min, int max, List<Card> valid, String outerMessage) {
|
||||||
@@ -322,17 +320,17 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
@Override
|
@Override
|
||||||
public List<Card> chooseCardsForEffect(List<Card> sourceList, SpellAbility sa, String title, int amount,
|
public List<Card> chooseCardsForEffect(List<Card> sourceList, SpellAbility sa, String title, int amount,
|
||||||
boolean isOptional) {
|
boolean isOptional) {
|
||||||
// If only one card to choose, use a dialog box.
|
// If only one card to choose, use a dialog box.
|
||||||
// Otherwise, use the order dialog to be able to grab multiple cards in one shot
|
// Otherwise, use the order dialog to be able to grab multiple cards in one shot
|
||||||
if (amount == 1) {
|
if (amount == 1) {
|
||||||
return Lists.newArrayList(chooseSingleCardForEffect(sourceList, sa, title, isOptional));
|
return Lists.newArrayList(chooseSingleCardForEffect(sourceList, sa, title, isOptional));
|
||||||
}
|
}
|
||||||
|
|
||||||
GuiUtils.setPanelSelection(sa.getSourceCard());
|
GuiUtils.setPanelSelection(sa.getSourceCard());
|
||||||
int remaining = isOptional ? -1 : Math.max(sourceList.size() - amount, 0);
|
int remaining = isOptional ? -1 : Math.max(sourceList.size() - amount, 0);
|
||||||
return GuiChoose.order(title, "Chosen Cards", remaining, sourceList, null, sa.getSourceCard());
|
return GuiChoose.order(title, "Chosen Cards", remaining, sourceList, null, sa.getSourceCard());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Card chooseSingleCardForEffect(Collection<Card> options, SpellAbility sa, String title, boolean isOptional) {
|
public Card chooseSingleCardForEffect(Collection<Card> options, SpellAbility sa, String title, boolean isOptional) {
|
||||||
// Human is supposed to read the message and understand from it what to choose
|
// Human is supposed to read the message and understand from it what to choose
|
||||||
@@ -340,7 +338,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
return null;
|
return null;
|
||||||
if ( !isOptional && options.size() == 1 )
|
if ( !isOptional && options.size() == 1 )
|
||||||
return Iterables.getFirst(options, null);
|
return Iterables.getFirst(options, null);
|
||||||
|
|
||||||
boolean canUseSelectCardsInput = true;
|
boolean canUseSelectCardsInput = true;
|
||||||
for(Card c : options) {
|
for(Card c : options) {
|
||||||
Zone cz = c.getZone();
|
Zone cz = c.getZone();
|
||||||
@@ -359,7 +357,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
Singletons.getControl().getInputQueue().setInputAndWait(input);
|
Singletons.getControl().getInputQueue().setInputAndWait(input);
|
||||||
return Iterables.getFirst(input.getSelected(), null);
|
return Iterables.getFirst(input.getSelected(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return isOptional ? GuiChoose.oneOrNone(title, options) : GuiChoose.one(title, options);
|
return isOptional ? GuiChoose.oneOrNone(title, options) : GuiChoose.one(title, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,7 +420,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
@Override
|
@Override
|
||||||
public void reveal(String string, Collection<Card> cards, ZoneType zone, Player owner) {
|
public void reveal(String string, Collection<Card> cards, ZoneType zone, Player owner) {
|
||||||
String message = string;
|
String message = string;
|
||||||
if ( StringUtils.isBlank(message) )
|
if ( StringUtils.isBlank(message) )
|
||||||
message = String.format("Looking at %s's %s", owner, zone);
|
message = String.format("Looking at %s's %s", owner, zone);
|
||||||
GuiChoose.oneOrNone(message, cards);
|
GuiChoose.oneOrNone(message, cards);
|
||||||
}
|
}
|
||||||
@@ -431,13 +429,13 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
public ImmutablePair<List<Card>, List<Card>> arrangeForScry(List<Card> topN) {
|
public ImmutablePair<List<Card>, List<Card>> arrangeForScry(List<Card> topN) {
|
||||||
List<Card> toBottom = null;
|
List<Card> toBottom = null;
|
||||||
List<Card> toTop = null;
|
List<Card> toTop = null;
|
||||||
|
|
||||||
if (topN.size() == 1) {
|
if (topN.size() == 1) {
|
||||||
if (willPutCardOnTop(topN.get(0)))
|
if (willPutCardOnTop(topN.get(0)))
|
||||||
toTop = topN;
|
toTop = topN;
|
||||||
else
|
else
|
||||||
toBottom = topN;
|
toBottom = topN;
|
||||||
} else {
|
} else {
|
||||||
toBottom = GuiChoose.order("Select cards to be put on the bottom of your library", "Cards to put on the bottom", -1, topN, null, null);
|
toBottom = GuiChoose.order("Select cards to be put on the bottom of your library", "Cards to put on the bottom", -1, topN, null, null);
|
||||||
topN.removeAll(toBottom);
|
topN.removeAll(toBottom);
|
||||||
if ( topN.isEmpty() )
|
if ( topN.isEmpty() )
|
||||||
@@ -633,7 +631,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
autoPassCancel(); // probably cancel, since something has happened
|
autoPassCancel(); // probably cancel, since something has happened
|
||||||
|
|
||||||
SpellAbility chosenSa = null;
|
SpellAbility chosenSa = null;
|
||||||
do {
|
do {
|
||||||
if (chosenSa != null) {
|
if (chosenSa != null) {
|
||||||
@@ -709,8 +707,8 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// end of not related candidates for move.
|
// end of not related candidates for move.
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.game.player.PlayerController#chooseBinary(java.lang.String, boolean)
|
* @see forge.game.player.PlayerController#chooseBinary(java.lang.String, boolean)
|
||||||
*/
|
*/
|
||||||
@@ -760,21 +758,21 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
public Pair<SpellAbilityStackInstance, GameObject> chooseTarget(SpellAbility saSpellskite, List<Pair<SpellAbilityStackInstance, GameObject>> allTargets) {
|
public Pair<SpellAbilityStackInstance, GameObject> chooseTarget(SpellAbility saSpellskite, List<Pair<SpellAbilityStackInstance, GameObject>> allTargets) {
|
||||||
if( allTargets.size() < 2)
|
if( allTargets.size() < 2)
|
||||||
return Iterables.getFirst(allTargets, null);
|
return Iterables.getFirst(allTargets, null);
|
||||||
|
|
||||||
final Function<Pair<SpellAbilityStackInstance, GameObject>, String> fnToString = new Function<Pair<SpellAbilityStackInstance, GameObject>, String>() {
|
final Function<Pair<SpellAbilityStackInstance, GameObject>, String> fnToString = new Function<Pair<SpellAbilityStackInstance, GameObject>, String>() {
|
||||||
@Override
|
@Override
|
||||||
public String apply(Pair<SpellAbilityStackInstance, GameObject> targ) {
|
public String apply(Pair<SpellAbilityStackInstance, GameObject> targ) {
|
||||||
return targ.getRight().toString() + " - " + targ.getLeft().getStackDescription();
|
return targ.getRight().toString() + " - " + targ.getLeft().getStackDescription();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
List<Pair<SpellAbilityStackInstance, GameObject>> chosen = GuiChoose.getChoices(saSpellskite.getSourceCard().getName(), 1, 1, allTargets, null, fnToString);
|
List<Pair<SpellAbilityStackInstance, GameObject>> chosen = GuiChoose.getChoices(saSpellskite.getSourceCard().getName(), 1, 1, allTargets, null, fnToString);
|
||||||
return Iterables.getFirst(chosen, null);
|
return Iterables.getFirst(chosen, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyOfValue(SpellAbility sa, GameObject realtedTarget, String value) {
|
public void notifyOfValue(SpellAbility sa, GameObject realtedTarget, String value) {
|
||||||
String message = formatNotificationMessage(sa, realtedTarget, value);
|
String message = formatNotificationMessage(sa, realtedTarget, value);
|
||||||
GuiDialog.message(message, sa.getSourceCard().getName());
|
GuiDialog.message(message, sa.getSourceCard().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -790,8 +788,8 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
return String.format(random ? "Randomly chosen number for %s is %s" : "%s choses number: %s", mayBeYou(target, player), value);
|
return String.format(random ? "Randomly chosen number for %s is %s" : "%s choses number: %s", mayBeYou(target, player), value);
|
||||||
case FlipACoin:
|
case FlipACoin:
|
||||||
String flipper = StringUtils.capitalize(mayBeYou(target, player));
|
String flipper = StringUtils.capitalize(mayBeYou(target, player));
|
||||||
return sa.hasParam("NoCall")
|
return sa.hasParam("NoCall")
|
||||||
? String.format("%s flip comes up %s", Lang.getPossesive(flipper), value)
|
? String.format("%s flip comes up %s", Lang.getPossesive(flipper), value)
|
||||||
: String.format("%s %s the flip", flipper, Lang.joinVerb(flipper, value));
|
: String.format("%s %s the flip", flipper, Lang.joinVerb(flipper, value));
|
||||||
case Protection:
|
case Protection:
|
||||||
String choser = StringUtils.capitalize(mayBeYou(target, player));
|
String choser = StringUtils.capitalize(mayBeYou(target, player));
|
||||||
@@ -800,7 +798,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
return String.format("%s effect's value for %s is %s", sa.getSourceCard().getName(), mayBeYou(target, player), value);
|
return String.format("%s effect's value for %s is %s", sa.getSourceCard().getName(), mayBeYou(target, player), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String mayBeYou(GameObject what, Player you) {
|
private String mayBeYou(GameObject what, Player you) {
|
||||||
return what == you ? "you" : what.toString();
|
return what == you ? "you" : what.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,14 +42,14 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
|||||||
private boolean finished = false;
|
private boolean finished = false;
|
||||||
protected final boolean isFinished() { return finished; }
|
protected final boolean isFinished() { return finished; }
|
||||||
protected final void setFinished() { finished = true; }
|
protected final void setFinished() { finished = true; }
|
||||||
|
|
||||||
// showMessage() is always the first method called
|
// showMessage() is always the first method called
|
||||||
@Override
|
@Override
|
||||||
public final void showMessageInitial() {
|
public final void showMessageInitial() {
|
||||||
finished = false;
|
finished = false;
|
||||||
showMessage();
|
showMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void showMessage();
|
protected abstract void showMessage();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,7 +58,6 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
|||||||
@Override
|
@Override
|
||||||
public void selectAbility(SpellAbility ab) { }
|
public void selectAbility(SpellAbility ab) { }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void selectButtonCancel() {
|
public final void selectButtonCancel() {
|
||||||
if( isFinished() ) return;
|
if( isFinished() ) return;
|
||||||
@@ -82,11 +81,10 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
|||||||
protected void onOk() {}
|
protected void onOk() {}
|
||||||
|
|
||||||
// to remove need for CMatchUI dependence
|
// to remove need for CMatchUI dependence
|
||||||
protected final void showMessage(String message) {
|
protected final void showMessage(String message) {
|
||||||
CMatchUI.SINGLETON_INSTANCE.showMessage(message);
|
CMatchUI.SINGLETON_INSTANCE.showMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected final void flashIncorrectAction() {
|
protected final void flashIncorrectAction() {
|
||||||
SDisplayUtil.remind(VPrompt.SINGLETON_INSTANCE);
|
SDisplayUtil.remind(VPrompt.SINGLETON_INSTANCE);
|
||||||
}
|
}
|
||||||
@@ -94,7 +92,7 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
|||||||
protected String getTurnPhasePriorityMessage(Game game) {
|
protected String getTurnPhasePriorityMessage(Game game) {
|
||||||
final PhaseHandler ph = game.getPhaseHandler();
|
final PhaseHandler ph = game.getPhaseHandler();
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
sb.append("Priority: ").append(ph.getPriorityPlayer()).append("\n");
|
sb.append("Priority: ").append(ph.getPriorityPlayer()).append("\n");
|
||||||
sb.append("Turn ").append(ph.getTurn()).append(" (").append(ph.getPlayerTurn()).append(")\n");
|
sb.append("Turn ").append(ph.getTurn()).append(" (").append(ph.getPlayerTurn()).append(")\n");
|
||||||
sb.append("Phase: ").append(ph.getPhase().nameForUi).append("\n");
|
sb.append("Phase: ").append(ph.getPhase().nameForUi).append("\n");
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class InputBlock extends InputSyncronizedBase {
|
|||||||
private final Combat combat;
|
private final Combat combat;
|
||||||
private final Player defender;
|
private final Player defender;
|
||||||
private final Player declarer;
|
private final Player declarer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for Constructor.
|
* TODO: Write javadoc for Constructor.
|
||||||
* @param priority
|
* @param priority
|
||||||
@@ -62,24 +62,24 @@ public class InputBlock extends InputSyncronizedBase {
|
|||||||
protected final void showMessage() {
|
protected final void showMessage() {
|
||||||
// could add "Reset Blockers" button
|
// could add "Reset Blockers" button
|
||||||
ButtonUtil.enableOnlyOk();
|
ButtonUtil.enableOnlyOk();
|
||||||
|
|
||||||
String prompt = declarer == defender ? "declare blockers." : "declare blockers for " + defender.getName();
|
String prompt = declarer == defender ? "declare blockers." : "declare blockers for " + defender.getName();
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder(declarer.getName());
|
final StringBuilder sb = new StringBuilder(declarer.getName());
|
||||||
sb.append(", ").append(prompt).append("\n\n");
|
sb.append(", ").append(prompt).append("\n\n");
|
||||||
|
|
||||||
if (this.currentAttacker == null) {
|
if (this.currentAttacker == null) {
|
||||||
sb.append("To Block, click on your opponent's attacker first, then your blocker(s).\n");
|
sb.append("To Block, click on your opponent's attacker first, then your blocker(s).\n");
|
||||||
sb.append("To cancel a block right-click on your blocker");
|
sb.append("To cancel a block right-click on your blocker");
|
||||||
showMessage(sb.toString());
|
}
|
||||||
} else {
|
else {
|
||||||
final String attackerName = this.currentAttacker.isFaceDown() ? "Morph" : this.currentAttacker.getName();
|
final String attackerName = this.currentAttacker.isFaceDown() ? "Morph" : this.currentAttacker.getName();
|
||||||
sb.append("Select a creature to block ").append(attackerName).append(" (");
|
sb.append("Select a creature to block ").append(attackerName).append(" (");
|
||||||
sb.append(this.currentAttacker.getUniqueNumber()).append("). ");
|
sb.append(this.currentAttacker.getUniqueNumber()).append("). ");
|
||||||
sb.append("To cancel a block right-click on your blocker");
|
sb.append("To cancel a block right-click on your blocker");
|
||||||
showMessage(sb.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showMessage(sb.toString());
|
||||||
CMatchUI.SINGLETON_INSTANCE.showCombat(combat);
|
CMatchUI.SINGLETON_INSTANCE.showCombat(combat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,14 +100,13 @@ public class InputBlock extends InputSyncronizedBase {
|
|||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final void onCardSelected(final Card card, final MouseEvent triggerEvent) {
|
public final void onCardSelected(final Card card, final MouseEvent triggerEvent) {
|
||||||
|
|
||||||
if (triggerEvent.getButton() == 3 && card.getController() == defender) {
|
if (triggerEvent.getButton() == 3 && card.getController() == defender) {
|
||||||
combat.removeFromCombat(card);
|
combat.removeFromCombat(card);
|
||||||
CMatchUI.SINGLETON_INSTANCE.fireEvent(new UiEventBlockerAssigned(card, (Card)null));
|
CMatchUI.SINGLETON_INSTANCE.fireEvent(new UiEventBlockerAssigned(card, (Card)null));
|
||||||
} else {
|
} else {
|
||||||
// is attacking?
|
// is attacking?
|
||||||
boolean isCorrectAction = false;
|
boolean isCorrectAction = false;
|
||||||
|
|
||||||
if (combat.isAttacking(card)) {
|
if (combat.isAttacking(card)) {
|
||||||
setCurrentAttacker(card);
|
setCurrentAttacker(card);
|
||||||
isCorrectAction = true;
|
isCorrectAction = true;
|
||||||
@@ -121,7 +120,7 @@ public class InputBlock extends InputSyncronizedBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCorrectAction) {
|
if (!isCorrectAction) {
|
||||||
flashIncorrectAction();
|
flashIncorrectAction();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user