Moved quest game initialization to fcontrol, since quest was a bad dependence from game

separated createGame and tartGame to make Fcontrol.attach optinal and called from UI code that starts a game
This commit is contained in:
Maxmtg
2013-07-18 21:37:02 +00:00
parent 5b2ceef0aa
commit 5b91a68b2f
16 changed files with 490 additions and 470 deletions

View File

@@ -19,7 +19,6 @@ import forge.game.GameNew;
import forge.game.Game; import forge.game.Game;
import forge.game.RegisteredPlayer; import forge.game.RegisteredPlayer;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
public class RestartGameEffect extends SpellAbilityEffect { public class RestartGameEffect extends SpellAbilityEffect {

View File

@@ -1,259 +1,261 @@
/* /*
* Forge: Play Magic: the Gathering. * Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team * Copyright (C) 2011 Forge Team
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package forge.control; package forge.control;
import java.awt.Component; import java.awt.Component;
import java.awt.event.ComponentAdapter; import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.awt.event.WindowListener; import java.awt.event.WindowListener;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JLayeredPane; import javax.swing.JLayeredPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.WindowConstants; import javax.swing.WindowConstants;
import forge.Card; import forge.Card;
import forge.Constant.Preferences; import forge.Constant.Preferences;
import forge.Singletons; import forge.Singletons;
import forge.control.KeyboardShortcuts.Shortcut; import forge.control.KeyboardShortcuts.Shortcut;
import forge.game.Game; import forge.game.Game;
import forge.game.player.LobbyPlayer; import forge.game.GameType;
import forge.game.player.Player; import forge.game.player.LobbyPlayer;
import forge.gui.GuiDialog; import forge.game.player.Player;
import forge.gui.SOverlayUtils; import forge.gui.GuiDialog;
import forge.gui.deckeditor.CDeckEditorUI; import forge.gui.SOverlayUtils;
import forge.gui.deckeditor.VDeckEditorUI; import forge.gui.deckeditor.CDeckEditorUI;
import forge.gui.framework.EDocID; import forge.gui.deckeditor.VDeckEditorUI;
import forge.gui.framework.InvalidLayoutFileException; import forge.gui.framework.EDocID;
import forge.gui.framework.SDisplayUtil; import forge.gui.framework.InvalidLayoutFileException;
import forge.gui.framework.SLayoutIO; import forge.gui.framework.SDisplayUtil;
import forge.gui.framework.SOverflowUtil; import forge.gui.framework.SLayoutIO;
import forge.gui.framework.SResizingUtil; import forge.gui.framework.SOverflowUtil;
import forge.gui.home.CHomeUI; import forge.gui.framework.SResizingUtil;
import forge.gui.home.VHomeUI; import forge.gui.home.CHomeUI;
import forge.gui.match.CMatchUI; import forge.gui.home.VHomeUI;
import forge.gui.match.VMatchUI; import forge.gui.match.CMatchUI;
import forge.gui.match.controllers.CDock; import forge.gui.match.VMatchUI;
import forge.gui.match.controllers.CLog; import forge.gui.match.controllers.CDock;
import forge.gui.match.controllers.CMessage; import forge.gui.match.controllers.CLog;
import forge.gui.match.controllers.CStack; import forge.gui.match.controllers.CMessage;
import forge.gui.match.nonsingleton.VField; import forge.gui.match.controllers.CStack;
import forge.gui.match.views.VAntes; import forge.gui.match.nonsingleton.VField;
import forge.gui.toolbox.FSkin; import forge.gui.match.views.VAntes;
import forge.net.NetServer; import forge.gui.toolbox.FSkin;
import forge.net.NetServer;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.properties.NewConstants; import forge.properties.NewConstants;
import forge.quest.data.QuestPreferences.QPref; import forge.quest.QuestController;
import forge.quest.io.QuestDataIO; import forge.quest.data.QuestPreferences.QPref;
import forge.sound.SoundSystem; import forge.quest.io.QuestDataIO;
import forge.view.FView; import forge.sound.SoundSystem;
import forge.view.FView;
/**
* <p> /**
* FControl. * <p>
* </p> * FControl.
* Controls all Forge UI functionality inside one JFrame. This class switches * </p>
* between various display states in that JFrame. Controllers are instantiated * Controls all Forge UI functionality inside one JFrame. This class switches
* separately by each state's top level view class. * between various display states in that JFrame. Controllers are instantiated
*/ * separately by each state's top level view class.
public enum FControl { */
instance; public enum FControl {
instance;
private List<Shortcut> shortcuts;
private JLayeredPane display; private List<Shortcut> shortcuts;
private Screens state = Screens.UNKNOWN; private JLayeredPane display;
private Screens state = Screens.UNKNOWN;
private WindowListener waDefault, waConcede, waLeaveBazaar, waLeaveEditor;
private WindowListener waDefault, waConcede, waLeaveBazaar, waLeaveEditor;
public static enum Screens {
UNKNOWN, public static enum Screens {
HOME_SCREEN, UNKNOWN,
MATCH_SCREEN, HOME_SCREEN,
DECK_EDITOR_CONSTRUCTED, MATCH_SCREEN,
QUEST_BAZAAR, DECK_EDITOR_CONSTRUCTED,
DECK_EDITOR_LIMITED, QUEST_BAZAAR,
DECK_EDITOR_QUEST, DECK_EDITOR_LIMITED,
QUEST_CARD_SHOP, DECK_EDITOR_QUEST,
DRAFTING_PROCESS QUEST_CARD_SHOP,
} DRAFTING_PROCESS
}
private final SoundSystem soundSystem = new SoundSystem();
private final SoundSystem soundSystem = new SoundSystem();
/**
* <p> /**
* FControl. * <p>
* </p> * FControl.
* Controls all Forge UI functionality inside one JFrame. This class * </p>
* switches between various display states in that JFrame. Controllers are * Controls all Forge UI functionality inside one JFrame. This class
* instantiated separately by each state's top level view class. * switches between various display states in that JFrame. Controllers are
*/ * instantiated separately by each state's top level view class.
private FControl() { */
this.waDefault = new WindowAdapter() { private FControl() {
@Override this.waDefault = new WindowAdapter() {
public void windowClosing(final WindowEvent e) { @Override
Singletons.getView().getFrame().setDefaultCloseOperation( public void windowClosing(final WindowEvent e) {
WindowConstants.EXIT_ON_CLOSE); Singletons.getView().getFrame().setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE);
System.exit(0);
} System.exit(0);
}; }
};
// "Close" button override during match
this.waConcede = new WindowAdapter() { // "Close" button override during match
@Override this.waConcede = new WindowAdapter() {
public void windowClosing(final WindowEvent e) { @Override
Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); public void windowClosing(final WindowEvent e) {
Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
if (!FControl.this.game.isGameOver())
stopGame(); if (!FControl.this.game.isGameOver())
else { stopGame();
Singletons.getControl().changeState(FControl.Screens.HOME_SCREEN); else {
SOverlayUtils.hideOverlay(); Singletons.getControl().changeState(FControl.Screens.HOME_SCREEN);
} SOverlayUtils.hideOverlay();
} }
}; }
};
// "Close" button override while inside bazaar (will probably be used later for other things)
this.waLeaveBazaar = new WindowAdapter() { // "Close" button override while inside bazaar (will probably be used later for other things)
@Override this.waLeaveBazaar = new WindowAdapter() {
public void windowClosing(final WindowEvent e) { @Override
Singletons.getView().getFrame().setDefaultCloseOperation( public void windowClosing(final WindowEvent e) {
WindowConstants.DO_NOTHING_ON_CLOSE); Singletons.getView().getFrame().setDefaultCloseOperation(
WindowConstants.DO_NOTHING_ON_CLOSE);
changeState(Screens.HOME_SCREEN);
} changeState(Screens.HOME_SCREEN);
}; }
};
this.waLeaveEditor = new WindowAdapter() {
@Override this.waLeaveEditor = new WindowAdapter() {
public void windowClosing(final WindowEvent ev) { @Override
Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); public void windowClosing(final WindowEvent ev) {
Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
if (CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().exit()) {
changeState(Screens.HOME_SCREEN); if (CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().exit()) {
} changeState(Screens.HOME_SCREEN);
} }
}; }
} };
}
/** After view and model have been initialized, control can start.
* @param isHeadlessMode */ /** After view and model have been initialized, control can start.
public void initialize() { * @param isHeadlessMode */
// Preloads skin components (using progress bar). public void initialize() {
FSkin.loadFull(); // Preloads skin components (using progress bar).
FSkin.loadFull();
//This must be done here or at least between the skin being loaded and any FTabbedPanes being created.
//Why,Swing? Why is this not a property of JTabbbedPane? //This must be done here or at least between the skin being loaded and any FTabbedPanes being created.
UIManager.put("TabbedPane.selected", FSkin.getColor(FSkin.Colors.CLR_ACTIVE)); //Why,Swing? Why is this not a property of JTabbbedPane?
UIManager.put("TabbedPane.contentOpaque", FSkin.getColor(FSkin.Colors.CLR_THEME)); UIManager.put("TabbedPane.selected", FSkin.getColor(FSkin.Colors.CLR_ACTIVE));
UIManager.put("TabbedPane.unselectedBackground", FSkin.getColor(FSkin.Colors.CLR_THEME2)); UIManager.put("TabbedPane.contentOpaque", FSkin.getColor(FSkin.Colors.CLR_THEME));
UIManager.put("TabbedPane.unselectedBackground", FSkin.getColor(FSkin.Colors.CLR_THEME2));
this.shortcuts = KeyboardShortcuts.attachKeyboardShortcuts();
this.display = FView.SINGLETON_INSTANCE.getLpnDocument(); this.shortcuts = KeyboardShortcuts.attachKeyboardShortcuts();
this.display = FView.SINGLETON_INSTANCE.getLpnDocument();
FSkin.setProgessBarMessage("About to load current quest.");
// Preload quest data if present FSkin.setProgessBarMessage("About to load current quest.");
final File dirQuests = new File(NewConstants.QUEST_SAVE_DIR); // Preload quest data if present
final String questname = Singletons.getModel().getQuestPreferences().getPref(QPref.CURRENT_QUEST); final File dirQuests = new File(NewConstants.QUEST_SAVE_DIR);
final File data = new File(dirQuests.getPath(), questname); final String questname = Singletons.getModel().getQuestPreferences().getPref(QPref.CURRENT_QUEST);
if (data.exists()) { final File data = new File(dirQuests.getPath(), questname);
Singletons.getModel().getQuest().load(QuestDataIO.loadData(data)); if (data.exists()) {
} Singletons.getModel().getQuest().load(QuestDataIO.loadData(data));
}
// Handles resizing in null layouts of layers in JLayeredPane.
Singletons.getView().getFrame().addComponentListener(new ComponentAdapter() { // Handles resizing in null layouts of layers in JLayeredPane.
@Override Singletons.getView().getFrame().addComponentListener(new ComponentAdapter() {
public void componentResized(final ComponentEvent e) { @Override
sizeChildren(); public void componentResized(final ComponentEvent e) {
} sizeChildren();
}); }
});
FView.SINGLETON_INSTANCE.getLpnDocument().addMouseListener(SOverflowUtil.getHideOverflowListener());
FView.SINGLETON_INSTANCE.getLpnDocument().addComponentListener(SResizingUtil.getWindowResizeListener()); FView.SINGLETON_INSTANCE.getLpnDocument().addMouseListener(SOverflowUtil.getHideOverflowListener());
FView.SINGLETON_INSTANCE.getLpnDocument().addComponentListener(SResizingUtil.getWindowResizeListener());
FSkin.setProgessBarMessage("Opening main window...");
SwingUtilities.invokeLater(new Runnable() { @Override FSkin.setProgessBarMessage("Opening main window...");
public void run() { Singletons.getView().initialize(); } }); SwingUtilities.invokeLater(new Runnable() { @Override
} public void run() { Singletons.getView().initialize(); } });
}
/**
* Switches between display states in top level JFrame. /**
*/ * Switches between display states in top level JFrame.
public void changeState(Screens screen) { */
clearChildren(JLayeredPane.DEFAULT_LAYER); public void changeState(Screens screen) {
this.state = screen; clearChildren(JLayeredPane.DEFAULT_LAYER);
this.state = screen;
Singletons.getView().getFrame().removeWindowListener(waDefault);
Singletons.getView().getFrame().removeWindowListener(waConcede); Singletons.getView().getFrame().removeWindowListener(waDefault);
Singletons.getView().getFrame().removeWindowListener(waLeaveBazaar); Singletons.getView().getFrame().removeWindowListener(waConcede);
Singletons.getView().getFrame().removeWindowListener(waLeaveEditor); Singletons.getView().getFrame().removeWindowListener(waLeaveBazaar);
Singletons.getView().getFrame().removeWindowListener(waLeaveEditor);
// Fire up new state
switch (screen) { // Fire up new state
case HOME_SCREEN: switch (screen) {
SOverlayUtils.hideTargetingOverlay(); case HOME_SCREEN:
VHomeUI.SINGLETON_INSTANCE.populate(); SOverlayUtils.hideTargetingOverlay();
CHomeUI.SINGLETON_INSTANCE.initialize(); VHomeUI.SINGLETON_INSTANCE.populate();
FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true); CHomeUI.SINGLETON_INSTANCE.initialize();
FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(new ImageIcon()); FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true);
Singletons.getView().getFrame().addWindowListener(waDefault); FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(new ImageIcon());
break; Singletons.getView().getFrame().addWindowListener(waDefault);
break;
case MATCH_SCREEN:
VMatchUI.SINGLETON_INSTANCE.populate(); case MATCH_SCREEN:
FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true); VMatchUI.SINGLETON_INSTANCE.populate();
FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true);
showMatchBackgroundImage(); showMatchBackgroundImage();
Singletons.getView().getFrame().addWindowListener(waConcede); Singletons.getView().getFrame().addWindowListener(waConcede);
SOverlayUtils.showTargetingOverlay(); SOverlayUtils.showTargetingOverlay();
break; break;
case DECK_EDITOR_CONSTRUCTED: case DECK_EDITOR_CONSTRUCTED:
case DECK_EDITOR_LIMITED: case DECK_EDITOR_LIMITED:
case DECK_EDITOR_QUEST: case DECK_EDITOR_QUEST:
case QUEST_CARD_SHOP: case QUEST_CARD_SHOP:
case DRAFTING_PROCESS: case DRAFTING_PROCESS:
SOverlayUtils.hideTargetingOverlay(); SOverlayUtils.hideTargetingOverlay();
VDeckEditorUI.SINGLETON_INSTANCE.populate(); VDeckEditorUI.SINGLETON_INSTANCE.populate();
FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true); FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true);
FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(new ImageIcon()); FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(new ImageIcon());
Singletons.getView().getFrame().addWindowListener(waLeaveEditor); Singletons.getView().getFrame().addWindowListener(waLeaveEditor);
break; break;
case QUEST_BAZAAR: case QUEST_BAZAAR:
SOverlayUtils.hideTargetingOverlay(); SOverlayUtils.hideTargetingOverlay();
display.add(Singletons.getView().getViewBazaar(), JLayeredPane.DEFAULT_LAYER); display.add(Singletons.getView().getViewBazaar(), JLayeredPane.DEFAULT_LAYER);
FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(false); FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(false);
sizeChildren(); sizeChildren();
Singletons.getView().getFrame().addWindowListener(waLeaveBazaar); Singletons.getView().getFrame().addWindowListener(waLeaveBazaar);
break; break;
default: default:
throw new RuntimeException("unhandled screen: " + screen); throw new RuntimeException("unhandled screen: " + screen);
} }
} }
private void showMatchBackgroundImage() { private void showMatchBackgroundImage() {
if (isMatchBackgroundImageVisible()) { if (isMatchBackgroundImageVisible()) {
FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(FSkin.getIcon(FSkin.Backgrounds.BG_MATCH)); FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(FSkin.getIcon(FSkin.Backgrounds.BG_MATCH));
@@ -264,190 +266,200 @@ public enum FControl {
return Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_MATCH_IMAGE_VISIBLE); return Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_MATCH_IMAGE_VISIBLE);
} }
public void changeStateAutoFixLayout(Screens newState, String stateName) { public void changeStateAutoFixLayout(Screens newState, String stateName) {
try { try {
changeState(newState); changeState(newState);
} catch (InvalidLayoutFileException ex) { } catch (InvalidLayoutFileException ex) {
GuiDialog.message("Your " + stateName + " layout file could not be read. It will be deleted after you press OK.\nThe game will proceed with default layout."); GuiDialog.message("Your " + stateName + " layout file could not be read. It will be deleted after you press OK.\nThe game will proceed with default layout.");
File fLayout = new File(SLayoutIO.getFilePreferred(newState)); File fLayout = new File(SLayoutIO.getFilePreferred(newState));
fLayout.delete(); fLayout.delete();
// try again // try again
changeState(newState); changeState(newState);
} }
} }
/** /**
* Returns the int reflecting the current state of the top level frame * Returns the int reflecting the current state of the top level frame
* (see field definitions and class methods for details). * (see field definitions and class methods for details).
* *
* @return {@link java.lang.Integer} * @return {@link java.lang.Integer}
* */ * */
public Screens getState() { public Screens getState() {
return this.state; return this.state;
} }
/** @return List<Shortcut> A list of attached keyboard shortcut descriptions and properties. */ /** @return List<Shortcut> A list of attached keyboard shortcut descriptions and properties. */
public List<Shortcut> getShortcuts() { public List<Shortcut> getShortcuts() {
return this.shortcuts; return this.shortcuts;
} }
/** Remove all children from a specified layer. */ /** Remove all children from a specified layer. */
private void clearChildren(final int layer0) { private void clearChildren(final int layer0) {
final Component[] children = FView.SINGLETON_INSTANCE.getLpnDocument() final Component[] children = FView.SINGLETON_INSTANCE.getLpnDocument()
.getComponentsInLayer(layer0); .getComponentsInLayer(layer0);
for (final Component c : children) { for (final Component c : children) {
display.remove(c); display.remove(c);
} }
} }
/** Sizes children of JLayeredPane to fully fit their layers. */ /** Sizes children of JLayeredPane to fully fit their layers. */
private void sizeChildren() { private void sizeChildren() {
Component[] children = display.getComponentsInLayer(JLayeredPane.DEFAULT_LAYER); Component[] children = display.getComponentsInLayer(JLayeredPane.DEFAULT_LAYER);
if (children.length != 0) { children[0].setSize(display.getSize()); } if (children.length != 0) { children[0].setSize(display.getSize()); }
children = display.getComponentsInLayer(FView.TARGETING_LAYER); children = display.getComponentsInLayer(FView.TARGETING_LAYER);
if (children.length != 0) { children[0].setSize(display.getSize()); } if (children.length != 0) { children[0].setSize(display.getSize()); }
children = display.getComponentsInLayer(JLayeredPane.MODAL_LAYER); children = display.getComponentsInLayer(JLayeredPane.MODAL_LAYER);
if (children.length != 0) { children[0].setSize(display.getSize()); } if (children.length != 0) { children[0].setSize(display.getSize()); }
} }
/** /**
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.
* @return * @return
*/ */
private Lobby lobby = null; private Lobby lobby = null;
public Lobby getLobby() { public Lobby getLobby() {
if (lobby == null) { if (lobby == null) {
lobby = new Lobby(); lobby = new Lobby();
} }
return lobby; return lobby;
} }
public Player getCurrentPlayer() { public Player getCurrentPlayer() {
// try current priority // try current priority
Player currentPriority = game.getPhaseHandler().getPriorityPlayer(); Player currentPriority = game.getPhaseHandler().getPriorityPlayer();
if( null != currentPriority && currentPriority.getLobbyPlayer() == getLobby().getGuiPlayer() ) if( null != currentPriority && currentPriority.getLobbyPlayer() == getLobby().getGuiPlayer() )
return currentPriority; return currentPriority;
// otherwise find just any player, belonging to this lobbyplayer // otherwise find just any player, belonging to this lobbyplayer
for(Player p : game.getPlayers()) for(Player p : game.getPlayers())
if(p.getLobbyPlayer() == getLobby().getGuiPlayer() ) if(p.getLobbyPlayer() == getLobby().getGuiPlayer() )
return p; return p;
return null; return null;
} }
public boolean mayShowCard(Card c) { public boolean mayShowCard(Card c) {
return game == null || !gameHasHumanPlayer || c.canBeShownTo(getCurrentPlayer()); return game == null || !gameHasHumanPlayer || c.canBeShownTo(getCurrentPlayer());
} }
/** /**
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.
* @return * @return
*/ */
public SoundSystem getSoundSystem() { public SoundSystem getSoundSystem() {
return soundSystem; return soundSystem;
} }
/** /**
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.
* @return * @return
*/ */
private final NetServer server = new NetServer(); private final NetServer server = new NetServer();
public NetServer getServer() { public NetServer getServer() {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return server; return server;
} }
private Game game; private Game game;
private boolean gameHasHumanPlayer; private boolean gameHasHumanPlayer;
public Game getObservedGame() { public Game getObservedGame() {
return game; return game;
} }
public final void stopGame() { public final void stopGame() {
List<Player> pp = new ArrayList<Player>(); List<Player> pp = new ArrayList<Player>();
for(Player p : game.getPlayers()) { for(Player p : game.getPlayers()) {
if ( p.getOriginalLobbyPlayer() == getLobby().getGuiPlayer() ) if ( p.getOriginalLobbyPlayer() == getLobby().getGuiPlayer() )
pp.add(p); pp.add(p);
} }
boolean hasHuman = !pp.isEmpty(); boolean hasHuman = !pp.isEmpty();
if ( pp.isEmpty() ) if ( pp.isEmpty() )
pp.addAll(game.getPlayers()); // no human? then all players surrender! pp.addAll(game.getPlayers()); // no human? then all players surrender!
for(Player p: pp) for(Player p: pp)
p.concede(); p.concede();
Player priorityPlayer = game.getPhaseHandler().getPriorityPlayer(); Player priorityPlayer = game.getPhaseHandler().getPriorityPlayer();
boolean humanHasPriority = priorityPlayer == null || priorityPlayer.getLobbyPlayer() == getLobby().getGuiPlayer(); boolean humanHasPriority = priorityPlayer == null || priorityPlayer.getLobbyPlayer() == getLobby().getGuiPlayer();
if ( hasHuman && humanHasPriority ) if ( hasHuman && humanHasPriority )
game.getAction().checkGameOverCondition(); game.getAction().checkGameOverCondition();
else else
game.isGameOver(); // this is synchronized method - it's used to make Game-0 thread see changes made here game.isGameOver(); // this is synchronized method - it's used to make Game-0 thread see changes made here
playbackControl.onGameStopRequested(); playbackControl.onGameStopRequested();
} }
private InputQueue inputQueue; private InputQueue inputQueue;
public InputQueue getInputQueue() { public InputQueue getInputQueue() {
return inputQueue; return inputQueue;
} }
private final FControlGameEventHandler fcVisitor = new FControlGameEventHandler(this); private final FControlGameEventHandler fcVisitor = new FControlGameEventHandler(this);
private final FControlGamePlayback playbackControl = new FControlGamePlayback(this); private final FControlGamePlayback playbackControl = new FControlGamePlayback(this);
public void attachToGame(Game game0) { public void attachToGame(Game game0) {
// TODO: Detach from other game we might be looking at // TODO: Detach from other game we might be looking at
inputQueue = new InputQueue();
if ( game0.getType() == GameType.Quest) {
this.game = game0; QuestController qc = Singletons.getModel().getQuest();
game.subscribeToEvents(Singletons.getControl().getSoundSystem()); // Reset new list when the Match round starts, not when each game starts
if (game0.getMatch().getPlayedGames().isEmpty()) {
LobbyPlayer humanLobbyPlayer = getLobby().getGuiPlayer(); qc.getCards().resetNewList();
// The UI controls should use these game data as models }
CMatchUI.SINGLETON_INSTANCE.initMatch(game.getRegisteredPlayers(), humanLobbyPlayer); game0.subscribeToEvents(qc); // this one listens to player's mulligans ATM
CDock.SINGLETON_INSTANCE.setModel(game, humanLobbyPlayer); }
CStack.SINGLETON_INSTANCE.setModel(game.getStack(), humanLobbyPlayer);
CLog.SINGLETON_INSTANCE.setModel(game.getGameLog()); inputQueue = new InputQueue();
this.game = game0;
Singletons.getModel().getPreferences().actuateMatchPreferences(); game.subscribeToEvents(Singletons.getControl().getSoundSystem());
changeStateAutoFixLayout(Screens.MATCH_SCREEN, "match"); LobbyPlayer humanLobbyPlayer = getLobby().getGuiPlayer();
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc()); // The UI controls should use these game data as models
CMatchUI.SINGLETON_INSTANCE.initMatch(game.getRegisteredPlayers(), humanLobbyPlayer);
CMessage.SINGLETON_INSTANCE.getInputControl().setGame(game); CDock.SINGLETON_INSTANCE.setModel(game, humanLobbyPlayer);
CStack.SINGLETON_INSTANCE.setModel(game.getStack(), humanLobbyPlayer);
// Listen to DuelOutcome event to show ViewWinLose CLog.SINGLETON_INSTANCE.setModel(game.getGameLog());
game.subscribeToEvents(fcVisitor);
// Add playback controls to match if needed Singletons.getModel().getPreferences().actuateMatchPreferences();
gameHasHumanPlayer = false;
for(Player p : game.getPlayers()) { changeStateAutoFixLayout(Screens.MATCH_SCREEN, "match");
if ( p.getController().getLobbyPlayer() == getLobby().getGuiPlayer() ) SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
gameHasHumanPlayer = true;
} CMessage.SINGLETON_INSTANCE.getInputControl().setGame(game);
if (!gameHasHumanPlayer) { // Listen to DuelOutcome event to show ViewWinLose
game.subscribeToEvents(playbackControl); game.subscribeToEvents(fcVisitor);
}
// Add playback controls to match if needed
VAntes.SINGLETON_INSTANCE.setModel(game.getRegisteredPlayers()); gameHasHumanPlayer = false;
for(Player p : game.getPlayers()) {
for (final VField field : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) { if ( p.getController().getLobbyPlayer() == getLobby().getGuiPlayer() )
field.getDetailsPanel().getLblLibrary().setHoverable(Preferences.DEV_MODE); gameHasHumanPlayer = true;
} }
// per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch if (!gameHasHumanPlayer) {
//Set Field shown to current player. game.subscribeToEvents(playbackControl);
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(game.getPlayers().get(0)); }
SDisplayUtil.showTab(nextField);
} VAntes.SINGLETON_INSTANCE.setModel(game.getRegisteredPlayers());
}
for (final VField field : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) {
field.getDetailsPanel().getLblLibrary().setHoverable(Preferences.DEV_MODE);
}
// per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch
//Set Field shown to current player.
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(game.getPlayers().get(0));
SDisplayUtil.showTab(nextField);
}
}

