From 1a1b1c71b638086f903b09c26a3c1b611e47073d Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Wed, 8 May 2013 20:32:09 +0000 Subject: [PATCH] Match moved from FModel to FControl (meaning the match, where a player currently controlled by UI is) MatchController is re-created each time you start a match (as it had been designed to do) joined most calls setting up UI obsevers over a match into a single method Match is started from EDT - that means issues with black screen instead of game launched should be gone now - players should get exceptions instead. --- .gitattributes | 2 +- src/main/java/forge/FThreads.java | 6 +- .../ability/effects/RestartGameEffect.java | 2 +- .../cardfactory/CardFactoryCreatures.java | 3 - src/main/java/forge/control/FControl.java | 11 +- .../java/forge/control/input/InputAttack.java | 2 +- .../java/forge/control/input/InputBase.java | 4 +- .../java/forge/control/input/InputLockUI.java | 2 +- .../{InputControl.java => InputQueue.java} | 4 +- src/main/java/forge/game/GameAction.java | 27 +- src/main/java/forge/game/GameNew.java | 334 ++++++++---------- src/main/java/forge/game/GameState.java | 14 +- src/main/java/forge/game/MatchController.java | 199 ++++++----- src/main/java/forge/game/ai/AiInputBlock.java | 2 +- .../java/forge/game/limited/GauntletMini.java | 29 +- .../java/forge/game/phase/PhaseHandler.java | 3 +- src/main/java/forge/game/phase/PhaseUtil.java | 2 +- .../java/forge/game/player/LobbyPlayerAi.java | 16 +- src/main/java/forge/game/zone/PlayerZone.java | 9 +- src/main/java/forge/gui/GuiDisplayUtil.java | 2 +- .../gauntlet/CSubmenuGauntletContests.java | 35 +- .../home/gauntlet/CSubmenuGauntletLoad.java | 34 +- .../home/gauntlet/CSubmenuGauntletQuick.java | 40 +-- .../gui/home/quest/SSubmenuQuestUtil.java | 12 +- .../home/sanctioned/CSubmenuConstructed.java | 41 +-- .../gui/home/sanctioned/CSubmenuDraft.java | 42 +-- .../gui/home/variant/CSubmenuArchenemy.java | 174 +++++---- .../gui/home/variant/CSubmenuPlanechase.java | 155 ++++---- .../gui/home/variant/CSubmenuVanguard.java | 141 ++++---- .../forge/gui/match/TargetingOverlay.java | 2 +- .../forge/gui/match/controllers/CDock.java | 4 +- .../forge/gui/match/nonsingleton/CField.java | 2 +- .../java/forge/gui/match/views/VAntes.java | 81 ++--- src/main/java/forge/model/FModel.java | 8 - src/main/java/forge/util/TextUtil.java | 14 + 35 files changed, 674 insertions(+), 784 deletions(-) rename src/main/java/forge/control/input/{InputControl.java => InputQueue.java} (97%) diff --git a/.gitattributes b/.gitattributes index 300309331d6..1b0467cbf2a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14096,7 +14096,6 @@ src/main/java/forge/control/input/InputAutoPassPriority.java -text src/main/java/forge/control/input/InputBase.java svneol=native#text/plain src/main/java/forge/control/input/InputBlock.java svneol=native#text/plain src/main/java/forge/control/input/InputCleanup.java svneol=native#text/plain -src/main/java/forge/control/input/InputControl.java svneol=native#text/plain src/main/java/forge/control/input/InputLockUI.java -text src/main/java/forge/control/input/InputMulligan.java svneol=native#text/plain src/main/java/forge/control/input/InputPartialParisMulligan.java -text @@ -14108,6 +14107,7 @@ src/main/java/forge/control/input/InputPayManaSimple.java svneol=native#text/pla src/main/java/forge/control/input/InputPayManaX.java -text src/main/java/forge/control/input/InputPayment.java -text src/main/java/forge/control/input/InputProliferate.java -text +src/main/java/forge/control/input/InputQueue.java svneol=native#text/plain src/main/java/forge/control/input/InputSelectCards.java -text src/main/java/forge/control/input/InputSelectCardsFromList.java -text src/main/java/forge/control/input/InputSelectMany.java -text diff --git a/src/main/java/forge/FThreads.java b/src/main/java/forge/FThreads.java index 60cfb6e4f5d..c9e4b828778 100644 --- a/src/main/java/forge/FThreads.java +++ b/src/main/java/forge/FThreads.java @@ -106,12 +106,12 @@ public class FThreads { Runnable toRun = proc; if( lockUI ) { // checkEDT("FThreads.invokeInNewthread", true) - Singletons.getModel().getMatch().getInput().lock(); + Singletons.getControl().getMatch().getInput().lock(); toRun = new Runnable() { @Override public void run() { proc.run(); - Singletons.getModel().getMatch().getInput().unlock(); + Singletons.getControl().getMatch().getInput().unlock(); } }; } @@ -119,7 +119,7 @@ public class FThreads { } public static void setInputAndWait(InputSynchronized input) { - Singletons.getModel().getMatch().getInput().setInput(input); + Singletons.getControl().getMatch().getInput().setInput(input); input.awaitLatchRelease(); } diff --git a/src/main/java/forge/card/ability/effects/RestartGameEffect.java b/src/main/java/forge/card/ability/effects/RestartGameEffect.java index 74c3de42b4d..1d0572989c3 100644 --- a/src/main/java/forge/card/ability/effects/RestartGameEffect.java +++ b/src/main/java/forge/card/ability/effects/RestartGameEffect.java @@ -49,7 +49,7 @@ public class RestartGameEffect extends SpellAbilityEffect { playerLibraries.put(p, newLibrary); } - GameNew.restartGame(Singletons.getModel().getMatch(), game, sa.getActivatingPlayer(), playerLibraries); + GameNew.restartGame(Singletons.getControl().getMatch(), game, sa.getActivatingPlayer(), playerLibraries); } /* (non-Javadoc) diff --git a/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java b/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java index cc655474576..2f930d63ce4 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java @@ -31,7 +31,6 @@ import forge.FThreads; import forge.CardPredicates.Presets; import forge.Command; import forge.CounterType; -import forge.Singletons; import forge.card.cost.Cost; import forge.card.mana.ManaCost; import forge.card.spellability.Ability; @@ -349,8 +348,6 @@ public class CardFactoryCreatures { } else { game.getAction().sacrifice(card, null); } - - Singletons.getModel().getMatch().getInput().setInput(target); } } // end resolve }; // end sacOrSac diff --git a/src/main/java/forge/control/FControl.java b/src/main/java/forge/control/FControl.java index 80b114d3617..1e814380851 100644 --- a/src/main/java/forge/control/FControl.java +++ b/src/main/java/forge/control/FControl.java @@ -33,6 +33,7 @@ import javax.swing.WindowConstants; import forge.Singletons; import forge.control.KeyboardShortcuts.Shortcut; +import forge.game.MatchController; import forge.game.ai.AiProfileUtil; import forge.game.player.HumanPlayer; import forge.gui.SOverlayUtils; @@ -112,7 +113,7 @@ public enum FControl { public void windowClosing(final WindowEvent e) { Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - if (!Singletons.getModel().getMatch().getCurrentGame().isGameOver()) + if (!getMatch().getCurrentGame().isGameOver()) CDock.SINGLETON_INSTANCE.concede(); else { Singletons.getControl().changeState(FControl.Screens.HOME_SCREEN); @@ -326,4 +327,12 @@ public enum FControl { // TODO Auto-generated method stub return server; } + + private MatchController match; + public MatchController getMatch() { + return match; + } + public void setMatch(MatchController newMatch) { + match = newMatch; + } } diff --git a/src/main/java/forge/control/input/InputAttack.java b/src/main/java/forge/control/input/InputAttack.java index ed5557a3b84..13df5c1c5da 100644 --- a/src/main/java/forge/control/input/InputAttack.java +++ b/src/main/java/forge/control/input/InputAttack.java @@ -102,7 +102,7 @@ public class InputAttack extends InputBase { game.getPhaseHandler().setCombat(!game.getCombat().getAttackers().isEmpty()); game.getPhaseHandler().setPlayersPriorityPermission(false); - Singletons.getModel().getMatch().getInput().updateObservers(); + Singletons.getControl().getMatch().getInput().updateObservers(); } @Override diff --git a/src/main/java/forge/control/input/InputBase.java b/src/main/java/forge/control/input/InputBase.java index fb917b670b4..f48debe7ec3 100644 --- a/src/main/java/forge/control/input/InputBase.java +++ b/src/main/java/forge/control/input/InputBase.java @@ -60,12 +60,12 @@ public abstract class InputBase implements java.io.Serializable, Input { // Removes this input from the stack and releases any latches (in synchronous imports) protected final void stop() { // clears a "temp" Input like Input_PayManaCost if there is one - Singletons.getModel().getMatch().getInput().removeInput(this); + Singletons.getControl().getMatch().getInput().removeInput(this); afterStop(); // sync inputs will release their latch there } protected final boolean isActive() { - return Singletons.getModel().getMatch().getInput().getInput() == this; + return Singletons.getControl().getMatch().getInput().getInput() == this; } protected void afterStop() { } diff --git a/src/main/java/forge/control/input/InputLockUI.java b/src/main/java/forge/control/input/InputLockUI.java index 404a31659d1..e3a053181c3 100644 --- a/src/main/java/forge/control/input/InputLockUI.java +++ b/src/main/java/forge/control/input/InputLockUI.java @@ -51,7 +51,7 @@ public class InputLockUI implements Input { }; protected final boolean isActive() { - return Singletons.getModel().getMatch().getInput().getInput() == this; + return Singletons.getControl().getMatch().getInput().getInput() == this; } protected void showMessage(String message) { diff --git a/src/main/java/forge/control/input/InputControl.java b/src/main/java/forge/control/input/InputQueue.java similarity index 97% rename from src/main/java/forge/control/input/InputControl.java rename to src/main/java/forge/control/input/InputQueue.java index 0e67e24e4cc..3d2e269da37 100644 --- a/src/main/java/forge/control/input/InputControl.java +++ b/src/main/java/forge/control/input/InputQueue.java @@ -41,14 +41,14 @@ import forge.util.MyObservable; * @author Forge * @version $Id$ */ -public class InputControl extends MyObservable implements java.io.Serializable { +public class InputQueue extends MyObservable implements java.io.Serializable { /** Constant serialVersionUID=3955194449319994301L. */ private static final long serialVersionUID = 3955194449319994301L; private final BlockingDeque inputStack = new LinkedBlockingDeque(); private final MatchController match; - public InputControl(MatchController matchController) { + public InputQueue(MatchController matchController) { match = matchController; } diff --git a/src/main/java/forge/game/GameAction.java b/src/main/java/forge/game/GameAction.java index 7e3574e4cc0..e2b9b0c2763 100644 --- a/src/main/java/forge/game/GameAction.java +++ b/src/main/java/forge/game/GameAction.java @@ -724,24 +724,15 @@ public class GameAction { */ public final Card moveTo(final ZoneType name, final Card c, final int libPosition) { // Call specific functions to set PlayerZone, then move onto moveTo - if (name.equals(ZoneType.Hand)) { - return this.moveToHand(c); - } else if (name.equals(ZoneType.Library)) { - return this.moveToLibrary(c, libPosition); - } else if (name.equals(ZoneType.Battlefield)) { - return this.moveToPlay(c); - } else if (name.equals(ZoneType.Graveyard)) { - return this.moveToGraveyard(c); - } else if (name.equals(ZoneType.Exile)) { - return this.exile(c); - } else if (name.equals(ZoneType.Ante)) { - final PlayerZone ante = c.getOwner().getZone(ZoneType.Ante); - return this.moveTo(ante, c); - } else if (name.equals(ZoneType.Command)) { - final PlayerZone command = c.getOwner().getZone(ZoneType.Command); - return this.moveTo(command, c); - } else { - return this.moveToStack(c); + switch(name) { + case Hand: return this.moveToHand(c); + case Library: return this.moveToLibrary(c, libPosition); + case Battlefield: return this.moveToPlay(c); + case Graveyard: return this.moveToGraveyard(c); + case Exile: return this.exile(c); + case Ante: return this.moveTo(c.getOwner().getZone(ZoneType.Ante), c); + case Command: return this.moveTo(c.getOwner().getZone(ZoneType.Command), c); + default: return this.moveToStack(c); } } diff --git a/src/main/java/forge/game/GameNew.java b/src/main/java/forge/game/GameNew.java index 96fe0092996..672c351132f 100644 --- a/src/main/java/forge/game/GameNew.java +++ b/src/main/java/forge/game/GameNew.java @@ -9,8 +9,6 @@ import java.util.Map.Entry; import java.util.Random; import java.util.Set; -import javax.swing.JOptionPane; - import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; @@ -19,20 +17,19 @@ import com.google.common.collect.Lists; import forge.Card; import forge.CardLists; import forge.CardPredicates; -import forge.Singletons; +import forge.card.trigger.Trigger; import forge.card.trigger.TriggerHandler; import forge.card.trigger.TriggerType; import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckSection; -import forge.game.event.FlipCoinEvent; import forge.game.phase.PhaseHandler; import forge.game.player.AIPlayer; import forge.game.player.LobbyPlayer; import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; -import forge.gui.match.views.VAntes; +import forge.gui.GuiDialog; import forge.item.CardDb; import forge.item.CardPrinted; import forge.item.IPaperCard; @@ -40,6 +37,7 @@ import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; import forge.util.Aggregates; import forge.util.MyRandom; +import forge.util.TextUtil; /** * Methods for all things related to starting a new game. @@ -47,7 +45,59 @@ import forge.util.MyRandom; */ public class GameNew { - public static final ForgePreferences preferences = Singletons.getModel().getPreferences(); + public static final ForgePreferences preferences = forge.Singletons.getModel().getPreferences(); + + private static void putCardsOnBattlefield(Player player, Iterable cards) { + PlayerZone bf = player.getZone(ZoneType.Battlefield); + if (cards != null) { + for (final IPaperCard cp : cards) { + Card c = cp.toForgeCard(player); + c.setOwner(player); + bf.add(c, false); + c.setSickness(true); + c.setStartsGameInPlay(true); + c.refreshUniqueNumber(); + } + } + + } + + private static void initVariantsZones(final Player player, final PlayerStartConditions psc) { + PlayerZone com = player.getZone(ZoneType.Command); + + // Mainly for avatar, but might find something else here + for (final IPaperCard c : psc.getCardsInCommand(player)) { + com.add(c.toForgeCard(player), false); + } + + // Schemes + List sd = new ArrayList(); + for(IPaperCard cp : psc.getSchemes(player)) sd.add(cp.toForgeCard(player)); + if ( !sd.isEmpty()) player.setSchemeDeck(sd); + + // Planes + List l = new ArrayList(); + for(IPaperCard cp : psc.getPlanes(player)) l.add(cp.toForgeCard(player)); + if ( !l.isEmpty() ) player.setPlanarDeck(l); + } + + private static Set getRemovedAnteCards(Deck toUse) { + final String keywordToRemove = "Remove CARDNAME from your deck before playing if you're not playing for ante."; + Set myRemovedAnteCards = new HashSet(); + for ( Entry ds : toUse ) { + for (Entry cp : ds.getValue()) { + if ( Iterables.contains(cp.getKey().getRules().getMainPart().getKeywords(), keywordToRemove) ) + myRemovedAnteCards.add(cp.getKey()); + } + } + + for(CardPrinted cp: myRemovedAnteCards) { + for ( Entry ds : toUse ) { + ds.getValue().remove(cp, Integer.MAX_VALUE); + } + } + return myRemovedAnteCards; + } private static void preparePlayerLibrary(Player player, final ZoneType zoneType, CardPool secion, boolean canRandomFoil, Random generator) { PlayerZone library = player.getZone(zoneType); @@ -79,6 +129,74 @@ public class GameNew { } } + // this is where the computer cheats + // changes AllZone.getComputerPlayer().getZone(Zone.Library) + + /** + *

