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

2
.gitattributes vendored
View File

@@ -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/InputBase.java svneol=native#text/plain
src/main/java/forge/control/input/InputBlock.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/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/InputLockUI.java -text
src/main/java/forge/control/input/InputMulligan.java svneol=native#text/plain src/main/java/forge/control/input/InputMulligan.java svneol=native#text/plain
src/main/java/forge/control/input/InputPartialParisMulligan.java -text 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/InputPayManaX.java -text
src/main/java/forge/control/input/InputPayment.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/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/InputSelectCards.java -text
src/main/java/forge/control/input/InputSelectCardsFromList.java -text src/main/java/forge/control/input/InputSelectCardsFromList.java -text
src/main/java/forge/control/input/InputSelectMany.java -text src/main/java/forge/control/input/InputSelectMany.java -text

View File

@@ -106,12 +106,12 @@ public class FThreads {
Runnable toRun = proc; Runnable toRun = proc;
if( lockUI ) { if( lockUI ) {
// checkEDT("FThreads.invokeInNewthread", true) // checkEDT("FThreads.invokeInNewthread", true)
Singletons.getModel().getMatch().getInput().lock(); Singletons.getControl().getMatch().getInput().lock();
toRun = new Runnable() { toRun = new Runnable() {
@Override @Override
public void run() { public void run() {
proc.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) { public static void setInputAndWait(InputSynchronized input) {
Singletons.getModel().getMatch().getInput().setInput(input); Singletons.getControl().getMatch().getInput().setInput(input);
input.awaitLatchRelease(); input.awaitLatchRelease();
} }

View File

@@ -49,7 +49,7 @@ public class RestartGameEffect extends SpellAbilityEffect {
playerLibraries.put(p, newLibrary); playerLibraries.put(p, newLibrary);
} }
GameNew.restartGame(Singletons.getModel().getMatch(), game, sa.getActivatingPlayer(), playerLibraries); GameNew.restartGame(Singletons.getControl().getMatch(), game, sa.getActivatingPlayer(), playerLibraries);
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -31,7 +31,6 @@ import forge.FThreads;
import forge.CardPredicates.Presets; import forge.CardPredicates.Presets;
import forge.Command; import forge.Command;
import forge.CounterType; import forge.CounterType;
import forge.Singletons;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.card.spellability.Ability; import forge.card.spellability.Ability;
@@ -349,8 +348,6 @@ public class CardFactoryCreatures {
} else { } else {
game.getAction().sacrifice(card, null); game.getAction().sacrifice(card, null);
} }
Singletons.getModel().getMatch().getInput().setInput(target);
} }
} // end resolve } // end resolve
}; // end sacOrSac }; // end sacOrSac

View File