View File

@@ -12,7 +12,6 @@ import forge.game.event.GameEventAnteCardsSelected;
import forge.game.player.LobbyPlayer; import forge.game.player.LobbyPlayer;
import forge.game.player.Player; import forge.game.player.Player;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.quest.QuestController;
/** /**
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
@@ -79,21 +78,16 @@ public class Match {
/** /**
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.
*/ */
public void startRound() { public Game createGame() {
currentGame = new Game(players, gameType, this); currentGame = new Game(players, gameType, this);
return currentGame;
if ( getGameType() == GameType.Quest) { }
QuestController qc = Singletons.getModel().getQuest();
// Reset new list when the Match round starts, not when each game starts
if (this.getPlayedGames().isEmpty()) {
qc.getCards().resetNewList();
}
currentGame.subscribeToEvents(qc); // this one listens to player's mulligans ATM
}
Singletons.getControl().attachToGame(currentGame);
/**
* TODO: Write javadoc for this method.
*/
public void startGame() {
final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL) && gameType == GameType.Constructed; final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL) && gameType == GameType.Constructed;
GameNew.newGame(currentGame, canRandomFoil, this.useAnte); GameNew.newGame(currentGame, canRandomFoil, this.useAnte);

View File

@@ -169,7 +169,8 @@ public class GauntletMini {
FThreads.invokeInEdtLater(new Runnable(){ FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void run() { public void run() {
mc.startRound(); Singletons.getControl().attachToGame(mc.createGame());
mc.startGame();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}); });

View File

@@ -127,7 +127,8 @@ public enum CSubmenuGauntletContests implements ICDoc {
FThreads.invokeInEdtLater(new Runnable(){ FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void run() { public void run() {
mc.startRound(); Singletons.getControl().attachToGame(mc.createGame());
mc.startGame();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}); });

View File

@@ -118,7 +118,8 @@ public enum CSubmenuGauntletLoad implements ICDoc {
FThreads.invokeInEdtLater(new Runnable(){ FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void run() { public void run() {
mc.startRound(); Singletons.getControl().attachToGame(mc.createGame());
mc.startGame();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}); });

View File

@@ -152,7 +152,8 @@ public enum CSubmenuGauntletQuick implements ICDoc {
FThreads.invokeInEdtLater(new Runnable(){ FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void run() { public void run() {
mc.startRound(); Singletons.getControl().attachToGame(mc.createGame());
mc.startGame();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}); });

View File

@@ -444,7 +444,8 @@ public class SSubmenuQuestUtil {
FThreads.invokeInEdtLater(new Runnable(){ FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void run() { public void run() {
mc.startRound(); Singletons.getControl().attachToGame(mc.createGame());
mc.startGame();
// no overlays here? // no overlays here?
} }
}); });

View File

@@ -127,7 +127,8 @@ public enum CSubmenuConstructed implements ICDoc {
FThreads.invokeInEdtLater(new Runnable(){ FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void run() { public void run() {
mc.startRound(); Singletons.getControl().attachToGame(mc.createGame());
mc.startGame();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}); });

View File

@@ -140,7 +140,8 @@ public enum CSubmenuDraft implements ICDoc {
FThreads.invokeInEdtLater(new Runnable(){ FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void run() { public void run() {
mc.startRound(); Singletons.getControl().attachToGame(mc.createGame());
mc.startGame();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}); });

View File

@@ -238,7 +238,8 @@ public enum CSubmenuArchenemy implements ICDoc {
FThreads.invokeInEdtLater(new Runnable(){ FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void run() { public void run() {
mc.startRound(); Singletons.getControl().attachToGame(mc.createGame());
mc.startGame();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}); });

View File

@@ -219,7 +219,8 @@ public enum CSubmenuPlanechase implements ICDoc {
FThreads.invokeInEdtLater(new Runnable(){ FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void run() { public void run() {
mc.startRound(); Singletons.getControl().attachToGame(mc.createGame());
mc.startGame();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}); });

View File

@@ -181,7 +181,8 @@ public enum CSubmenuVanguard implements ICDoc {
FThreads.invokeInEdtLater(new Runnable(){ FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void run() { public void run() {
mc.startRound(); Singletons.getControl().attachToGame(mc.createGame());
mc.startGame();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}); });

View File

@@ -78,7 +78,8 @@ public class ControlWinLose {
executeAnte(); executeAnte();
} }
match.startRound(); Singletons.getControl().attachToGame(match.createGame());
match.startGame();
} }
/** Action performed when "restart" button is pressed in default win/lose UI. */ /** Action performed when "restart" button is pressed in default win/lose UI. */
@@ -86,7 +87,8 @@ public class ControlWinLose {
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
saveOptions(); saveOptions();
match.clearGamesPlayed(); match.clearGamesPlayed();
match.startRound(); Singletons.getControl().attachToGame(match.createGame());
match.startGame();
} }
/** Action performed when "quit" button is pressed in default win/lose UI. */ /** Action performed when "quit" button is pressed in default win/lose UI. */

View File

@@ -202,11 +202,12 @@ public class GauntletWinLose extends ControlWinLose {
players.add(RegisteredPlayer.fromDeck(gd.getUserDeck()).setPlayer(lobby.getGuiPlayer())); players.add(RegisteredPlayer.fromDeck(gd.getUserDeck()).setPlayer(lobby.getGuiPlayer()));
players.add(RegisteredPlayer.fromDeck(aiDeck).setPlayer(lobby.getAiPlayer())); players.add(RegisteredPlayer.fromDeck(aiDeck).setPlayer(lobby.getAiPlayer()));
Match newMatch = new Match(GameType.Gauntlet, players); Match mc = new Match(GameType.Gauntlet, players);
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
saveOptions(); saveOptions();
newMatch.startRound(); Singletons.getControl().attachToGame(mc.createGame());
mc.startGame();
} else { } else {
super.actionOnContinue(); super.actionOnContinue();
} }

View File

@@ -32,7 +32,7 @@ public final class Main {
// HACK - temporary solution to "Comparison method violates it's general contract!" crash // HACK - temporary solution to "Comparison method violates it's general contract!" crash
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true"); System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
boolean isHeadlessMode = false; boolean isHeadlessMode = !true;
// Start splash screen first, then data models, then controller. // Start splash screen first, then data models, then controller.
if(!isHeadlessMode) if(!isHeadlessMode)
@@ -48,6 +48,8 @@ public final class Main {
// ok, done with possible interactive startup // ok, done with possible interactive startup
} }
@Override @Override