mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18: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)) {
|
||||
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 (p.getController() instanceof PlayerControllerHuman) {
|
||||
final PlayerControllerHuman controller = (PlayerControllerHuman) p.getController();
|
||||
this.gameView = controller.getGameView();
|
||||
this.fcVisitor = new FControlGameEventHandler(GuiBase.getInterface(), controller.getGameView());
|
||||
break;
|
||||
LocalGameView gameView = controller.getGameView();
|
||||
game.subscribeToEvents(new FControlGameEventHandler(GuiBase.getInterface(), gameView));
|
||||
gameViews.add(gameView);
|
||||
humanCount++;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
List<PlayerView> sortedPlayerViews = new ArrayList<PlayerView>();
|
||||
for (Player p : sortedPlayers) {
|
||||
sortedPlayerViews.add(getGameView().getPlayerView(p));
|
||||
}
|
||||
CMatchUI.SINGLETON_INSTANCE.initMatch(sortedPlayerViews, humanCount != 1);
|
||||
|
||||
attachToGame(this.gameView, openAllHands);
|
||||
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());
|
||||
@@ -72,9 +71,8 @@ public enum VAntes implements IVDoc<CAntes> {
|
||||
parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0"));
|
||||
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());
|
||||
|
||||
Reference in New Issue
Block a user