@@ -33,6 +33,7 @@ import javax.swing.WindowConstants;
import forge.Singletons; import forge.Singletons;
import forge.control.KeyboardShortcuts.Shortcut; import forge.control.KeyboardShortcuts.Shortcut;
import forge.game.MatchController;
import forge.game.ai.AiProfileUtil; import forge.game.ai.AiProfileUtil;
import forge.game.player.HumanPlayer; import forge.game.player.HumanPlayer;
import forge.gui.SOverlayUtils; import forge.gui.SOverlayUtils;
@@ -112,7 +113,7 @@ public enum FControl {
public void windowClosing(final WindowEvent e) { public void windowClosing(final WindowEvent e) {
Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
if (!Singletons.getModel().getMatch().getCurrentGame().isGameOver()) if (!getMatch().getCurrentGame().isGameOver())
CDock.SINGLETON_INSTANCE.concede(); CDock.SINGLETON_INSTANCE.concede();
else { else {
Singletons.getControl().changeState(FControl.Screens.HOME_SCREEN); Singletons.getControl().changeState(FControl.Screens.HOME_SCREEN);
@@ -326,4 +327,12 @@ public enum FControl {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return server; 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().setCombat(!game.getCombat().getAttackers().isEmpty());
game.getPhaseHandler().setPlayersPriorityPermission(false); game.getPhaseHandler().setPlayersPriorityPermission(false);
Singletons.getModel().getMatch().getInput().updateObservers(); Singletons.getControl().getMatch().getInput().updateObservers();
} }
@Override @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) // Removes this input from the stack and releases any latches (in synchronous imports)
protected final void stop() { protected final void stop() {
// clears a "temp" Input like Input_PayManaCost if there is one // 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 afterStop(); // sync inputs will release their latch there
} }
protected final boolean isActive() { protected final boolean isActive() {
return Singletons.getModel().getMatch().getInput().getInput() == this; return Singletons.getControl().getMatch().getInput().getInput() == this;
} }
protected void afterStop() { } protected void afterStop() { }

View File

@@ -51,7 +51,7 @@ public class InputLockUI implements Input {
}; };
protected final boolean isActive() { protected final boolean isActive() {
return Singletons.getModel().getMatch().getInput().getInput() == this; return Singletons.getControl().getMatch().getInput().getInput() == this;
} }
protected void showMessage(String message) { protected void showMessage(String message) {

View File

@@ -41,14 +41,14 @@ import forge.util.MyObservable;
* @author Forge * @author Forge
* @version $Id$ * @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>. */ /** Constant <code>serialVersionUID=3955194449319994301L</code>. */
private static final long serialVersionUID = 3955194449319994301L; private static final long serialVersionUID = 3955194449319994301L;
private final BlockingDeque<Input> inputStack = new LinkedBlockingDeque<Input>(); private final BlockingDeque<Input> inputStack = new LinkedBlockingDeque<Input>();
private final MatchController match; private final MatchController match;
public InputControl(MatchController matchController) { public InputQueue(MatchController matchController) {
match = 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) { public final Card moveTo(final ZoneType name, final Card c, final int libPosition) {
// Call specific functions to set PlayerZone, then move onto moveTo // Call specific functions to set PlayerZone, then move onto moveTo
if (name.equals(ZoneType.Hand)) { switch(name) {
return this.moveToHand(c); case Hand: return this.moveToHand(c);
} else if (name.equals(ZoneType.Library)) { case Library: return this.moveToLibrary(c, libPosition);
return this.moveToLibrary(c, libPosition); case Battlefield: return this.moveToPlay(c);
} else if (name.equals(ZoneType.Battlefield)) { case Graveyard: return this.moveToGraveyard(c);
return this.moveToPlay(c); case Exile: return this.exile(c);
} else if (name.equals(ZoneType.Graveyard)) { case Ante: return this.moveTo(c.getOwner().getZone(ZoneType.Ante), c);
return this.moveToGraveyard(c); case Command: return this.moveTo(c.getOwner().getZone(ZoneType.Command), c);
} else if (name.equals(ZoneType.Exile)) { default: return this.moveToStack(c);
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);
} }
} }

View File

@@ -9,8 +9,6 @@ import java.util.Map.Entry;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import javax.swing.JOptionPane;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
@@ -19,20 +17,19 @@ import com.google.common.collect.Lists;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.CardPredicates; import forge.CardPredicates;
import forge.Singletons; import forge.card.trigger.Trigger;
import forge.card.trigger.TriggerHandler; import forge.card.trigger.TriggerHandler;
import forge.card.trigger.TriggerType; import forge.card.trigger.TriggerType;
import forge.deck.CardPool; import forge.deck.CardPool;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.game.event.FlipCoinEvent;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.player.AIPlayer; import forge.game.player.AIPlayer;
import forge.game.player.LobbyPlayer; import forge.game.player.LobbyPlayer;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.match.views.VAntes; import forge.gui.GuiDialog;
import forge.item.CardDb; import forge.item.CardDb;
import forge.item.CardPrinted; import forge.item.CardPrinted;
import forge.item.IPaperCard; import forge.item.IPaperCard;
@@ -40,6 +37,7 @@ import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.util.Aggregates; import forge.util.Aggregates;
import forge.util.MyRandom; import forge.util.MyRandom;
import forge.util.TextUtil;
/** /**
* Methods for all things related to starting a new game. * Methods for all things related to starting a new game.
@@ -47,7 +45,59 @@ import forge.util.MyRandom;
*/ */
public class GameNew { 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) { private static void preparePlayerLibrary(Player player, final ZoneType zoneType, CardPool secion, boolean canRandomFoil, Random generator) {
PlayerZone library = player.getZone(zoneType); PlayerZone library = player.getZone(zoneType);
@@ -79,283 +129,6 @@ public class GameNew {
} }
} }
/**
* Constructor for new game allowing card lists to be put into play
* immediately, and life totals to be adjusted, for computer and human.
*
* 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) {
Card.resetUniqueNumber();
// need this code here, otherwise observables fail
forge.card.trigger.Trigger.resetIDs();
TriggerHandler trigHandler = game.getTriggerHandler();
trigHandler.clearDelayedTrigger();
// friendliness
boolean useAnte = preferences.getPrefBoolean(FPref.UI_ANTE);
final Set<CardPrinted> rAICards = new HashSet<CardPrinted>();
Map<Player, Set<CardPrinted>> removedAnteCards = new HashMap<Player, Set<CardPrinted>>();
for (Entry<Player, PlayerStartConditions> p : playersConditions.entrySet()) {
final Player player = p.getKey();
final PlayerStartConditions psc = p.getValue();
player.setStartingLife(psc.getStartingLife());
player.setMaxHandSize(psc.getStartingHand());
player.setStartingHandSize(psc.getStartingHand());
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) {
Deck sideboarded = player.getController().sideboard(psc.getCurrentDeck(), gameType);
psc.setCurrentDeck(sideboarded);
} else {
psc.restoreOriginalDeck();
}
Deck myDeck = psc.getCurrentDeck();
Set<CardPrinted> myRemovedAnteCards = useAnte ? null : getRemovedAnteCards(myDeck);
Random generator = MyRandom.getRandom();
preparePlayerLibrary(player, ZoneType.Library, myDeck.getMain(), canRandomFoil, generator);
if(hasSideboard)
preparePlayerLibrary(player, ZoneType.Sideboard, myDeck.get(DeckSection.Sideboard), canRandomFoil, generator);
// Shuffling
if (player instanceof AIPlayer && preferences.getPrefBoolean(FPref.UI_SMOOTH_LAND)) {
// AI may do this instead of shuffling its deck
final Iterable<Card> c1 = GameNew.smoothComputerManaCurve(player.getCardsIn(ZoneType.Library));
player.getZone(ZoneType.Library).setCards(c1);
} else {
player.shuffle();
}
if(player instanceof AIPlayer) {
rAICards.addAll(getCardsAiCantPlayWell(myDeck));
}
player.updateObservers();
player.getZone(ZoneType.Battlefield).updateObservers();
player.getZone(ZoneType.Hand).updateObservers();
player.getZone(ZoneType.Command).updateObservers();
player.getZone(ZoneType.Battlefield).updateObservers();
if( myRemovedAnteCards != null && !myRemovedAnteCards.isEmpty() )
removedAnteCards.put(player, myRemovedAnteCards);
}
if (rAICards.size() > 0) {
String message = 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);
}
}
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()));
}
JOptionPane.showMessageDialog(null, ante.toString(), "", JOptionPane.INFORMATION_MESSAGE);
}
// Deciding which cards go to ante
if (preferences.getPrefBoolean(FPref.UI_ANTE)) {
final String nl = System.getProperty("line.separator");
final StringBuilder msg = new StringBuilder();
for (final Player p : game.getPlayers()) {
final List<Card> lib = p.getCardsIn(ZoneType.Library);
Predicate<Card> goodForAnte = Predicates.not(CardPredicates.Presets.BASIC_LANDS);
Card ante = Aggregates.random(Iterables.filter(lib, goodForAnte));
if (ante == null) {
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);
}
determineFirstTurnPlayer(match.getLastGameOutcome(), game);
// Draw <handsize> cards
for (final Player p1 : game.getPlayers()) {
p1.drawCards(p1.getMaxHandSize());
}
}
// ultimate of Karn the Liberated
public static void restartGame(final MatchController match, final GameState game, final Player startingTurn, Map<Player, List<Card>> playerLibraries) {
Map<LobbyPlayer, PlayerStartConditions> players = match.getPlayers();
Map<Player, PlayerStartConditions> playersConditions = new HashMap<Player, PlayerStartConditions>();
for (Player p : game.getPlayers()) {
playersConditions.put(p, players.get(p.getLobbyPlayer()));
}
game.setAge(GameAge.Mulligan);
match.getInput().clearInput();
//Card.resetUniqueNumber();
// need this code here, otherwise observables fail
forge.card.trigger.Trigger.resetIDs();
TriggerHandler trigHandler = game.getTriggerHandler();
trigHandler.clearDelayedTrigger();
trigHandler.cleanUpTemporaryTriggers();
trigHandler.suppressMode(TriggerType.ChangesZone);
game.getStack().reset();
GameAction action = game.getAction();
for (Entry<Player, PlayerStartConditions> p : playersConditions.entrySet()) {
final Player player = p.getKey();
player.setStartingLife(p.getValue().getStartingLife());
player.setNumLandsPlayed(0);
putCardsOnBattlefield(player, p.getValue().getCardsOnBattlefield(player));
PlayerZone library = player.getZone(ZoneType.Library);
List<Card> newLibrary = playerLibraries.get(player);
for (Card c : newLibrary) {
action.moveTo(library, c);
}
player.shuffle();
player.getZone(ZoneType.Battlefield).updateObservers();
player.updateObservers();
player.getZone(ZoneType.Hand).updateObservers();
}
trigHandler.clearSuppression(TriggerType.ChangesZone);
PhaseHandler phaseHandler = game.getPhaseHandler();
phaseHandler.setPlayerTurn(startingTurn);
// Draw <handsize> cards
for (final Player p : game.getPlayers()) {
p.drawCards(p.getMaxHandSize());
}
}
/**
* 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 // this is where the computer cheats
// changes AllZone.getComputerPlayer().getZone(Zone.Library) // changes AllZone.getComputerPlayer().getZone(Zone.Library)
@@ -412,19 +185,196 @@ public class GameNew {
return library; return library;
} // smoothComputerManaCurve() } // smoothComputerManaCurve()
// decides who goes first when starting another game, used by newGame() 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;
}
/** /**
* <p> * Constructor for new game allowing card lists to be put into play
* seeWhoPlaysFirstCoinToss. * immediately, and life totals to be adjusted, for computer and human.
* </p> *
* @return * TODO: Accept something like match state as parameter. Match should be aware of players,
* their decks and other special starting conditions.
*/ */
private static Player seeWhoPlaysFirstDice(final GameState game) { public static void newGame(final GameState game, final boolean canRandomFoil) {
// Play the Flip Coin sound
game.getEvents().post(new FlipCoinEvent());
List<Player> allPlayers = game.getPlayers(); Card.resetUniqueNumber();
return allPlayers.get(MyRandom.getRandom().nextInt(allPlayers.size())); // need this code here, otherwise observables fail
Trigger.resetIDs();
TriggerHandler trigHandler = game.getTriggerHandler();
trigHandler.clearDelayedTrigger();
// friendliness
boolean useAnte = preferences.getPrefBoolean(FPref.UI_ANTE);
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();
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));
initVariantsZones(player, psc);
boolean hasSideboard = psc.getOriginalDeck().has(DeckSection.Sideboard);
if (canSideBoard && hasSideboard) {
Deck sideboarded = player.getController().sideboard(psc.getCurrentDeck(), gameType);
psc.setCurrentDeck(sideboarded);
} else {
psc.restoreOriginalDeck();
}
Deck myDeck = psc.getCurrentDeck();
Set<CardPrinted> myRemovedAnteCards = useAnte ? null : getRemovedAnteCards(myDeck);
Random generator = MyRandom.getRandom();
preparePlayerLibrary(player, ZoneType.Library, myDeck.getMain(), canRandomFoil, generator);
if(hasSideboard)
preparePlayerLibrary(player, ZoneType.Sideboard, myDeck.get(DeckSection.Sideboard), canRandomFoil, generator);
// Shuffling
if (player instanceof AIPlayer && preferences.getPrefBoolean(FPref.UI_SMOOTH_LAND)) {
// AI may do this instead of shuffling its deck
final Iterable<Card> c1 = GameNew.smoothComputerManaCurve(player.getCardsIn(ZoneType.Library));
player.getZone(ZoneType.Library).setCards(c1);
} else {
player.shuffle();
} }
if(player instanceof AIPlayer) {
rAICards.addAll(getCardsAiCantPlayWell(myDeck));
}
player.updateObservers();
player.getZone(ZoneType.Battlefield).updateObservers();
player.getZone(ZoneType.Hand).updateObservers();
player.getZone(ZoneType.Command).updateObservers();
player.getZone(ZoneType.Battlefield).updateObservers();
if( myRemovedAnteCards != null && !myRemovedAnteCards.isEmpty() )
removedAnteCards.put(player, myRemovedAnteCards);
}
if (rAICards.size() > 0) {
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 {
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(TextUtil.buildFourColumnList("From the " + ants.getKey().getName() + "'s deck:", ants.getValue()));
}
GuiDialog.message(ante.toString());
}
// Deciding which cards go to ante
if (preferences.getPrefBoolean(FPref.UI_ANTE)) {
final String nl = System.getProperty("line.separator");
final StringBuilder msg = new StringBuilder();
for (final Player p : game.getPlayers()) {
final List<Card> lib = p.getCardsIn(ZoneType.Library);
Predicate<Card> goodForAnte = Predicates.not(CardPredicates.Presets.BASIC_LANDS);
Card ante = Aggregates.random(Iterables.filter(lib, goodForAnte));
if (ante == null) {
throw new RuntimeException(p + " library is empty.");
}
game.getGameLog().add("Ante", p + " anted " + ante, 0);
game.getAction().moveTo(ZoneType.Ante, ante);
msg.append(p.getName()).append(" ante: ").append(ante).append(nl);
}
GuiDialog.message(msg.toString(), "Ante");
}
// Draw <handsize> cards
for (final Player p1 : game.getPlayers()) {
p1.drawCards(p1.getMaxHandSize());
}
}
// ultimate of Karn the Liberated
public static void restartGame(final MatchController match, final GameState game, final Player startingTurn, Map<Player, List<Card>> playerLibraries) {
Map<LobbyPlayer, PlayerStartConditions> players = match.getPlayers();
Map<Player, PlayerStartConditions> playersConditions = new HashMap<Player, PlayerStartConditions>();
for (Player p : game.getPlayers()) {
playersConditions.put(p, players.get(p.getLobbyPlayer()));
}
game.setAge(GameAge.Mulligan);
match.getInput().clearInput();
//Card.resetUniqueNumber();
// need this code here, otherwise observables fail
forge.card.trigger.Trigger.resetIDs();
TriggerHandler trigHandler = game.getTriggerHandler();
trigHandler.clearDelayedTrigger();
trigHandler.cleanUpTemporaryTriggers();
trigHandler.suppressMode(TriggerType.ChangesZone);
game.getStack().reset();
GameAction action = game.getAction();
for (Entry<Player, PlayerStartConditions> p : playersConditions.entrySet()) {
final Player player = p.getKey();
player.setStartingLife(p.getValue().getStartingLife());
player.setNumLandsPlayed(0);
putCardsOnBattlefield(player, p.getValue().getCardsOnBattlefield(player));
PlayerZone library = player.getZone(ZoneType.Library);
List<Card> newLibrary = playerLibraries.get(player);
for (Card c : newLibrary) {
action.moveTo(library, c);
}
player.shuffle();
player.getZone(ZoneType.Battlefield).updateObservers();
player.updateObservers();
player.getZone(ZoneType.Hand).updateObservers();
}
trigHandler.clearSuppression(TriggerType.ChangesZone);
PhaseHandler phaseHandler = game.getPhaseHandler();
phaseHandler.setPlayerTurn(startingTurn);
// Draw <handsize> cards
for (final Player p : game.getPlayers()) {
p.drawCards(p.getMaxHandSize());
}
}
// this is where the computer cheats
// changes AllZone.getComputerPlayer().getZone(Zone.Library)
} }

