Don't prompt to declare blockers if no creatures can block

This commit is contained in:
drdev
2013-11-30 22:01:04 +00:00
parent 2ffc18cc89
commit 9ca9dc797e
6 changed files with 87 additions and 72 deletions

View File

@@ -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

View File

@@ -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();

View File

@@ -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

View File

@@ -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();
} }

View File

@@ -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");

View File

@@ -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();
} }