mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Don't prompt to declare blockers if no creatures can block
This commit is contained in:
@@ -35,16 +35,13 @@ 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();
|
||||||
@@ -96,7 +93,6 @@ public class InputQueue extends Observable {
|
|||||||
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();
|
||||||
|
|||||||
@@ -556,12 +556,15 @@ public class PhaseHandler implements java.io.Serializable {
|
|||||||
whoDeclaresBlockers = combat.getAttackingPlayer();
|
whoDeclaresBlockers = combat.getAttackingPlayer();
|
||||||
}
|
}
|
||||||
if (combat.isPlayerAttacked(p)) {
|
if (combat.isPlayerAttacked(p)) {
|
||||||
|
if (CombatUtil.canBlock(p, combat)) {
|
||||||
whoDeclaresBlockers.getController().declareBlockers(p, combat);
|
whoDeclaresBlockers.getController().declareBlockers(p, combat);
|
||||||
} else
|
}
|
||||||
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
|
||||||
|
|||||||
@@ -271,7 +271,6 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
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;
|
||||||
@@ -290,7 +289,6 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@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";
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -86,7 +85,6 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,15 +71,15 @@ public class InputBlock extends InputSyncronizedBase {
|
|||||||
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,7 +100,6 @@ 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));
|
||||||
|
|||||||
Reference in New Issue
Block a user