View File

@@ -94,13 +94,14 @@ public class GameState {
*/ */
public GameState(Iterable<LobbyPlayer> players2, GameType t, MatchController match0) { /* no more zones to map here */ public GameState(Iterable<LobbyPlayer> players2, GameType t, MatchController match0) { /* no more zones to map here */
type = t; type = t;
match = match0;
List<Player> players = new ArrayList<Player>(); List<Player> players = new ArrayList<Player>();
for (LobbyPlayer p : players2) { for (LobbyPlayer p : players2) {
Player pl = p.getPlayer(this); Player pl = p.getPlayer(this);
players.add(pl); players.add(pl);
ingamePlayers.add(pl); ingamePlayers.add(pl);
} }
match = match0;
allPlayers = Collections.unmodifiableList(players); allPlayers = Collections.unmodifiableList(players);
roIngamePlayers = Collections.unmodifiableList(ingamePlayers); roIngamePlayers = Collections.unmodifiableList(ingamePlayers);
action = new GameAction(this); action = new GameAction(this);
@@ -116,11 +117,10 @@ public class GameState {
if ( match0.getGameType() == GameType.Quest) if ( match0.getGameType() == GameType.Quest)
events.register(Singletons.getModel().getQuest()); // this one listens to player's mulligans ATM events.register(Singletons.getModel().getQuest()); // this one listens to player's mulligans ATM
events.register(Singletons.getControl().getSoundSystem());
events.register(gameLog); events.register(gameLog);
} }
/** /**
* Gets the players who are still fighting to win. * Gets the players who are still fighting to win.
* *
@@ -455,10 +455,14 @@ public class GameState {
return colorChanger; return colorChanger;
} }
public GameAction getAction() { public final GameAction getAction() {
return action; return action;
} }
public final MatchController getMatch() {
return match;
}
/** /**
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.
* @param playerTurn * @param playerTurn

View File

@@ -7,22 +7,24 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import javax.swing.JOptionPane;
import forge.Constant.Preferences; import forge.Constant.Preferences;
import forge.FThreads; import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.card.trigger.TriggerType; import forge.card.trigger.TriggerType;
import forge.control.FControl; import forge.control.FControl;
import forge.control.input.InputControl; import forge.control.input.InputQueue;
import forge.deck.Deck; import forge.deck.Deck;
import forge.error.BugReporter; import forge.error.BugReporter;
import forge.game.ai.AiProfileUtil;
import forge.game.event.DuelOutcomeEvent; import forge.game.event.DuelOutcomeEvent;
import forge.game.player.AIPlayer; import forge.game.event.FlipCoinEvent;
import forge.game.player.HumanPlayer; import forge.game.player.HumanPlayer;
import forge.game.player.LobbyPlayer; import forge.game.player.LobbyPlayer;
import forge.game.player.LobbyPlayerHuman; import forge.game.player.LobbyPlayerHuman;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerStatistics; import forge.game.player.PlayerStatistics;
import forge.game.zone.ZoneType;
import forge.gui.InputProxy; import forge.gui.InputProxy;
import forge.gui.framework.EDocID; import forge.gui.framework.EDocID;
import forge.gui.framework.SDisplayUtil; 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.nonsingleton.VField;
import forge.gui.match.views.VAntes; import forge.gui.match.views.VAntes;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.util.MyRandom;
/** /**
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
@@ -46,7 +49,7 @@ import forge.properties.ForgePreferences.FPref;
public class MatchController { public class MatchController {
private final Map<LobbyPlayer, PlayerStartConditions> players = new HashMap<LobbyPlayer, PlayerStartConditions>(); 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 gamesPerMatch = 3;
private int gamesToWinMatch = 2; private int gamesToWinMatch = 2;
@@ -56,10 +59,15 @@ public class MatchController {
private final List<GameOutcome> gamesPlayed = new ArrayList<GameOutcome>(); private final List<GameOutcome> gamesPlayed = new ArrayList<GameOutcome>();
private final List<GameOutcome> gamesPlayedRo; 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); gamesPlayedRo = Collections.unmodifiableList(gamesPlayed);
players.putAll(map);
gameType = type;
} }
/** /**
@@ -133,7 +141,7 @@ public class MatchController {
*/ */
public void startRound() { public void startRound() {
input = new InputControl(this); inputQueue = new InputQueue(this);
currentGame = new GameState(players.keySet(), gameType, this); currentGame = new GameState(players.keySet(), gameType, this);
Map<Player, PlayerStartConditions> startConditions = new HashMap<Player, PlayerStartConditions>(); Map<Player, PlayerStartConditions> startConditions = new HashMap<Player, PlayerStartConditions>();
@@ -141,30 +149,33 @@ public class MatchController {
startConditions.put(p, players.get(p.getLobbyPlayer())); startConditions.put(p, players.get(p.getLobbyPlayer()));
} }
// Set the current AI profile. try {
for (Player p : currentGame.getPlayers()) { attachUiToMatch(this, FControl.SINGLETON_INSTANCE.getLobby().getGuiPlayer());
if ( !(p instanceof AIPlayer))
continue;
AIPlayer ai = (AIPlayer) p;
String currentAiProfile = Singletons.getModel().getPreferences().getPref(FPref.UI_CURRENT_AI_PROFILE); final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL) && gameType == GameType.Constructed;
String lastProfileChosen = this.getPlayedGames().isEmpty() ? currentAiProfile : ai.getLobbyPlayer().getAiProfile(); GameNew.newGame(currentGame, canRandomFoil);
determineFirstTurnPlayer(getLastGameOutcome(), currentGame);
// TODO: implement specific AI profiles for quest mode. currentGame.setAge(GameAge.Mulligan);
boolean wantRandomProfile = currentAiProfile.equals(AiProfileUtil.AI_PROFILE_RANDOM_DUEL) getInput().clearInput();
|| (this.getPlayedGames().isEmpty() && currentAiProfile.equals(AiProfileUtil.AI_PROFILE_RANDOM_MATCH));
String profileToSet = wantRandomProfile ? AiProfileUtil.getRandomProfile() : lastProfileChosen; // Update observers
currentGame.getGameLog().updateObservers();
ai.getLobbyPlayer().setAiProfile(profileToSet); } catch (Exception e) {
System.out.println(String.format("AI profile %s was chosen for the lobby player %s.", ai.getLobbyPlayer().getAiProfile(), ai.getLobbyPlayer().getName())); BugReporter.reportException(e);
} }
try { }
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; HumanPlayer localHuman = null;
for(Player p : currentGame.getPlayers()) { for(Player p : currentGame.getPlayers()) {
if ( p.getLobbyPlayer() != FControl.SINGLETON_INSTANCE.getLobby().getGuiPlayer()) if ( p.getLobbyPlayer() != humanLobbyPlayer)
continue; continue;
localHuman = (HumanPlayer) p; localHuman = (HumanPlayer) p;
break; break;
@@ -176,7 +187,7 @@ public class MatchController {
// The UI controls should use these game data as models // The UI controls should use these game data as models
CMatchUI.SINGLETON_INSTANCE.initMatch(currentGame.getRegisteredPlayers(), localHuman); CMatchUI.SINGLETON_INSTANCE.initMatch(currentGame.getRegisteredPlayers(), localHuman);
CDock.SINGLETON_INSTANCE.onGameStarts(currentGame, localHuman); CDock.SINGLETON_INSTANCE.setModel(currentGame, localHuman);
CStack.SINGLETON_INSTANCE.setModel(currentGame.getStack()); CStack.SINGLETON_INSTANCE.setModel(currentGame.getStack());
CLog.SINGLETON_INSTANCE.setModel(currentGame.getGameLog()); CLog.SINGLETON_INSTANCE.setModel(currentGame.getGameLog());
CCombat.SINGLETON_INSTANCE.setModel(currentGame); CCombat.SINGLETON_INSTANCE.setModel(currentGame);
@@ -185,55 +196,27 @@ public class MatchController {
Singletons.getControl().changeState(FControl.Screens.MATCH_SCREEN); Singletons.getControl().changeState(FControl.Screens.MATCH_SCREEN);
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc()); SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
// black magic still
InputProxy inputProxy = CMessage.SINGLETON_INSTANCE.getInputControl(); InputProxy inputProxy = CMessage.SINGLETON_INSTANCE.getInputControl();
inputProxy.setMatch(this); inputProxy.setMatch(match);
input.addObserver(inputProxy);
// models shall notify controllers of changes // models shall notify controllers of changes
currentGame.getStack().addObserver(inputProxy); currentGame.getStack().addObserver(inputProxy);
currentGame.getStack().addObserver(CStack.SINGLETON_INSTANCE); currentGame.getStack().addObserver(CStack.SINGLETON_INSTANCE);
currentGame.getPhaseHandler().addObserver(inputProxy); currentGame.getPhaseHandler().addObserver(inputProxy);
currentGame.getGameLog().addObserver(CLog.SINGLETON_INSTANCE); currentGame.getGameLog().addObserver(CLog.SINGLETON_INSTANCE);
// some observers are set in CMatchUI.initMatch // some observers were set in CMatchUI.initMatch
// black magic still
match.getInput().addObserver(inputProxy);
VAntes.SINGLETON_INSTANCE.setModel(currentGame.getRegisteredPlayers());
final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL) && gameType == GameType.Constructed;
GameNew.newGame(this, startConditions, currentGame, canRandomFoil);
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()) { for (final VField field : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) {
field.getLblLibrary().setHoverable(Preferences.DEV_MODE); field.getLblLibrary().setHoverable(Preferences.DEV_MODE);
} }
if (this.getPlayedGames().isEmpty()) {
VAntes.SINGLETON_INSTANCE.clearAnteCards();
}
// per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch // per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch
CMessage.SINGLETON_INSTANCE.updateGameInfo(match);
CMessage.SINGLETON_INSTANCE.updateGameInfo(this);
// Update observers
currentGame.getGameLog().updateObservers();
} catch (Exception e) {
BugReporter.reportException(e);
}
}
/**
* This should become constructor once.
*/
public void initMatch(GameType type, Map<LobbyPlayer, PlayerStartConditions> map) {
gamesPlayed.clear();
players.clear();
players.putAll(map);
gameType = type;
} }
/** /**
@@ -345,8 +328,8 @@ public class MatchController {
return players; return players;
} }
public final InputControl getInput() { public final InputQueue getInput() {
return input; return inputQueue;
} }
/** /**
@@ -366,4 +349,44 @@ public class MatchController {
currentGame.setAge(GameAge.Play); currentGame.setAge(GameAge.Play);
getInput().clearInput(); 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); game.getPhaseHandler().setPlayersPriorityPermission(false);
// was not added to stack, so will be replaced by plain update // 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 java.util.List;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby; import forge.control.Lobby;
import forge.deck.Deck; 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();
@Override
public Object doInBackground() {
MatchStartHelper starter = new MatchStartHelper();
Lobby lobby = Singletons.getControl().getLobby(); Lobby lobby = Singletons.getControl().getLobby();
starter.addPlayer(lobby.getGuiPlayer(), humanDeck); starter.addPlayer(lobby.getGuiPlayer(), humanDeck);
starter.addPlayer(lobby.getAiPlayer(), aiOpponents.get(currentRound - 1)); starter.addPlayer(lobby.getAiPlayer(), aiOpponents.get(currentRound - 1));
MatchController mc = Singletons.getModel().getMatch(); final MatchController mc = new MatchController(gauntletType, starter.getPlayerMap());
mc.initMatch(gauntletType, starter.getPlayerMap()); FThreads.invokeInEdtLater(new Runnable(){
mc.startRound();
return null;
}
@Override @Override
public void done() { public void run() {
mc.startRound();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}; });
worker.execute();
} }

View File

@@ -753,8 +753,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
} else { } else {
// pass the priority to other player // pass the priority to other player
this.pPlayerPriority = nextPlayer; this.pPlayerPriority = nextPlayer;
Singletons.getModel().getMatch().getInput().updateObservers(); updateObservers();
} }
} }

View File

@@ -86,7 +86,7 @@ public class PhaseUtil {
final PhaseHandler ph = game.getPhaseHandler(); final PhaseHandler ph = game.getPhaseHandler();
final Player turn = ph.getPlayerTurn(); final Player turn = ph.getPlayerTurn();
CMessage.SINGLETON_INSTANCE.updateGameInfo(Singletons.getModel().getMatch()); CMessage.SINGLETON_INSTANCE.updateGameInfo(Singletons.getControl().getMatch());
game.getCombat().reset(turn); game.getCombat().reset(turn);

View File

@@ -1,6 +1,9 @@
package forge.game.player; package forge.game.player;
import forge.Singletons;
import forge.game.GameState; import forge.game.GameState;
import forge.game.ai.AiProfileUtil;
import forge.properties.ForgePreferences.FPref;
public class LobbyPlayerAi extends LobbyPlayer { public class LobbyPlayerAi extends LobbyPlayer {
public LobbyPlayerAi(String name) { public LobbyPlayerAi(String name) {
@@ -24,7 +27,18 @@ public class LobbyPlayerAi extends LobbyPlayer {
@Override @Override
public Player getPlayer(GameState game) { 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 @Override

View File

@@ -88,14 +88,11 @@ public class PlayerZone extends Zone {
c.addObserver(this); c.addObserver(this);
c.setTurnInZone(c.getGame().getPhaseHandler().getTurn()); c.setTurnInZone(c.getGame().getPhaseHandler().getTurn());
this.cardList.add(c);
if (!this.is(ZoneType.Battlefield)) { if (!this.is(ZoneType.Battlefield)) {
c.setTapped(false); c.setTapped(false);
} } else if (update) { // setTapped has already called update once
this.cardList.add(c);
if (update) {
this.update(); this.update();
} }
} }

View File

@@ -690,7 +690,7 @@ public final class GuiDisplayUtil {
} }
private static GameState getGame() { private static GameState getGame() {
return Singletons.getModel().getMatch().getCurrentGame(); return Singletons.getControl().getMatch().getCurrentGame();
} }
} // end class GuiDisplayUtil } // end class GuiDisplayUtil

View File

@@ -12,11 +12,10 @@ import java.util.List;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import forge.Command; import forge.Command;
import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby; import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
@@ -245,10 +244,6 @@ public enum CSubmenuGauntletContests implements ICDoc {
} }
}); });
final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() {
@Override
public Object doInBackground() {
final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData();
Deck aiDeck = gd.getDecks().get(gd.getCompleted()); Deck aiDeck = gd.getDecks().get(gd.getCompleted());
MatchStartHelper starter = new MatchStartHelper(); MatchStartHelper starter = new MatchStartHelper();
@@ -257,18 +252,14 @@ public enum CSubmenuGauntletContests implements ICDoc {
starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck()); starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck());
starter.addPlayer(lobby.getAiPlayer(), aiDeck); starter.addPlayer(lobby.getAiPlayer(), aiDeck);
MatchController mc = Singletons.getModel().getMatch(); final MatchController mc = new MatchController(GameType.Gauntlet, starter.getPlayerMap());
mc.initMatch(GameType.Gauntlet, starter.getPlayerMap()); FThreads.invokeInEdtLater(new Runnable(){
mc.startRound();
return null;
}
@Override @Override
public void done() { public void run() {
mc.startRound();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}; });
worker.execute();
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -8,9 +8,8 @@ import java.util.List;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import forge.Command; import forge.Command;
import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby; import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
@@ -107,9 +106,6 @@ 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 GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData();
final Deck aiDeck = gd.getDecks().get(gd.getCompleted()); final Deck aiDeck = gd.getDecks().get(gd.getCompleted());
@@ -118,18 +114,14 @@ public enum CSubmenuGauntletLoad implements ICDoc {
starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck()); starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck());
starter.addPlayer(lobby.getAiPlayer(), aiDeck); starter.addPlayer(lobby.getAiPlayer(), aiDeck);
MatchController mc = Singletons.getModel().getMatch(); final MatchController mc = new MatchController(GameType.Gauntlet, starter.getPlayerMap());
mc.initMatch(GameType.Gauntlet, starter.getPlayerMap()); FThreads.invokeInEdtLater(new Runnable(){
mc.startRound();
return null;
}
@Override @Override
public void done() { public void run() {
mc.startRound();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}; });
worker.execute();
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -14,11 +14,10 @@ import java.util.Set;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import forge.Command; import forge.Command;
import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby; import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
@@ -288,12 +287,9 @@ public enum CSubmenuGauntletQuick implements ICDoc {
// Reset all variable fields to 0, stamps and saves automatically. // Reset all variable fields to 0, stamps and saves automatically.
FModel.SINGLETON_INSTANCE.getGauntletData().reset(); FModel.SINGLETON_INSTANCE.getGauntletData().reset();
FModel.SINGLETON_INSTANCE.getGauntletData() FModel.SINGLETON_INSTANCE.getGauntletData().setUserDeck(userDeck);
.setUserDeck(userDeck);
final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() {
@Override
public Object doInBackground() {
final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData();
final Deck aiDeck = gd.getDecks().get(gd.getCompleted()); final Deck aiDeck = gd.getDecks().get(gd.getCompleted());
@@ -303,18 +299,14 @@ public enum CSubmenuGauntletQuick implements ICDoc {
starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck()); starter.addPlayer(lobby.getGuiPlayer(), gd.getUserDeck());
starter.addPlayer(lobby.getAiPlayer(), aiDeck); starter.addPlayer(lobby.getAiPlayer(), aiDeck);
MatchController mc = Singletons.getModel().getMatch(); final MatchController mc = new MatchController(GameType.Gauntlet, starter.getPlayerMap());
mc.initMatch(GameType.Gauntlet, starter.getPlayerMap()); FThreads.invokeInEdtLater(new Runnable(){
mc.startRound();
return null;
}
@Override @Override
public void done() { public void run() {
mc.startRound();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}; });
worker.execute();
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -11,11 +11,13 @@ import javax.swing.SwingWorker;
import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.ImmutablePair;
import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.card.CardEdition; import forge.card.CardEdition;
import forge.control.FControl; import forge.control.FControl;
import forge.deck.Deck; import forge.deck.Deck;
import forge.game.GameType; import forge.game.GameType;
import forge.game.MatchController;
import forge.game.MatchStartHelper; import forge.game.MatchStartHelper;
import forge.game.PlayerStartConditions; import forge.game.PlayerStartConditions;
import forge.game.player.LobbyPlayer; import forge.game.player.LobbyPlayer;
@@ -417,8 +419,14 @@ public class SSubmenuQuestUtil {
aiPlayer.setIconImageKey(event.getIconImageKey()); aiPlayer.setIconImageKey(event.getIconImageKey());
msh.addPlayer(aiPlayer, aiStart); msh.addPlayer(aiPlayer, aiStart);
Singletons.getModel().getMatch().initMatch(GameType.Quest, msh.getPlayerMap()); final MatchController mc = new MatchController(GameType.Quest, msh.getPlayerMap());
Singletons.getModel().getMatch().startRound(); FThreads.invokeInEdtLater(new Runnable(){
@Override
public void run() {
mc.startRound();
// no overlays here?
}
});
} }
/** Duplicate in DeckEditorQuestMenu and /** Duplicate in DeckEditorQuestMenu and

View File

@@ -5,9 +5,8 @@ import java.awt.event.ActionListener;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import forge.Command; import forge.Command;
import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby; import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
@@ -111,38 +110,22 @@ public enum CSubmenuConstructed implements ICDoc {
return; return;
} }
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SOverlayUtils.startGameOverlay(); SOverlayUtils.startGameOverlay();
SOverlayUtils.showOverlay(); SOverlayUtils.showOverlay();
}
});
final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() { final MatchStartHelper starter = new MatchStartHelper();
@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(); Lobby lobby = Singletons.getControl().getLobby();
starter.addPlayer(lobby.getGuiPlayer(), humanDeck); starter.addPlayer(lobby.getGuiPlayer(), humanDeck);
starter.addPlayer(lobby.getAiPlayer(), aiDeck); starter.addPlayer(lobby.getAiPlayer(), aiDeck);
final MatchController mc = new MatchController(gameType, starter.getPlayerMap());
MatchController mc = Singletons.getModel().getMatch(); FThreads.invokeInEdtLater(new Runnable(){
mc.initMatch(gameType, starter.getPlayerMap());
mc.startRound();
return null;
}
@Override @Override
public void done() { public void run() {
mc.startRound();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}; });
worker.execute();
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -8,9 +8,8 @@ import java.util.List;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import forge.Command; import forge.Command;
import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.control.FControl; import forge.control.FControl;
import forge.control.Lobby; import forge.control.Lobby;
@@ -124,9 +123,7 @@ public enum CSubmenuDraft implements ICDoc {
} }
}); });
final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() {
@Override
public Object doInBackground() {
DeckGroup opponentDecks = Singletons.getModel().getDecks().getDraft().get(humanDeck.getName()); DeckGroup opponentDecks = Singletons.getModel().getDecks().getDraft().get(humanDeck.getName());
Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex); Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex);
if (aiDeck == null) { if (aiDeck == null) {
@@ -138,19 +135,14 @@ public enum CSubmenuDraft implements ICDoc {
starter.addPlayer(lobby.getGuiPlayer(), humanDeck); starter.addPlayer(lobby.getGuiPlayer(), humanDeck);
starter.addPlayer(lobby.getAiPlayer(), aiDeck); starter.addPlayer(lobby.getAiPlayer(), aiDeck);
MatchController mc = Singletons.getModel().getMatch(); final MatchController mc = new MatchController(GameType.Draft, starter.getPlayerMap());
mc.initMatch(GameType.Draft, starter.getPlayerMap()); FThreads.invokeInEdtLater(new Runnable(){
mc.startRound();
return null;
}
@Override @Override
public void done() { public void run() {
mc.startRound();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}; });
worker.execute();
} }
/** */ /** */

