Support showing prompt for second human player

This commit is contained in:
drdev
2014-09-23 13:38:39 +00:00
parent b7ceefc8c4
commit efefedd445
29 changed files with 260 additions and 172 deletions

1
.gitattributes vendored
View File

@@ -16988,6 +16988,7 @@ forge-gui/src/main/java/forge/match/input/InputBlock.java -text
forge-gui/src/main/java/forge/match/input/InputConfirm.java -text
forge-gui/src/main/java/forge/match/input/InputConfirmMulligan.java -text
forge-gui/src/main/java/forge/match/input/InputLockUI.java -text
forge-gui/src/main/java/forge/match/input/InputNone.java -text
forge-gui/src/main/java/forge/match/input/InputPassPriority.java -text
forge-gui/src/main/java/forge/match/input/InputPayMana.java -text
forge-gui/src/main/java/forge/match/input/InputPayManaOfCostPayment.java -text

View File

@@ -52,7 +52,6 @@ import forge.gui.framework.SLayoutIO;
import forge.interfaces.IButton;
import forge.interfaces.IGuiBase;
import forge.item.PaperCard;
import forge.match.input.InputQueue;
import forge.model.FModel;
import forge.screens.deckeditor.CDeckEditorUI;
import forge.screens.deckeditor.controllers.CEditorQuestCardShop;
@@ -235,12 +234,12 @@ public class GuiDesktop implements IGuiBase {
}
@Override
public IButton getBtnOK() {
public IButton getBtnOK(PlayerView playerView) {
return VMatchUI.SINGLETON_INSTANCE.getBtnOK();
}
@Override
public IButton getBtnCancel() {
public IButton getBtnCancel(PlayerView playerView) {
return VMatchUI.SINGLETON_INSTANCE.getBtnCancel();
}
@@ -426,7 +425,7 @@ public class GuiDesktop implements IGuiBase {
}
@Override
public void showPromptMessage(final String message) {
public void showPromptMessage(final PlayerView playerView, final String message) {
CMatchUI.SINGLETON_INSTANCE.showMessage(message);
}
@@ -435,11 +434,6 @@ public class GuiDesktop implements IGuiBase {
return CMatchUI.SINGLETON_INSTANCE.stopAtPhase(playerTurn, phase);
}
@Override
public InputQueue getInputQueue() {
return FControl.instance.getInputQueue();
}
public Object showManaPool(final PlayerView player) {
return null; //not needed since mana pool icons are always visible
}

View File

@@ -63,6 +63,7 @@ import forge.gui.framework.SLayoutIO;
import forge.gui.framework.SOverflowUtil;
import forge.gui.framework.SResizingUtil;
import forge.match.input.InputQueue;
import forge.match.input.InputSynchronized;
import forge.menus.ForgeMenu;
import forge.model.FModel;
import forge.player.GamePlayerUtil;
@@ -407,19 +408,20 @@ public enum FControl implements KeyEventDispatcher {
public Player getCurrentPlayer() {
if (game == null) { return null; }
// try current priority
Player currentPriority = game.getPhaseHandler().getPriorityPlayer();
if (null != currentPriority && currentPriority.getLobbyPlayer() == getGuiPlayer()) {
return currentPriority;
LobbyPlayer lobbyPlayer = getGuiPlayer();
if (gameViews.size() > 1) {
//account for if second human player is currently being prompted
InputSynchronized activeInput = InputQueue.getActiveInput();
if (activeInput != null) {
lobbyPlayer = activeInput.getOwner().getLobbyPlayer();
}
}
// otherwise find just any player, belonging to this lobbyplayer
for (Player p : game.getPlayers()) {
if (p.getLobbyPlayer() == getGuiPlayer()) {
if (p.getLobbyPlayer() == lobbyPlayer) {
return p;
}
}
return null;
}
@@ -511,15 +513,16 @@ public enum FControl implements KeyEventDispatcher {
if (p.getController() instanceof PlayerControllerHuman) {
final PlayerControllerHuman controller = (PlayerControllerHuman) p.getController();
LocalGameView gameView = controller.getGameView();
game.subscribeToEvents(new FControlGameEventHandler(GuiBase.getInterface(), gameView));
game.subscribeToEvents(new FControlGameEventHandler(gameView));
gameViews.add(gameView);
humanCount++;
}
}
if (humanCount == 0) { //watch game but do not participate
LocalGameView gameView = new WatchLocalGame(game, GuiBase.getInterface());
game.subscribeToEvents(new FControlGameEventHandler(GuiBase.getInterface(), gameView));
LocalGameView gameView = new WatchLocalGame(GuiBase.getInterface(), game);
gameView.setLocalPlayer(sortedPlayers.get(0));
game.subscribeToEvents(new FControlGameEventHandler(gameView));
gameViews.add(gameView);
}
else if (humanCount == sortedPlayers.size()) {

View File

@@ -36,7 +36,6 @@ import forge.game.zone.ZoneType;
import forge.interfaces.IButton;
import forge.interfaces.IGuiBase;
import forge.item.PaperCard;
import forge.match.input.InputQueue;
import forge.properties.ForgeConstants;
import forge.screens.match.FControl;
import forge.screens.match.views.VPlayerPanel;
@@ -238,13 +237,18 @@ public class GuiMobile implements IGuiBase {
}
@Override
public IButton getBtnOK() {
return FControl.getView().getActivePrompt().getBtnOk();
public IButton getBtnOK(PlayerView player) {
return FControl.getView().getPrompt(player).getBtnOk();
}
@Override
public IButton getBtnCancel() {
return FControl.getView().getActivePrompt().getBtnCancel();
public IButton getBtnCancel(PlayerView player) {
return FControl.getView().getPrompt(player).getBtnCancel();
}
@Override
public void showPromptMessage(final PlayerView player, String message) {
FControl.getView().getPrompt(player).setMessage(message);
}
@Override
@@ -358,21 +362,11 @@ public class GuiMobile implements IGuiBase {
FControl.setHighlighted(player, b);
}
@Override
public void showPromptMessage(String message) {
FControl.showMessage(message);
}
@Override
public boolean stopAtPhase(final PlayerView playerTurn, final PhaseType phase) {
return FControl.stopAtPhase(playerTurn, phase);
}
@Override
public InputQueue getInputQueue() {
return FControl.getInputQueue();
}
@Override
public Object showManaPool(final PlayerView player) {
VPlayerPanel playerPanel = FControl.getPlayerPanel(player);

View File

@@ -48,6 +48,7 @@ import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType;
import forge.match.input.InputPlaybackControl;
import forge.match.input.InputQueue;
import forge.match.input.InputSynchronized;
import forge.model.FModel;
import forge.player.GamePlayerUtil;
import forge.player.PlayerControllerHuman;
@@ -175,15 +176,16 @@ public class FControl {
if (p.getController() instanceof PlayerControllerHuman) {
final PlayerControllerHuman controller = (PlayerControllerHuman) p.getController();
LocalGameView gameView = controller.getGameView();
game.subscribeToEvents(new FControlGameEventHandler(GuiBase.getInterface(), gameView));
game.subscribeToEvents(new FControlGameEventHandler(gameView));
gameViews.add(gameView);
humanCount++;
}
}
if (humanCount == 0) { //watch game but do not participate
LocalGameView gameView = new WatchLocalGame(game, GuiBase.getInterface());
game.subscribeToEvents(new FControlGameEventHandler(GuiBase.getInterface(), gameView));
LocalGameView gameView = new WatchLocalGame(GuiBase.getInterface(), game);
gameView.setLocalPlayer(sortedPlayers.get(0));
game.subscribeToEvents(new FControlGameEventHandler(gameView));
gameViews.add(gameView);
}
else if (humanCount == sortedPlayers.size()) {
@@ -281,13 +283,6 @@ public class FControl {
}
}
public static void showMessage(final String s0) {
view.getActivePrompt().setMessage(s0);
}
public static void showMessage(final PlayerView playerView, final String s0) {
view.getPrompt(playerView).setMessage(s0);
}
public static VPlayerPanel getPlayerPanel(final PlayerView playerView) {
return view.getPlayerPanels().get(playerView);
}
@@ -314,19 +309,20 @@ public class FControl {
public static Player getCurrentPlayer() {
if (game == null) { return null; }
// try current priority
Player currentPriority = game.getPhaseHandler().getPriorityPlayer();
if (null != currentPriority && currentPriority.getLobbyPlayer() == getGuiPlayer()) {
return currentPriority;
LobbyPlayer lobbyPlayer = getGuiPlayer();
if (gameViews.size() > 1) {
//account for if second human player is currently being prompted
InputSynchronized activeInput = InputQueue.getActiveInput();
if (activeInput != null) {
lobbyPlayer = activeInput.getOwner().getLobbyPlayer();
}
}
// otherwise find just any player, belonging to this lobbyplayer
for (Player p : game.getPlayers()) {
if (p.getLobbyPlayer() == getGuiPlayer()) {
if (p.getLobbyPlayer() == lobbyPlayer) {
return p;
}
}
return null;
}

View File

@@ -49,9 +49,9 @@ import forge.game.player.Player;
import forge.game.zone.PlayerZone;
import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
import forge.interfaces.IGuiBase;
import forge.match.input.ButtonUtil;
import forge.match.input.InputBase;
import forge.match.input.InputNone;
import forge.model.FModel;
import forge.player.GamePlayerUtil;
import forge.properties.ForgePreferences.FPref;
@@ -64,11 +64,9 @@ import forge.view.PlayerView;
public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
private final IGuiBase gui;
private final LocalGameView gameView;
public FControlGameEventHandler(final IGuiBase gui, final LocalGameView gameView) {
this.gui = gui;
this.gameView = gameView;
public FControlGameEventHandler(final LocalGameView gameView0) {
gameView = gameView0;
}
@Subscribe
@@ -81,11 +79,11 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
public Void visit(final GameEventTurnPhase ev) {
if (phaseUpdPlanned.getAndSet(true)) return null;
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
FThreads.invokeInEdtNowOrLater(gameView.getGui(), new Runnable() {
@Override
public void run() {
phaseUpdPlanned.set(false);
gui.updatePhase();
gameView.getGui().updatePhase();
}
});
return null;
@@ -98,11 +96,11 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
@Override
public Void visit(GameEventPlayerPriority event) {
if (combatUpdPlanned.getAndSet(true)) { return null; }
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
FThreads.invokeInEdtNowOrLater(gameView.getGui(), new Runnable() {
@Override
public void run() {
combatUpdPlanned.set(false);
gui.showCombat(gameView.getCombat());
gameView.getGui().showCombat(gameView.getCombat());
}
});
return null;
@@ -118,11 +116,11 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
if (turnUpdPlanned.getAndSet(true)) { return null; }
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
FThreads.invokeInEdtNowOrLater(gameView.getGui(), new Runnable() {
@Override
public void run() {
turnUpdPlanned.set(false);
gui.updateTurn(gameView.getPlayerView(event.turnOwner));
gameView.getGui().updateTurn(gameView.getPlayerView(event.turnOwner));
}
});
return null;
@@ -137,7 +135,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
options.add(fakeCard);
options.add(gameView.getCardView(kv.getValue()));
}
SGuiChoose.reveal(gui, "These cards were chosen to ante", options);
SGuiChoose.reveal(gameView.getGui(), "These cards were chosen to ante", options);
return null;
}
@@ -147,10 +145,10 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
return null;
}
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
FThreads.invokeInEdtNowOrLater(gameView.getGui(), new Runnable() {
@Override
public void run() {
gui.updatePlayerControl();
gameView.getGui().updatePlayerControl();
}
});
return null;
@@ -159,25 +157,26 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
private final Runnable unlockGameThreadOnGameOver = new Runnable() {
@Override
public void run() {
gui.getInputQueue().onGameOver(true); // this will unlock any game threads waiting for inputs to complete
gameView.getInputQueue().onGameOver(true); // this will unlock any game threads waiting for inputs to complete
}
};
@Override
public Void visit(GameEventGameOutcome ev) {
FThreads.invokeInEdtNowOrLater(gui, unlockGameThreadOnGameOver);
FThreads.invokeInEdtNowOrLater(gameView.getGui(), unlockGameThreadOnGameOver);
return null;
}
@Override
public Void visit(GameEventGameFinished ev) {
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
FThreads.invokeInEdtNowOrLater(gameView.getGui(), new Runnable() {
@Override
public void run() {
InputNone inputNone = new InputNone(gameView);
InputBase.cancelAwaitNextInput(); //ensure "Waiting for opponent..." doesn't appear behind WinLo
gui.showPromptMessage(""); //clear prompt behind WinLose overlay
ButtonUtil.update(gui, "", "", false, false, false);
gui.finishGame();
gameView.getGui().showPromptMessage(inputNone.getOwner(), ""); //clear prompt behind WinLose overlay
ButtonUtil.update(inputNone, "", "", false, false, false);
gameView.getGui().finishGame();
gameView.updateAchievements();
}
});
@@ -189,28 +188,28 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
@Override
public void run() {
stackUpdPlanned.set(false);
gui.updateStack();
gameView.getGui().updateStack();
}
};
@Override
public Void visit(GameEventSpellAbilityCast event) {
if (!stackUpdPlanned.getAndSet(true)) {
FThreads.invokeInEdtNowOrLater(gui, updStack);
FThreads.invokeInEdtNowOrLater(gameView.getGui(), updStack);
}
return null;
}
@Override
public Void visit(GameEventSpellResolved event) {
if (!stackUpdPlanned.getAndSet(true)) {
FThreads.invokeInEdtNowOrLater(gui, updStack);
FThreads.invokeInEdtNowOrLater(gameView.getGui(), updStack);
}
return null;
}
@Override
public Void visit(GameEventSpellRemovedFromStack event) {
if (!stackUpdPlanned.getAndSet(true)) {
FThreads.invokeInEdtNowOrLater(gui, updStack);
FThreads.invokeInEdtNowOrLater(gameView.getGui(), updStack);
}
return null;
}
@@ -220,7 +219,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
@Override
public void run() {
synchronized (zonesToUpdate) {
gui.updateZones(zonesToUpdate);
gameView.getGui().updateZones(zonesToUpdate);
zonesToUpdate.clear();
}
}
@@ -261,7 +260,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
}
}
if (needUpdate) {
FThreads.invokeInEdtNowOrLater(gui, updZones);
FThreads.invokeInEdtNowOrLater(gameView.getGui(), updZones);
}
return null;
}
@@ -272,7 +271,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
public void run() {
synchronized (cardsToUpdate) {
final Iterable<CardView> newCardsToUpdate = gameView.getRefreshedCardViews(cardsToUpdate);
gui.updateCards(newCardsToUpdate);
gameView.getGui().updateCards(newCardsToUpdate);
cardsToUpdate.clear();
}
}
@@ -339,7 +338,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
}
}
if (needUpdate) {
FThreads.invokeInEdtNowOrLater(gui, updCards);
FThreads.invokeInEdtNowOrLater(gameView.getGui(), updCards);
}
return null;
}
@@ -351,7 +350,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
Iterables.addAll(cardsToUpdate, cc);
}
if (needUpdate) {
FThreads.invokeInEdtNowOrLater(gui, updCards);
FThreads.invokeInEdtNowOrLater(gameView.getGui(), updCards);
}
return null;
}
@@ -373,14 +372,14 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
@Override
public Void visit(GameEventCardStatsChanged event) {
final Iterable<CardView> cardViews = gameView.getCardViews(event.cards);
gui.refreshCardDetails(cardViews);
gameView.getGui().refreshCardDetails(cardViews);
return updateManyCards(cardViews);
}
@Override
public Void visit(GameEventPlayerStatsChanged event) {
for (final Player p : event.players) {
gui.refreshCardDetails(gameView.getCardViews(p.getAllCards()));
gameView.getGui().refreshCardDetails(gameView.getCardViews(p.getAllCards()));
}
return null;
}
@@ -396,7 +395,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
private final Runnable updManaPool = new Runnable() {
@Override public void run() {
synchronized (manaPoolUpdate) {
gui.updateManaPool(gameView.getPlayerViews(manaPoolUpdate));
gameView.getGui().updateManaPool(gameView.getPlayerViews(manaPoolUpdate));
manaPoolUpdate.clear();
}
}
@@ -412,7 +411,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
}
}
if (invokeUpdate) {
FThreads.invokeInEdtNowOrLater(gui, updManaPool);
FThreads.invokeInEdtNowOrLater(gameView.getGui(), updManaPool);
}
return null;
}
@@ -422,7 +421,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
private final Runnable updLives = new Runnable() {
@Override public void run() {
synchronized (livesUpdate) {
gui.updateLives(gameView.getPlayerViews(livesUpdate));
gameView.getGui().updateLives(gameView.getPlayerViews(livesUpdate));
livesUpdate.clear();
}
}
@@ -437,7 +436,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
}
}
if (invokeUpdate) {
FThreads.invokeInEdtNowOrLater(gui, updLives);
FThreads.invokeInEdtNowOrLater(gameView.getGui(), updLives);
}
return null;
}
@@ -452,7 +451,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
}
}
if (invokeUpdate) {
FThreads.invokeInEdtNowOrLater(gui, updLives);
FThreads.invokeInEdtNowOrLater(gameView.getGui(), updLives);
}
return null;
}

