mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
Start refactoring to make Human v. Human support better
This commit is contained in:
@@ -54,7 +54,6 @@ import forge.interfaces.IGuiBase;
|
||||
import forge.item.PaperCard;
|
||||
import forge.match.input.InputQueue;
|
||||
import forge.model.FModel;
|
||||
import forge.player.GamePlayerUtil;
|
||||
import forge.screens.deckeditor.CDeckEditorUI;
|
||||
import forge.screens.deckeditor.controllers.CEditorQuestCardShop;
|
||||
import forge.screens.match.CMatchUI;
|
||||
@@ -286,7 +285,7 @@ public class GuiDesktop implements IGuiBase {
|
||||
|
||||
@Override
|
||||
public void updatePlayerControl() {
|
||||
CMatchUI.SINGLETON_INSTANCE.initHandViews(GamePlayerUtil.getGuiPlayer());
|
||||
CMatchUI.SINGLETON_INSTANCE.initHandViews();
|
||||
SLayoutIO.loadLayout(null);
|
||||
VMatchUI.SINGLETON_INSTANCE.populate();
|
||||
for (VHand h : VMatchUI.SINGLETON_INSTANCE.getHands()) {
|
||||
|
||||
@@ -27,6 +27,8 @@ import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -75,11 +77,6 @@ import forge.quest.io.QuestDataIO;
|
||||
import forge.screens.deckeditor.CDeckEditorUI;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.screens.match.VMatchUI;
|
||||
import forge.screens.match.controllers.CDock;
|
||||
import forge.screens.match.controllers.CLog;
|
||||
import forge.screens.match.controllers.CPlayers;
|
||||
import forge.screens.match.controllers.CStack;
|
||||
import forge.screens.match.views.VAntes;
|
||||
import forge.screens.match.views.VField;
|
||||
import forge.sound.MusicPlaylist;
|
||||
import forge.sound.SoundSystem;
|
||||
@@ -88,7 +85,6 @@ import forge.toolbox.FSkin;
|
||||
import forge.toolbox.special.PhaseIndicator;
|
||||
import forge.view.FFrame;
|
||||
import forge.view.FView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.LocalGameView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.WatchLocalGame;
|
||||
@@ -104,13 +100,14 @@ import forge.view.WatchLocalGame;
|
||||
public enum FControl implements KeyEventDispatcher {
|
||||
instance;
|
||||
|
||||
private Game game;
|
||||
private List<LocalGameView> gameViews = new ArrayList<LocalGameView>();
|
||||
private ForgeMenu forgeMenu;
|
||||
private List<Shortcut> shortcuts;
|
||||
private JLayeredPane display;
|
||||
private FScreen currentScreen;
|
||||
private boolean altKeyLastDown;
|
||||
private CloseAction closeAction;
|
||||
private PlayerView localPlayer;
|
||||
|
||||
public static enum CloseAction {
|
||||
NONE,
|
||||
@@ -170,12 +167,12 @@ public enum FControl implements KeyEventDispatcher {
|
||||
}
|
||||
|
||||
public CloseAction getCloseAction() {
|
||||
return this.closeAction;
|
||||
return closeAction;
|
||||
}
|
||||
|
||||
public void setCloseAction(CloseAction closeAction0) {
|
||||
if (this.closeAction == closeAction0) { return; }
|
||||
this.closeAction = closeAction0;
|
||||
if (closeAction == closeAction0) { return; }
|
||||
closeAction = closeAction0;
|
||||
Singletons.getView().getNavigationBar().updateBtnCloseTooltip();
|
||||
|
||||
final ForgePreferences prefs = FModel.getPreferences();
|
||||
@@ -186,10 +183,10 @@ public enum FControl implements KeyEventDispatcher {
|
||||
public boolean canExitForge(boolean forRestart) {
|
||||
String action = (forRestart ? "Restart" : "Exit");
|
||||
String userPrompt = "Are you sure you wish to " + (forRestart ? "restart" : "exit") + " Forge?";
|
||||
if (this.gameView != null) {
|
||||
if (game != null) {
|
||||
userPrompt = "A game is currently active. " + userPrompt;
|
||||
}
|
||||
if (!FOptionPane.showConfirmDialog(userPrompt, action + " Forge", action, "Cancel", this.gameView == null)) { //default Yes if no game active
|
||||
if (!FOptionPane.showConfirmDialog(userPrompt, action + " Forge", action, "Cancel", game == null)) { //default Yes if no game active
|
||||
return false;
|
||||
}
|
||||
if (!CDeckEditorUI.SINGLETON_INSTANCE.canSwitchAway(true)) {
|
||||
@@ -212,14 +209,14 @@ public enum FControl implements KeyEventDispatcher {
|
||||
// Preloads skin components (using progress bar).
|
||||
FSkin.loadFull(true);
|
||||
|
||||
this.soundSystem = new SoundSystem(GuiBase.getInterface());
|
||||
soundSystem = new SoundSystem(GuiBase.getInterface());
|
||||
|
||||
this.shortcuts = KeyboardShortcuts.attachKeyboardShortcuts();
|
||||
this.display = FView.SINGLETON_INSTANCE.getLpnDocument();
|
||||
shortcuts = KeyboardShortcuts.attachKeyboardShortcuts();
|
||||
display = FView.SINGLETON_INSTANCE.getLpnDocument();
|
||||
|
||||
final ForgePreferences prefs = FModel.getPreferences();
|
||||
|
||||
this.closeAction = CloseAction.valueOf(prefs.getPref(FPref.UI_CLOSE_ACTION));
|
||||
closeAction = CloseAction.valueOf(prefs.getPref(FPref.UI_CLOSE_ACTION));
|
||||
|
||||
FView.SINGLETON_INSTANCE.setSplashProgessBarMessage("About to load current quest.");
|
||||
// Preload quest data if present
|
||||
@@ -267,14 +264,14 @@ public enum FControl implements KeyEventDispatcher {
|
||||
}
|
||||
|
||||
public ForgeMenu getForgeMenu() {
|
||||
if (this.forgeMenu == null) {
|
||||
this.forgeMenu = new ForgeMenu();
|
||||
if (forgeMenu == null) {
|
||||
forgeMenu = new ForgeMenu();
|
||||
}
|
||||
return this.forgeMenu;
|
||||
return forgeMenu;
|
||||
}
|
||||
|
||||
public FScreen getCurrentScreen() {
|
||||
return this.currentScreen;
|
||||
return currentScreen;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -286,14 +283,14 @@ public enum FControl implements KeyEventDispatcher {
|
||||
public boolean setCurrentScreen(FScreen screen, boolean previousScreenClosed) {
|
||||
//TODO: Uncomment the line below if this function stops being used to refresh
|
||||
//the current screen in some places (such as Continue and Restart in the match screen)
|
||||
//if (this.currentScreen == screen) { return; }
|
||||
//if (currentScreen == screen) { return; }
|
||||
|
||||
//give previous screen a chance to perform special switch handling and/or cancel switching away from screen
|
||||
if (this.currentScreen != screen && !Singletons.getView().getNavigationBar().canSwitch(screen)) {
|
||||
if (currentScreen != screen && !Singletons.getView().getNavigationBar().canSwitch(screen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.currentScreen == FScreen.MATCH_SCREEN) { //hide targeting overlay and reset image if was on match screen
|
||||
if (currentScreen == FScreen.MATCH_SCREEN) { //hide targeting overlay and reset image if was on match screen
|
||||
SOverlayUtils.hideTargetingOverlay();
|
||||
if (isMatchBackgroundImageVisible()) {
|
||||
FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(new ImageIcon());
|
||||
@@ -304,7 +301,7 @@ public enum FControl implements KeyEventDispatcher {
|
||||
SOverlayUtils.hideOverlay();
|
||||
ImageCache.clear(); //reduce memory usage by clearing image cache when switching screens
|
||||
|
||||
this.currentScreen = screen;
|
||||
currentScreen = screen;
|
||||
|
||||
//load layout for new current screen
|
||||
try {
|
||||
@@ -335,14 +332,14 @@ public enum FControl implements KeyEventDispatcher {
|
||||
}
|
||||
|
||||
public boolean ensureScreenActive(FScreen screen) {
|
||||
if (this.currentScreen == screen) { return true; }
|
||||
if (currentScreen == screen) { return true; }
|
||||
|
||||
return setCurrentScreen(screen);
|
||||
}
|
||||
|
||||
/** @return List<Shortcut> A list of attached keyboard shortcut descriptions and properties. */
|
||||
public List<Shortcut> getShortcuts() {
|
||||
return this.shortcuts;
|
||||
return shortcuts;
|
||||
}
|
||||
|
||||
/** Remove all children from a specified layer. */
|
||||
@@ -374,17 +371,6 @@ public enum FControl implements KeyEventDispatcher {
|
||||
return soundSystem;
|
||||
}
|
||||
|
||||
private Game game;
|
||||
private IGameView gameView;
|
||||
|
||||
public IGameView getGameView() {
|
||||
return this.gameView;
|
||||
}
|
||||
|
||||
public PlayerView getLocalPlayer() {
|
||||
return localPlayer;
|
||||
}
|
||||
|
||||
public final void stopGame() {
|
||||
List<Player> pp = new ArrayList<Player>();
|
||||
for (Player p : game.getPlayers()) {
|
||||
@@ -410,7 +396,7 @@ public enum FControl implements KeyEventDispatcher {
|
||||
}
|
||||
else {
|
||||
game.isGameOver(); // this is synchronized method - it's used to make Game-0 thread see changes made here
|
||||
inputQueue.onGameOver(false); //release any waiting input, effectively passing priority
|
||||
getInputQueue().onGameOver(false); //release any waiting input, effectively passing priority
|
||||
}
|
||||
|
||||
if (playbackControl != null) {
|
||||
@@ -418,74 +404,148 @@ public enum FControl implements KeyEventDispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
private InputQueue inputQueue;
|
||||
public Player getCurrentPlayer() {
|
||||
if (game == null) { return null; }
|
||||
|
||||
// try current priority
|
||||
Player currentPriority = game.getPhaseHandler().getPriorityPlayer();
|
||||
if (null != currentPriority && currentPriority.getLobbyPlayer() == getGuiPlayer()) {
|
||||
return currentPriority;
|
||||
}
|
||||
|
||||
// otherwise find just any player, belonging to this lobbyplayer
|
||||
for (Player p : game.getPlayers()) {
|
||||
if (p.getLobbyPlayer() == getGuiPlayer()) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public LocalGameView getGameView() {
|
||||
return getGameView(getCurrentPlayer());
|
||||
}
|
||||
public LocalGameView getGameView(Player player) {
|
||||
switch (gameViews.size()) {
|
||||
case 1:
|
||||
return gameViews.get(0);
|
||||
case 0:
|
||||
return null;
|
||||
default:
|
||||
if (player != null && player.getController() instanceof PlayerControllerHuman) {
|
||||
return ((PlayerControllerHuman)player.getController()).getGameView();
|
||||
}
|
||||
return gameViews.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
public InputQueue getInputQueue() {
|
||||
return inputQueue;
|
||||
LocalGameView gameView = getGameView();
|
||||
if (gameView != null) {
|
||||
return gameView.getInputQueue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final void startGameInSameMatch() {
|
||||
this.startGameWithUi(this.game.getMatch());
|
||||
startGameWithUi(game.getMatch());
|
||||
}
|
||||
public final void startGameAndClearMatch() {
|
||||
if (this.game != null) {
|
||||
this.game.getMatch().clearGamesPlayed();
|
||||
if (game != null) {
|
||||
game.getMatch().clearGamesPlayed();
|
||||
}
|
||||
startGameInSameMatch();
|
||||
}
|
||||
|
||||
public final void startGameWithUi(final Match match) {
|
||||
if (this.gameView != null) {
|
||||
this.setCurrentScreen(FScreen.MATCH_SCREEN);
|
||||
if (game != null) {
|
||||
setCurrentScreen(FScreen.MATCH_SCREEN);
|
||||
SOverlayUtils.hideOverlay();
|
||||
FOptionPane.showMessageDialog("Cannot start a new game while another game is already in progress.");
|
||||
return; //TODO: See if it's possible to run multiple games at once without crashing
|
||||
}
|
||||
|
||||
setPlayerName(match.getPlayers());
|
||||
this.game = match.createGame();
|
||||
inputQueue = new InputQueue(game);
|
||||
|
||||
boolean anyPlayerIsAi = false;
|
||||
for (final Player p : game.getPlayers()) {
|
||||
if (p.getLobbyPlayer() instanceof LobbyPlayerAi) {
|
||||
anyPlayerIsAi = true;
|
||||
break;
|
||||
getSoundSystem().setBackgroundMusic(MusicPlaylist.MATCH);
|
||||
|
||||
game = match.createGame();
|
||||
|
||||
if (game.getRules().getGameType() == GameType.Quest) {
|
||||
QuestController qc = FModel.getQuest();
|
||||
// Reset new list when the Match round starts, not when each game starts
|
||||
if (game.getMatch().getPlayedGames().isEmpty()) {
|
||||
qc.getCards().resetNewList();
|
||||
}
|
||||
game.subscribeToEvents(qc); // this one listens to player's mulligans ATM
|
||||
}
|
||||
|
||||
final LobbyPlayer me = getGuiPlayer();
|
||||
for (final Player p : game.getPlayers()) {
|
||||
if (p.getLobbyPlayer().equals(me)) {
|
||||
final PlayerControllerHuman controller = (PlayerControllerHuman) p.getController();
|
||||
this.gameView = controller.getGameView();
|
||||
this.fcVisitor = new FControlGameEventHandler(GuiBase.getInterface(), controller.getGameView());
|
||||
break;
|
||||
}
|
||||
}
|
||||
game.subscribeToEvents(getSoundSystem());
|
||||
|
||||
final String[] indices = FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",");
|
||||
|
||||
// Instantiate all required field slots (user at 0)
|
||||
final List<Player> sortedPlayers = new ArrayList<Player>(game.getRegisteredPlayers());
|
||||
Collections.sort(sortedPlayers, new Comparator<Player>() {
|
||||
@Override
|
||||
public int compare(Player p1, Player p2) {
|
||||
int v1 = p1.getController() instanceof PlayerControllerHuman ? 0 : 1;
|
||||
int v2 = p2.getController() instanceof PlayerControllerHuman ? 0 : 1;
|
||||
return Integer.compare(v1, v2);
|
||||
}
|
||||
});
|
||||
|
||||
gameViews.clear();
|
||||
|
||||
int i = 0;
|
||||
int avatarIndex = 0;
|
||||
int humanCount = 0;
|
||||
for (Player p : sortedPlayers) {
|
||||
if (i < indices.length) {
|
||||
avatarIndex = Integer.parseInt(indices[i]);
|
||||
i++;
|
||||
}
|
||||
p.getLobbyPlayer().setAvatarIndex(avatarIndex);
|
||||
|
||||
if (!anyPlayerIsAi) {
|
||||
// If there are no AI's, allow all players to see all cards (hotseat
|
||||
// mode).
|
||||
for (final Player p : game.getPlayers()) {
|
||||
if (p.getController() instanceof PlayerControllerHuman) {
|
||||
final PlayerControllerHuman controller = (PlayerControllerHuman) p.getController();
|
||||
controller.setMayLookAtAllCards(true);
|
||||
}
|
||||
LocalGameView gameView = controller.getGameView();
|
||||
game.subscribeToEvents(new FControlGameEventHandler(GuiBase.getInterface(), gameView));
|
||||
gameViews.add(gameView);
|
||||
humanCount++;
|
||||
}
|
||||
}
|
||||
|
||||
boolean openAllHands = !anyPlayerIsAi;
|
||||
if (this.gameView == null) {
|
||||
// Watch game but do not participate
|
||||
openAllHands = true;
|
||||
final LocalGameView gameView = new WatchLocalGame(game, inputQueue);
|
||||
this.gameView = gameView;
|
||||
this.fcVisitor = new FControlGameEventHandler(GuiBase.getInterface(), gameView);
|
||||
this.playbackControl = new FControlGamePlayback(GuiBase.getInterface(), gameView);
|
||||
this.playbackControl.setGame(game);
|
||||
this.game.subscribeToEvents(playbackControl);
|
||||
if (humanCount == 0) { //watch game but do not participate
|
||||
LocalGameView gameView = new WatchLocalGame(game, GuiBase.getInterface());
|
||||
game.subscribeToEvents(new FControlGameEventHandler(GuiBase.getInterface(), gameView));
|
||||
gameViews.add(gameView);
|
||||
}
|
||||
else if (humanCount == sortedPlayers.size()) {
|
||||
//if there are no AI's, allow all players to see all cards (hotseat mode).
|
||||
for (Player p : sortedPlayers) {
|
||||
((PlayerControllerHuman) p.getController()).setMayLookAtAllCards(true);
|
||||
}
|
||||
}
|
||||
|
||||
attachToGame(this.gameView, openAllHands);
|
||||
List<PlayerView> sortedPlayerViews = new ArrayList<PlayerView>();
|
||||
for (Player p : sortedPlayers) {
|
||||
sortedPlayerViews.add(getGameView().getPlayerView(p));
|
||||
}
|
||||
CMatchUI.SINGLETON_INSTANCE.initMatch(sortedPlayerViews, humanCount != 1);
|
||||
|
||||
actuateMatchPreferences();
|
||||
|
||||
setCurrentScreen(FScreen.MATCH_SCREEN);
|
||||
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
|
||||
|
||||
// per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch
|
||||
//Set Field shown to current player.
|
||||
if (humanCount > 0) {
|
||||
final VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(sortedPlayerViews.get(0));
|
||||
SDisplayUtil.showTab(nextField);
|
||||
}
|
||||
|
||||
// It's important to run match in a different thread to allow GUI inputs to be invoked from inside game.
|
||||
// Game is set on pause while gui player takes decisions
|
||||
@@ -499,64 +559,14 @@ public enum FControl implements KeyEventDispatcher {
|
||||
}
|
||||
|
||||
public final void endCurrentGame() {
|
||||
if (this.gameView == null) { return; }
|
||||
if (game == null) { return; }
|
||||
|
||||
Singletons.getView().getNavigationBar().closeTab(FScreen.MATCH_SCREEN);
|
||||
|
||||
this.gameView = null;
|
||||
game = null;
|
||||
}
|
||||
|
||||
private FControlGameEventHandler fcVisitor;
|
||||
private FControlGamePlayback playbackControl;
|
||||
private void attachToGame(final IGameView game0, final boolean openAllHands) {
|
||||
if (game0.getGameType().equals(GameType.Quest)) {
|
||||
QuestController qc = FModel.getQuest();
|
||||
// Reset new list when the Match round starts, not when each game starts
|
||||
if (game0.isFirstGameInMatch()) {
|
||||
qc.getCards().resetNewList();
|
||||
}
|
||||
game0.subscribeToEvents(qc); // this one listens to player's mulligans ATM
|
||||
}
|
||||
|
||||
game0.subscribeToEvents(Singletons.getControl().getSoundSystem());
|
||||
|
||||
//switch back to match screen music
|
||||
Singletons.getControl().getSoundSystem().setBackgroundMusic(MusicPlaylist.MATCH);
|
||||
|
||||
final LobbyPlayer humanLobbyPlayer = getGuiPlayer();
|
||||
// The UI controls should use these game data as models
|
||||
final List<PlayerView> players = game0.getPlayers();
|
||||
CMatchUI.SINGLETON_INSTANCE.initMatch(game0, players, humanLobbyPlayer, openAllHands);
|
||||
|
||||
localPlayer = null;
|
||||
for (final PlayerView p : players) {
|
||||
if (p.getLobbyPlayer() == humanLobbyPlayer) {
|
||||
localPlayer = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CDock.SINGLETON_INSTANCE.setModel(game0);
|
||||
CStack.SINGLETON_INSTANCE.setModel(game0, localPlayer);
|
||||
CPlayers.SINGLETON_INSTANCE.setModel(game0);
|
||||
CLog.SINGLETON_INSTANCE.setModel(game0);
|
||||
|
||||
actuateMatchPreferences();
|
||||
VAntes.SINGLETON_INSTANCE.setModel(players);
|
||||
|
||||
setCurrentScreen(FScreen.MATCH_SCREEN);
|
||||
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
|
||||
|
||||
// Listen to DuelOutcome event to show ViewWinLose
|
||||
game0.subscribeToEvents(fcVisitor);
|
||||
|
||||
// per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch
|
||||
//Set Field shown to current player.
|
||||
if (localPlayer != null) {
|
||||
final VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(localPlayer);
|
||||
SDisplayUtil.showTab(nextField);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.KeyEventDispatcher#dispatchKeyEvent(java.awt.event.KeyEvent)
|
||||
|
||||
@@ -115,7 +115,7 @@ public class KeyboardShortcuts {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; }
|
||||
CDock.SINGLETON_INSTANCE.alphaStrike();
|
||||
Singletons.getControl().getGameView().alphaStrike();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ import javax.swing.JMenu;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
@@ -53,6 +52,7 @@ import forge.gui.framework.SDisplayUtil;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.menus.IMenuProvider;
|
||||
import forge.model.FModel;
|
||||
import forge.player.LobbyPlayerHuman;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.quest.QuestDraftUtils;
|
||||
import forge.screens.match.controllers.CAntes;
|
||||
@@ -73,7 +73,6 @@ import forge.toolbox.special.PhaseLabel;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CombatView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.ViewUtil;
|
||||
import forge.view.arcane.CardPanel;
|
||||
@@ -90,7 +89,6 @@ import forge.view.arcane.PlayArea;
|
||||
public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private IGameView game;
|
||||
private List<PlayerView> sortedPlayers;
|
||||
private VMatchUI view;
|
||||
private boolean allHands;
|
||||
@@ -123,17 +121,14 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
/**
|
||||
* Instantiates at a match.
|
||||
*/
|
||||
public void initMatch(final IGameView game, final List<PlayerView> players, final LobbyPlayer localPlayer, final boolean allHands) {
|
||||
this.game = game;
|
||||
this.allHands = allHands;
|
||||
public void initMatch(final List<PlayerView> sortedPlayers0, final boolean allHands0) {
|
||||
sortedPlayers = sortedPlayers0;
|
||||
allHands = allHands0;
|
||||
view = VMatchUI.SINGLETON_INSTANCE;
|
||||
// TODO fix for use with multiplayer
|
||||
|
||||
final String[] indices = FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",");
|
||||
|
||||
// Instantiate all required field slots (user at 0)
|
||||
sortedPlayers = shiftPlayersPlaceLocalFirst(players, localPlayer);
|
||||
|
||||
final List<VField> fields = new ArrayList<VField>();
|
||||
final List<VCommand> commands = new ArrayList<VCommand>();
|
||||
|
||||
@@ -141,7 +136,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
for (final PlayerView p : sortedPlayers) {
|
||||
// A field must be initialized after it's instantiated, to update player info.
|
||||
// No player, no init.
|
||||
VField f = new VField(EDocID.Fields[i], p, localPlayer);
|
||||
VField f = new VField(EDocID.Fields[i], p);
|
||||
VCommand c = new VCommand(EDocID.Commands[i], p);
|
||||
fields.add(f);
|
||||
commands.add(c);
|
||||
@@ -157,20 +152,17 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
view.setCommandViews(commands);
|
||||
view.setFieldViews(fields);
|
||||
|
||||
VPlayers.SINGLETON_INSTANCE.init(players);
|
||||
VPlayers.SINGLETON_INSTANCE.init(sortedPlayers0);
|
||||
|
||||
initHandViews(localPlayer, allHands);
|
||||
initHandViews();
|
||||
}
|
||||
|
||||
public void initHandViews(final LobbyPlayer localPlayer) {
|
||||
this.initHandViews(localPlayer, this.allHands);
|
||||
}
|
||||
public void initHandViews(final LobbyPlayer localPlayer, final boolean allHands) {
|
||||
public void initHandViews() {
|
||||
final List<VHand> hands = new ArrayList<VHand>();
|
||||
|
||||
int i = 0;
|
||||
for (final PlayerView p : sortedPlayers) {
|
||||
if (allHands || p.getLobbyPlayer().equals(localPlayer) || ViewUtil.mayViewAny(p.getHandCards())) {
|
||||
if (allHands || p.getLobbyPlayer() instanceof LobbyPlayerHuman || ViewUtil.mayViewAny(p.getHandCards())) {
|
||||
VHand newHand = new VHand(EDocID.Hands[i], p);
|
||||
newHand.getLayoutControl().initialize();
|
||||
hands.add(newHand);
|
||||
@@ -181,22 +173,6 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
view.setHandViews(hands);
|
||||
}
|
||||
|
||||
private List<PlayerView> shiftPlayersPlaceLocalFirst(final List<PlayerView> players, final LobbyPlayer localPlayer) {
|
||||
// get an arranged list so that the first local player is at index 0
|
||||
final List<PlayerView> sortedPlayers = Lists.newArrayList(players);
|
||||
int ixFirstHuman = -1;
|
||||
for (int i = 0; i < players.size(); i++) {
|
||||
if (sortedPlayers.get(i).getLobbyPlayer() == localPlayer) {
|
||||
ixFirstHuman = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ixFirstHuman > 0) {
|
||||
sortedPlayers.add(0, sortedPlayers.remove(ixFirstHuman));
|
||||
}
|
||||
return sortedPlayers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all phase buttons in all fields to "inactive", so highlight won't
|
||||
* be drawn on them. "Enabled" state remains the same.
|
||||
@@ -299,7 +275,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
}
|
||||
|
||||
public void showCombat(final CombatView combat) {
|
||||
if (combat != null && combat.getNumAttackers() > 0 && game.peekStack() == null) {
|
||||
if (combat != null && combat.getNumAttackers() > 0 && Singletons.getControl().getGameView().peekStack() == null) {
|
||||
if (selectedDocBeforeCombat == null) {
|
||||
IVDoc<? extends ICDoc> combatDoc = EDocID.REPORT_COMBAT.getDoc();
|
||||
if (combatDoc.getParentCell() != null) {
|
||||
|
||||
@@ -40,7 +40,6 @@ import forge.toolbox.FSkin;
|
||||
import forge.toolbox.SaveOpenDialog;
|
||||
import forge.toolbox.SaveOpenDialog.Filetypes;
|
||||
import forge.view.FView;
|
||||
import forge.view.IGameView;
|
||||
|
||||
/**
|
||||
* Controls the dock panel in the match UI.
|
||||
@@ -52,11 +51,6 @@ public enum CDock implements ICDoc {
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private int arcState;
|
||||
private IGameView game;
|
||||
|
||||
public void setModel(final IGameView game0) {
|
||||
game = game0;
|
||||
}
|
||||
|
||||
/**
|
||||
* End turn.
|
||||
@@ -156,33 +150,6 @@ public enum CDock implements ICDoc {
|
||||
//FModel.SINGLETON_INSTANCE.getPreferences().save();
|
||||
}
|
||||
|
||||
/** Attack with everyone. */
|
||||
public void alphaStrike() {
|
||||
game.alphaStrike();
|
||||
/* TODO: rewrite this!
|
||||
final Player p = this.findAffectedPlayer();
|
||||
final Combat combat = FControl.instance.getObservedGame().getCombat();
|
||||
if (this.game.isCombatDeclareAttackers()) {
|
||||
List<Player> defenders = p.getOpponents();
|
||||
|
||||
for (Card c : CardLists.filter(p.getCardsIn(ZoneType.Battlefield), Presets.CREATURES)) {
|
||||
if (combat.isAttacking(c))
|
||||
continue;
|
||||
|
||||
for(Player defender : defenders)
|
||||
if( CombatUtil.canAttack(c, defender, combat)) {
|
||||
combat.addAttacker(c, defender);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//human.updateObservers();
|
||||
|
||||
// TODO Is this redrawing immediately?
|
||||
FView.SINGLETON_INSTANCE.getFrame().repaint();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/** Toggle targeting overlay painting. */
|
||||
public void toggleTargeting() {
|
||||
arcState++;
|
||||
@@ -271,7 +238,7 @@ public enum CDock implements ICDoc {
|
||||
VDock.SINGLETON_INSTANCE.getBtnAlphaStrike().setCommand(new UiCommand() {
|
||||
@Override
|
||||
public void run() {
|
||||
alphaStrike();
|
||||
Singletons.getControl().getGameView().alphaStrike();
|
||||
}
|
||||
});
|
||||
VDock.SINGLETON_INSTANCE.getBtnTargeting().setCommand(new UiCommand() {
|
||||
|
||||
@@ -23,7 +23,6 @@ import java.awt.event.MouseListener;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.Singletons;
|
||||
import forge.UiCommand;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -41,8 +40,6 @@ import forge.view.PlayerView;
|
||||
public class CField implements ICDoc {
|
||||
// The one who owns cards on this side of table
|
||||
private final PlayerView player;
|
||||
// Tho one who looks at screen and 'performs actions'
|
||||
private final LobbyPlayer viewer;
|
||||
private final VField view;
|
||||
private boolean initializedAlready = false;
|
||||
|
||||
@@ -60,9 +57,8 @@ public class CField implements ICDoc {
|
||||
* @param v0   {@link forge.screens.match.views.VField}
|
||||
* @param playerViewer
|
||||
*/
|
||||
public CField(final PlayerView player0, final VField v0, LobbyPlayer playerViewer) {
|
||||
public CField(final PlayerView player0, final VField v0) {
|
||||
this.player = player0;
|
||||
this.viewer = playerViewer;
|
||||
this.view = v0;
|
||||
|
||||
final ZoneAction handAction = new ZoneAction(player, ZoneType.Hand, MatchConstants.HUMANHAND);
|
||||
@@ -74,7 +70,7 @@ public class CField implements ICDoc {
|
||||
@Override
|
||||
protected void doAction(final CardView c) {
|
||||
// activate cards only via your own flashback button
|
||||
if (player.getLobbyPlayer() != CField.this.viewer) {
|
||||
if (player.getLobbyPlayer() != Singletons.getControl().getGuiPlayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,7 +84,7 @@ public class CField implements ICDoc {
|
||||
|
||||
Function<Byte, Void> manaAction = new Function<Byte, Void>() {
|
||||
public Void apply(Byte colorCode) {
|
||||
if (CField.this.player.getLobbyPlayer() == CField.this.viewer) {
|
||||
if (CField.this.player.getLobbyPlayer() == Singletons.getControl().getGuiPlayer()) {
|
||||
Singletons.getControl().getGameView().useMana(colorCode.byteValue());
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -5,8 +5,6 @@ import forge.UiCommand;
|
||||
import forge.FThreads;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.screens.match.views.VLog;
|
||||
import forge.view.IGameView;
|
||||
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
||||
@@ -20,8 +18,6 @@ public enum CLog implements ICDoc, Observer {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private IGameView model;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||
*/
|
||||
@@ -41,19 +37,10 @@ public enum CLog implements ICDoc, Observer {
|
||||
private final Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
VLog.SINGLETON_INSTANCE.updateConsole(model);
|
||||
VLog.SINGLETON_INSTANCE.updateConsole();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param game0
|
||||
*/
|
||||
public void setModel(final IGameView game0) {
|
||||
model = game0;
|
||||
model.addLogObserver(this);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,6 @@ package forge.screens.match.controllers;
|
||||
import forge.UiCommand;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.screens.match.views.VPlayers;
|
||||
import forge.view.IGameView;
|
||||
|
||||
/**
|
||||
* Controls the combat panel in the match UI.
|
||||
@@ -14,7 +13,6 @@ import forge.view.IGameView;
|
||||
public enum CPlayers implements ICDoc {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
private IGameView game;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||
@@ -36,11 +34,6 @@ public enum CPlayers implements ICDoc {
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
VPlayers.SINGLETON_INSTANCE.update(game);
|
||||
VPlayers.SINGLETON_INSTANCE.update();
|
||||
}
|
||||
|
||||
public void setModel(IGameView game) {
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.gui.framework.SDisplayUtil;
|
||||
import forge.screens.match.views.VStack;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
/**
|
||||
* Controls the combat panel in the match UI.
|
||||
@@ -18,9 +16,6 @@ public enum CStack implements ICDoc {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private IGameView model;
|
||||
private PlayerView localPlayer;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||
*/
|
||||
@@ -39,12 +34,6 @@ public enum CStack implements ICDoc {
|
||||
@Override
|
||||
public void update() {
|
||||
SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
|
||||
VStack.SINGLETON_INSTANCE.updateStack(model, localPlayer);
|
||||
VStack.SINGLETON_INSTANCE.updateStack();
|
||||
}
|
||||
|
||||
public void setModel(final IGameView game0, final PlayerView localPlayer) {
|
||||
model = game0;
|
||||
this.localPlayer = localPlayer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ public final class GameMenu {
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
controller.alphaStrike();
|
||||
Singletons.getControl().getGameView().alphaStrike();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package forge.screens.match.views;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@@ -26,6 +25,7 @@ import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.Singletons;
|
||||
import forge.gui.CardPicturePanel;
|
||||
import forge.gui.WrapLayout;
|
||||
import forge.gui.framework.DragCell;
|
||||
@@ -55,7 +55,6 @@ public enum VAntes implements IVDoc<CAntes> {
|
||||
private final FScrollPane scroller = new FScrollPane(pnl, false);
|
||||
private final SortedSet<AntePanel> allAntes = new TreeSet<AntePanel>();
|
||||
|
||||
private Iterable<PlayerView> players;
|
||||
//========== Constructor
|
||||
private VAntes() {
|
||||
pnl.setLayout(new WrapLayout());
|
||||
@@ -73,8 +72,7 @@ public enum VAntes implements IVDoc<CAntes> {
|
||||
parentCell.getBody().add(scroller, "w 100%!, h 100%!");
|
||||
}
|
||||
|
||||
public final void setModel(final List<PlayerView> players) {
|
||||
this.players = players;
|
||||
public final void setModel() {
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -122,7 +120,7 @@ public enum VAntes implements IVDoc<CAntes> {
|
||||
allAntes.clear();
|
||||
pnl.removeAll();
|
||||
|
||||
for (final PlayerView p : players) {
|
||||
for (final PlayerView p : Singletons.getControl().getGameView().getPlayers()) {
|
||||
for (final CardView c : p.getAnteCards()) {
|
||||
final AntePanel pnlTemp = new AntePanel(c);
|
||||
allAntes.add(pnlTemp);
|
||||
|
||||
@@ -28,7 +28,6 @@ import javax.swing.border.Border;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
@@ -84,7 +83,7 @@ public class VField implements IVDoc<CField> {
|
||||
* @param p   {@link forge.game.player.Player}
|
||||
* @param id0   {@link forge.gui.framework.EDocID}
|
||||
*/
|
||||
public VField(final EDocID id0, final PlayerView p, final LobbyPlayer playerViewer) {
|
||||
public VField(final EDocID id0, final PlayerView p) {
|
||||
this.docID = id0;
|
||||
id0.setDoc(this);
|
||||
|
||||
@@ -98,7 +97,7 @@ public class VField implements IVDoc<CField> {
|
||||
// (haven't looked into it too deeply). Doublestrike 12-04-12
|
||||
tabletop = new PlayArea(scroller, id0 == EDocID.FIELD_1, player, ZoneType.Battlefield);
|
||||
|
||||
control = new CField(player, this, playerViewer);
|
||||
control = new CField(player, this);
|
||||
|
||||
avatarArea.setOpaque(false);
|
||||
avatarArea.setBackground(FSkin.getColor(FSkin.Colors.CLR_HOVER));
|
||||
|
||||
@@ -25,6 +25,7 @@ import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.game.GameLogEntry;
|
||||
import forge.game.GameLogEntryType;
|
||||
import forge.gui.framework.DragCell;
|
||||
@@ -38,6 +39,7 @@ import forge.screens.match.controllers.CLog;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinFont;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.LocalGameView;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of game log report.
|
||||
@@ -124,8 +126,9 @@ public enum VLog implements IVDoc<CLog> {
|
||||
* <p>
|
||||
* @param model contains list of log entries.
|
||||
*/
|
||||
public void updateConsole(final IGameView model) {
|
||||
public void updateConsole() {
|
||||
if (isGameLogConsoleVisible()) {
|
||||
LocalGameView model = Singletons.getControl().getGameView();
|
||||
resetDisplayIfNewGame(model);
|
||||
displayNewGameLogEntries(model);
|
||||
// Important : refreshLayout() needs to be called every update.
|
||||
|
||||
@@ -28,6 +28,7 @@ import javax.swing.ScrollPaneConstants;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.Singletons;
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
@@ -39,7 +40,6 @@ import forge.toolbox.FScrollPanel;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinnedLabel;
|
||||
import forge.view.CardView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
/**
|
||||
@@ -142,10 +142,10 @@ public enum VPlayers implements IVDoc<CPlayers> {
|
||||
//========== Observer update methods
|
||||
|
||||
/** @param game {@link forge.game.player.Player} */
|
||||
public void update(final IGameView game) {
|
||||
public void update() {
|
||||
// No need to update if this panel isn't showing
|
||||
if (parentCell == null || !this.equals(parentCell.getSelected())) { return; }
|
||||
boolean isCommander = game.isCommander();
|
||||
boolean isCommander = Singletons.getControl().getGameView().isCommander();
|
||||
|
||||
for(final Entry<PlayerView, JLabel[]> rr : infoLBLs.entrySet()) {
|
||||
PlayerView p0 = rr.getKey();
|
||||
|
||||
@@ -36,8 +36,10 @@ import javax.swing.border.EmptyBorder;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.ImageCache;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardDetailUtil;
|
||||
import forge.card.CardDetailUtil.DetailColors;
|
||||
import forge.game.player.Player;
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
@@ -51,7 +53,7 @@ import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinnedTextArea;
|
||||
import forge.view.CardView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.LocalGameView;
|
||||
import forge.view.StackItemView;
|
||||
import forge.view.arcane.CardPanel;
|
||||
|
||||
@@ -132,9 +134,10 @@ public enum VStack implements IVDoc<CStack> {
|
||||
//========== Observer update methods
|
||||
|
||||
/**
|
||||
* @param model
|
||||
* @param models
|
||||
* @param viewer */
|
||||
public void updateStack(final IGameView model, final PlayerView localPlayer) {
|
||||
public void updateStack() {
|
||||
final LocalGameView model = Singletons.getControl().getGameView();
|
||||
final List<StackItemView> items = model.getStack();
|
||||
tab.setText("Stack : " + items.size());
|
||||
|
||||
@@ -145,7 +148,7 @@ public enum VStack implements IVDoc<CStack> {
|
||||
|
||||
boolean isFirst = true;
|
||||
for (final StackItemView item : items) {
|
||||
final StackInstanceTextArea tar = new StackInstanceTextArea(model, item, localPlayer);
|
||||
final StackInstanceTextArea tar = new StackInstanceTextArea(model, item);
|
||||
|
||||
scroller.add(tar, "pushx, growx" + (isFirst ? "" : ", gaptop 2px"));
|
||||
|
||||
@@ -175,9 +178,10 @@ public enum VStack implements IVDoc<CStack> {
|
||||
|
||||
private final CardView sourceCard;
|
||||
|
||||
public StackInstanceTextArea(final IGameView game, final StackItemView item, final PlayerView localPlayer) {
|
||||
public StackInstanceTextArea(final IGameView game, final StackItemView item) {
|
||||
sourceCard = item.getSource();
|
||||
|
||||
final Player localPlayer = Singletons.getControl().getCurrentPlayer();
|
||||
final String txt = (item.isOptionalTrigger() && item.getActivatingPlayer().equals(localPlayer)
|
||||
? "(OPTIONAL) " : "") + item.getText();
|
||||
|
||||
@@ -302,7 +306,7 @@ public enum VStack implements IVDoc<CStack> {
|
||||
add(jmiAlwaysNo);
|
||||
}
|
||||
|
||||
public void setStackInstance(final IGameView game, final StackItemView item, final PlayerView localPlayer) {
|
||||
public void setStackInstance(final IGameView game, final StackItemView item, final Player localPlayer) {
|
||||
this.game = game;
|
||||
this.item = item;
|
||||
triggerID = Integer.valueOf(item.getSourceTrigger());
|
||||
|
||||
@@ -239,12 +239,12 @@ public class GuiMobile implements IGuiBase {
|
||||
|
||||
@Override
|
||||
public IButton getBtnOK() {
|
||||
return FControl.getView().getPrompt().getBtnOk();
|
||||
return FControl.getView().getActivePrompt().getBtnOk();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IButton getBtnCancel() {
|
||||
return FControl.getView().getPrompt().getBtnCancel();
|
||||
return FControl.getView().getActivePrompt().getBtnCancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,6 +6,8 @@ import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -23,7 +25,6 @@ import forge.Forge;
|
||||
import forge.Graphics;
|
||||
import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.ai.LobbyPlayerAi;
|
||||
import forge.assets.FImage;
|
||||
import forge.assets.FSkin;
|
||||
import forge.assets.FTextureRegionImage;
|
||||
@@ -71,7 +72,6 @@ import forge.view.CardView;
|
||||
import forge.view.CardView.CardStateView;
|
||||
import forge.view.CombatView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.LocalGameView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.WatchLocalGame;
|
||||
@@ -80,13 +80,10 @@ public class FControl {
|
||||
private FControl() { } //don't allow creating instance
|
||||
|
||||
private static Game game;
|
||||
private static IGameView gameView;
|
||||
private static List<LocalGameView> gameViews = new ArrayList<LocalGameView>();
|
||||
private static MatchScreen view;
|
||||
private static InputQueue inputQueue;
|
||||
private static final EventBus uiEvents;
|
||||
private static boolean gameHasHumanPlayer;
|
||||
private static final MatchUiEventVisitor visitor = new MatchUiEventVisitor();
|
||||
private static FControlGameEventHandler fcVisitor;
|
||||
private static FControlGamePlayback playbackControl;
|
||||
private static final Map<LobbyPlayer, FImage> avatarImages = new HashMap<LobbyPlayer, FImage>();
|
||||
|
||||
@@ -147,30 +144,63 @@ public class FControl {
|
||||
game.subscribeToEvents(qc); // this one listens to player's mulligans ATM
|
||||
}
|
||||
|
||||
inputQueue = new InputQueue(game);
|
||||
|
||||
game.subscribeToEvents(Forge.getSoundSystem());
|
||||
|
||||
Player humanLobbyPlayer = game.getRegisteredPlayers().get(0);
|
||||
// The UI controls should use these game data as models
|
||||
initMatch(game.getRegisteredPlayers(), humanLobbyPlayer);
|
||||
final String[] indices = FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",");
|
||||
|
||||
actuateMatchPreferences();
|
||||
// Instantiate all required field slots (user at 0)
|
||||
final List<Player> sortedPlayers = new ArrayList<Player>(game.getRegisteredPlayers());
|
||||
Collections.sort(sortedPlayers, new Comparator<Player>() {
|
||||
@Override
|
||||
public int compare(Player p1, Player p2) {
|
||||
int v1 = p1.getController() instanceof PlayerControllerHuman ? 0 : 1;
|
||||
int v2 = p2.getController() instanceof PlayerControllerHuman ? 0 : 1;
|
||||
return Integer.compare(v1, v2);
|
||||
}
|
||||
});
|
||||
|
||||
// Listen to DuelOutcome event to show ViewWinLose
|
||||
game.subscribeToEvents(fcVisitor);
|
||||
gameViews.clear();
|
||||
List<VPlayerPanel> playerPanels = new ArrayList<VPlayerPanel>();
|
||||
|
||||
// Add playback controls to match if needed
|
||||
gameHasHumanPlayer = false;
|
||||
boolean gameHasAiPlayer = false;
|
||||
for (Player p : game.getPlayers()) {
|
||||
if (p.getController().getLobbyPlayer() == getGuiPlayer()) {
|
||||
gameHasHumanPlayer = true;
|
||||
} else if (p.getLobbyPlayer() instanceof LobbyPlayerAi) {
|
||||
gameHasAiPlayer = true;
|
||||
int i = 0;
|
||||
int avatarIndex = 0;
|
||||
int humanCount = 0;
|
||||
for (Player p : sortedPlayers) {
|
||||
if (i < indices.length) {
|
||||
avatarIndex = Integer.parseInt(indices[i]);
|
||||
i++;
|
||||
}
|
||||
p.getLobbyPlayer().setAvatarIndex(avatarIndex);
|
||||
|
||||
if (p.getController() instanceof PlayerControllerHuman) {
|
||||
final PlayerControllerHuman controller = (PlayerControllerHuman) p.getController();
|
||||
LocalGameView gameView = controller.getGameView();
|
||||
game.subscribeToEvents(new FControlGameEventHandler(GuiBase.getInterface(), gameView));
|
||||
gameViews.add(gameView);
|
||||
humanCount++;
|
||||
}
|
||||
}
|
||||
if (!gameHasHumanPlayer) {
|
||||
|
||||
if (humanCount == 0) { //watch game but do not participate
|
||||
LocalGameView gameView = new WatchLocalGame(game, GuiBase.getInterface());
|
||||
game.subscribeToEvents(new FControlGameEventHandler(GuiBase.getInterface(), gameView));
|
||||
gameViews.add(gameView);
|
||||
}
|
||||
else if (humanCount == sortedPlayers.size()) {
|
||||
//if there are no AI's, allow all players to see all cards (hotseat mode).
|
||||
for (Player p : sortedPlayers) {
|
||||
((PlayerControllerHuman) p.getController()).setMayLookAtAllCards(true);
|
||||
}
|
||||
}
|
||||
|
||||
for (Player p : sortedPlayers) {
|
||||
playerPanels.add(new VPlayerPanel(getGameView(p).getPlayerView(p), humanCount == 0 || p.getController() instanceof PlayerControllerHuman));
|
||||
}
|
||||
view = new MatchScreen(playerPanels);
|
||||
|
||||
if (humanCount == 0) {
|
||||
playbackControl = new FControlGamePlayback(GuiBase.getInterface(), getGameView());
|
||||
playbackControl.setGame(game);
|
||||
game.subscribeToEvents(playbackControl);
|
||||
|
||||
//add special object that pauses game if screen touched
|
||||
@@ -189,16 +219,7 @@ public class FControl {
|
||||
});
|
||||
}
|
||||
|
||||
if (!gameHasAiPlayer) {
|
||||
// If there are no AI's, allow all players to see all cards (hotseat
|
||||
// mode).
|
||||
for (final Player p : game.getPlayers()) {
|
||||
if (p.getController() instanceof PlayerControllerHuman) {
|
||||
final PlayerControllerHuman controller = (PlayerControllerHuman) p.getController();
|
||||
controller.setMayLookAtAllCards(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
actuateMatchPreferences();
|
||||
|
||||
Forge.openScreen(view);
|
||||
|
||||
@@ -216,8 +237,21 @@ public class FControl {
|
||||
return game;
|
||||
}
|
||||
|
||||
public static IGameView getGameView() {
|
||||
return gameView;
|
||||
public static LocalGameView getGameView() {
|
||||
return getGameView(getCurrentPlayer());
|
||||
}
|
||||
public static LocalGameView getGameView(Player player) {
|
||||
switch (gameViews.size()) {
|
||||
case 1:
|
||||
return gameViews.get(0);
|
||||
case 0:
|
||||
return null;
|
||||
default:
|
||||
if (player != null && player.getController() instanceof PlayerControllerHuman) {
|
||||
return ((PlayerControllerHuman)player.getController()).getGameView();
|
||||
}
|
||||
return gameViews.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static MatchScreen getView() {
|
||||
@@ -225,7 +259,11 @@ public class FControl {
|
||||
}
|
||||
|
||||
public static InputQueue getInputQueue() {
|
||||
return inputQueue;
|
||||
LocalGameView gameView = getGameView();
|
||||
if (gameView != null) {
|
||||
return gameView.getInputQueue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean stopAtPhase(final PlayerView turn, final PhaseType phase) {
|
||||
@@ -234,69 +272,7 @@ public class FControl {
|
||||
}
|
||||
|
||||
public static void endCurrentTurn() {
|
||||
gameView.passPriorityUntilEndOfTurn();
|
||||
}
|
||||
|
||||
public static void initMatch(final List<Player> players, Player localPlayer) {
|
||||
final String[] indices = FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",");
|
||||
|
||||
// Instantiate all required field slots (user at 0)
|
||||
final List<Player> sortedPlayers = shiftPlayersPlaceLocalFirst(players, localPlayer);
|
||||
|
||||
List<VPlayerPanel> playerPanels = new ArrayList<VPlayerPanel>();
|
||||
|
||||
int i = 0;
|
||||
int avatarIndex = 0;
|
||||
for (Player p : sortedPlayers) {
|
||||
if (i < indices.length) {
|
||||
avatarIndex = Integer.parseInt(indices[i]);
|
||||
i++;
|
||||
}
|
||||
p.getLobbyPlayer().setAvatarIndex(avatarIndex);
|
||||
}
|
||||
|
||||
final LocalGameView localGameView;
|
||||
final boolean isWatchingGame;
|
||||
if (localPlayer.getController() instanceof PlayerControllerHuman) {
|
||||
final PlayerControllerHuman controller = (PlayerControllerHuman) localPlayer.getController();
|
||||
localGameView = controller.getGameView();
|
||||
gameView = localGameView;
|
||||
fcVisitor = new FControlGameEventHandler(GuiBase.getInterface(), localGameView);
|
||||
isWatchingGame = false;
|
||||
} else {
|
||||
// Watch game but do not participate
|
||||
localGameView = new WatchLocalGame(game, inputQueue);
|
||||
gameView = localGameView;
|
||||
fcVisitor = new FControlGameEventHandler(GuiBase.getInterface(), localGameView);
|
||||
isWatchingGame = true;
|
||||
}
|
||||
|
||||
for (Player p : sortedPlayers) {
|
||||
playerPanels.add(new VPlayerPanel(localGameView.getPlayerView(p)));
|
||||
}
|
||||
view = new MatchScreen(localGameView, localGameView.getPlayerView(localPlayer), playerPanels);
|
||||
|
||||
if (isWatchingGame) {
|
||||
playbackControl = new FControlGamePlayback(GuiBase.getInterface(), localGameView);
|
||||
playbackControl.setGame(game);
|
||||
game.subscribeToEvents(playbackControl);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Player> shiftPlayersPlaceLocalFirst(final List<Player> players, Player localPlayer) {
|
||||
// get an arranged list so that the first local player is at index 0
|
||||
List<Player> sortedPlayers = new ArrayList<Player>(players);
|
||||
int ixFirstHuman = -1;
|
||||
for (int i = 0; i < players.size(); i++) {
|
||||
if (sortedPlayers.get(i) == localPlayer) {
|
||||
ixFirstHuman = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ixFirstHuman > 0) {
|
||||
sortedPlayers.add(0, sortedPlayers.remove(ixFirstHuman));
|
||||
}
|
||||
return sortedPlayers;
|
||||
getGameView().passPriorityUntilEndOfTurn();
|
||||
}
|
||||
|
||||
public static void resetAllPhaseButtons() {
|
||||
@@ -306,7 +282,10 @@ public class FControl {
|
||||
}
|
||||
|
||||
public static void showMessage(final String s0) {
|
||||
view.getPrompt().setMessage(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) {
|
||||
@@ -333,6 +312,8 @@ 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()) {
|
||||
@@ -350,7 +331,7 @@ public class FControl {
|
||||
}
|
||||
|
||||
public static void alphaStrike() {
|
||||
gameView.alphaStrike();
|
||||
getGameView().alphaStrike();
|
||||
}
|
||||
|
||||
public static void showCombat(CombatView combat) {
|
||||
@@ -537,7 +518,7 @@ public class FControl {
|
||||
}
|
||||
else {
|
||||
game.isGameOver(); // this is synchronized method - it's used to make Game-0 thread see changes made here
|
||||
inputQueue.onGameOver(false); //release any waiting input, effectively passing priority
|
||||
getInputQueue().onGameOver(false); //release any waiting input, effectively passing priority
|
||||
}
|
||||
|
||||
if (playbackControl != null) {
|
||||
@@ -556,6 +537,7 @@ public class FControl {
|
||||
public static void pause() {
|
||||
Forge.getSoundSystem().pause();
|
||||
//pause playback if needed
|
||||
InputQueue inputQueue = getInputQueue();
|
||||
if (inputQueue != null && inputQueue.getInput() instanceof InputPlaybackControl) {
|
||||
((InputPlaybackControl)inputQueue.getInput()).pause();
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.google.common.collect.Maps;
|
||||
import forge.Forge;
|
||||
import forge.menu.FMenuBar;
|
||||
import forge.model.FModel;
|
||||
import forge.player.LobbyPlayerHuman;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.screens.FScreen;
|
||||
@@ -34,7 +35,6 @@ import forge.animation.AbilityEffect;
|
||||
import forge.assets.FSkinColor;
|
||||
import forge.assets.FSkinTexture;
|
||||
import forge.assets.FSkinColor.Colors;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.toolbox.FEvent;
|
||||
import forge.toolbox.FEvent.FEventHandler;
|
||||
import forge.toolbox.FScrollPane;
|
||||
@@ -42,52 +42,72 @@ import forge.util.Callback;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CombatView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
public class MatchScreen extends FScreen {
|
||||
public static FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS);
|
||||
|
||||
private final IGameView gameView;
|
||||
private final Map<PlayerView, VPlayerPanel> playerPanels = Maps.newHashMap();
|
||||
private final VPrompt prompt;
|
||||
private final VLog log;
|
||||
private final VStack stack;
|
||||
private final VDevMenu devMenu;
|
||||
private final FieldScroller scroller;
|
||||
private final VPrompt bottomPlayerPrompt, topPlayerPrompt;
|
||||
private VPlayerPanel bottomPlayerPanel, topPlayerPanel;
|
||||
private AbilityEffect activeEffect;
|
||||
|
||||
public MatchScreen(final IGameView game, PlayerView localPlayer, List<VPlayerPanel> playerPanels0) {
|
||||
public MatchScreen(List<VPlayerPanel> playerPanels0) {
|
||||
super(new FMenuBar());
|
||||
this.gameView = game;
|
||||
|
||||
scroller = add(new FieldScroller());
|
||||
|
||||
int humanCount = 0;
|
||||
for (VPlayerPanel playerPanel : playerPanels0) {
|
||||
playerPanels.put(playerPanel.getPlayer(), scroller.add(playerPanel));
|
||||
if (playerPanel.getPlayer().getLobbyPlayer() instanceof LobbyPlayerHuman) {
|
||||
humanCount++;
|
||||
}
|
||||
}
|
||||
bottomPlayerPanel = playerPanels0.get(0);
|
||||
topPlayerPanel = playerPanels0.get(1);
|
||||
topPlayerPanel.setFlipped(true);
|
||||
bottomPlayerPanel.setSelectedZone(ZoneType.Hand);
|
||||
|
||||
prompt = add(new VPrompt("", "",
|
||||
bottomPlayerPrompt = add(new VPrompt("", "",
|
||||
new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
game.selectButtonOk();
|
||||
FControl.getGameView().selectButtonOk();
|
||||
}
|
||||
},
|
||||
new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
game.selectButtonCancel();
|
||||
FControl.getGameView().selectButtonCancel();
|
||||
}
|
||||
}));
|
||||
|
||||
log = new VLog(game);
|
||||
if (humanCount > 1) { //show top prompt if multiple human players
|
||||
topPlayerPrompt = add(new VPrompt("", "",
|
||||
new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
FControl.getGameView().selectButtonOk();
|
||||
}
|
||||
},
|
||||
new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
FControl.getGameView().selectButtonCancel();
|
||||
}
|
||||
}));
|
||||
}
|
||||
else {
|
||||
topPlayerPrompt = null;
|
||||
}
|
||||
|
||||
log = new VLog();
|
||||
log.setDropDownContainer(this);
|
||||
stack = new VStack(game, localPlayer);
|
||||
stack = new VStack();
|
||||
stack.setDropDownContainer(this);
|
||||
devMenu = new VDevMenu();
|
||||
devMenu.setDropDownContainer(this);
|
||||
@@ -96,7 +116,7 @@ public class MatchScreen extends FScreen {
|
||||
players.setDropDownContainer(this);
|
||||
|
||||
FMenuBar menuBar = (FMenuBar)getHeader();
|
||||
menuBar.addTab("Game", new VGameMenu(game));
|
||||
menuBar.addTab("Game", new VGameMenu());
|
||||
menuBar.addTab("Players (" + playerPanels.size() + ")", players);
|
||||
menuBar.addTab("Log", log);
|
||||
menuBar.addTab("Dev", devMenu);
|
||||
@@ -109,6 +129,20 @@ public class MatchScreen extends FScreen {
|
||||
devMenu.getMenuTab().setVisible(ForgePreferences.DEV_MODE);
|
||||
}
|
||||
|
||||
public VPrompt getActivePrompt() {
|
||||
if (topPlayerPrompt != null && topPlayerPanel.getPlayer().equals(FControl.getCurrentPlayer())) {
|
||||
return topPlayerPrompt;
|
||||
}
|
||||
return bottomPlayerPrompt;
|
||||
}
|
||||
|
||||
public VPrompt getPrompt(PlayerView playerView) {
|
||||
if (topPlayerPrompt == null || bottomPlayerPanel.getPlayer() == playerView) {
|
||||
return bottomPlayerPrompt;
|
||||
}
|
||||
return topPlayerPrompt;
|
||||
}
|
||||
|
||||
public VLog getLog() {
|
||||
return log;
|
||||
}
|
||||
@@ -117,10 +151,6 @@ public class MatchScreen extends FScreen {
|
||||
return stack;
|
||||
}
|
||||
|
||||
public VPrompt getPrompt() {
|
||||
return prompt;
|
||||
}
|
||||
|
||||
public VPlayerPanel getTopPlayerPanel() {
|
||||
return topPlayerPanel;
|
||||
}
|
||||
@@ -142,8 +172,12 @@ public class MatchScreen extends FScreen {
|
||||
|
||||
@Override
|
||||
protected void doLayout(float startY, float width, float height) {
|
||||
if (topPlayerPrompt != null) {
|
||||
bottomPlayerPrompt.setBounds(0, startY, width, VPrompt.HEIGHT);
|
||||
startY += VPrompt.HEIGHT;
|
||||
}
|
||||
scroller.setBounds(0, startY, width, height - VPrompt.HEIGHT - startY);
|
||||
prompt.setBounds(0, height - VPrompt.HEIGHT, width, VPrompt.HEIGHT);
|
||||
bottomPlayerPrompt.setBounds(0, height - VPrompt.HEIGHT, width, VPrompt.HEIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,7 +196,7 @@ public class MatchScreen extends FScreen {
|
||||
}
|
||||
|
||||
//draw arrows for combat
|
||||
final CombatView combat = gameView.getCombat();
|
||||
final CombatView combat = FControl.getGameView().getCombat();
|
||||
if (combat != null) {
|
||||
for (final CardView attacker : combat.getAttackers()) {
|
||||
//connect each attacker with planeswalker it's attacking if applicable
|
||||
@@ -190,12 +224,12 @@ public class MatchScreen extends FScreen {
|
||||
switch (keyCode) {
|
||||
case Keys.ENTER:
|
||||
case Keys.SPACE:
|
||||
if (prompt.getBtnOk().trigger()) { //trigger OK on Enter or Space
|
||||
if (getActivePrompt().getBtnOk().trigger()) { //trigger OK on Enter or Space
|
||||
return true;
|
||||
}
|
||||
return prompt.getBtnCancel().trigger(); //trigger Cancel if can't trigger OK
|
||||
return getActivePrompt().getBtnCancel().trigger(); //trigger Cancel if can't trigger OK
|
||||
case Keys.ESCAPE:
|
||||
return prompt.getBtnCancel().trigger(); //otherwise trigger Cancel
|
||||
return getActivePrompt().getBtnCancel().trigger(); //otherwise trigger Cancel
|
||||
case Keys.BACK:
|
||||
return true; //suppress Back button so it's not bumped when trying to press OK or Cancel buttons
|
||||
case Keys.A: //alpha strike on Ctrl+A
|
||||
@@ -218,7 +252,7 @@ public class MatchScreen extends FScreen {
|
||||
break;
|
||||
case Keys.Z: //undo on Ctrl+Z
|
||||
if (KeyInputAdapter.isCtrlKeyDown()) {
|
||||
gameView.tryUndoLastAction();
|
||||
FControl.getGameView().tryUndoLastAction();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -14,13 +14,9 @@ import forge.screens.match.FControl;
|
||||
import forge.screens.settings.SettingsScreen;
|
||||
import forge.toolbox.FEvent;
|
||||
import forge.toolbox.FEvent.FEventHandler;
|
||||
import forge.view.IGameView;
|
||||
|
||||
public class VGameMenu extends FDropDownMenu {
|
||||
private final IGameView gameView;
|
||||
|
||||
public VGameMenu(IGameView gameView0) {
|
||||
gameView = gameView0;
|
||||
public VGameMenu() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,7 +67,7 @@ public class VGameMenu extends FDropDownMenu {
|
||||
//if re-enabling auto-yields, auto-yield to current ability on stack if applicable
|
||||
SpellAbility ability = game.getStack().peekAbility();
|
||||
if (ability != null && ability.isAbility() && localPlayer.getController().shouldAutoYield(ability.toUnsuppressedString())) {
|
||||
gameView.passPriority();
|
||||
FControl.getGameView().passPriority();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ import forge.game.GameLogEntryType;
|
||||
import forge.menu.FDropDown;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.screens.match.FControl;
|
||||
import forge.toolbox.FDisplayObject;
|
||||
import forge.util.Utils;
|
||||
import forge.view.IGameView;
|
||||
|
||||
public class VLog extends FDropDown {
|
||||
private static final float PADDING = Utils.scale(5);
|
||||
@@ -25,10 +25,7 @@ public class VLog extends FDropDown {
|
||||
private static final FSkinColor ROW_COLOR = ALT_ROW_COLOR.darker();
|
||||
private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT);
|
||||
|
||||
private final IGameView gameView;
|
||||
|
||||
public VLog(IGameView log0) {
|
||||
gameView = log0;
|
||||
public VLog() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +45,7 @@ public class VLog extends FDropDown {
|
||||
clear();
|
||||
|
||||
GameLogEntryType logVerbosityFilter = GameLogEntryType.valueOf(FModel.getPreferences().getPref(FPref.DEV_LOG_ENTRY_TYPE));
|
||||
List<GameLogEntry> logEntrys = gameView.getLogEntries(logVerbosityFilter);
|
||||
List<GameLogEntry> logEntrys = FControl.getGameView().getLogEntries(logVerbosityFilter);
|
||||
|
||||
LogEntryDisplay logEntryDisplay;
|
||||
float width = maxWidth - getMenuTab().getScreenPosition().x; //stretch from tab to edge of screen
|
||||
|
||||
@@ -44,9 +44,10 @@ public class VPlayerPanel extends FContainer {
|
||||
private final List<InfoTab> tabs = new ArrayList<InfoTab>();
|
||||
private InfoTab selectedTab;
|
||||
|
||||
public VPlayerPanel(PlayerView player0) {
|
||||
public VPlayerPanel(PlayerView player0, boolean showHand) {
|
||||
player = player0;
|
||||
phaseIndicator = add(new VPhaseIndicator());
|
||||
|
||||
field = add(new VField(player));
|
||||
avatar = add(new VAvatar(player));
|
||||
lblLife = add(new LifeLabel());
|
||||
@@ -65,6 +66,10 @@ public class VPlayerPanel extends FContainer {
|
||||
addZoneDisplay(ZoneType.Exile, FSkinImage.EXILE);
|
||||
|
||||
commandZone = add(new CommandZoneDisplay(player));
|
||||
|
||||
if (showHand) {
|
||||
setSelectedZone(ZoneType.Hand);
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerView getPlayer() {
|
||||
|
||||
@@ -19,6 +19,7 @@ import forge.card.CardDetailUtil;
|
||||
import forge.card.CardRenderer;
|
||||
import forge.card.CardZoom;
|
||||
import forge.card.CardDetailUtil.DetailColors;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.menu.FCheckBoxMenuItem;
|
||||
import forge.menu.FDropDown;
|
||||
@@ -47,17 +48,13 @@ public class VStack extends FDropDown {
|
||||
private static final float ALPHA_COMPOSITE = 0.5f;
|
||||
private static final TextRenderer textRenderer = new TextRenderer(true);
|
||||
|
||||
private final IGameView gameView;
|
||||
private final PlayerView localPlayer;
|
||||
private StackInstanceDisplay activeItem;
|
||||
private StackItemView activeStackInstance;
|
||||
private Map<PlayerView, Object> playersWithValidTargets;
|
||||
|
||||
private int stackSize;
|
||||
|
||||
public VStack(IGameView gameView0, PlayerView localPlayer0) {
|
||||
gameView = gameView0;
|
||||
localPlayer = localPlayer0;
|
||||
public VStack() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,7 +90,7 @@ public class VStack extends FDropDown {
|
||||
activeStackInstance = null; //reset before updating stack
|
||||
restoreOldZones();
|
||||
|
||||
final List<StackItemView> stack = gameView.getStack();
|
||||
final List<StackItemView> stack = FControl.getGameView().getStack();
|
||||
if (stackSize != stack.size()) {
|
||||
int oldStackSize = stackSize;
|
||||
stackSize = stack.size();
|
||||
@@ -124,7 +121,7 @@ public class VStack extends FDropDown {
|
||||
float totalWidth = maxWidth - FControl.getView().getTopPlayerPanel().getTabs().iterator().next().getRight(); //keep avatar, life total, and hand tab visible to left of stack
|
||||
float width = totalWidth - 2 * MARGINS;
|
||||
|
||||
final List<StackItemView> stack = gameView.getStack();
|
||||
final List<StackItemView> stack = FControl.getGameView().getStack();
|
||||
if (stack.isEmpty()) { //show label if stack empty
|
||||
FLabel label = add(new FLabel.Builder().text("[Empty]").font(FONT).align(HAlignment.CENTER).build());
|
||||
|
||||
@@ -204,7 +201,7 @@ public class VStack extends FDropDown {
|
||||
|
||||
text = stackInstance.getText();
|
||||
if (stackInstance.isOptionalTrigger() &&
|
||||
stackInstance0.getActivatingPlayer().getLobbyPlayer().equals(localPlayer)) {
|
||||
stackInstance0.getActivatingPlayer().equals(FControl.getCurrentPlayer())) {
|
||||
text = "(OPTIONAL) " + text;
|
||||
}
|
||||
|
||||
@@ -227,11 +224,14 @@ public class VStack extends FDropDown {
|
||||
VStack.this.updateSizeAndPosition();
|
||||
return true;
|
||||
}
|
||||
if (localPlayer != null) { //don't show menu if tapping on art
|
||||
Player player = FControl.getCurrentPlayer();
|
||||
if (player != null) { //don't show menu if tapping on art
|
||||
if (stackInstance.isAbility()) {
|
||||
FPopupMenu menu = new FPopupMenu() {
|
||||
@Override
|
||||
protected void buildMenu() {
|
||||
final IGameView gameView = FControl.getGameView();
|
||||
final Player player = FControl.getCurrentPlayer();
|
||||
final String key = stackInstance.getKey();
|
||||
final boolean autoYield = gameView.shouldAutoYield(key);
|
||||
addItem(new FCheckBoxMenuItem("Auto-Yield", autoYield,
|
||||
@@ -245,7 +245,7 @@ public class VStack extends FDropDown {
|
||||
}
|
||||
}
|
||||
}));
|
||||
if (stackInstance.isOptionalTrigger() && stackInstance.getActivatingPlayer() == localPlayer) {
|
||||
if (stackInstance.isOptionalTrigger() && stackInstance.getActivatingPlayer().equals(player)) {
|
||||
final int triggerID = stackInstance.getSourceTrigger();
|
||||
addItem(new FCheckBoxMenuItem("Always Yes",
|
||||
gameView.shouldAlwaysAcceptTrigger(triggerID),
|
||||
|
||||
@@ -22,12 +22,10 @@ import java.util.Observer;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.game.Game;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.gui.SOptionPane;
|
||||
import forge.view.CardView;
|
||||
import forge.view.LocalGameView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.SpellAbilityView;
|
||||
|
||||
@@ -43,48 +41,21 @@ public class InputProxy implements Observer {
|
||||
|
||||
/** The input. */
|
||||
private AtomicReference<Input> input = new AtomicReference<Input>();
|
||||
private final Game game;
|
||||
private final LocalGameView gameView;
|
||||
|
||||
// private static final boolean DEBUG_INPUT = true; // false;
|
||||
|
||||
private final PlayerControllerHuman controller;
|
||||
public InputProxy(final PlayerControllerHuman controller, final Game game) {
|
||||
this.controller = controller;
|
||||
this.game = game;
|
||||
public InputProxy(final LocalGameView gameView0) {
|
||||
this.gameView = gameView0;
|
||||
}
|
||||
|
||||
private IGuiBase getGui() {
|
||||
return this.controller.getGui();
|
||||
}
|
||||
|
||||
public boolean passPriority() {
|
||||
return passPriority(false);
|
||||
}
|
||||
public boolean passPriorityUntilEndOfTurn() {
|
||||
return passPriority(true);
|
||||
}
|
||||
private boolean passPriority(final boolean passUntilEndOfTurn) {
|
||||
final Input inp = getInput();
|
||||
if (inp instanceof InputPassPriority) {
|
||||
if (passUntilEndOfTurn) {
|
||||
controller.autoPassUntilEndOfTurn();
|
||||
}
|
||||
inp.selectButtonOK();
|
||||
return true;
|
||||
}
|
||||
|
||||
FThreads.invokeInEdtNowOrLater(getGui(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SOptionPane.showMessageDialog(getGui(), "Cannot pass priority at this time.");
|
||||
}
|
||||
});
|
||||
return false;
|
||||
return this.gameView.getGui();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void update(final Observable observable, final Object obj) {
|
||||
final Input nextInput = getGui().getInputQueue().getActualInput(game);
|
||||
final Input nextInput = gameView.getInputQueue().getActualInput(gameView);
|
||||
/* if(DEBUG_INPUT)
|
||||
System.out.printf("%s ... \t%s on %s, \tstack = %s%n",
|
||||
FThreads.debugGetStackTraceItem(6, true), nextInput == null ? "null" : nextInput.getClass().getSimpleName(),
|
||||
@@ -137,7 +108,7 @@ public class InputProxy implements Observer {
|
||||
public final void selectPlayer(final PlayerView player, final ITriggerEvent triggerEvent) {
|
||||
final Input inp = getInput();
|
||||
if (inp != null) {
|
||||
inp.selectPlayer(controller.getPlayer(player), triggerEvent);
|
||||
inp.selectPlayer(gameView.getPlayer(player), triggerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +124,7 @@ public class InputProxy implements Observer {
|
||||
public final boolean selectCard(final CardView cardView, final ITriggerEvent triggerEvent) {
|
||||
final Input inp = getInput();
|
||||
if (inp != null) {
|
||||
return inp.selectCard(controller.getCard(cardView), triggerEvent);
|
||||
return inp.selectCard(gameView.getCard(cardView), triggerEvent);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -161,7 +132,7 @@ public class InputProxy implements Observer {
|
||||
public final void selectAbility(final SpellAbilityView ab) {
|
||||
final Input inp = getInput();
|
||||
if (inp != null) {
|
||||
inp.selectAbility(controller.getSpellAbility(ab));
|
||||
inp.selectAbility(gameView.getSpellAbility(ab));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +151,7 @@ public class InputProxy implements Observer {
|
||||
}
|
||||
|
||||
/** @return {@link forge.gui.InputProxy.InputBase} */
|
||||
private Input getInput() {
|
||||
public Input getInput() {
|
||||
return this.input.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@ import java.util.concurrent.BlockingDeque;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.player.Player;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.view.IGameView;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -37,22 +36,18 @@ public class InputQueue extends Observable {
|
||||
private final BlockingDeque<InputSynchronized> inputStack = new LinkedBlockingDeque<InputSynchronized>();
|
||||
private final InputLockUI inputLock;
|
||||
|
||||
public InputQueue(final Game game) {
|
||||
public InputQueue(final Game game, final InputProxy inputProxy) {
|
||||
inputLock = new InputLockUI(game, this);
|
||||
for (final Player p : game.getPlayers()) {
|
||||
if (p.getController() instanceof PlayerControllerHuman) {
|
||||
this.addObserver(((PlayerControllerHuman) p.getController()).getInputProxy());
|
||||
}
|
||||
}
|
||||
addObserver(inputProxy);
|
||||
}
|
||||
|
||||
public final void updateObservers() {
|
||||
this.setChanged();
|
||||
this.notifyObservers();
|
||||
setChanged();
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
public final Input getInput() {
|
||||
return inputStack.isEmpty() ? null : this.inputStack.peek();
|
||||
return inputStack.isEmpty() ? null : inputStack.peek();
|
||||
}
|
||||
|
||||
public final void removeInput(Input inp) {
|
||||
@@ -71,9 +66,9 @@ public class InputQueue extends Observable {
|
||||
*
|
||||
* @return a {@link forge.gui.input.InputBase} object.
|
||||
*/
|
||||
public final Input getActualInput(final Game game) {
|
||||
public final Input getActualInput(final IGameView gameView) {
|
||||
Input topMost = inputStack.peek(); // incoming input to Control
|
||||
if (topMost != null && !game.isGameOver()) {
|
||||
if (topMost != null && !gameView.isGameOver()) {
|
||||
return topMost;
|
||||
}
|
||||
return inputLock;
|
||||
@@ -85,10 +80,10 @@ public class InputQueue extends Observable {
|
||||
}
|
||||
|
||||
public void setInput(final InputSynchronized input) {
|
||||
this.inputStack.push(input);
|
||||
inputStack.push(input);
|
||||
inputLock.setGui(input.getGui());
|
||||
syncPoint();
|
||||
this.updateObservers();
|
||||
updateObservers();
|
||||
}
|
||||
|
||||
public void syncPoint() {
|
||||
|
||||
@@ -29,7 +29,6 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
|
||||
cdlDone.countDown();
|
||||
}
|
||||
|
||||
|
||||
public void showAndWait() {
|
||||
getGui().getInputQueue().setInput(this);
|
||||
awaitLatchRelease();
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.achievement.AchievementCollection;
|
||||
import forge.card.CardCharacteristicName;
|
||||
@@ -118,9 +119,6 @@ import forge.view.StackItemView;
|
||||
* Handles phase skips for now.
|
||||
*/
|
||||
public class PlayerControllerHuman extends PlayerController {
|
||||
|
||||
private IGuiBase gui;
|
||||
private final InputProxy inputProxy;
|
||||
private final GameView gameView;
|
||||
/**
|
||||
* Cards this player may look at right now, for example when searching a
|
||||
@@ -131,9 +129,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.gui = gui;
|
||||
this.inputProxy = new InputProxy(this, game0);
|
||||
this.gameView = new GameView(game0);
|
||||
this.gameView = new GameView(game0, gui);
|
||||
|
||||
// aggressively cache a view for each player (also caches cards)
|
||||
for (final Player player : game.getRegisteredPlayers()) {
|
||||
@@ -142,11 +138,11 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
}
|
||||
|
||||
public IGuiBase getGui() {
|
||||
return gui;
|
||||
return gameView.getGui();
|
||||
}
|
||||
|
||||
public InputProxy getInputProxy() {
|
||||
return inputProxy;
|
||||
return gameView.getInputProxy();
|
||||
}
|
||||
|
||||
public LocalGameView getGameView() {
|
||||
@@ -1334,8 +1330,8 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
* What follows are the View methods.
|
||||
*/
|
||||
private class GameView extends LocalGameView {
|
||||
public GameView(Game game) {
|
||||
super(game);
|
||||
public GameView(Game game0, IGuiBase gui0) {
|
||||
super(game0, gui0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1395,12 +1391,29 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
|
||||
@Override
|
||||
public boolean passPriority() {
|
||||
return getInputProxy().passPriority();
|
||||
return passPriority(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passPriorityUntilEndOfTurn() {
|
||||
return getInputProxy().passPriorityUntilEndOfTurn();
|
||||
return passPriority(true);
|
||||
}
|
||||
private boolean passPriority(final boolean passUntilEndOfTurn) {
|
||||
final Input inp = gameView.getInputProxy().getInput();
|
||||
if (inp instanceof InputPassPriority) {
|
||||
if (passUntilEndOfTurn) {
|
||||
autoPassUntilEndOfTurn();
|
||||
}
|
||||
inp.selectButtonOK();
|
||||
return true;
|
||||
}
|
||||
|
||||
FThreads.invokeInEdtNowOrLater(getGui(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SOptionPane.showMessageDialog(getGui(), "Cannot pass priority at this time.");
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1472,11 +1485,11 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
|
||||
@Override
|
||||
public boolean getDisableAutoYields() {
|
||||
return this.getGame().getDisableAutoYields();
|
||||
return game.getDisableAutoYields();
|
||||
}
|
||||
@Override
|
||||
public void setDisableAutoYields(final boolean b) {
|
||||
this.getGame().setDisableAutoYields(b);
|
||||
game.setDisableAutoYields(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,16 +27,37 @@ import forge.game.player.RegisteredPlayer;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.match.input.InputProxy;
|
||||
import forge.match.input.InputQueue;
|
||||
|
||||
public abstract class LocalGameView implements IGameView {
|
||||
protected final Game game;
|
||||
protected final IGuiBase gui;
|
||||
protected final InputQueue inputQueue;
|
||||
protected final InputProxy inputProxy;
|
||||
|
||||
private final Game game;
|
||||
public LocalGameView(final Game game) {
|
||||
this.game = game;
|
||||
public LocalGameView(Game game0, IGuiBase gui0) {
|
||||
game = game0;
|
||||
gui = gui0;
|
||||
inputProxy = new InputProxy(this);
|
||||
inputQueue = new InputQueue(game, inputProxy);
|
||||
}
|
||||
|
||||
protected final Game getGame() {
|
||||
return this.game;
|
||||
public final Game getGame() {
|
||||
return game;
|
||||
}
|
||||
|
||||
public final IGuiBase getGui() {
|
||||
return gui;
|
||||
}
|
||||
|
||||
public final InputQueue getInputQueue() {
|
||||
return inputQueue;
|
||||
}
|
||||
|
||||
public InputProxy getInputProxy() {
|
||||
return inputProxy;
|
||||
}
|
||||
|
||||
/** Cache of players. */
|
||||
@@ -60,17 +81,17 @@ public abstract class LocalGameView implements IGameView {
|
||||
*/
|
||||
@Override
|
||||
public GameType getGameType() {
|
||||
return this.game.getMatch().getRules().getGameType();
|
||||
return game.getMatch().getRules().getGameType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTurnNumber() {
|
||||
return this.game.getPhaseHandler().getTurn();
|
||||
return game.getPhaseHandler().getTurn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCommandZoneNeeded() {
|
||||
return this.game.getMatch().getRules().getGameType().isCommandZoneNeeded();
|
||||
return game.getMatch().getRules().getGameType().isCommandZoneNeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,37 +114,37 @@ public abstract class LocalGameView implements IGameView {
|
||||
*/
|
||||
@Override
|
||||
public boolean isFirstGameInMatch() {
|
||||
return this.game.getMatch().getPlayedGames().isEmpty();
|
||||
return game.getMatch().getPlayedGames().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatchOver() {
|
||||
return this.game.getMatch().isMatchOver();
|
||||
return game.getMatch().isMatchOver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumGamesInMatch() {
|
||||
return this.game.getMatch().getRules().getGamesPerMatch();
|
||||
return game.getMatch().getRules().getGamesPerMatch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumPlayedGamesInMatch() {
|
||||
return this.game.getMatch().getPlayedGames().size();
|
||||
return game.getMatch().getPlayedGames().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<GameOutcome> getOutcomesOfMatch() {
|
||||
return Iterables.unmodifiableIterable(this.game.getMatch().getPlayedGames());
|
||||
return Iterables.unmodifiableIterable(game.getMatch().getPlayedGames());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatchWonBy(final LobbyPlayer p) {
|
||||
return this.game.getMatch().isWonBy(p);
|
||||
return game.getMatch().isWonBy(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGamesWonBy(final LobbyPlayer p) {
|
||||
return this.game.getMatch().getGamesWonBy(p);
|
||||
return game.getMatch().getGamesWonBy(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,7 +154,7 @@ public abstract class LocalGameView implements IGameView {
|
||||
|
||||
@Override
|
||||
public Deck getDeck(final LobbyPlayer player) {
|
||||
for (final RegisteredPlayer rp : this.game.getMatch().getPlayers()) {
|
||||
for (final RegisteredPlayer rp : game.getMatch().getPlayers()) {
|
||||
if (rp.getPlayer().equals(player)) {
|
||||
return rp.getDeck();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ package forge.view;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.match.input.Input;
|
||||
import forge.match.input.InputPlaybackControl;
|
||||
import forge.match.input.InputQueue;
|
||||
@@ -16,9 +17,6 @@ import forge.util.ITriggerEvent;
|
||||
*
|
||||
*/
|
||||
public class WatchLocalGame extends LocalGameView {
|
||||
|
||||
private final InputQueue inputQueue;
|
||||
|
||||
/**
|
||||
* @param game
|
||||
* the @{link Game} to attach to.
|
||||
@@ -26,9 +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(final Game game, final InputQueue inputQueue) {
|
||||
super(game);
|
||||
this.inputQueue = inputQueue;
|
||||
public WatchLocalGame(Game game0, IGuiBase gui0) {
|
||||
super(game0, gui0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user