View File

@@ -7,11 +7,10 @@ import java.util.List;
import java.util.Vector; import java.util.Vector;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import forge.Command; import forge.Command;
import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.control.FControl; import forge.control.FControl;
import forge.control.Lobby; import forge.control.Lobby;
@@ -156,17 +155,9 @@ public enum CSubmenuArchenemy implements ICDoc {
/** @param lists0 &emsp; {@link java.util.List}<{@link javax.swing.JList}> */ /** @param lists0 &emsp; {@link java.util.List}<{@link javax.swing.JList}> */
private void startGame() { private void startGame() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SOverlayUtils.startGameOverlay();
SOverlayUtils.showOverlay();
}
});
final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() {
@Override
public Object doInBackground() {
boolean usedDefaults = false; boolean usedDefaults = false;
List<Deck> playerDecks = new ArrayList<Deck>(); List<Deck> playerDecks = new ArrayList<Deck>();
@@ -176,7 +167,7 @@ public enum CSubmenuArchenemy implements ICDoc {
if (d == null) { if (d == null) {
//ERROR! //ERROR!
GuiDialog.message("No deck selected for player " + (i + 1)); GuiDialog.message("No deck selected for player " + (i + 1));
return null; return;
} }
playerDecks.add(d); playerDecks.add(d);
} }
@@ -215,7 +206,7 @@ public enum CSubmenuArchenemy implements ICDoc {
if (schemes == null) { if (schemes == null) {
//ERROR! //ERROR!
GuiDialog.message("No scheme deck selected!"); GuiDialog.message("No scheme deck selected!");
return null; return;
} }
if (usedDefaults) { if (usedDefaults) {
@@ -223,6 +214,10 @@ public enum CSubmenuArchenemy implements ICDoc {
GuiDialog.message("Using default scheme deck."); GuiDialog.message("Using default scheme deck.");
} }
// won't cancel after this point
SOverlayUtils.startGameOverlay();
SOverlayUtils.showOverlay();
Lobby lobby = Singletons.getControl().getLobby(); Lobby lobby = Singletons.getControl().getLobby();
MatchStartHelper helper = new MatchStartHelper(); MatchStartHelper helper = new MatchStartHelper();
for (int i = 0; i < view.getNumPlayers(); i++) { for (int i = 0; i < view.getNumPlayers(); i++) {
@@ -237,19 +232,16 @@ public enum CSubmenuArchenemy implements ICDoc {
helper.addPlayer(player, playerDecks.get(i)); helper.addPlayer(player, playerDecks.get(i));
} }
} }
MatchController mc = Singletons.getModel().getMatch();
mc.initMatch(GameType.Archenemy, helper.getPlayerMap());
mc.startRound();
return null;
}
final MatchController mc = new MatchController(GameType.Archenemy, helper.getPlayerMap());
FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void done() { public void run() {
mc.startRound();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}; });
worker.execute();
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -7,11 +7,10 @@ import java.util.List;
import java.util.Vector; import java.util.Vector;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import forge.Command; import forge.Command;
import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.control.FControl; import forge.control.FControl;
import forge.control.Lobby; import forge.control.Lobby;
@@ -149,18 +148,6 @@ public enum CSubmenuPlanechase implements ICDoc {
/** @param lists0 &emsp; {@link java.util.List}<{@link javax.swing.JList}> */ /** @param lists0 &emsp; {@link java.util.List}<{@link javax.swing.JList}> */
private void startGame() { private void startGame() {
SwingUtilities.invokeLater(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(); Lobby lobby = Singletons.getControl().getLobby();
MatchStartHelper helper = new MatchStartHelper(); MatchStartHelper helper = new MatchStartHelper();
List<Deck> playerDecks = new ArrayList<Deck>(); List<Deck> playerDecks = new ArrayList<Deck>();
@@ -170,7 +157,7 @@ public enum CSubmenuPlanechase implements ICDoc {
if (d == null) { if (d == null) {
//ERROR! //ERROR!
GuiDialog.message("No deck selected for player " + (i + 1)); GuiDialog.message("No deck selected for player " + (i + 1));
return null; return;
} }
playerDecks.add(d); playerDecks.add(d);
@@ -213,7 +200,7 @@ public enum CSubmenuPlanechase implements ICDoc {
if (planes == null) { if (planes == null) {
//ERROR! //ERROR!
GuiDialog.message("No planar deck selected for player" + (i+1) + "!"); GuiDialog.message("No planar deck selected for player" + (i+1) + "!");
return null; return;
} }
if (useDefault) { if (useDefault) {
@@ -224,19 +211,17 @@ public enum CSubmenuPlanechase implements ICDoc {
helper.addPlanechasePlayer(player, playerDecks.get(i), planes); helper.addPlanechasePlayer(player, playerDecks.get(i), planes);
} }
MatchController mc = Singletons.getModel().getMatch(); SOverlayUtils.startGameOverlay();
mc.initMatch(GameType.Planechase, helper.getPlayerMap()); SOverlayUtils.showOverlay();
mc.startRound();
return null;
}
final MatchController mc = new MatchController(GameType.Planechase, helper.getPlayerMap());
FThreads.invokeInEdtLater(new Runnable(){
@Override @Override
public void done() { public void run() {
mc.startRound();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}; });
worker.execute();
} }

View File

@@ -7,11 +7,10 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import forge.Command; import forge.Command;
import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby; import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
@@ -113,9 +112,7 @@ public enum CSubmenuVanguard implements ICDoc {
} }
}); });
final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() {
@Override
public Object doInBackground() {
Random rnd = new Random(); Random rnd = new Random();
String nl = System.getProperty("line.separator"); String nl = System.getProperty("line.separator");
boolean usedDefaults = false; boolean usedDefaults = false;
@@ -128,7 +125,7 @@ public enum CSubmenuVanguard implements ICDoc {
if (d == null) { if (d == null) {
//ERROR! //ERROR!
GuiDialog.message("No deck selected for player " + (i + 1)); GuiDialog.message("No deck selected for player " + (i + 1));
return null; return;
} }
playerDecks.add(d); playerDecks.add(d);
} }
@@ -164,13 +161,12 @@ public enum CSubmenuVanguard implements ICDoc {
if (avatar == null) { if (avatar == null) {
//ERROR! //ERROR!
GuiDialog.message("No avatar selected for player " + (i + 1)); GuiDialog.message("No avatar selected for player " + (i + 1));
return null; return;
} }
playerAvatars.add(avatar); playerAvatars.add(avatar);
} }
if (usedDefaults) { if (usedDefaults) {
GuiDialog.message(defaultAvatarInfo.toString()); GuiDialog.message(defaultAvatarInfo.toString());
} }
@@ -181,19 +177,14 @@ public enum CSubmenuVanguard implements ICDoc {
helper.addVanguardPlayer(player, playerDecks.get(i), playerAvatars.get(i)); helper.addVanguardPlayer(player, playerDecks.get(i), playerAvatars.get(i));
} }
MatchController mc = Singletons.getModel().getMatch(); final MatchController mc = new MatchController(GameType.Vanguard, helper.getPlayerMap());
mc.initMatch(GameType.Vanguard, helper.getPlayerMap()); FThreads.invokeInEdtLater(new Runnable(){
mc.startRound();
return null;
}
@Override @Override
public void done() { public void run() {
mc.startRound();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
}; });
worker.execute();
} }

