diff --git a/src/main/java/forge/control/InputQueue.java b/src/main/java/forge/control/InputQueue.java index cb8344cc000..72ddad2ef0d 100644 --- a/src/main/java/forge/control/InputQueue.java +++ b/src/main/java/forge/control/InputQueue.java @@ -88,11 +88,19 @@ public class InputQueue extends MyObservable implements java.io.Serializable { public void setInputAndWait(InputSynchronized input) { this.inputStack.push(input); + syncPoint(); this.updateObservers(); input.awaitLatchRelease(); } + + public void syncPoint() { + synchronized (inputLock) { + // acquire and release lock, so that actions from Game thread happen before EDT reads their results + } + } + /** * TODO: Write javadoc for this method. */ diff --git a/src/main/java/forge/game/player/PlayerControllerHuman.java b/src/main/java/forge/game/player/PlayerControllerHuman.java index 3fb6870675b..7822f2f3ed1 100644 --- a/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -493,7 +493,7 @@ public class PlayerControllerHuman extends PlayerController { case COMBAT_DECLARE_ATTACKERS: game.getCombat().initiatePossibleDefenders(player.getOpponents()); - InputSynchronized inpAttack = new InputAttack(player); + InputSynchronized inpAttack = new InputAttack(player, game.getCombat()); Singletons.getControl().getInputQueue().setInputAndWait(inpAttack); return; diff --git a/src/main/java/forge/gui/InputProxy.java b/src/main/java/forge/gui/InputProxy.java index 2214fa6e9d1..29b466c287e 100644 --- a/src/main/java/forge/gui/InputProxy.java +++ b/src/main/java/forge/gui/InputProxy.java @@ -62,6 +62,7 @@ public class InputProxy implements Observer { Runnable showMessage = new Runnable() { @Override public void run() { Input current = getInput(); + Singletons.getControl().getInputQueue().syncPoint(); //System.out.printf("\t%s > showMessage @ %s/%s during %s%n", FThreads.debugGetCurrThreadId(), nextInput.getClass().getSimpleName(), current.getClass().getSimpleName(), game.getPhaseHandler().debugPrintState()); current.showMessageInitial(); } diff --git a/src/main/java/forge/gui/input/InputAttack.java b/src/main/java/forge/gui/input/InputAttack.java index d9bad95d779..5151b193973 100644 --- a/src/main/java/forge/gui/input/InputAttack.java +++ b/src/main/java/forge/gui/input/InputAttack.java @@ -26,10 +26,9 @@ import com.google.common.collect.Iterables; import forge.Card; import forge.CardPredicates; import forge.GameEntity; -import forge.game.Game; +import forge.game.phase.Combat; import forge.game.phase.CombatUtil; import forge.game.player.Player; -import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.util.MyObservable; import forge.view.ButtonUtil; @@ -47,14 +46,15 @@ public class InputAttack extends InputSyncronizedBase { private static final long serialVersionUID = 7849903731842214245L; - private final Game game; - private List defenders; + private final Combat combat; + private final List defenders; private GameEntity currentDefender; private final Player player; - public InputAttack(Player human) { - player = human; - game = human.getGame(); + public InputAttack(Player human, Combat combat) { + this.player = human; + this.combat = combat; + this.defenders = combat.getDefenders(); } @@ -64,7 +64,7 @@ public class InputAttack extends InputSyncronizedBase { // TODO still seems to have some issues with multiple planeswalkers ButtonUtil.enableOnlyOk(); - defenders = game.getCombat().getDefenders(); + setCurrentDefender(defenders.isEmpty() ? null : defenders.get(0)); if ( null == currentDefender ) { @@ -78,8 +78,8 @@ public class InputAttack extends InputSyncronizedBase { continue; // do not force for(GameEntity def : defenders ) { - if( CombatUtil.canAttack(c, def, game.getCombat()) ) { - game.getCombat().addAttacker(c, currentDefender); + if( CombatUtil.canAttack(c, def, combat) ) { + combat.addAttacker(c, currentDefender); break; } } @@ -110,9 +110,9 @@ public class InputAttack extends InputSyncronizedBase { /** {@inheritDoc} */ @Override protected final void onCardSelected(final Card card, boolean isMetaDown) { - final List att = game.getCombat().getAttackers(); + final List att = combat.getAttackers(); if (isMetaDown && att.contains(card) && !card.hasKeyword("CARDNAME attacks each turn if able.")) { - game.getCombat().removeFromCombat(card); + combat.removeFromCombat(card); showCombat(); return; } @@ -128,12 +128,11 @@ public class InputAttack extends InputSyncronizedBase { } } - Zone zone = game.getZoneOf(card); - if (zone.is(ZoneType.Battlefield, player) && CombatUtil.canAttack(card, currentDefender, game.getCombat())) { - if( game.getCombat().isAttacking(card)) { - game.getCombat().removeFromCombat(card); + if (player.getZone(ZoneType.Battlefield).contains(card) && CombatUtil.canAttack(card, currentDefender, combat)) { + if( combat.isAttacking(card)) { + combat.removeFromCombat(card); } - game.getCombat().addAttacker(card, currentDefender); + combat.addAttacker(card, currentDefender); showCombat(); } else { diff --git a/src/main/java/forge/gui/match/CMatchUI.java b/src/main/java/forge/gui/match/CMatchUI.java index 1ca54e866c5..6a87c8d1db7 100644 --- a/src/main/java/forge/gui/match/CMatchUI.java +++ b/src/main/java/forge/gui/match/CMatchUI.java @@ -42,6 +42,7 @@ import forge.gui.match.controllers.CMessage; import forge.gui.match.controllers.CPicture; import forge.gui.match.nonsingleton.VCommand; import forge.gui.match.nonsingleton.VField; +import forge.gui.match.nonsingleton.VField.PhaseLabel; import forge.gui.match.nonsingleton.VHand; import forge.gui.match.views.VPlayers; import forge.gui.toolbox.FSkin; @@ -233,23 +234,8 @@ public enum CMatchUI { */ public final boolean stopAtPhase(final Player turn, final PhaseType phase) { VField vf = getFieldViewFor(turn); - - switch (phase) { - case UPKEEP: return vf.getLblUpkeep().getEnabled(); - case DRAW: return vf.getLblDraw().getEnabled(); - case MAIN1: return vf.getLblMain1().getEnabled(); - case COMBAT_BEGIN: return vf.getLblBeginCombat().getEnabled(); - case COMBAT_DECLARE_ATTACKERS: return vf.getLblDeclareAttackers().getEnabled(); - case COMBAT_DECLARE_BLOCKERS: return vf.getLblDeclareBlockers().getEnabled(); - case COMBAT_FIRST_STRIKE_DAMAGE: return vf.getLblFirstStrike().getEnabled(); - case COMBAT_DAMAGE: return vf.getLblCombatDamage().getEnabled(); - case COMBAT_END: return vf.getLblEndCombat().getEnabled(); - case MAIN2: return vf.getLblMain2().getEnabled(); - case END_OF_TURN: return vf.getLblEndTurn().getEnabled(); - default: - } - - return true; + PhaseLabel label = vf.getLabelFor(phase); + return label == null || label.isTurnedOn(); } public void setCard(final Card c) {