+ * smoothComputerManaCurve. + *

+ * + * @param in + * an array of {@link forge.Card} objects. + * @return an array of {@link forge.Card} objects. + */ + private static Iterable smoothComputerManaCurve(final Iterable in) { + final List library = Lists.newArrayList(in); + CardLists.shuffle(library); + + // remove all land, keep non-basicland in there, shuffled + List land = CardLists.filter(library, CardPredicates.Presets.LANDS); + for (Card c : land) { + if (c.isLand()) { + library.remove(c); + } + } + + try { + // mana weave, total of 7 land + // The Following have all been reduced by 1, to account for the + // computer starting first. + library.add(5, land.get(0)); + library.add(6, land.get(1)); + library.add(8, land.get(2)); + library.add(9, land.get(3)); + library.add(10, land.get(4)); + + library.add(12, land.get(5)); + library.add(15, land.get(6)); + } catch (final IndexOutOfBoundsException e) { + System.err.println("Error: cannot smooth mana curve, not enough land"); + return in; + } + + // add the rest of land to the end of the deck + for (int i = 0; i < land.size(); i++) { + if (!library.contains(land.get(i))) { + library.add(land.get(i)); + } + } + + // check + for (int i = 0; i < library.size(); i++) { + System.out.println(library.get(i)); + } + + return library; + } // smoothComputerManaCurve() + + private static List getCardsAiCantPlayWell(final Deck toUse) { + List result = new ArrayList(); + + for ( Entry ds : toUse ) { + for (Entry cp : ds.getValue()) { + if ( cp.getKey().getRules().getAiHints().getRemAIDecks() ) + result.add(cp.getKey()); + } + } + return result; + } + /** * Constructor for new game allowing card lists to be put into play * immediately, and life totals to be adjusted, for computer and human. @@ -86,11 +204,11 @@ public class GameNew { * TODO: Accept something like match state as parameter. Match should be aware of players, * their decks and other special starting conditions. */ - public static void newGame(final MatchController match, final Map playersConditions, final GameState game, final boolean canRandomFoil) { + public static void newGame(final GameState game, final boolean canRandomFoil) { Card.resetUniqueNumber(); // need this code here, otherwise observables fail - forge.card.trigger.Trigger.resetIDs(); + Trigger.resetIDs(); TriggerHandler trigHandler = game.getTriggerHandler(); trigHandler.clearDelayedTrigger(); @@ -99,23 +217,23 @@ public class GameNew { final Set rAICards = new HashSet(); Map> removedAnteCards = new HashMap>(); + + GameType gameType = game.getType(); + boolean isFirstGame = game.getMatch().getPlayedGames().isEmpty(); + boolean canSideBoard = !isFirstGame && gameType.isSideboardingAllowed(); - for (Entry p : playersConditions.entrySet()) { - final Player player = p.getKey(); - final PlayerStartConditions psc = p.getValue(); + final Map playersConditions = game.getMatch().getPlayers(); + for (Player player : game.getPlayers()) { + final PlayerStartConditions psc = playersConditions.get(player.getLobbyPlayer()); player.setStartingLife(psc.getStartingLife()); player.setMaxHandSize(psc.getStartingHand()); player.setStartingHandSize(psc.getStartingHand()); - putCardsOnBattlefield(player, psc.getCardsOnBattlefield(player)); + putCardsOnBattlefield(player, psc.getCardsOnBattlefield(player)); initVariantsZones(player, psc); - GameType gameType = match.getGameType(); - boolean isFirstGame = match.getPlayedGames().isEmpty(); boolean hasSideboard = psc.getOriginalDeck().has(DeckSection.Sideboard); - boolean canSideBoard = !isFirstGame && gameType.isSideboardingAllowed() && hasSideboard; - - if (canSideBoard) { + if (canSideBoard && hasSideboard) { Deck sideboarded = player.getController().sideboard(psc.getCurrentDeck(), gameType); psc.setCurrentDeck(sideboarded); } else { @@ -154,23 +272,23 @@ public class GameNew { } if (rAICards.size() > 0) { - String message = buildFourColumnList("AI deck contains the following cards that it can't play or may be buggy:", rAICards); + String message = TextUtil.buildFourColumnList("AI deck contains the following cards that it can't play or may be buggy:", rAICards); if (GameType.Quest == game.getType() || GameType.Sealed == game.getType() || GameType.Draft == game.getType()) { // log, but do not visually warn. quest decks are supposedly already vetted by the quest creator, // sealed and draft decks do not get any AI-unplayable picks but may contain several // received/picked but unplayable cards in the sideboard. System.err.println(message); } else { - JOptionPane.showMessageDialog(null, message, "", JOptionPane.INFORMATION_MESSAGE); + GuiDialog.message(message); } } if (!removedAnteCards.isEmpty()) { StringBuilder ante = new StringBuilder("The following ante cards were removed:\n\n"); for (Entry> ants : removedAnteCards.entrySet()) { - ante.append(buildFourColumnList("From the " + ants.getKey().getName() + "'s deck:", ants.getValue())); + ante.append(TextUtil.buildFourColumnList("From the " + ants.getKey().getName() + "'s deck:", ants.getValue())); } - JOptionPane.showMessageDialog(null, ante.toString(), "", JOptionPane.INFORMATION_MESSAGE); + GuiDialog.message(ante.toString()); } // Deciding which cards go to ante @@ -186,19 +304,18 @@ public class GameNew { throw new RuntimeException(p + " library is empty."); } game.getGameLog().add("Ante", p + " anted " + ante, 0); - VAntes.SINGLETON_INSTANCE.addAnteCard(p, ante); game.getAction().moveTo(ZoneType.Ante, ante); msg.append(p.getName()).append(" ante: ").append(ante).append(nl); } - JOptionPane.showMessageDialog(null, msg, "Ante", JOptionPane.INFORMATION_MESSAGE); + GuiDialog.message(msg.toString(), "Ante"); } - determineFirstTurnPlayer(match.getLastGameOutcome(), game); - // Draw cards for (final Player p1 : game.getPlayers()) { p1.drawCards(p1.getMaxHandSize()); } + + } // ultimate of Karn the Liberated @@ -255,176 +372,9 @@ public class GameNew { } } - /** - * TODO: Write javadoc for this method. - * @param match - * @param game - */ - private static void determineFirstTurnPlayer(final GameOutcome lastGameOutcome, final GameState game) { - // Only cut/coin toss if it's the first game of the match - Player goesFirst; - Player humanPlayer = Singletons.getControl().getPlayer(); - boolean isFirstGame = lastGameOutcome == null; - if (isFirstGame) { - goesFirst = GameNew.seeWhoPlaysFirstDice(game); - } else { - - goesFirst = lastGameOutcome.isWinner(humanPlayer.getLobbyPlayer()) ? humanPlayer.getOpponent() : humanPlayer; - } - String message = goesFirst + ( isFirstGame ? " has won the coin toss." : " lost the last game."); - boolean willPlay = goesFirst.getController().getWillPlayOnFirstTurn(message); - if ( goesFirst != humanPlayer ) { - JOptionPane.showMessageDialog(null, message + "\nComputer Going First", "You are drawing", JOptionPane.INFORMATION_MESSAGE); - } - goesFirst = willPlay ? goesFirst : goesFirst.getOpponent(); - game.getPhaseHandler().setPlayerTurn(goesFirst); - } - - private static void initVariantsZones(final Player player, final PlayerStartConditions psc) { - PlayerZone com = player.getZone(ZoneType.Command); - - // Mainly for avatar, but might find something else here - for (final IPaperCard c : psc.getCardsInCommand(player)) { - com.add(c.toForgeCard(player), false); - } - - // Schemes - List sd = new ArrayList(); - for(IPaperCard cp : psc.getSchemes(player)) sd.add(cp.toForgeCard(player)); - if ( !sd.isEmpty()) player.setSchemeDeck(sd); - - // Planes - List l = new ArrayList(); - for(IPaperCard cp : psc.getPlanes(player)) l.add(cp.toForgeCard(player)); - if ( !l.isEmpty() ) player.setPlanarDeck(l); - } - - private static List getCardsAiCantPlayWell(final Deck toUse) { - List result = new ArrayList(); - - for ( Entry ds : toUse ) { - for (Entry cp : ds.getValue()) { - if ( cp.getKey().getRules().getAiHints().getRemAIDecks() ) - result.add(cp.getKey()); - } - } - return result; - } - - private static Set getRemovedAnteCards(Deck toUse) { - final String keywordToRemove = "Remove CARDNAME from your deck before playing if you're not playing for ante."; - Set myRemovedAnteCards = new HashSet(); - for ( Entry ds : toUse ) { - for (Entry cp : ds.getValue()) { - if ( Iterables.contains(cp.getKey().getRules().getMainPart().getKeywords(), keywordToRemove) ) - myRemovedAnteCards.add(cp.getKey()); - } - } - - for(CardPrinted cp: myRemovedAnteCards) { - for ( Entry ds : toUse ) { - ds.getValue().remove(cp, Integer.MAX_VALUE); - } - } - return myRemovedAnteCards; - } - private static void putCardsOnBattlefield(Player player, Iterable cards) { - PlayerZone bf = player.getZone(ZoneType.Battlefield); - if (cards != null) { - for (final IPaperCard cp : cards) { - Card c = cp.toForgeCard(player); - c.setOwner(player); - bf.add(c, false); - c.setSickness(true); - c.setStartsGameInPlay(true); - c.refreshUniqueNumber(); - } - } - - } - - private static String buildFourColumnList(String firstLine, Iterable cAnteRemoved) { - StringBuilder sb = new StringBuilder(firstLine); - int i = 0; - for(CardPrinted cp: cAnteRemoved) { - if ( i != 0 ) sb.append(", "); - if ( i % 4 == 0 ) sb.append("\n"); - sb.append(cp); - i++; - } - return sb.toString(); - } // this is where the computer cheats // changes AllZone.getComputerPlayer().getZone(Zone.Library) - /** - *

- * smoothComputerManaCurve. - *

- * - * @param in - * an array of {@link forge.Card} objects. - * @return an array of {@link forge.Card} objects. - */ - private static Iterable smoothComputerManaCurve(final Iterable in) { - final List library = Lists.newArrayList(in); - CardLists.shuffle(library); - - // remove all land, keep non-basicland in there, shuffled - List land = CardLists.filter(library, CardPredicates.Presets.LANDS); - for (Card c : land) { - if (c.isLand()) { - library.remove(c); - } - } - - try { - // mana weave, total of 7 land - // The Following have all been reduced by 1, to account for the - // computer starting first. - library.add(5, land.get(0)); - library.add(6, land.get(1)); - library.add(8, land.get(2)); - library.add(9, land.get(3)); - library.add(10, land.get(4)); - - library.add(12, land.get(5)); - library.add(15, land.get(6)); - } catch (final IndexOutOfBoundsException e) { - System.err.println("Error: cannot smooth mana curve, not enough land"); - return in; - } - - // add the rest of land to the end of the deck - for (int i = 0; i < land.size(); i++) { - if (!library.contains(land.get(i))) { - library.add(land.get(i)); - } - } - - // check - for (int i = 0; i < library.size(); i++) { - System.out.println(library.get(i)); - } - - return library; - } // smoothComputerManaCurve() - - // decides who goes first when starting another game, used by newGame() - /** - *

- * seeWhoPlaysFirstCoinToss. - *

- * @return - */ - private static Player seeWhoPlaysFirstDice(final GameState game) { - // Play the Flip Coin sound - game.getEvents().post(new FlipCoinEvent()); - - List allPlayers = game.getPlayers(); - return allPlayers.get(MyRandom.getRandom().nextInt(allPlayers.size())); - } - } diff --git a/src/main/java/forge/game/GameState.java b/src/main/java/forge/game/GameState.java index 6a6f21d2867..2fdf3406165 100644 --- a/src/main/java/forge/game/GameState.java +++ b/src/main/java/forge/game/GameState.java @@ -94,19 +94,20 @@ public class GameState { */ public GameState(Iterable players2, GameType t, MatchController match0) { /* no more zones to map here */ type = t; + match = match0; List players = new ArrayList(); for (LobbyPlayer p : players2) { Player pl = p.getPlayer(this); players.add(pl); ingamePlayers.add(pl); } - match = match0; + allPlayers = Collections.unmodifiableList(players); roIngamePlayers = Collections.unmodifiableList(ingamePlayers); action = new GameAction(this); stack = new MagicStack(this); phaseHandler = new PhaseHandler(this); - + untap = new Untap(this); upkeep = new Upkeep(this); cleanup = new Cleanup(this); @@ -116,10 +117,9 @@ public class GameState { if ( match0.getGameType() == GameType.Quest) events.register(Singletons.getModel().getQuest()); // this one listens to player's mulligans ATM - events.register(Singletons.getControl().getSoundSystem()); events.register(gameLog); - } + /** * Gets the players who are still fighting to win. @@ -455,10 +455,14 @@ public class GameState { return colorChanger; } - public GameAction getAction() { + public final GameAction getAction() { return action; } + public final MatchController getMatch() { + return match; + } + /** * TODO: Write javadoc for this method. * @param playerTurn diff --git a/src/main/java/forge/game/MatchController.java b/src/main/java/forge/game/MatchController.java index 17ece6f21e1..fba720efdfe 100644 --- a/src/main/java/forge/game/MatchController.java +++ b/src/main/java/forge/game/MatchController.java @@ -7,22 +7,24 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import javax.swing.JOptionPane; + import forge.Constant.Preferences; import forge.FThreads; import forge.Singletons; import forge.card.trigger.TriggerType; import forge.control.FControl; -import forge.control.input.InputControl; +import forge.control.input.InputQueue; import forge.deck.Deck; import forge.error.BugReporter; -import forge.game.ai.AiProfileUtil; import forge.game.event.DuelOutcomeEvent; -import forge.game.player.AIPlayer; +import forge.game.event.FlipCoinEvent; import forge.game.player.HumanPlayer; import forge.game.player.LobbyPlayer; import forge.game.player.LobbyPlayerHuman; import forge.game.player.Player; import forge.game.player.PlayerStatistics; +import forge.game.zone.ZoneType; import forge.gui.InputProxy; import forge.gui.framework.EDocID; import forge.gui.framework.SDisplayUtil; @@ -37,6 +39,7 @@ import forge.gui.match.controllers.CStack; import forge.gui.match.nonsingleton.VField; import forge.gui.match.views.VAntes; import forge.properties.ForgePreferences.FPref; +import forge.util.MyRandom; /** * TODO: Write javadoc for this type. @@ -46,7 +49,7 @@ import forge.properties.ForgePreferences.FPref; public class MatchController { private final Map players = new HashMap(); - private GameType gameType = GameType.Constructed; + private final GameType gameType; private int gamesPerMatch = 3; private int gamesToWinMatch = 2; @@ -56,10 +59,15 @@ public class MatchController { private final List gamesPlayed = new ArrayList(); private final List gamesPlayedRo; - private InputControl input; + private InputQueue inputQueue; - public MatchController() { + /** + * This should become constructor once. + */ + public MatchController(GameType type, Map map) { gamesPlayedRo = Collections.unmodifiableList(gamesPlayed); + players.putAll(map); + gameType = type; } /** @@ -133,7 +141,7 @@ public class MatchController { */ public void startRound() { - input = new InputControl(this); + inputQueue = new InputQueue(this); currentGame = new GameState(players.keySet(), gameType, this); Map startConditions = new HashMap(); @@ -141,83 +149,16 @@ public class MatchController { startConditions.put(p, players.get(p.getLobbyPlayer())); } - // Set the current AI profile. - for (Player p : currentGame.getPlayers()) { - if ( !(p instanceof AIPlayer)) - continue; - AIPlayer ai = (AIPlayer) p; - - String currentAiProfile = Singletons.getModel().getPreferences().getPref(FPref.UI_CURRENT_AI_PROFILE); - String lastProfileChosen = this.getPlayedGames().isEmpty() ? currentAiProfile : ai.getLobbyPlayer().getAiProfile(); - - // TODO: implement specific AI profiles for quest mode. - boolean wantRandomProfile = currentAiProfile.equals(AiProfileUtil.AI_PROFILE_RANDOM_DUEL) - || (this.getPlayedGames().isEmpty() && currentAiProfile.equals(AiProfileUtil.AI_PROFILE_RANDOM_MATCH)); - - String profileToSet = wantRandomProfile ? AiProfileUtil.getRandomProfile() : lastProfileChosen; - - ai.getLobbyPlayer().setAiProfile(profileToSet); - System.out.println(String.format("AI profile %s was chosen for the lobby player %s.", ai.getLobbyPlayer().getAiProfile(), ai.getLobbyPlayer().getName())); - } - try { - - HumanPlayer localHuman = null; - for(Player p : currentGame.getPlayers()) { - if ( p.getLobbyPlayer() != FControl.SINGLETON_INSTANCE.getLobby().getGuiPlayer()) - continue; - localHuman = (HumanPlayer) p; - break; - } - if (null == localHuman) - throw new IllegalStateException("Cannot start a game without a human yet!"); - - FControl.SINGLETON_INSTANCE.setPlayer(localHuman); - - // The UI controls should use these game data as models - CMatchUI.SINGLETON_INSTANCE.initMatch(currentGame.getRegisteredPlayers(), localHuman); - CDock.SINGLETON_INSTANCE.onGameStarts(currentGame, localHuman); - CStack.SINGLETON_INSTANCE.setModel(currentGame.getStack()); - CLog.SINGLETON_INSTANCE.setModel(currentGame.getGameLog()); - CCombat.SINGLETON_INSTANCE.setModel(currentGame); - - Singletons.getModel().getPreferences().actuateMatchPreferences(); - Singletons.getControl().changeState(FControl.Screens.MATCH_SCREEN); - SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc()); - - // black magic still - InputProxy inputProxy = CMessage.SINGLETON_INSTANCE.getInputControl(); - inputProxy.setMatch(this); - input.addObserver(inputProxy); - - // models shall notify controllers of changes - currentGame.getStack().addObserver(inputProxy); - currentGame.getStack().addObserver(CStack.SINGLETON_INSTANCE); - currentGame.getPhaseHandler().addObserver(inputProxy); - currentGame.getGameLog().addObserver(CLog.SINGLETON_INSTANCE); - // some observers are set in CMatchUI.initMatch - - + attachUiToMatch(this, FControl.SINGLETON_INSTANCE.getLobby().getGuiPlayer()); final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL) && gameType == GameType.Constructed; - GameNew.newGame(this, startConditions, currentGame, canRandomFoil); - + GameNew.newGame(currentGame, canRandomFoil); + determineFirstTurnPlayer(getLastGameOutcome(), currentGame); + currentGame.setAge(GameAge.Mulligan); getInput().clearInput(); - // TODO restore this functionality!!! - //VMatchUI.SINGLETON_INSTANCE.getViewDevMode().getDocument().setVisible(Preferences.DEV_MODE); - for (final VField field : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) { - field.getLblLibrary().setHoverable(Preferences.DEV_MODE); - } - - if (this.getPlayedGames().isEmpty()) { - VAntes.SINGLETON_INSTANCE.clearAnteCards(); - } - - // per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch - - CMessage.SINGLETON_INSTANCE.updateGameInfo(this); // Update observers currentGame.getGameLog().updateObservers(); } catch (Exception e) { @@ -226,14 +167,56 @@ public class MatchController { } - /** - * This should become constructor once. - */ - public void initMatch(GameType type, Map map) { - gamesPlayed.clear(); - players.clear(); - players.putAll(map); - gameType = type; + public static void attachUiToMatch(MatchController match, LobbyPlayerHuman humanLobbyPlayer) { + FControl.SINGLETON_INSTANCE.setMatch(match); + + GameState currentGame = match.getCurrentGame(); + currentGame.getEvents().register(Singletons.getControl().getSoundSystem()); + + HumanPlayer localHuman = null; + for(Player p : currentGame.getPlayers()) { + if ( p.getLobbyPlayer() != humanLobbyPlayer) + continue; + localHuman = (HumanPlayer) p; + break; + } + if (null == localHuman) + throw new IllegalStateException("Cannot start a game without a human yet!"); + + FControl.SINGLETON_INSTANCE.setPlayer(localHuman); + + // The UI controls should use these game data as models + CMatchUI.SINGLETON_INSTANCE.initMatch(currentGame.getRegisteredPlayers(), localHuman); + CDock.SINGLETON_INSTANCE.setModel(currentGame, localHuman); + CStack.SINGLETON_INSTANCE.setModel(currentGame.getStack()); + CLog.SINGLETON_INSTANCE.setModel(currentGame.getGameLog()); + CCombat.SINGLETON_INSTANCE.setModel(currentGame); + + Singletons.getModel().getPreferences().actuateMatchPreferences(); + Singletons.getControl().changeState(FControl.Screens.MATCH_SCREEN); + SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc()); + + InputProxy inputProxy = CMessage.SINGLETON_INSTANCE.getInputControl(); + inputProxy.setMatch(match); + + // models shall notify controllers of changes + currentGame.getStack().addObserver(inputProxy); + currentGame.getStack().addObserver(CStack.SINGLETON_INSTANCE); + currentGame.getPhaseHandler().addObserver(inputProxy); + currentGame.getGameLog().addObserver(CLog.SINGLETON_INSTANCE); + // some observers were set in CMatchUI.initMatch + + // black magic still + match.getInput().addObserver(inputProxy); + + VAntes.SINGLETON_INSTANCE.setModel(currentGame.getRegisteredPlayers()); + + for (final VField field : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) { + field.getLblLibrary().setHoverable(Preferences.DEV_MODE); + } + + // per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch + CMessage.SINGLETON_INSTANCE.updateGameInfo(match); } /** @@ -345,8 +328,8 @@ public class MatchController { return players; } - public final InputControl getInput() { - return input; + public final InputQueue getInput() { + return inputQueue; } /** @@ -366,4 +349,44 @@ public class MatchController { currentGame.setAge(GameAge.Play); getInput().clearInput(); } + + /** + * TODO: Write javadoc for this method. + * @param match + * @param game + */ + private void determineFirstTurnPlayer(final GameOutcome lastGameOutcome, final GameState game) { + // Only cut/coin toss if it's the first game of the match + Player goesFirst; + Player humanPlayer = Singletons.getControl().getPlayer(); + boolean isFirstGame = lastGameOutcome == null; + if (isFirstGame) { + goesFirst = seeWhoPlaysFirstDice(game); + } else { + goesFirst = lastGameOutcome.isWinner(humanPlayer.getLobbyPlayer()) ? humanPlayer.getOpponent() : humanPlayer; + } + String message = goesFirst + ( isFirstGame ? " has won the coin toss." : " lost the last game."); + boolean willPlay = goesFirst.getController().getWillPlayOnFirstTurn(message); + if ( goesFirst != humanPlayer ) { + JOptionPane.showMessageDialog(null, message + "\nComputer Going First", "You are drawing", JOptionPane.INFORMATION_MESSAGE); + } + goesFirst = willPlay ? goesFirst : goesFirst.getOpponent(); + game.getPhaseHandler().setPlayerTurn(goesFirst); + } + + // decides who goes first when starting another game, used by newGame() + /** + *

+ * seeWhoPlaysFirstCoinToss. + *

+ * @return + */ + private Player seeWhoPlaysFirstDice(final GameState game) { + // Play the Flip Coin sound + game.getEvents().post(new FlipCoinEvent()); + + List allPlayers = game.getPlayers(); + return allPlayers.get(MyRandom.getRandom().nextInt(allPlayers.size())); + } + } diff --git a/src/main/java/forge/game/ai/AiInputBlock.java b/src/main/java/forge/game/ai/AiInputBlock.java index 90638e7092a..8d65e48a269 100644 --- a/src/main/java/forge/game/ai/AiInputBlock.java +++ b/src/main/java/forge/game/ai/AiInputBlock.java @@ -36,6 +36,6 @@ public class AiInputBlock extends InputBase { game.getPhaseHandler().setPlayersPriorityPermission(false); // was not added to stack, so will be replaced by plain update - Singletons.getModel().getMatch().getInput().updateObservers(); + Singletons.getControl().getMatch().getInput().updateObservers(); } } diff --git a/src/main/java/forge/game/limited/GauntletMini.java b/src/main/java/forge/game/limited/GauntletMini.java index ae4b9a8bdd0..8888724e4c0 100644 --- a/src/main/java/forge/game/limited/GauntletMini.java +++ b/src/main/java/forge/game/limited/GauntletMini.java @@ -21,8 +21,8 @@ import java.util.ArrayList; import java.util.List; import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; +import forge.FThreads; import forge.Singletons; import forge.control.Lobby; import forge.deck.Deck; @@ -162,28 +162,19 @@ public class GauntletMini { } }); - final SwingWorker worker = new SwingWorker() { + final MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + starter.addPlayer(lobby.getGuiPlayer(), humanDeck); + starter.addPlayer(lobby.getAiPlayer(), aiOpponents.get(currentRound - 1)); + + final MatchController mc = new MatchController(gauntletType, starter.getPlayerMap()); + FThreads.invokeInEdtLater(new Runnable(){ @Override - - public Object doInBackground() { - - MatchStartHelper starter = new MatchStartHelper(); - Lobby lobby = Singletons.getControl().getLobby(); - starter.addPlayer(lobby.getGuiPlayer(), humanDeck); - starter.addPlayer(lobby.getAiPlayer(), aiOpponents.get(currentRound - 1)); - - MatchController mc = Singletons.getModel().getMatch(); - mc.initMatch(gauntletType, starter.getPlayerMap()); + public void run() { mc.startRound(); - return null; - } - - @Override - public void done() { SOverlayUtils.hideOverlay(); } - }; - worker.execute(); + }); } diff --git a/src/main/java/forge/game/phase/PhaseHandler.java b/src/main/java/forge/game/phase/PhaseHandler.java index 6a4320bd52e..0a6a6a4e177 100644 --- a/src/main/java/forge/game/phase/PhaseHandler.java +++ b/src/main/java/forge/game/phase/PhaseHandler.java @@ -753,8 +753,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { } else { // pass the priority to other player this.pPlayerPriority = nextPlayer; - Singletons.getModel().getMatch().getInput().updateObservers(); - + updateObservers(); } } diff --git a/src/main/java/forge/game/phase/PhaseUtil.java b/src/main/java/forge/game/phase/PhaseUtil.java index 360d0470e43..caef9c9bf1d 100644 --- a/src/main/java/forge/game/phase/PhaseUtil.java +++ b/src/main/java/forge/game/phase/PhaseUtil.java @@ -86,7 +86,7 @@ public class PhaseUtil { final PhaseHandler ph = game.getPhaseHandler(); final Player turn = ph.getPlayerTurn(); - CMessage.SINGLETON_INSTANCE.updateGameInfo(Singletons.getModel().getMatch()); + CMessage.SINGLETON_INSTANCE.updateGameInfo(Singletons.getControl().getMatch()); game.getCombat().reset(turn); diff --git a/src/main/java/forge/game/player/LobbyPlayerAi.java b/src/main/java/forge/game/player/LobbyPlayerAi.java index bc42736989e..a522a8788f8 100644 --- a/src/main/java/forge/game/player/LobbyPlayerAi.java +++ b/src/main/java/forge/game/player/LobbyPlayerAi.java @@ -1,6 +1,9 @@ package forge.game.player; +import forge.Singletons; import forge.game.GameState; +import forge.game.ai.AiProfileUtil; +import forge.properties.ForgePreferences.FPref; public class LobbyPlayerAi extends LobbyPlayer { public LobbyPlayerAi(String name) { @@ -24,7 +27,18 @@ public class LobbyPlayerAi extends LobbyPlayer { @Override public Player getPlayer(GameState game) { - return new AIPlayer(this, game); + AIPlayer ai = new AIPlayer(this, game); + + String currentAiProfile = Singletons.getModel().getPreferences().getPref(FPref.UI_CURRENT_AI_PROFILE); + String lastProfileChosen = game.getMatch().getPlayedGames().isEmpty() ? currentAiProfile : getAiProfile(); + + // TODO: implement specific AI profiles for quest mode. + boolean wantRandomProfile = currentAiProfile.equals(AiProfileUtil.AI_PROFILE_RANDOM_DUEL) + || game.getMatch().getPlayedGames().isEmpty() && currentAiProfile.equals(AiProfileUtil.AI_PROFILE_RANDOM_MATCH); + + setAiProfile(wantRandomProfile ? AiProfileUtil.getRandomProfile() : lastProfileChosen); + System.out.println(String.format("AI profile %s was chosen for the lobby player %s.", getAiProfile(), getName())); + return ai; } @Override diff --git a/src/main/java/forge/game/zone/PlayerZone.java b/src/main/java/forge/game/zone/PlayerZone.java index fdec652afb4..7d916b53ba0 100644 --- a/src/main/java/forge/game/zone/PlayerZone.java +++ b/src/main/java/forge/game/zone/PlayerZone.java @@ -88,14 +88,11 @@ public class PlayerZone extends Zone { c.addObserver(this); c.setTurnInZone(c.getGame().getPhaseHandler().getTurn()); - + this.cardList.add(c); + if (!this.is(ZoneType.Battlefield)) { c.setTapped(false); - } - - this.cardList.add(c); - - if (update) { + } else if (update) { // setTapped has already called update once this.update(); } } diff --git a/src/main/java/forge/gui/GuiDisplayUtil.java b/src/main/java/forge/gui/GuiDisplayUtil.java index 14c71ab6a22..9dd345905db 100644 --- a/src/main/java/forge/gui/GuiDisplayUtil.java +++ b/src/main/java/forge/gui/GuiDisplayUtil.java @@ -690,7 +690,7 @@ public final class GuiDisplayUtil { } private static GameState getGame() { - return Singletons.getModel().getMatch().getCurrentGame(); + return Singletons.getControl().getMatch().getCurrentGame(); } } // end class GuiDisplayUtil diff --git a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java index 3b49df4ab5b..0897085d508 100644 --- a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java +++ b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java @@ -12,11 +12,10 @@ import java.util.List; import javax.swing.JList; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; - import org.apache.commons.lang3.ArrayUtils; import forge.Command; +import forge.FThreads; import forge.Singletons; import forge.control.Lobby; import forge.deck.Deck; @@ -245,30 +244,22 @@ public enum CSubmenuGauntletContests implements ICDoc { } }); - final SwingWorker worker = new SwingWorker() { + Deck aiDeck = gd.getDecks().get(gd.getCompleted()); + + MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + + starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck()); + starter.addPlayer(lobby.getAiPlayer(), aiDeck); + + final MatchController mc = new MatchController(GameType.Gauntlet, starter.getPlayerMap()); + FThreads.invokeInEdtLater(new Runnable(){ @Override - public Object doInBackground() { - final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); - Deck aiDeck = gd.getDecks().get(gd.getCompleted()); - - MatchStartHelper starter = new MatchStartHelper(); - Lobby lobby = Singletons.getControl().getLobby(); - - starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck()); - starter.addPlayer(lobby.getAiPlayer(), aiDeck); - - MatchController mc = Singletons.getModel().getMatch(); - mc.initMatch(GameType.Gauntlet, starter.getPlayerMap()); + public void run() { mc.startRound(); - return null; - } - - @Override - public void done() { SOverlayUtils.hideOverlay(); } - }; - worker.execute(); + }); } /* (non-Javadoc) diff --git a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java index e86b5e7d05f..b5217027ab0 100644 --- a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java +++ b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java @@ -8,9 +8,8 @@ import java.util.List; import javax.swing.JButton; import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; - import forge.Command; +import forge.FThreads; import forge.Singletons; import forge.control.Lobby; import forge.deck.Deck; @@ -107,29 +106,22 @@ public enum CSubmenuGauntletLoad implements ICDoc { } }); - final SwingWorker worker = new SwingWorker() { - @Override - public Object doInBackground() { - final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); - final Deck aiDeck = gd.getDecks().get(gd.getCompleted()); + final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); + final Deck aiDeck = gd.getDecks().get(gd.getCompleted()); - MatchStartHelper starter = new MatchStartHelper(); - Lobby lobby = Singletons.getControl().getLobby(); - starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck()); - starter.addPlayer(lobby.getAiPlayer(), aiDeck); - - MatchController mc = Singletons.getModel().getMatch(); - mc.initMatch(GameType.Gauntlet, starter.getPlayerMap()); + MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck()); + starter.addPlayer(lobby.getAiPlayer(), aiDeck); + + final MatchController mc = new MatchController(GameType.Gauntlet, starter.getPlayerMap()); + FThreads.invokeInEdtLater(new Runnable(){ + @Override + public void run() { mc.startRound(); - return null; - } - - @Override - public void done() { SOverlayUtils.hideOverlay(); } - }; - worker.execute(); + }); } /* (non-Javadoc) diff --git a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletQuick.java b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletQuick.java index 61551fe5a1c..d464f9415a4 100644 --- a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletQuick.java +++ b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletQuick.java @@ -14,11 +14,10 @@ import java.util.Set; import javax.swing.JList; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; - import org.apache.commons.lang3.ArrayUtils; import forge.Command; +import forge.FThreads; import forge.Singletons; import forge.control.Lobby; import forge.deck.Deck; @@ -288,33 +287,26 @@ public enum CSubmenuGauntletQuick implements ICDoc { // Reset all variable fields to 0, stamps and saves automatically. FModel.SINGLETON_INSTANCE.getGauntletData().reset(); - FModel.SINGLETON_INSTANCE.getGauntletData() - .setUserDeck(userDeck); + FModel.SINGLETON_INSTANCE.getGauntletData().setUserDeck(userDeck); - final SwingWorker worker = new SwingWorker() { + + final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); + final Deck aiDeck = gd.getDecks().get(gd.getCompleted()); + + MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + + starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck()); + starter.addPlayer(lobby.getAiPlayer(), aiDeck); + + final MatchController mc = new MatchController(GameType.Gauntlet, starter.getPlayerMap()); + FThreads.invokeInEdtLater(new Runnable(){ @Override - public Object doInBackground() { - final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); - final Deck aiDeck = gd.getDecks().get(gd.getCompleted()); - - MatchStartHelper starter = new MatchStartHelper(); - Lobby lobby = Singletons.getControl().getLobby(); - - starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck()); - starter.addPlayer(lobby.getAiPlayer(), aiDeck); - - MatchController mc = Singletons.getModel().getMatch(); - mc.initMatch(GameType.Gauntlet, starter.getPlayerMap()); + public void run() { mc.startRound(); - return null; - } - - @Override - public void done() { SOverlayUtils.hideOverlay(); } - }; - worker.execute(); + }); } /* (non-Javadoc) diff --git a/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java b/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java index 2db559e165f..80f3311e38f 100644 --- a/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java +++ b/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java @@ -11,11 +11,13 @@ import javax.swing.SwingWorker; import org.apache.commons.lang3.tuple.ImmutablePair; +import forge.FThreads; import forge.Singletons; import forge.card.CardEdition; import forge.control.FControl; import forge.deck.Deck; import forge.game.GameType; +import forge.game.MatchController; import forge.game.MatchStartHelper; import forge.game.PlayerStartConditions; import forge.game.player.LobbyPlayer; @@ -417,8 +419,14 @@ public class SSubmenuQuestUtil { aiPlayer.setIconImageKey(event.getIconImageKey()); msh.addPlayer(aiPlayer, aiStart); - Singletons.getModel().getMatch().initMatch(GameType.Quest, msh.getPlayerMap()); - Singletons.getModel().getMatch().startRound(); + final MatchController mc = new MatchController(GameType.Quest, msh.getPlayerMap()); + FThreads.invokeInEdtLater(new Runnable(){ + @Override + public void run() { + mc.startRound(); + // no overlays here? + } + }); } /** Duplicate in DeckEditorQuestMenu and diff --git a/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java b/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java index 31a7e7f82b9..c877d91034b 100644 --- a/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java +++ b/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java @@ -5,9 +5,8 @@ import java.awt.event.ActionListener; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; - import forge.Command; +import forge.FThreads; import forge.Singletons; import forge.control.Lobby; import forge.deck.Deck; @@ -111,38 +110,22 @@ public enum CSubmenuConstructed implements ICDoc { return; } - SwingUtilities.invokeLater(new Runnable() { + SOverlayUtils.startGameOverlay(); + SOverlayUtils.showOverlay(); + + final MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + starter.addPlayer(lobby.getGuiPlayer(), humanDeck); + starter.addPlayer(lobby.getAiPlayer(), aiDeck); + final MatchController mc = new MatchController(gameType, starter.getPlayerMap()); + + FThreads.invokeInEdtLater(new Runnable(){ @Override public void run() { - SOverlayUtils.startGameOverlay(); - SOverlayUtils.showOverlay(); - } - }); - - final SwingWorker worker = new SwingWorker() { - @Override - public Object doInBackground() { - Deck humanDeck = VSubmenuConstructed.SINGLETON_INSTANCE.getDcHuman().getDeck(); - Deck aiDeck = VSubmenuConstructed.SINGLETON_INSTANCE.getDcAi().getDeck(); - - MatchStartHelper starter = new MatchStartHelper(); - Lobby lobby = Singletons.getControl().getLobby(); - starter.addPlayer(lobby.getGuiPlayer(), humanDeck); - starter.addPlayer(lobby.getAiPlayer(), aiDeck); - - MatchController mc = Singletons.getModel().getMatch(); - mc.initMatch(gameType, starter.getPlayerMap()); mc.startRound(); - - return null; - } - - @Override - public void done() { SOverlayUtils.hideOverlay(); } - }; - worker.execute(); + }); } /* (non-Javadoc) diff --git a/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java b/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java index f737c9d5049..5373a70ef30 100644 --- a/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java +++ b/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java @@ -8,9 +8,8 @@ import java.util.List; import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; - import forge.Command; +import forge.FThreads; import forge.Singletons; import forge.control.FControl; import forge.control.Lobby; @@ -124,33 +123,26 @@ public enum CSubmenuDraft implements ICDoc { } }); - final SwingWorker worker = new SwingWorker() { + + DeckGroup opponentDecks = Singletons.getModel().getDecks().getDraft().get(humanDeck.getName()); + Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex); + if (aiDeck == null) { + throw new IllegalStateException("Draft: Computer deck is null!"); + } + + MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + starter.addPlayer(lobby.getGuiPlayer(), humanDeck); + starter.addPlayer(lobby.getAiPlayer(), aiDeck); + + final MatchController mc = new MatchController(GameType.Draft, starter.getPlayerMap()); + FThreads.invokeInEdtLater(new Runnable(){ @Override - public Object doInBackground() { - DeckGroup opponentDecks = Singletons.getModel().getDecks().getDraft().get(humanDeck.getName()); - Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex); - if (aiDeck == null) { - throw new IllegalStateException("Draft: Computer deck is null!"); - } - - MatchStartHelper starter = new MatchStartHelper(); - Lobby lobby = Singletons.getControl().getLobby(); - starter.addPlayer(lobby.getGuiPlayer(), humanDeck); - starter.addPlayer(lobby.getAiPlayer(), aiDeck); - - MatchController mc = Singletons.getModel().getMatch(); - mc.initMatch(GameType.Draft, starter.getPlayerMap()); + public void run() { mc.startRound(); - - return null; - } - - @Override - public void done() { SOverlayUtils.hideOverlay(); } - }; - worker.execute(); + }); } /** */ diff --git a/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java b/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java index 01bcb30cc77..4e6b6461f72 100644 --- a/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java +++ b/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java @@ -7,11 +7,10 @@ import java.util.List; import java.util.Vector; import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; - import com.google.common.base.Predicate; import forge.Command; +import forge.FThreads; import forge.Singletons; import forge.control.FControl; import forge.control.Lobby; @@ -156,100 +155,93 @@ public enum CSubmenuArchenemy implements ICDoc { /** @param lists0   {@link java.util.List}<{@link javax.swing.JList}> */ private void startGame() { - SwingUtilities.invokeLater(new Runnable() { + + + + boolean usedDefaults = false; + + List playerDecks = new ArrayList(); + for (int i = 0; i < view.getNumPlayers(); i++) { + Deck d = view.getDeckChoosers().get(i).getDeck(); + + if (d == null) { + //ERROR! + GuiDialog.message("No deck selected for player " + (i + 1)); + return; + } + playerDecks.add(d); + } + + List schemes = null; + Object obj = view.getArchenemySchemes().getSelectedValue(); + + boolean useDefault = VSubmenuArchenemy.SINGLETON_INSTANCE.getCbUseDefaultSchemes().isSelected(); + useDefault &= playerDecks.get(0).has(DeckSection.Schemes); + + System.out.println(useDefault); + if (useDefault) { + schemes = playerDecks.get(0).get(DeckSection.Schemes).toFlatList(); + System.out.println(schemes.toString()); + usedDefaults = true; + } else { + if (obj instanceof String) { + String sel = (String) obj; + if (sel.equals("Random")) { + if (view.getAllSchemeDecks().isEmpty()) { + //Generate if no constructed scheme decks are available + System.out.println("Generating scheme deck - no others available"); + schemes = DeckgenUtil.generateSchemeDeck().toFlatList(); + } else { + System.out.println("Using scheme deck: " + Aggregates.random(view.getAllSchemeDecks()).getName()); + schemes = Aggregates.random(view.getAllSchemeDecks()).get(DeckSection.Schemes).toFlatList(); + } + } else { + //Generate + schemes = DeckgenUtil.generateSchemeDeck().toFlatList(); + } + } else { + schemes = ((Deck) obj).get(DeckSection.Schemes).toFlatList(); + } + } + if (schemes == null) { + //ERROR! + GuiDialog.message("No scheme deck selected!"); + return; + } + + if (usedDefaults) { + + GuiDialog.message("Using default scheme deck."); + } + + // won't cancel after this point + SOverlayUtils.startGameOverlay(); + SOverlayUtils.showOverlay(); + + Lobby lobby = Singletons.getControl().getLobby(); + MatchStartHelper helper = new MatchStartHelper(); + for (int i = 0; i < view.getNumPlayers(); i++) { + LobbyPlayer player = i == 0 ? lobby.getGuiPlayer() : lobby.getAiPlayer(); + + if (i == 0) { + + helper.addArchenemy(player, playerDecks.get(i), schemes); + helper.getPlayerMap().get(player).setStartingLife(10 + (10 * (view.getNumPlayers() - 1))); + } else { + + helper.addPlayer(player, playerDecks.get(i)); + } + } + + final MatchController mc = new MatchController(GameType.Archenemy, helper.getPlayerMap()); + FThreads.invokeInEdtLater(new Runnable(){ @Override public void run() { - SOverlayUtils.startGameOverlay(); - SOverlayUtils.showOverlay(); + mc.startRound(); + SOverlayUtils.hideOverlay(); } }); - final SwingWorker worker = new SwingWorker() { - @Override - public Object doInBackground() { - boolean usedDefaults = false; - - List playerDecks = new ArrayList(); - for (int i = 0; i < view.getNumPlayers(); i++) { - Deck d = view.getDeckChoosers().get(i).getDeck(); - - if (d == null) { - //ERROR! - GuiDialog.message("No deck selected for player " + (i + 1)); - return null; - } - playerDecks.add(d); - } - - List schemes = null; - Object obj = view.getArchenemySchemes().getSelectedValue(); - - boolean useDefault = VSubmenuArchenemy.SINGLETON_INSTANCE.getCbUseDefaultSchemes().isSelected(); - useDefault &= playerDecks.get(0).has(DeckSection.Schemes); - - System.out.println(useDefault); - if (useDefault) { - schemes = playerDecks.get(0).get(DeckSection.Schemes).toFlatList(); - System.out.println(schemes.toString()); - usedDefaults = true; - } else { - if (obj instanceof String) { - String sel = (String) obj; - if (sel.equals("Random")) { - if (view.getAllSchemeDecks().isEmpty()) { - //Generate if no constructed scheme decks are available - System.out.println("Generating scheme deck - no others available"); - schemes = DeckgenUtil.generateSchemeDeck().toFlatList(); - } else { - System.out.println("Using scheme deck: " + Aggregates.random(view.getAllSchemeDecks()).getName()); - schemes = Aggregates.random(view.getAllSchemeDecks()).get(DeckSection.Schemes).toFlatList(); - } - } else { - //Generate - schemes = DeckgenUtil.generateSchemeDeck().toFlatList(); - } - } else { - schemes = ((Deck) obj).get(DeckSection.Schemes).toFlatList(); - } - } - if (schemes == null) { - //ERROR! - GuiDialog.message("No scheme deck selected!"); - return null; - } - - if (usedDefaults) { - - GuiDialog.message("Using default scheme deck."); - } - - Lobby lobby = Singletons.getControl().getLobby(); - MatchStartHelper helper = new MatchStartHelper(); - for (int i = 0; i < view.getNumPlayers(); i++) { - LobbyPlayer player = i == 0 ? lobby.getGuiPlayer() : lobby.getAiPlayer(); - - if (i == 0) { - - helper.addArchenemy(player, playerDecks.get(i), schemes); - helper.getPlayerMap().get(player).setStartingLife(10 + (10 * (view.getNumPlayers() - 1))); - } else { - - helper.addPlayer(player, playerDecks.get(i)); - } - } - MatchController mc = Singletons.getModel().getMatch(); - mc.initMatch(GameType.Archenemy, helper.getPlayerMap()); - mc.startRound(); - - return null; - } - - @Override - public void done() { - SOverlayUtils.hideOverlay(); - } - }; - worker.execute(); } /* (non-Javadoc) diff --git a/src/main/java/forge/gui/home/variant/CSubmenuPlanechase.java b/src/main/java/forge/gui/home/variant/CSubmenuPlanechase.java index 4a597ded24f..f2fa55f8116 100644 --- a/src/main/java/forge/gui/home/variant/CSubmenuPlanechase.java +++ b/src/main/java/forge/gui/home/variant/CSubmenuPlanechase.java @@ -7,11 +7,10 @@ import java.util.List; import java.util.Vector; import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; - import com.google.common.base.Predicate; import forge.Command; +import forge.FThreads; import forge.Singletons; import forge.control.FControl; import forge.control.Lobby; @@ -149,94 +148,80 @@ public enum CSubmenuPlanechase implements ICDoc { /** @param lists0   {@link java.util.List}<{@link javax.swing.JList}> */ private void startGame() { - SwingUtilities.invokeLater(new Runnable() { + Lobby lobby = Singletons.getControl().getLobby(); + MatchStartHelper helper = new MatchStartHelper(); + List playerDecks = new ArrayList(); + for (int i = 0; i < view.getNumPlayers(); i++) { + Deck d = view.getDeckChoosers().get(i).getDeck(); + + if (d == null) { + //ERROR! + GuiDialog.message("No deck selected for player " + (i + 1)); + return; + } + playerDecks.add(d); + + + List planes = null; + Object obj = view.getPlanarDeckLists().get(i).getSelectedValue(); + + boolean useDefault = VSubmenuPlanechase.SINGLETON_INSTANCE.getCbUseDefaultPlanes().isSelected(); + useDefault &= playerDecks.get(i).has(DeckSection.Planes); + + System.out.println(useDefault); + if (useDefault) { + + planes = playerDecks.get(i).get(DeckSection.Planes).toFlatList(); + System.out.println(planes.toString()); + + } else { + + if (obj instanceof String) { + String sel = (String) obj; + if (sel.equals("Random")) { + if (view.getAllPlanarDecks().isEmpty()) { + //Generate if no constructed scheme decks are available + System.out.println("Generating planar deck - no others available"); + planes = DeckgenUtil.generatePlanarDeck().toFlatList(); + } else { + System.out.println("Using planar deck: " + Aggregates.random(view.getAllPlanarDecks()).getName()); + planes = Aggregates.random(view.getAllPlanarDecks()).get(DeckSection.Planes).toFlatList(); + } + + } else { + + //Generate + planes = DeckgenUtil.generatePlanarDeck().toFlatList(); + } + } else { + planes = ((Deck) obj).get(DeckSection.Planes).toFlatList(); + } + } + if (planes == null) { + //ERROR! + GuiDialog.message("No planar deck selected for player" + (i+1) + "!"); + return; + } + + if (useDefault) { + + GuiDialog.message("Player " + (i+1) + " will use a default planar deck."); + } + LobbyPlayer player = i == 0 ? lobby.getGuiPlayer() : lobby.getAiPlayer(); + helper.addPlanechasePlayer(player, playerDecks.get(i), planes); + } + + SOverlayUtils.startGameOverlay(); + SOverlayUtils.showOverlay(); + + final MatchController mc = new MatchController(GameType.Planechase, helper.getPlayerMap()); + FThreads.invokeInEdtLater(new Runnable(){ @Override public void run() { - SOverlayUtils.startGameOverlay(); - SOverlayUtils.showOverlay(); - } - }); - - final SwingWorker worker = new SwingWorker() { - @Override - public Object doInBackground() { - - Lobby lobby = Singletons.getControl().getLobby(); - MatchStartHelper helper = new MatchStartHelper(); - List playerDecks = new ArrayList(); - for (int i = 0; i < view.getNumPlayers(); i++) { - Deck d = view.getDeckChoosers().get(i).getDeck(); - - if (d == null) { - //ERROR! - GuiDialog.message("No deck selected for player " + (i + 1)); - return null; - } - playerDecks.add(d); - - - List planes = null; - Object obj = view.getPlanarDeckLists().get(i).getSelectedValue(); - - boolean useDefault = VSubmenuPlanechase.SINGLETON_INSTANCE.getCbUseDefaultPlanes().isSelected(); - useDefault &= playerDecks.get(i).has(DeckSection.Planes); - - System.out.println(useDefault); - if (useDefault) { - - planes = playerDecks.get(i).get(DeckSection.Planes).toFlatList(); - System.out.println(planes.toString()); - - } else { - - if (obj instanceof String) { - String sel = (String) obj; - if (sel.equals("Random")) { - if (view.getAllPlanarDecks().isEmpty()) { - //Generate if no constructed scheme decks are available - System.out.println("Generating planar deck - no others available"); - planes = DeckgenUtil.generatePlanarDeck().toFlatList(); - } else { - System.out.println("Using planar deck: " + Aggregates.random(view.getAllPlanarDecks()).getName()); - planes = Aggregates.random(view.getAllPlanarDecks()).get(DeckSection.Planes).toFlatList(); - } - - } else { - - //Generate - planes = DeckgenUtil.generatePlanarDeck().toFlatList(); - } - } else { - planes = ((Deck) obj).get(DeckSection.Planes).toFlatList(); - } - } - if (planes == null) { - //ERROR! - GuiDialog.message("No planar deck selected for player" + (i+1) + "!"); - return null; - } - - if (useDefault) { - - GuiDialog.message("Player " + (i+1) + " will use a default planar deck."); - } - LobbyPlayer player = i == 0 ? lobby.getGuiPlayer() : lobby.getAiPlayer(); - helper.addPlanechasePlayer(player, playerDecks.get(i), planes); - } - - MatchController mc = Singletons.getModel().getMatch(); - mc.initMatch(GameType.Planechase, helper.getPlayerMap()); mc.startRound(); - - return null; - } - - @Override - public void done() { SOverlayUtils.hideOverlay(); } - }; - worker.execute(); + }); } diff --git a/src/main/java/forge/gui/home/variant/CSubmenuVanguard.java b/src/main/java/forge/gui/home/variant/CSubmenuVanguard.java index f0e336fb20d..e6276e667ac 100644 --- a/src/main/java/forge/gui/home/variant/CSubmenuVanguard.java +++ b/src/main/java/forge/gui/home/variant/CSubmenuVanguard.java @@ -7,11 +7,10 @@ import java.util.List; import java.util.Random; import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; - import com.google.common.collect.Iterables; import forge.Command; +import forge.FThreads; import forge.Singletons; import forge.control.Lobby; import forge.deck.Deck; @@ -113,87 +112,79 @@ public enum CSubmenuVanguard implements ICDoc { } }); - final SwingWorker worker = new SwingWorker() { - @Override - public Object doInBackground() { - Random rnd = new Random(); - String nl = System.getProperty("line.separator"); - boolean usedDefaults = false; - StringBuilder defaultAvatarInfo = new StringBuilder("The following decks will use a default avatar:" + nl); - List playerDecks = new ArrayList(); - for (int i = 0; i < view.getNumPlayers(); i++) { - Deck d = view.getDeckChoosers().get(i).getDeck(); + Random rnd = new Random(); + String nl = System.getProperty("line.separator"); + boolean usedDefaults = false; + StringBuilder defaultAvatarInfo = new StringBuilder("The following decks will use a default avatar:" + nl); - if (d == null) { - //ERROR! - GuiDialog.message("No deck selected for player " + (i + 1)); - return null; - } - playerDecks.add(d); - } + List playerDecks = new ArrayList(); + for (int i = 0; i < view.getNumPlayers(); i++) { + Deck d = view.getDeckChoosers().get(i).getDeck(); - List playerAvatars = new ArrayList(); - for (int i = 0; i < view.getNumPlayers(); i++) { - CardPrinted avatar = null; - Object obj = view.getAvatarLists().get(i).getSelectedValue(); - - boolean useDefault = VSubmenuVanguard.SINGLETON_INSTANCE.getCbDefaultAvatars().isSelected(); - useDefault &= playerDecks.get(i).get(DeckSection.Avatar) != null; - - if (useDefault) { - avatar = playerDecks.get(i).get(DeckSection.Avatar).get(0); - defaultAvatarInfo.append("Player " + (i + 1) + ": "); - defaultAvatarInfo.append(avatar.getName() + nl); - usedDefaults = true; - } else { - - if (obj instanceof String) { - //Random is the only string in the list so grab a random avatar. - if (i == 0) { - //HUMAN - avatar = Iterables.get(view.getAllAvatars(), rnd.nextInt(Iterables.size(view.getNonRandomHumanAvatars()))); - } else { - //AI - avatar = Iterables.get(view.getAllAiAvatars(), rnd.nextInt(Iterables.size(view.getNonRandomAiAvatars()))); - } - } else { - avatar = (CardPrinted) obj; - } - } - if (avatar == null) { - //ERROR! - GuiDialog.message("No avatar selected for player " + (i + 1)); - return null; - } - playerAvatars.add(avatar); - } - - if (usedDefaults) { - - GuiDialog.message(defaultAvatarInfo.toString()); - } - - Lobby lobby = Singletons.getControl().getLobby(); - MatchStartHelper helper = new MatchStartHelper(); - for (int i = 0; i < view.getNumPlayers(); i++) { - LobbyPlayer player = i == 0 ? lobby.getGuiPlayer() : lobby.getAiPlayer(); - - helper.addVanguardPlayer(player, playerDecks.get(i), playerAvatars.get(i)); - } - MatchController mc = Singletons.getModel().getMatch(); - mc.initMatch(GameType.Vanguard, helper.getPlayerMap()); - mc.startRound(); - - return null; + if (d == null) { + //ERROR! + GuiDialog.message("No deck selected for player " + (i + 1)); + return; } + playerDecks.add(d); + } + List playerAvatars = new ArrayList(); + for (int i = 0; i < view.getNumPlayers(); i++) { + CardPrinted avatar = null; + Object obj = view.getAvatarLists().get(i).getSelectedValue(); + + boolean useDefault = VSubmenuVanguard.SINGLETON_INSTANCE.getCbDefaultAvatars().isSelected(); + useDefault &= playerDecks.get(i).get(DeckSection.Avatar) != null; + + if (useDefault) { + avatar = playerDecks.get(i).get(DeckSection.Avatar).get(0); + defaultAvatarInfo.append("Player " + (i + 1) + ": "); + defaultAvatarInfo.append(avatar.getName() + nl); + usedDefaults = true; + } else { + + if (obj instanceof String) { + //Random is the only string in the list so grab a random avatar. + if (i == 0) { + //HUMAN + avatar = Iterables.get(view.getAllAvatars(), rnd.nextInt(Iterables.size(view.getNonRandomHumanAvatars()))); + } else { + //AI + avatar = Iterables.get(view.getAllAiAvatars(), rnd.nextInt(Iterables.size(view.getNonRandomAiAvatars()))); + } + } else { + avatar = (CardPrinted) obj; + } + } + if (avatar == null) { + //ERROR! + GuiDialog.message("No avatar selected for player " + (i + 1)); + return; + } + playerAvatars.add(avatar); + } + + if (usedDefaults) { + GuiDialog.message(defaultAvatarInfo.toString()); + } + + Lobby lobby = Singletons.getControl().getLobby(); + MatchStartHelper helper = new MatchStartHelper(); + for (int i = 0; i < view.getNumPlayers(); i++) { + LobbyPlayer player = i == 0 ? lobby.getGuiPlayer() : lobby.getAiPlayer(); + + helper.addVanguardPlayer(player, playerDecks.get(i), playerAvatars.get(i)); + } + final MatchController mc = new MatchController(GameType.Vanguard, helper.getPlayerMap()); + FThreads.invokeInEdtLater(new Runnable(){ @Override - public void done() { + public void run() { + mc.startRound(); SOverlayUtils.hideOverlay(); } - }; - worker.execute(); + }); } diff --git a/src/main/java/forge/gui/match/TargetingOverlay.java b/src/main/java/forge/gui/match/TargetingOverlay.java index 73c33234dd7..a65246b0bbd 100644 --- a/src/main/java/forge/gui/match/TargetingOverlay.java +++ b/src/main/java/forge/gui/match/TargetingOverlay.java @@ -284,7 +284,7 @@ public enum TargetingOverlay { @Override public void paintComponent(final Graphics g) { - final Combat combat = Singletons.getModel().getMatch().getCurrentGame().getCombat(); // this will get deprecated too + final Combat combat = Singletons.getControl().getMatch().getCurrentGame().getCombat(); // this will get deprecated too // No need for this except in match view if (FControl.SINGLETON_INSTANCE.getState() != FControl.Screens.MATCH_SCREEN) { return; } diff --git a/src/main/java/forge/gui/match/controllers/CDock.java b/src/main/java/forge/gui/match/controllers/CDock.java index 0ada575baf5..a16a4837bfc 100644 --- a/src/main/java/forge/gui/match/controllers/CDock.java +++ b/src/main/java/forge/gui/match/controllers/CDock.java @@ -67,7 +67,7 @@ public enum CDock implements ICDoc { private GameState game; private Player player; - public void onGameStarts(GameState game0, Player player0) { + public void setModel(GameState game0, Player player0) { game = game0; player = player0; @@ -149,7 +149,7 @@ public enum CDock implements ICDoc { * View deck list. */ private void viewDeckList() { - showDeck(Singletons.getModel().getMatch().getPlayersDeck(player.getLobbyPlayer())); + showDeck(Singletons.getControl().getMatch().getPlayersDeck(player.getLobbyPlayer())); } /** diff --git a/src/main/java/forge/gui/match/nonsingleton/CField.java b/src/main/java/forge/gui/match/nonsingleton/CField.java index a19a7f145fc..f90d49e71a3 100644 --- a/src/main/java/forge/gui/match/nonsingleton/CField.java +++ b/src/main/java/forge/gui/match/nonsingleton/CField.java @@ -197,7 +197,7 @@ public class CField implements ICDoc { /** */ private void manaAction(byte colorCode) { if (CField.this.player == CField.this.playerViewer) { - final Input in = Singletons.getModel().getMatch().getInput().getInput(); + final Input in = Singletons.getControl().getMatch().getInput().getInput(); if (in instanceof InputPayManaBase) { // Do something ((InputPayManaBase) in).selectManaPool(colorCode); diff --git a/src/main/java/forge/gui/match/views/VAntes.java b/src/main/java/forge/gui/match/views/VAntes.java index b8fc86f49d0..37b88a7a488 100644 --- a/src/main/java/forge/gui/match/views/VAntes.java +++ b/src/main/java/forge/gui/match/views/VAntes.java @@ -18,8 +18,9 @@ package forge.gui.match.views; import java.awt.Dimension; -import java.util.Comparator; import java.util.Iterator; +import java.util.Observable; +import java.util.Observer; import java.util.SortedSet; import java.util.TreeSet; @@ -30,6 +31,7 @@ import javax.swing.SwingConstants; import net.miginfocom.swing.MigLayout; import forge.Card; import forge.game.player.Player; +import forge.game.zone.ZoneType; import forge.gui.CardPicturePanel; import forge.gui.WrapLayout; import forge.gui.framework.DragCell; @@ -44,7 +46,7 @@ import forge.gui.toolbox.FLabel; * *

(V at beginning of class name denotes a view class.) */ -public enum VAntes implements IVDoc { +public enum VAntes implements IVDoc, Observer { /** */ SINGLETON_INSTANCE; @@ -52,18 +54,11 @@ public enum VAntes implements IVDoc { private DragCell parentCell; private final DragTab tab = new DragTab("Ante"); - // Other fields - private final Comparator c = new Comparator() { - @Override - public int compare(AntePanel arg0, AntePanel arg1) { - return arg0.getID().compareTo(arg1.getID()); - } - }; - private final JPanel pnl = new JPanel(); private final JScrollPane scroller = new JScrollPane(pnl); - private final SortedSet allAntes = new TreeSet(c); + private final SortedSet allAntes = new TreeSet(); + private Iterable players; //========== Constructor private VAntes() { pnl.setLayout(new WrapLayout()); @@ -83,6 +78,14 @@ public enum VAntes implements IVDoc { parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0")); parentCell.getBody().add(scroller, "w 100%!, h 100%!"); } + + public final void setModel(Iterable playerz) { + players = playerz; + for(Player p: players) { + p.getZone(ZoneType.Ante).addObserver(this); + } + update(null, null); + } /* (non-Javadoc) * @see forge.gui.framework.IVDoc#setParentCell() @@ -125,50 +128,34 @@ public enum VAntes implements IVDoc { } //========== Setters / getters - /** - * @param p0   {@link forge.game.player.Player} - * @param c0   {@link forge.Card} - */ - public void addAnteCard(final Player p0, final Card c0) { - final AntePanel pnlTemp = new AntePanel(p0, c0); - allAntes.add(pnlTemp); - pnl.add(pnlTemp); - } + @Override + public void update(Observable o, Object arg) { + allAntes.clear(); + pnl.removeAll(); - /** - * @param p0   {@link forge.game.player.Player} - * @param c0   {@link forge.Card} - */ - public void removeAnteCard(final Player p0, final Card c0) { - final Iterator itr = allAntes.iterator(); - while (itr.hasNext()) { - final AntePanel pnlTemp = itr.next(); - - if (pnlTemp.getPlayer().equals(p0) && pnlTemp.getCard().equals(c0)) { - pnl.remove(pnlTemp); - itr.remove(); + for(Player p : players) { + for(Card c : p.getZone(ZoneType.Ante)) { + final AntePanel pnlTemp = new AntePanel(c); + allAntes.add(pnlTemp); } } - } - /** */ - public void clearAnteCards() { - allAntes.clear(); + for(AntePanel ap : allAntes) { + pnl.add(ap); + } } //========= Private class handling @SuppressWarnings("serial") - private class AntePanel extends JPanel { - private final Player player; + private class AntePanel extends JPanel implements Comparable { private final Card card; /** * * @param p0   {@link forge.game.player.Player} * @param c0   {@link forge.Card} */ - public AntePanel(final Player p0, final Card c0) { + public AntePanel(final Card c0) { super(); - player = p0; card = c0; final Dimension d = new Dimension(160, 250); @@ -178,25 +165,21 @@ public enum VAntes implements IVDoc { setOpaque(false); setLayout(new MigLayout("gap 0, insets 0, wrap")); - add(new FLabel.Builder().fontSize(14).text(player.getName()) - .fontAlign(SwingConstants.CENTER).build(), "w 160px, h 20px"); + add(new FLabel.Builder().fontSize(14).text(card.getOwner().getName()) + .fontAlign(SwingConstants.CENTER).build(), "w 160px, h 20px"); CardPicturePanel picPanel = new CardPicturePanel(); add(picPanel, "w 160px, h 230px"); picPanel.setCard(c0); } - /** @return {@link forge.game.player.Player} */ - public Player getPlayer() { - return player; - } - /** @return {@link forge.Card} */ public Card getCard() { return card; } - public String getID() { - return player.getName() + card.getName(); + @Override + public int compareTo(AntePanel o) { + return o.card.getUniqueNumber() - card.getUniqueNumber(); } } } diff --git a/src/main/java/forge/model/FModel.java b/src/main/java/forge/model/FModel.java index 5b834a9c35d..263661889a1 100644 --- a/src/main/java/forge/model/FModel.java +++ b/src/main/java/forge/model/FModel.java @@ -39,7 +39,6 @@ import forge.card.cardfactory.CardStorageReader; import forge.deck.CardCollections; import forge.error.BugReporter; import forge.error.ExceptionHandler; -import forge.game.MatchController; import forge.game.limited.GauntletMini; import forge.gauntlet.GauntletData; import forge.item.CardDb; @@ -81,8 +80,6 @@ public enum FModel { private final QuestController quest; private final CardCollections decks; - private final MatchController match; - private final EditionCollection editions; private final FormatCollection formats; private final IStorageView boosters; @@ -155,8 +152,6 @@ public enum FModel { this.blocks = new StorageView(new CardBlock.Reader("res/blockdata/blocks.txt", editions)); this.fantasyBlocks = new StorageView(new CardBlock.Reader("res/blockdata/fantasyblocks.txt", editions)); this.worlds = new StorageView(new QuestWorld.Reader("res/quest/world/worlds.txt")); - - this.match = new MatchController(); // TODO - there's got to be a better place for this...oblivion? Preferences.DEV_MODE = this.preferences.getPrefBoolean(FPref.DEV_MODE_ENABLED); @@ -396,9 +391,6 @@ public enum FModel { this.gauntletData = data0; } - public MatchController getMatch() { - return match; - } public GauntletMini getGauntletMini() { diff --git a/src/main/java/forge/util/TextUtil.java b/src/main/java/forge/util/TextUtil.java index efb834febd1..92cee2b039a 100644 --- a/src/main/java/forge/util/TextUtil.java +++ b/src/main/java/forge/util/TextUtil.java @@ -9,6 +9,8 @@ import java.util.Map.Entry; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; +import forge.item.CardPrinted; + /** * TODO: Write javadoc for this type. * @@ -105,4 +107,16 @@ public class TextUtil { return val.toString().substring(0, 1).toUpperCase(Locale.ENGLISH) + val.toString().substring(1).toLowerCase(Locale.ENGLISH); } + + public static String buildFourColumnList(String firstLine, Iterable cAnteRemoved) { + StringBuilder sb = new StringBuilder(firstLine); + int i = 0; + for(CardPrinted cp: cAnteRemoved) { + if ( i != 0 ) sb.append(", "); + if ( i % 4 == 0 ) sb.append("\n"); + sb.append(cp); + i++; + } + return sb.toString(); + } }