View File

@@ -284,7 +284,7 @@ public enum TargetingOverlay {
@Override @Override
public void paintComponent(final Graphics g) { 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 // No need for this except in match view
if (FControl.SINGLETON_INSTANCE.getState() != FControl.Screens.MATCH_SCREEN) { return; } 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 GameState game;
private Player player; private Player player;
public void onGameStarts(GameState game0, Player player0) { public void setModel(GameState game0, Player player0) {
game = game0; game = game0;
player = player0; player = player0;
@@ -149,7 +149,7 @@ public enum CDock implements ICDoc {
* View deck list. * View deck list.
*/ */
private void viewDeckList() { 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) { private void manaAction(byte colorCode) {
if (CField.this.player == CField.this.playerViewer) { 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) { if (in instanceof InputPayManaBase) {
// Do something // Do something
((InputPayManaBase) in).selectManaPool(colorCode); ((InputPayManaBase) in).selectManaPool(colorCode);

View File

@@ -18,8 +18,9 @@
package forge.gui.match.views; package forge.gui.match.views;
import java.awt.Dimension; import java.awt.Dimension;
import java.util.Comparator;
import java.util.Iterator; import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
@@ -30,6 +31,7 @@ import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import forge.Card; import forge.Card;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.gui.CardPicturePanel; import forge.gui.CardPicturePanel;
import forge.gui.WrapLayout; import forge.gui.WrapLayout;
import forge.gui.framework.DragCell; 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> * <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; SINGLETON_INSTANCE;
@@ -52,18 +54,11 @@ public enum VAntes implements IVDoc<CAntes> {
private DragCell parentCell; private DragCell parentCell;
private final DragTab tab = new DragTab("Ante"); 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 JPanel pnl = new JPanel();
private final JScrollPane scroller = new JScrollPane(pnl); 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 //========== Constructor
private VAntes() { private VAntes() {
pnl.setLayout(new WrapLayout()); pnl.setLayout(new WrapLayout());
@@ -84,6 +79,14 @@ public enum VAntes implements IVDoc<CAntes> {
parentCell.getBody().add(scroller, "w 100%!, h 100%!"); 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) /* (non-Javadoc)
* @see forge.gui.framework.IVDoc#setParentCell() * @see forge.gui.framework.IVDoc#setParentCell()
*/ */
@@ -125,50 +128,34 @@ public enum VAntes implements IVDoc<CAntes> {
} }
//========== Setters / getters //========== Setters / getters
/** @Override
* @param p0 &emsp; {@link forge.game.player.Player} public void update(Observable o, Object arg) {
* @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);
}
/**
* @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();
}
}
}
/** */
public void clearAnteCards() {
allAntes.clear(); allAntes.clear();
pnl.removeAll();
for(Player p : players) {
for(Card c : p.getZone(ZoneType.Ante)) {
final AntePanel pnlTemp = new AntePanel(c);
allAntes.add(pnlTemp);
}
}
for(AntePanel ap : allAntes) {
pnl.add(ap);
}
} }
//========= Private class handling //========= Private class handling
@SuppressWarnings("serial") @SuppressWarnings("serial")
private class AntePanel extends JPanel { private class AntePanel extends JPanel implements Comparable<AntePanel> {
private final Player player;
private final Card card; private final Card card;
/** /**
* *
* @param p0 &emsp; {@link forge.game.player.Player} * @param p0 &emsp; {@link forge.game.player.Player}
* @param c0 &emsp; {@link forge.Card} * @param c0 &emsp; {@link forge.Card}
*/ */
public AntePanel(final Player p0, final Card c0) { public AntePanel(final Card c0) {
super(); super();
player = p0;
card = c0; card = c0;
final Dimension d = new Dimension(160, 250); final Dimension d = new Dimension(160, 250);
@@ -178,25 +165,21 @@ public enum VAntes implements IVDoc<CAntes> {
setOpaque(false); setOpaque(false);
setLayout(new MigLayout("gap 0, insets 0, wrap")); setLayout(new MigLayout("gap 0, insets 0, wrap"));
add(new FLabel.Builder().fontSize(14).text(player.getName()) add(new FLabel.Builder().fontSize(14).text(card.getOwner().getName())
.fontAlign(SwingConstants.CENTER).build(), "w 160px, h 20px"); .fontAlign(SwingConstants.CENTER).build(), "w 160px, h 20px");
CardPicturePanel picPanel = new CardPicturePanel(); CardPicturePanel picPanel = new CardPicturePanel();
add(picPanel, "w 160px, h 230px"); add(picPanel, "w 160px, h 230px");
picPanel.setCard(c0); picPanel.setCard(c0);
} }
/** @return {@link forge.game.player.Player} */
public Player getPlayer() {
return player;
}
/** @return {@link forge.Card} */ /** @return {@link forge.Card} */
public Card getCard() { public Card getCard() {
return card; return card;
} }
public String getID() { @Override
return player.getName() + card.getName(); 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.deck.CardCollections;
import forge.error.BugReporter; import forge.error.BugReporter;
import forge.error.ExceptionHandler; import forge.error.ExceptionHandler;
import forge.game.MatchController;
import forge.game.limited.GauntletMini; import forge.game.limited.GauntletMini;
import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletData;
import forge.item.CardDb; import forge.item.CardDb;
@@ -81,8 +80,6 @@ public enum FModel {
private final QuestController quest; private final QuestController quest;
private final CardCollections decks; private final CardCollections decks;
private final MatchController match;
private final EditionCollection editions; private final EditionCollection editions;
private final FormatCollection formats; private final FormatCollection formats;
private final IStorageView<BoosterTemplate> boosters; 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.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.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.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? // TODO - there's got to be a better place for this...oblivion?
Preferences.DEV_MODE = this.preferences.getPrefBoolean(FPref.DEV_MODE_ENABLED); Preferences.DEV_MODE = this.preferences.getPrefBoolean(FPref.DEV_MODE_ENABLED);
@@ -396,9 +391,6 @@ public enum FModel {
this.gauntletData = data0; this.gauntletData = data0;
} }
public MatchController getMatch() {
return match;
}
public GauntletMini getGauntletMini() { 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.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import forge.item.CardPrinted;
/** /**
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
@@ -105,4 +107,16 @@ public class TextUtil {
return val.toString().substring(0, 1).toUpperCase(Locale.ENGLISH) + return val.toString().substring(0, 1).toUpperCase(Locale.ENGLISH) +
val.toString().substring(1).toLowerCase(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();
}
} }