View File

@@ -102,13 +102,13 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
*/
@Override
public Void visit(GameEventGameFinished event) {
gui.getInputQueue().removeInput(inputPlayback);
gameView.getInputQueue().removeInput(inputPlayback);
return null;
}
@Override
public Void visit(GameEventGameStarted event) {
gui.getInputQueue().setInput(inputPlayback);
gameView.getInputQueue().setInput(inputPlayback);
return null;
}

View File

@@ -21,7 +21,6 @@ import forge.game.player.IHasIcon;
import forge.game.player.RegisteredPlayer;
import forge.game.zone.ZoneType;
import forge.item.PaperCard;
import forge.match.input.InputQueue;
import forge.sound.IAudioClip;
import forge.sound.IAudioMusic;
import forge.util.ITriggerEvent;
@@ -59,11 +58,10 @@ public interface IGuiBase {
void showCombat(CombatView combat);
void setUsedToPay(CardView card, boolean b);
void setHighlighted(PlayerView player, boolean b);
void showPromptMessage(String message);
void showPromptMessage(PlayerView playerView, String message);
boolean stopAtPhase(PlayerView playerTurn, PhaseType phase);
InputQueue getInputQueue();
IButton getBtnOK();
IButton getBtnCancel();
IButton getBtnOK(PlayerView playerView);
IButton getBtnCancel(PlayerView playerView);
void focusButton(IButton button);
void flashIncorrectAction();
void updatePhase();

View File

@@ -19,17 +19,20 @@ package forge.match.input;
import forge.interfaces.IButton;
import forge.interfaces.IGuiBase;
import forge.view.PlayerView;
/**
* Manages match UI OK/Cancel button enabling and focus
*/
public class ButtonUtil {
public static void update(final IGuiBase gui, boolean okEnabled, boolean cancelEnabled, boolean focusOk) {
update(gui, "OK", "Cancel", okEnabled, cancelEnabled, focusOk);
public static void update(final Input input, boolean okEnabled, boolean cancelEnabled, boolean focusOk) {
update(input, "OK", "Cancel", okEnabled, cancelEnabled, focusOk);
}
public static void update(final IGuiBase gui, String okLabel, String cancelLabel, boolean okEnabled, boolean cancelEnabled, boolean focusOk) {
IButton btnOk = gui.getBtnOK();
IButton btnCancel = gui.getBtnCancel();
public static void update(final Input input, String okLabel, String cancelLabel, boolean okEnabled, boolean cancelEnabled, boolean focusOk) {
IGuiBase gui = input.getGui();
PlayerView owner = input.getOwner();
IButton btnOk = gui.getBtnOK(owner);
IButton btnCancel = gui.getBtnCancel(owner);
btnOk.setText(okLabel);
btnCancel.setText(cancelLabel);

View File

@@ -3,9 +3,15 @@ package forge.match.input;
import forge.game.card.Card;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.interfaces.IGuiBase;
import forge.util.ITriggerEvent;
import forge.view.PlayerView;
public interface Input {
PlayerView getOwner();
IGuiBase getGui();
void showMessageInitial();
boolean selectCard(Card card, ITriggerEvent triggerEvent);

View File

@@ -100,10 +100,10 @@ public class InputAttack extends InputSyncronizedBase {
private void updatePrompt() {
if (canCallBackAttackers()) {
ButtonUtil.update(getGui(), "OK", "Call Back", true, true, true);
ButtonUtil.update(this, "OK", "Call Back", true, true, true);
}
else {
ButtonUtil.update(getGui(), "OK", "Alpha Strike", true, true, true);
ButtonUtil.update(this, "OK", "Alpha Strike", true, true, true);
}
}

View File

@@ -29,6 +29,8 @@ import forge.game.spellability.SpellAbility;
import forge.interfaces.IGuiBase;
import forge.player.PlayerControllerHuman;
import forge.util.ITriggerEvent;
import forge.view.LocalGameView;
import forge.view.PlayerView;
/**
* <p>
@@ -43,14 +45,20 @@ public abstract class InputBase implements java.io.Serializable, Input {
private static final long serialVersionUID = -6539552513871194081L;
private final PlayerControllerHuman controller;
public InputBase(final PlayerControllerHuman controller) {
this.controller = controller;
public InputBase(final PlayerControllerHuman controller0) {
controller = controller0;
}
public final PlayerControllerHuman getController() {
return this.controller;
return controller;
}
public LocalGameView getGameView() {
return controller.getGameView();
}
public PlayerView getOwner() {
return controller.getPlayerView(controller.getPlayer());
}
public IGuiBase getGui() {
return getController().getGui();
return controller.getGui();
}
private boolean finished = false;
@@ -59,7 +67,7 @@ public abstract class InputBase implements java.io.Serializable, Input {
finished = true;
if (allowAwaitNextInput()) {
awaitNextInput(getGui());
awaitNextInput(this);
}
}
@@ -70,18 +78,18 @@ public abstract class InputBase implements java.io.Serializable, Input {
private static final Timer awaitNextInputTimer = new Timer();
private static TimerTask awaitNextInputTask;
public static void awaitNextInput(final IGuiBase gui) {
public static void awaitNextInput(final Input input) {
//delay updating prompt to await next input briefly so buttons don't flicker disabled then enabled
awaitNextInputTask = new TimerTask() {
@Override
public void run() {
FThreads.invokeInEdtLater(gui, new Runnable() {
FThreads.invokeInEdtLater(input.getGui(), new Runnable() {
@Override
public void run() {
synchronized (awaitNextInputTimer) {
if (awaitNextInputTask != null) {
gui.showPromptMessage("Waiting for opponent...");
ButtonUtil.update(gui, false, false, false);
input.getGui().showPromptMessage(input.getOwner(), "Waiting for opponent...");
ButtonUtil.update(input, false, false, false);
awaitNextInputTask = null;
}
}
@@ -150,7 +158,7 @@ public abstract class InputBase implements java.io.Serializable, Input {
// to remove need for CMatchUI dependence
protected final void showMessage(final String message) {
getGui().showPromptMessage(message);
getGui().showPromptMessage(getOwner(), message);
}
protected final void flashIncorrectAction() {

View File

@@ -74,7 +74,7 @@ public class InputBlock extends InputSyncronizedBase {
@Override
protected final void showMessage() {
// could add "Reset Blockers" button
ButtonUtil.update(getGui(), true, false, true);
ButtonUtil.update(this, true, false, true);
if (currentAttacker == null) {
showMessage("Select another attacker to declare blockers for.");

View File

@@ -56,7 +56,7 @@ public class InputConfirm extends InputSyncronizedBase {
/** {@inheritDoc} */
@Override
protected final void showMessage() {
ButtonUtil.update(getGui(), yesButtonText, noButtonText, true, true, defaultYes);
ButtonUtil.update(this, yesButtonText, noButtonText, true, true, defaultYes);
showMessage(message);
}

View File

@@ -72,11 +72,11 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
}
if (isCommander) {
ButtonUtil.update(getGui(), "Keep", "Exile", true, false, true);
ButtonUtil.update(this, "Keep", "Exile", true, false, true);
sb.append("Will you keep your hand or choose some cards to exile those and draw one less card?");
}
else {
ButtonUtil.update(getGui(), "Keep", "Mulligan", true, true, true);
ButtonUtil.update(this, "Keep", "Mulligan", true, true, true);
sb.append("Do you want to keep your hand?");
}
@@ -144,7 +144,7 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
getGui().setUsedToPay(getController().getCardView(c0), true);
selected.add(c0);
}
ButtonUtil.update(getGui(), "Keep", "Exile", true, !selected.isEmpty(), true);
ButtonUtil.update(this, "Keep", "Exile", true, !selected.isEmpty(), true);
}
return true;
}

View File

@@ -10,22 +10,31 @@ import forge.game.spellability.SpellAbility;
import forge.interfaces.IGuiBase;
import forge.util.ITriggerEvent;
import forge.util.ThreadUtil;
import forge.view.PlayerView;
public class InputLockUI implements Input {
private final AtomicInteger iCall = new AtomicInteger();
private IGuiBase gui;
private final InputQueue inputQueue;
private final Game game;
public InputLockUI(final Game game, final InputQueue inputQueue) {
this.game = game;
public InputLockUI(final Game game0, final InputQueue inputQueue0) {
game = game0;
inputQueue = inputQueue0;
}
private IGuiBase getGui() {
@Override
public PlayerView getOwner() {
return null;
}
@Override
public IGuiBase getGui() {
return gui;
}
public void setGui(final IGuiBase gui) {
this.gui = gui;
public void setGui(final IGuiBase gui0) {
gui = gui0;
}
public void showMessageInitial() {
@@ -56,17 +65,17 @@ public class InputLockUI implements Input {
private final Runnable showMessageFromEdt = new Runnable() {
@Override
public void run() {
ButtonUtil.update(getGui(), "", "", false, false, false);
ButtonUtil.update(InputLockUI.this, "", "", false, false, false);
showMessage("Waiting for actions...");
}
};
protected final boolean isActive() {
return getGui().getInputQueue().getInput() == this;
return inputQueue.getInput() == this;
}
protected void showMessage(String message) {
getGui().showPromptMessage(message);
getGui().showPromptMessage(getOwner(), message);
}
@Override

View File

@@ -0,0 +1,54 @@
package forge.match.input;
import forge.game.card.Card;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.interfaces.IGuiBase;
import forge.util.ITriggerEvent;
import forge.view.LocalGameView;
import forge.view.PlayerView;
public class InputNone implements Input {
private final IGuiBase gui;
private final PlayerView owner;
public InputNone(LocalGameView gameView) {
gui = gameView.getGui();
owner = gameView.getLocalPlayerView();
}
@Override
public IGuiBase getGui() {
return gui;
}
@Override
public PlayerView getOwner() {
return owner;
}
@Override
public void showMessageInitial() {
}
@Override
public boolean selectCard(Card card, ITriggerEvent triggerEvent) {
return false;
}
@Override
public void selectAbility(SpellAbility ab) {
}
@Override
public void selectPlayer(Player player, ITriggerEvent triggerEvent) {
}
@Override
public void selectButtonOK() {
}
@Override
public void selectButtonCancel() {
}
}

View File

@@ -57,10 +57,10 @@ public class InputPassPriority extends InputSyncronizedBase {
showMessage(getTurnPhasePriorityMessage(player.getGame()));
chosenSa = null;
if (getController().canUndoLastAction()) { //allow undoing with cancel button if can undo last action
ButtonUtil.update(getGui(), "OK", "Undo", true, true, true);
ButtonUtil.update(this, "OK", "Undo", true, true, true);
}
else { //otherwise allow ending turn with cancel button
ButtonUtil.update(getGui(), "OK", "End Turn", true, true, true);
ButtonUtil.update(this, "OK", "End Turn", true, true, true);
}
}

View File

@@ -371,10 +371,10 @@ public abstract class InputPayMana extends InputSyncronizedBase {
protected void updateButtons() {
if (supportAutoPay()) {
ButtonUtil.update(getGui(), "Auto", "Cancel", false, true, false);
ButtonUtil.update(this, "Auto", "Cancel", false, true, false);
}
else {
ButtonUtil.update(getGui(), "", "Cancel", false, true, false);
ButtonUtil.update(this, "", "Cancel", false, true, false);
}
}
@@ -393,7 +393,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
canPayManaCost = proc.getResult();
}
if (canPayManaCost) { //enabled Auto button if mana cost can be paid
ButtonUtil.update(getGui(), "Auto", "Cancel", true, true, true);
ButtonUtil.update(this, "Auto", "Cancel", true, true, true);
}
}
showMessage(getMessage());

View File

@@ -55,10 +55,10 @@ public class InputPlaybackControl extends InputSyncronizedBase implements InputS
private void setPause(boolean pause) {
isPaused = pause;
if (isPaused) {
ButtonUtil.update(getGui(), "Resume", "Step", true, true, true);
ButtonUtil.update(this, "Resume", "Step", true, true, true);
}
else {
ButtonUtil.update(getGui(), "Pause", isFast ? "1x Speed" : "10x Faster", true, true, true);
ButtonUtil.update(this, "Pause", isFast ? "1x Speed" : "10x Faster", true, true, true);
}
}

View File

@@ -46,11 +46,11 @@ public class InputProxy implements Observer {
// private static final boolean DEBUG_INPUT = true; // false;
public InputProxy(final LocalGameView gameView0) {
this.gameView = gameView0;
gameView = gameView0;
}
private IGuiBase getGui() {
return this.gameView.getGui();
return gameView.getGui();
}
@Override
@@ -61,11 +61,11 @@ public class InputProxy implements Observer {
FThreads.debugGetStackTraceItem(6, true), nextInput == null ? "null" : nextInput.getClass().getSimpleName(),
game.getPhaseHandler().debugPrintState(), Singletons.getControl().getInputQueue().printInputStack());
*/
this.input.set(nextInput);
input.set(nextInput);
Runnable showMessage = new Runnable() {
@Override public void run() {
Input current = getInput();
getGui().getInputQueue().syncPoint();
gameView.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();
}
@@ -152,6 +152,6 @@ public class InputProxy implements Observer {
/** @return {@link forge.gui.InputProxy.InputBase} */
public Input getInput() {
return this.input.get();
return input.get();
}
}

View File

@@ -33,6 +33,12 @@ import forge.view.IGameView;
* @version $Id: InputQueue.java 24769 2014-02-09 13:56:04Z Hellfish $
*/
public class InputQueue extends Observable {
private static InputSynchronized activeInput;
public static InputSynchronized getActiveInput() {
return activeInput;
}
private final BlockingDeque<InputSynchronized> inputStack = new LinkedBlockingDeque<InputSynchronized>();
private final InputLockUI inputLock;
@@ -56,6 +62,9 @@ public class InputQueue extends Observable {
if (topMostInput != inp) {
throw new RuntimeException("Cannot remove input " + inp.getClass().getSimpleName() + " because it's not on top of stack. Stack = " + inputStack );
}
if (inp == activeInput) {
activeInput = null;
}
updateObservers();
}
@@ -80,6 +89,7 @@ public class InputQueue extends Observable {
}
public void setInput(final InputSynchronized input) {
activeInput = input;
inputStack.push(input);
inputLock.setGui(input.getGui());
syncPoint();

View File

@@ -44,7 +44,7 @@ public abstract class InputSelectManyBase<T extends GameEntity> extends InputSyn
@Override
public final void showMessage() {
showMessage(getMessage());
ButtonUtil.update(getGui(), hasEnoughTargets(), allowCancel, true);
ButtonUtil.update(this, hasEnoughTargets(), allowCancel, true);
}
@Override

View File

@@ -78,19 +78,19 @@ public final class InputSelectTargets extends InputSyncronizedBase {
if (!tgt.isMinTargetsChosen(sa.getHostCard(), sa) || tgt.isDividedAsYouChoose()) {
if (mandatory && tgt.hasCandidates(sa, true)) {
// Player has to click on a target
ButtonUtil.update(getGui(), false, false, false);
ButtonUtil.update(this, false, false, false);
}
else {
ButtonUtil.update(getGui(), false, true, false);
ButtonUtil.update(this, false, true, false);
}
}
else {
if (mandatory && tgt.hasCandidates(sa, true)) {
// Player has to click on a target or ok
ButtonUtil.update(getGui(), true, false, true);
ButtonUtil.update(this, true, false, true);
}
else {
ButtonUtil.update(getGui(), true, true, true);
ButtonUtil.update(this, true, true, true);
}
}
}

View File

@@ -30,7 +30,7 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
}
public void showAndWait() {
getGui().getInputQueue().setInput(this);
getGameView().getInputQueue().setInput(this);
awaitLatchRelease();
}
@@ -46,7 +46,7 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
});
// thread irrelevant
getGui().getInputQueue().removeInput(InputSyncronizedBase.this);
getGameView().getInputQueue().removeInput(InputSyncronizedBase.this);
cdlDone.countDown();
}

View File

@@ -18,13 +18,17 @@ public class LobbyPlayerHuman extends LobbyPlayer implements IGameEntitiesFactor
@Override
public PlayerController createControllerFor(Player human) {
return new PlayerControllerHuman(human.getGame(), human, this, gui);
PlayerControllerHuman controller = new PlayerControllerHuman(human.getGame(), human, this, gui);
controller.getGameView().setLocalPlayer(human);
return controller;
}
@Override
public Player createIngamePlayer(Game game, final int id) {
Player player = new Player(GuiDisplayUtil.personalizeHuman(getName()), game, id);
player.setFirstController(new PlayerControllerHuman(game, player, this, gui));
PlayerControllerHuman controller = new PlayerControllerHuman(game, player, this, gui);
player.setFirstController(controller);
controller.getGameView().setLocalPlayer(player);
return player;
}

View File

@@ -89,6 +89,7 @@ import forge.match.input.InputBase;
import forge.match.input.InputBlock;
import forge.match.input.InputConfirm;
import forge.match.input.InputConfirmMulligan;
import forge.match.input.InputNone;
import forge.match.input.InputPassPriority;
import forge.match.input.InputPayMana;
import forge.match.input.InputProliferate;
@@ -129,7 +130,7 @@ public class PlayerControllerHuman extends PlayerController {
public PlayerControllerHuman(final Game game0, final Player p, final LobbyPlayer lp, final IGuiBase gui) {
super(game0, p, lp);
this.gameView = new GameView(game0, gui);
this.gameView = new GameView(gui, game0);
// aggressively cache a view for each player (also caches cards)
for (final Player player : game.getRegisteredPlayers()) {
@@ -796,9 +797,10 @@ public class PlayerControllerHuman extends PlayerController {
//allow user to cancel auto-pass
InputBase.cancelAwaitNextInput(); //don't overwrite prompt with awaiting opponent
PhaseType phase = getAutoPassUntilPhase();
getGui().showPromptMessage("Yielding until " + (phase == PhaseType.CLEANUP ? "end of turn" : phase.nameForUi.toString()) +
InputNone inputNone = new InputNone(gameView);
getGui().showPromptMessage(inputNone.getOwner(), "Yielding until " + (phase == PhaseType.CLEANUP ? "end of turn" : phase.nameForUi.toString()) +
".\nYou may cancel this yield to take an action.");
ButtonUtil.update(getGui(), false, true, false);
ButtonUtil.update(inputNone, false, true, false);
}
}
@@ -814,9 +816,10 @@ public class PlayerControllerHuman extends PlayerController {
super.autoPassCancel();
//prevent prompt getting stuck on yielding message while actually waiting for next input opportunity
getGui().showPromptMessage("");
ButtonUtil.update(getGui(), false, false, false);
InputBase.awaitNextInput(getGui());
InputNone inputNone = new InputNone(gameView);
getGui().showPromptMessage(inputNone.getOwner(), "");
ButtonUtil.update(inputNone, false, false, false);
InputBase.awaitNextInput(inputNone);
}
@Override
@@ -1330,8 +1333,8 @@ public class PlayerControllerHuman extends PlayerController {
* What follows are the View methods.
*/
private class GameView extends LocalGameView {
public GameView(Game game0, IGuiBase gui0) {
super(game0, gui0);
public GameView(IGuiBase gui0, Game game0) {
super(gui0, game0);
}
@Override
@@ -1363,7 +1366,7 @@ public class PlayerControllerHuman extends PlayerController {
}
if (game.getStack().undo()) {
final Input currentInput = getGui().getInputQueue().getInput();
final Input currentInput = inputQueue.getInput();
if (currentInput instanceof InputPassPriority) {
currentInput.showMessageInitial(); //ensure prompt updated if needed
}
@@ -1384,7 +1387,7 @@ public class PlayerControllerHuman extends PlayerController {
@Override
public void confirm() {
if (getGui().getInputQueue().getInput() instanceof InputConfirm) {
if (inputQueue.getInput() instanceof InputConfirm) {
selectButtonOk();
}
}
@@ -1418,7 +1421,7 @@ public class PlayerControllerHuman extends PlayerController {
@Override
public void useMana(final byte mana) {
final Input input = getGui().getInputQueue().getInput();
final Input input = inputQueue.getInput();
if (input instanceof InputPayMana) {
((InputPayMana) input).useManaFromPool(mana);
}
@@ -1587,11 +1590,9 @@ public class PlayerControllerHuman extends PlayerController {
return gameView.getPlayerViews(players);
}
/**
* @param p
* @return
* @see forge.view.LocalGameView#getPlayerView(forge.game.player.Player)
*/
public PlayerView getPlayerView() {
return gameView.getPlayerView(getPlayer());
}
public PlayerView getPlayerView(Player p) {
return gameView.getPlayerView(p);
}
@@ -2003,7 +2004,7 @@ public class PlayerControllerHuman extends PlayerController {
}
public void winGame() {
Input input = getGui().getInputQueue().getInput();
Input input = gameView.getInputQueue().getInput();
if (!(input instanceof InputPassPriority)) {
SOptionPane.showMessageDialog(getGui(), "You must have priority to use this feature.", "Win Game", SOptionPane.INFORMATION_ICON);
return;

View File

@@ -36,8 +36,9 @@ public abstract class LocalGameView implements IGameView {
protected final IGuiBase gui;
protected final InputQueue inputQueue;
protected final InputProxy inputProxy;
private PlayerView localPlayerView;
public LocalGameView(Game game0, IGuiBase gui0) {
public LocalGameView(IGuiBase gui0, Game game0) {
game = game0;
gui = gui0;
inputProxy = new InputProxy(this);
@@ -60,6 +61,14 @@ public abstract class LocalGameView implements IGameView {
return inputProxy;
}
public PlayerView getLocalPlayerView() {
return localPlayerView;
}
public void setLocalPlayer(Player localPlayer) {
localPlayerView = getPlayerView(localPlayer);
}
/** Cache of players. */
private final Cache<Player, PlayerView> players = new Cache<>();
/** Cache of cards. */

View File

@@ -24,8 +24,8 @@ public class WatchLocalGame extends LocalGameView {
* the {@link InputQueue} of the game to enable playback
* controls, or {@code null} to disallow them.
*/
public WatchLocalGame(Game game0, IGuiBase gui0) {
super(game0, gui0);
public WatchLocalGame(IGuiBase gui0, Game game0) {
super(gui0, game0);
}
@Override
@@ -158,5 +158,4 @@ public class WatchLocalGame extends LocalGameView {
public DevModeCheats cheat() {
return null;
}
}