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.
This commit is contained in:
Maxmtg
2013-05-08 20:32:09 +00:00
parent 06a89309a0
commit 1a1b1c71b6
35 changed files with 674 additions and 784 deletions

View File

@@ -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();
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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() { }

View File

@@ -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) {

View File

@@ -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 <code>serialVersionUID=3955194449319994301L</code>. */
private static final long serialVersionUID = 3955194449319994301L;
private final BlockingDeque<Input> inputStack = new LinkedBlockingDeque<Input>();
private final MatchController match;
public InputControl(MatchController matchController) {
public InputQueue(MatchController matchController) {
match = matchController;
}

View File

@@ -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);
}
}

View File

@@ -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<? extends IPaperCard> 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<Card> sd = new ArrayList<Card>();
for(IPaperCard cp : psc.getSchemes(player)) sd.add(cp.toForgeCard(player));
if ( !sd.isEmpty()) player.setSchemeDeck(sd);
// Planes
List<Card> l = new ArrayList<Card>();
for(IPaperCard cp : psc.getPlanes(player)) l.add(cp.toForgeCard(player));
if ( !l.isEmpty() ) player.setPlanarDeck(l);
}
private static Set<CardPrinted> getRemovedAnteCards(Deck toUse) {
final String keywordToRemove = "Remove CARDNAME from your deck before playing if you're not playing for ante.";
Set<CardPrinted> myRemovedAnteCards = new HashSet<CardPrinted>();
for ( Entry<DeckSection, CardPool> ds : toUse ) {
for (Entry<CardPrinted, Integer> cp : ds.getValue()) {
if ( Iterables.contains(cp.getKey().getRules().getMainPart().getKeywords(), keywordToRemove) )
myRemovedAnteCards.add(cp.getKey());
}
}
for(CardPrinted cp: myRemovedAnteCards) {
for ( Entry<DeckSection, CardPool> 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)
/**
* <p>
* smoothComputerManaCurve.
* </p>
*
* @param in
* an array of {@link forge.Card} objects.
* @return an array of {@link forge.Card} objects.
*/
private static Iterable<Card> smoothComputerManaCurve(final Iterable<Card> in) {
final List<Card> library = Lists.newArrayList(in);
CardLists.shuffle(library);
// remove all land, keep non-basicland in there, shuffled
List<Card> 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<CardPrinted> getCardsAiCantPlayWell(final Deck toUse) {
List<CardPrinted> result = new ArrayList<CardPrinted>();
for ( Entry<DeckSection, CardPool> ds : toUse ) {
for (Entry<CardPrinted, Integer> 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<Player, PlayerStartConditions> 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<CardPrinted> rAICards = new HashSet<CardPrinted>();
Map<Player, Set<CardPrinted>> removedAnteCards = new HashMap<Player, Set<CardPrinted>>();
GameType gameType = game.getType();
boolean isFirstGame = game.getMatch().getPlayedGames().isEmpty();
boolean canSideBoard = !isFirstGame && gameType.isSideboardingAllowed();
for (Entry<Player, PlayerStartConditions> p : playersConditions.entrySet()) {
final Player player = p.getKey();
final PlayerStartConditions psc = p.getValue();
final Map<LobbyPlayer, PlayerStartConditions> 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<Player, Set<CardPrinted>> 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 <handsize> 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<Card> sd = new ArrayList<Card>();
for(IPaperCard cp : psc.getSchemes(player)) sd.add(cp.toForgeCard(player));
if ( !sd.isEmpty()) player.setSchemeDeck(sd);
// Planes
List<Card> l = new ArrayList<Card>();
for(IPaperCard cp : psc.getPlanes(player)) l.add(cp.toForgeCard(player));
if ( !l.isEmpty() ) player.setPlanarDeck(l);
}
private static List<CardPrinted> getCardsAiCantPlayWell(final Deck toUse) {
List<CardPrinted> result = new ArrayList<CardPrinted>();
for ( Entry<DeckSection, CardPool> ds : toUse ) {
for (Entry<CardPrinted, Integer> cp : ds.getValue()) {
if ( cp.getKey().getRules().getAiHints().getRemAIDecks() )
result.add(cp.getKey());
}
}
return result;
}
private static Set<CardPrinted> getRemovedAnteCards(Deck toUse) {
final String keywordToRemove = "Remove CARDNAME from your deck before playing if you're not playing for ante.";
Set<CardPrinted> myRemovedAnteCards = new HashSet<CardPrinted>();
for ( Entry<DeckSection, CardPool> ds : toUse ) {
for (Entry<CardPrinted, Integer> cp : ds.getValue()) {
if ( Iterables.contains(cp.getKey().getRules().getMainPart().getKeywords(), keywordToRemove) )
myRemovedAnteCards.add(cp.getKey());
}
}
for(CardPrinted cp: myRemovedAnteCards) {
for ( Entry<DeckSection, CardPool> ds : toUse ) {
ds.getValue().remove(cp, Integer.MAX_VALUE);
}
}
return myRemovedAnteCards;
}
private static void putCardsOnBattlefield(Player player, Iterable<? extends IPaperCard> 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<CardPrinted> 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)
/**
* <p>
* smoothComputerManaCurve.
* </p>
*
* @param in
* an array of {@link forge.Card} objects.
* @return an array of {@link forge.Card} objects.
*/
private static Iterable<Card> smoothComputerManaCurve(final Iterable<Card> in) {
final List<Card> library = Lists.newArrayList(in);
CardLists.shuffle(library);
// remove all land, keep non-basicland in there, shuffled
List<Card> 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()
/**
* <p>
* seeWhoPlaysFirstCoinToss.
* </p>
* @return
*/
private static Player seeWhoPlaysFirstDice(final GameState game) {
// Play the Flip Coin sound
game.getEvents().post(new FlipCoinEvent());
List<Player> allPlayers = game.getPlayers();
return allPlayers.get(MyRandom.getRandom().nextInt(allPlayers.size()));
}
}

View File

@@ -94,19 +94,20 @@ public class GameState {
*/
public GameState(Iterable<LobbyPlayer> players2, GameType t, MatchController match0) { /* no more zones to map here */
type = t;
match = match0;
List<Player> players = new ArrayList<Player>();
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

View File

@@ -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<LobbyPlayer, PlayerStartConditions> players = new HashMap<LobbyPlayer, PlayerStartConditions>();
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<GameOutcome> gamesPlayed = new ArrayList<GameOutcome>();
private final List<GameOutcome> gamesPlayedRo;
private InputControl input;
private InputQueue inputQueue;
public MatchController() {
/**
* This should become constructor once.
*/
public MatchController(GameType type, Map<LobbyPlayer, PlayerStartConditions> 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<Player, PlayerStartConditions> startConditions = new HashMap<Player, PlayerStartConditions>();
@@ -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<LobbyPlayer, PlayerStartConditions> 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()
/**
* <p>
* seeWhoPlaysFirstCoinToss.
* </p>
* @return
*/
private Player seeWhoPlaysFirstDice(final GameState game) {
// Play the Flip Coin sound
game.getEvents().post(new FlipCoinEvent());
List<Player> allPlayers = game.getPlayers();
return allPlayers.get(MyRandom.getRandom().nextInt(allPlayers.size()));
}
}

View File

@@ -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();
}
}

View File

@@ -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<Object, Void> worker = new SwingWorker<Object, Void>() {
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();
});
}

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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<Object, Void> worker = new SwingWorker<Object, Void>() {
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)

View File

@@ -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<Object, Void> worker = new SwingWorker<Object, Void>() {
@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)

View File

@@ -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<Object, Void> worker = new SwingWorker<Object, Void>() {
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)

View File

@@ -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

View File

@@ -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<Object, Void> worker = new SwingWorker<Object, Void>() {
@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)

View File

@@ -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<Object, Void> worker = new SwingWorker<Object, Void>() {
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();
});
}
/** */

View File

@@ -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 &emsp; {@link java.util.List}<{@link javax.swing.JList}> */
private void startGame() {
SwingUtilities.invokeLater(new Runnable() {
boolean usedDefaults = false;
List<Deck> playerDecks = new ArrayList<Deck>();
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<CardPrinted> 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<Object, Void> worker = new SwingWorker<Object, Void>() {
@Override
public Object doInBackground() {
boolean usedDefaults = false;
List<Deck> playerDecks = new ArrayList<Deck>();
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<CardPrinted> 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)

View File

@@ -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 &emsp; {@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<Deck> playerDecks = new ArrayList<Deck>();
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<CardPrinted> 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<Object, Void> worker = new SwingWorker<Object, Void>() {
@Override
public Object doInBackground() {
Lobby lobby = Singletons.getControl().getLobby();
MatchStartHelper helper = new MatchStartHelper();
List<Deck> playerDecks = new ArrayList<Deck>();
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<CardPrinted> 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();
});
}

View File

@@ -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<Object, Void> worker = new SwingWorker<Object, Void>() {
@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<Deck> playerDecks = new ArrayList<Deck>();
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<Deck> playerDecks = new ArrayList<Deck>();
for (int i = 0; i < view.getNumPlayers(); i++) {
Deck d = view.getDeckChoosers().get(i).getDeck();
List<CardPrinted> playerAvatars = new ArrayList<CardPrinted>();
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<CardPrinted> playerAvatars = new ArrayList<CardPrinted>();
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();
});
}

View File

@@ -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; }

View File

@@ -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()));
}
/**

View File

@@ -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);

View File

@@ -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;
*
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
*/
public enum VAntes implements IVDoc<CAntes> {
public enum VAntes implements IVDoc<CAntes>, Observer {
/** */
SINGLETON_INSTANCE;
@@ -52,18 +54,11 @@ public enum VAntes implements IVDoc<CAntes> {
private DragCell parentCell;
private final DragTab tab = new DragTab("Ante");
// Other fields
private final Comparator<AntePanel> c = new Comparator<AntePanel>() {
@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<AntePanel> allAntes = new TreeSet<AntePanel>(c);
private final SortedSet<AntePanel> allAntes = new TreeSet<AntePanel>();
private Iterable<Player> players;
//========== Constructor
private VAntes() {
pnl.setLayout(new WrapLayout());
@@ -83,6 +78,14 @@ public enum VAntes implements IVDoc<CAntes> {
parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0"));
parentCell.getBody().add(scroller, "w 100%!, h 100%!");
}
public final void setModel(Iterable<Player> 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<CAntes> {
}
//========== Setters / getters
/**
* @param p0 &emsp; {@link forge.game.player.Player}
* @param c0 &emsp; {@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 &emsp; {@link forge.game.player.Player}
* @param c0 &emsp; {@link forge.Card}
*/
public void removeAnteCard(final Player p0, final Card c0) {
final Iterator<AntePanel> 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<AntePanel> {
private final Card card;
/**
*
* @param p0 &emsp; {@link forge.game.player.Player}
* @param c0 &emsp; {@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<CAntes> {
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();
}
}
}

View File

@@ -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<BoosterTemplate> boosters;
@@ -155,8 +152,6 @@ public enum FModel {
this.blocks = new StorageView<CardBlock>(new CardBlock.Reader("res/blockdata/blocks.txt", editions));
this.fantasyBlocks = new StorageView<CardBlock>(new CardBlock.Reader("res/blockdata/fantasyblocks.txt", editions));
this.worlds = new StorageView<QuestWorld>(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() {

View File

@@ -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<CardPrinted> 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();
}
}