GameView: do not store Game anymore, get it from Match

This commit is contained in:
Hans Mackowiak
2020-11-28 19:02:33 +01:00
parent 70e75bde91
commit 88c017f962
18 changed files with 274 additions and 238 deletions

View File

@@ -267,7 +267,7 @@ public class PlayerControllerAi extends PlayerController {
}
@Override
public Player chooseStartingPlayer(boolean isFirstGame) {
public Player chooseStartingPlayer(boolean isFirstgame) {
return this.player; // AI is brave :)
}
@@ -364,7 +364,7 @@ public class PlayerControllerAi extends PlayerController {
if (destinationZone == ZoneType.Graveyard) {
// In presence of Volrath's Shapeshifter in deck, try to place the best creature on top of the graveyard
if (!CardLists.filter(game.getCardsInGame(), new Predicate<Card>() {
if (!CardLists.filter(getGame().getCardsInGame(), new Predicate<Card>() {
@Override
public boolean apply(Card card) {
// need a custom predicate here since Volrath's Shapeshifter may have a different name OTB
@@ -485,7 +485,7 @@ public class PlayerControllerAi extends PlayerController {
public void playSpellAbilityNoStack(SpellAbility effectSA, boolean canSetupTargets) {
if (canSetupTargets)
brains.doTrigger(effectSA, true); // first parameter does not matter, since return value won't be used
ComputerUtil.playNoStack(player, effectSA, game);
ComputerUtil.playNoStack(player, effectSA, getGame());
}
@Override
@@ -522,7 +522,7 @@ public class PlayerControllerAi extends PlayerController {
chosen = validTypes.iterator().next();
System.err.println("AI has no idea how to choose " + kindOfType +", defaulting to arbitrary element: chosen");
}
game.getAction().nofityOfValue(sa, player, chosen, player);
getGame().getAction().nofityOfValue(sa, player, chosen, player);
return chosen;
}
@@ -617,10 +617,10 @@ public class PlayerControllerAi extends PlayerController {
if (sa instanceof LandAbility) {
if (sa.canPlay()) {
sa.resolve();
game.updateLastStateForCard(sa.getHostCard());
getGame().updateLastStateForCard(sa.getHostCard());
}
} else {
ComputerUtil.handlePlayingSpellAbility(player, sa, game);
ComputerUtil.handlePlayingSpellAbility(player, sa, getGame());
}
}
@@ -659,7 +659,7 @@ public class PlayerControllerAi extends PlayerController {
// - End of hack for Exile a card from library Cumulative Upkeep -
if (ComputerUtilCost.canPayCost(ability, c.getController())) {
ComputerUtil.playNoStack(c.getController(), ability, game);
ComputerUtil.playNoStack(c.getController(), ability, getGame());
return true;
}
return false;
@@ -889,8 +889,8 @@ public class PlayerControllerAi extends PlayerController {
public String chooseProtectionType(String string, SpellAbility sa, List<String> choices) {
String choice = choices.get(0);
SpellAbility hostsa = null; //for Protect sub-ability
if (game.stack.size() > 1) {
for (SpellAbilityStackInstance si : game.getStack()) {
if (getGame().stack.size() > 1) {
for (SpellAbilityStackInstance si : getGame().getStack()) {
SpellAbility spell = si.getSpellAbility(true);
if (sa != spell && sa.getHostCard() != spell.getHostCard()) {
String s = ProtectAi.toProtectFrom(spell.getHostCard(), sa);
@@ -901,10 +901,10 @@ public class PlayerControllerAi extends PlayerController {
}
}
}
final Combat combat = game.getCombat();
final Combat combat = getGame().getCombat();
if (combat != null) {
if (game.stack.size() == 1) {
SpellAbility topstack = game.stack.peekAbility();
if (getGame().stack.size() == 1) {
SpellAbility topstack = getGame().stack.peekAbility();
if (topstack.getSubAbility() == sa) {
hostsa = topstack;
}
@@ -927,7 +927,7 @@ public class PlayerControllerAi extends PlayerController {
}
}
}
final PhaseHandler ph = game.getPhaseHandler();
final PhaseHandler ph = getGame().getPhaseHandler();
if (ph.getPlayerTurn() == sa.getActivatingPlayer() && ph.getPhase() == PhaseType.MAIN1 && sa.getTargetCard() != null) {
AiAttackController aiAtk = new AiAttackController(sa.getActivatingPlayer(), sa.getTargetCard());
String s = aiAtk.toProtectAttacker(sa);
@@ -942,7 +942,7 @@ public class PlayerControllerAi extends PlayerController {
list.addAll(opp.getCreaturesInPlay());
}
if (list.isEmpty()) {
list = CardLists.filterControlledBy(game.getCardsInGame(), player.getOpponents());
list = CardLists.filterControlledBy(getGame().getCardsInGame(), player.getOpponents());
}
if (!list.isEmpty()) {
choice = ComputerUtilCard.getMostProminentColor(list);
@@ -961,7 +961,7 @@ public class PlayerControllerAi extends PlayerController {
emptyAbility.setSVar(sVar, sa.getSVar(sVar));
}
if (ComputerUtilCost.willPayUnlessCost(sa, player, cost, alreadyPaid, allPayers) && ComputerUtilCost.canPayCost(emptyAbility, player)) {
ComputerUtil.playNoStack(player, emptyAbility, game); // AI needs something to resolve to pay that cost
ComputerUtil.playNoStack(player, emptyAbility, getGame()); // AI needs something to resolve to pay that cost
return true;
}
return false;
@@ -1007,7 +1007,7 @@ public class PlayerControllerAi extends PlayerController {
@Override
public void playTrigger(Card host, WrappedAbility wrapperAbility, boolean isMandatory) {
if (prepareSingleSa(host, wrapperAbility, isMandatory)) {
ComputerUtil.playNoStack(wrapperAbility.getActivatingPlayer(), wrapperAbility, game);
ComputerUtil.playNoStack(wrapperAbility.getActivatingPlayer(), wrapperAbility, getGame());
}
}
@@ -1019,9 +1019,9 @@ public class PlayerControllerAi extends PlayerController {
Spell spell = (Spell) tgtSA;
if (brains.canPlayFromEffectAI(spell, !optional, noManaCost) == AiPlayDecision.WillPlay || !optional) {
if (noManaCost) {
return ComputerUtil.playSpellAbilityWithoutPayingManaCost(player, tgtSA, game);
return ComputerUtil.playSpellAbilityWithoutPayingManaCost(player, tgtSA, getGame());
} else {
return ComputerUtil.playStack(tgtSA, player, game);
return ComputerUtil.playStack(tgtSA, player, getGame());
}
} else
return false; // didn't play spell
@@ -1167,7 +1167,7 @@ public class PlayerControllerAi extends PlayerController {
return SpecialCardAi.CursedScroll.chooseCard(player, sa);
}
} else {
CardCollectionView list = CardLists.filterControlledBy(game.getCardsInGame(), player.getOpponents());
CardCollectionView list = CardLists.filterControlledBy(getGame().getCardsInGame(), player.getOpponents());
list = CardLists.filter(list, Predicates.not(Presets.LANDS));
if (!list.isEmpty()) {
return list.get(0).getName();

View File

@@ -62,6 +62,12 @@ import org.apache.commons.lang3.tuple.Pair;
* Represents the state of a <i>single game</i>, a new instance is created for each game.
*/
public class Game {
private static int maxId = 0;
private static int nextId() { return ++maxId; }
/** The ID. */
private int id;
private final GameRules rules;
private final PlayerCollection allPlayers = new PlayerCollection();
private final PlayerCollection ingamePlayers = new PlayerCollection();
@@ -107,6 +113,15 @@ public class Game {
private final GameView view;
private final Tracker tracker = new Tracker();
/**
* Gets the id.
*
* @return the id
*/
public int getId() {
return this.id;
}
public Player getMonarch() {
return monarch;
}
@@ -204,9 +219,11 @@ public class Game {
changeZoneLKIInfo.clear();
}
public Game(List<RegisteredPlayer> players0, GameRules rules0, Match match0) { /* no more zones to map here */
public Game(Iterable<RegisteredPlayer> players0, GameRules rules0, Match match0) { /* no more zones to map here */
rules = rules0;
match = match0;
this.id = nextId();
match.addGame(this);
int highestTeam = -1;
for (RegisteredPlayer psc : players0) {
@@ -217,6 +234,9 @@ public class Game {
}
}
// View needs to be done before PlayerController
view = new GameView(this);
int plId = 0;
for (RegisteredPlayer psc : players0) {
IGameEntitiesFactory factory = (IGameEntitiesFactory)psc.getPlayer();
@@ -248,7 +268,8 @@ public class Game {
endOfCombat = new Phase(PhaseType.COMBAT_END);
endOfTurn = new Phase(PhaseType.END_OF_TURN);
view = new GameView(this);
// update players
view.updatePlayers(this);
subscribeToEvents(gameLog.getEventVisitor());
}
@@ -437,7 +458,7 @@ public class Game {
view.updateGameOver(this);
// The log shall listen to events and generate text internally
fireEvent(new GameEventGameOutcome(result, match.getPlayedGames()));
fireEvent(new GameEventGameOutcome(result, match.getOutcomes()));
}
public Zone getZoneOf(final Card card) {

View File

@@ -5,6 +5,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import com.google.common.collect.Iterables;
import com.google.common.eventbus.Subscribe;
import forge.LobbyPlayer;
@@ -131,8 +132,8 @@ public class GameLogFormatter extends IGameEventVisitor.Base<GameLogEntry> {
return new GameLogEntry(GameLogEntryType.STACK_RESOLVE, modeChoiceOutcome);
}
private static GameLogEntry generateSummary(final List<GameOutcome> gamesPlayed) {
final GameOutcome outcome1 = gamesPlayed.get(0);
private static GameLogEntry generateSummary(final Collection<GameOutcome> gamesPlayed) {
final GameOutcome outcome1 = Iterables.getFirst(gamesPlayed, null);
final HashMap<RegisteredPlayer, String> players = outcome1.getPlayerNames();
final HashMap<RegisteredPlayer, Integer> winCount = new HashMap<>();

View File

@@ -22,6 +22,7 @@ import forge.LobbyPlayer;
import forge.game.player.Player;
import forge.game.player.PlayerOutcome;
import forge.game.player.PlayerStatistics;
import forge.game.player.PlayerView;
import forge.game.player.RegisteredPlayer;
import forge.item.PaperCard;
@@ -45,18 +46,10 @@ public final class GameOutcome implements Iterable<Entry<RegisteredPlayer, Playe
public static class AnteResult implements Serializable {
private static final long serialVersionUID = 5087554550408543192L;
public final List<PaperCard> lostCards;
public final List<PaperCard> wonCards;
public final List<PaperCard> lostCards = Lists.newArrayList();
public final List<PaperCard> wonCards = Lists.newArrayList();
private AnteResult(List<PaperCard> cards, boolean won) {
// Need empty lists for other results for addition of change ownership cards
if (won) {
this.wonCards = cards;
this.lostCards = new ArrayList<>();
} else {
this.lostCards = cards;
this.wonCards = new ArrayList<>();
}
public AnteResult() {
}
public void addWon(List<PaperCard> cards) {
@@ -66,14 +59,6 @@ public final class GameOutcome implements Iterable<Entry<RegisteredPlayer, Playe
public void addLost(List<PaperCard> cards) {
this.lostCards.addAll(cards);
}
public static AnteResult won(List<PaperCard> cards) {
return new AnteResult(cards, true);
}
public static AnteResult lost(List<PaperCard> cards) {
return new AnteResult(cards, false);
}
}
private int lastTurnNumber = 0;
@@ -83,7 +68,7 @@ public final class GameOutcome implements Iterable<Entry<RegisteredPlayer, Playe
private final HashMap<RegisteredPlayer, PlayerStatistics> playerRating = new HashMap<>();
private final HashMap<RegisteredPlayer, String> playerNames = new HashMap<>();
public final Map<RegisteredPlayer, AnteResult> anteResult = new HashMap<>();
private final Map<RegisteredPlayer, AnteResult> anteResult = new HashMap<>();
private GameEndReason winCondition;
public GameOutcome(GameEndReason reason, final Iterable<Player> players) {
@@ -242,4 +227,31 @@ public final class GameOutcome implements Iterable<Entry<RegisteredPlayer, Playe
public String getOutcomeString(RegisteredPlayer player) {
return playerNames.get(player) + " " + playerRating.get(player).getOutcome();
}
public void addAnteWon(RegisteredPlayer pl, List<PaperCard> cards) {
if (!anteResult.containsKey(pl)) {
anteResult.put(pl, new AnteResult());
}
anteResult.get(pl).addWon(cards);
}
public void addAnteLost(RegisteredPlayer pl, List<PaperCard> cards) {
if (!anteResult.containsKey(pl)) {
anteResult.put(pl, new AnteResult());
}
anteResult.get(pl).addWon(cards);
}
public AnteResult getAnteResult(RegisteredPlayer pl) {
return anteResult.get(pl);
}
public AnteResult getAnteResult(PlayerView pv) {
for (Map.Entry<RegisteredPlayer, AnteResult> e : this.anteResult.entrySet()) {
if (pv.isLobbyPlayer(e.getKey().getPlayer())) {
return e.getValue();
}
}
return null;
}
}

View File

@@ -11,8 +11,8 @@ import forge.game.combat.Combat;
import forge.game.combat.CombatView;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.player.PlayerView;
import forge.game.player.RegisteredPlayer;
import forge.game.spellability.StackItemView;
import forge.game.zone.MagicStack;
import forge.trackable.TrackableObject;
@@ -24,11 +24,11 @@ import java.util.List;
public class GameView extends TrackableObject {
private static final long serialVersionUID = 8522884512960961528L;
private final transient Game game; //TODO: Remove this when possible before network support added
private final transient Match match; //TODO: Remove this when possible before network support added
public GameView(final Game game0) {
super(-1, game0.getTracker()); //ID not needed
game = game0;
public GameView(final Game game) {
super(game.getId(), game.getTracker());
match = game.getMatch();
set(TrackableProperty.Title, game.getMatch().getTitle());
set(TrackableProperty.WinningTeam, -1);
@@ -39,15 +39,26 @@ public class GameView extends TrackableObject {
set(TrackableProperty.NumGamesInMatch, rules.getGamesPerMatch());
set(TrackableProperty.GameLog, game.getGameLog());
set(TrackableProperty.NumPlayedGamesInMatch, game.getMatch().getPlayedGames().size());
set(TrackableProperty.NumPlayedGamesInMatch, game.getMatch().getOutcomes().size());
set(TrackableProperty.Players, PlayerView.getCollection(game.getPlayers()));
}
public Match getMatch() {
return match;
}
public Game getGame() {
return getMatch().getGameById(getId()); // Match currently has only One running Game
}
public FCollectionView<PlayerView> getPlayers() {
return get(TrackableProperty.Players);
}
public void updatePlayers(final Game game) {
set(TrackableProperty.Players, PlayerView.getCollection(game.getPlayers()));
}
public String getTitle() {
return get(TrackableProperty.Title);
}
@@ -193,31 +204,35 @@ public class GameView extends TrackableObject {
//TODO: Find better ways to make this information available to all GUIs without using the Game class
public boolean isMatchWonBy(LobbyPlayer questPlayer) {
return game.getMatch().isWonBy(questPlayer);
return getMatch().isWonBy(questPlayer);
}
public Iterable<GameOutcome> getOutcomesOfMatch() {
return game.getMatch().getOutcomes();
return getMatch().getOutcomes();
}
public boolean isWinner(LobbyPlayer guiPlayer) {
return game.getOutcome().isWinner(guiPlayer);
return getOutcome().isWinner(guiPlayer);
}
public int getGamesWonBy(LobbyPlayer questPlayer) {
return game.getMatch().getGamesWonBy(questPlayer);
return getMatch().getGamesWonBy(questPlayer);
}
public Deck getDeck(final String lobbyPlayerName) {
for (final Player p : game.getRegisteredPlayers()) {
if (p.getLobbyPlayer().getName().equals(lobbyPlayerName)) {
return p.getRegisteredPlayer().getDeck();
public Deck getDeck(final PlayerView pv) {
for (final RegisteredPlayer rp : getMatch().getPlayers()) {
if (pv.isLobbyPlayer(rp.getPlayer())) {
return rp.getDeck();
}
}
return null;
}
public GameOutcome getOutcome() {
return getMatch().getOutcomeById(getId());
}
public AnteResult getAnteResult(PlayerView player) {
return game.getOutcome().anteResult.get(game.getPlayer(player).getRegisteredPlayer());
return getOutcome().getAnteResult(player);
}
}

View File

@@ -29,11 +29,13 @@ public class Match {
private final GameRules rules;
private final String title;
private final List<GameOutcome> gamesPlayed = new ArrayList<>();
private final List<GameOutcome> gamesPlayedRo;
private Game lastGame = null;
private final Map<Integer, Game> runningGames = Maps.newHashMap();
private final Map<Integer, GameOutcome> gameOutcomes = Maps.newHashMap();
private GameOutcome lastOutcome = null;
public Match(final GameRules rules0, final List<RegisteredPlayer> players0, final String title) {
gamesPlayedRo = Collections.unmodifiableList(gamesPlayed);
players = Collections.unmodifiableList(Lists.newArrayList(players0));
rules = rules0;
this.title = title;
@@ -54,15 +56,12 @@ public class Match {
return titleAppend.toString();
}
public final List<GameOutcome> getPlayedGames() {
return gamesPlayedRo;
}
public void addGamePlayed(Game finished) {
if (!finished.isGameOver()) {
throw new IllegalStateException("Game is not over yet.");
}
gamesPlayed.add(finished.getOutcome());
lastOutcome = finished.getOutcome();
gameOutcomes.put(finished.getId(), finished.getOutcome());
}
public Game createGame() {
@@ -85,9 +84,7 @@ public class Match {
game.fireEvent(new GameEventAnteCardsSelected(list));
}
GameOutcome lastOutcome = gamesPlayed.isEmpty() ? null : gamesPlayed.get(gamesPlayed.size() - 1);
game.getAction().startGame(lastOutcome, startGameHook);
game.getAction().startGame(this.lastOutcome, startGameHook);
if (rules.useAnte()) {
executeAnte(game);
@@ -97,26 +94,44 @@ public class Match {
// will pull UI dialog, when the UI is listening
game.fireEvent(new GameEventGameFinished());
// FIXME needed to close the Match Dialog because that this moment there isn't any game
lastGame = game;
runningGames.remove(game.getId());
//run GC after game is finished
System.gc();
}
public Game getGameById(int id) {
if (runningGames.containsKey(id)) {
return runningGames.get(id);
}
// FIXME fallback for last game in case the UI is outdated
return lastGame;
}
public GameOutcome getOutcomeById(int id) {
return gameOutcomes.get(id);
}
public void addGame(Game game) {
runningGames.put(game.getId(), game);
}
public void clearGamesPlayed() {
gamesPlayed.clear();
gameOutcomes.clear();
for (RegisteredPlayer p : players) {
p.restoreDeck();
}
}
public void clearLastGame() {
gamesPlayed.remove(gamesPlayed.size() - 1);
}
public Iterable<GameOutcome> getOutcomes() {
return gamesPlayedRo;
public Collection<GameOutcome> getOutcomes() {
return gameOutcomes.values();
}
public boolean isMatchOver() {
int[] victories = new int[players.size()];
for (GameOutcome go : gamesPlayed) {
for (GameOutcome go : getOutcomes()) {
LobbyPlayer winner = go.getWinningLobbyPlayer();
int i = 0;
for (RegisteredPlayer p : players) {
@@ -136,7 +151,7 @@ public class Match {
public int getGamesWonBy(LobbyPlayer questPlayer) {
int sum = 0;
for (GameOutcome go : gamesPlayed) {
for (GameOutcome go : getOutcomes()) {
if (questPlayer.equals(go.getWinningLobbyPlayer())) {
sum++;
}
@@ -145,7 +160,7 @@ public class Match {
}
public Multiset<RegisteredPlayer> getGamesWon() {
final Multiset<RegisteredPlayer> won = HashMultiset.create(players.size());
for (final GameOutcome go : gamesPlayedRo) {
for (final GameOutcome go : getOutcomes()) {
if (go.getWinningPlayer() == null) {
// Game hasn't finished yet. Exit early.
return won;
@@ -161,7 +176,7 @@ public class Match {
public RegisteredPlayer getWinner() {
if (this.isMatchOver()) {
return gamesPlayedRo.get(gamesPlayedRo.size()-1).getWinningPlayer();
return lastOutcome.getWinningPlayer();
}
return null;
}
@@ -214,16 +229,16 @@ public class Match {
final FCollectionView<Player> players = game.getPlayers();
final List<RegisteredPlayer> playersConditions = game.getMatch().getPlayers();
boolean isFirstGame = game.getMatch().getPlayedGames().isEmpty();
boolean isFirstGame = gameOutcomes.isEmpty();
boolean canSideBoard = !isFirstGame && rules.getGameType().isSideboardingAllowed();
// Only allow this if feature flag is on AND for certain match types
boolean sideboardForAIs = rules.getSideboardForAI() &&
rules.getGameType().getDeckFormat().equals(DeckFormat.Constructed);
PlayerController sideboardProxy = null;
if (canSideBoard && sideboardForAIs) {
for (int i = 0; i < playersConditions.size(); i++) {
for (int i = 0; i < players.size(); i++) {
final Player player = players.get(i);
final RegisteredPlayer psc = playersConditions.get(i);
//final RegisteredPlayer psc = playersConditions.get(i);
if (!player.getController().isAI()) {
sideboardProxy = player.getController();
break;
@@ -337,11 +352,7 @@ public class Match {
for(Card c : lostOwnership) {
lostPaperOwnership.add((PaperCard)c.getPaperCard());
}
if (outcome.anteResult.containsKey(registered)) {
outcome.anteResult.get(registered).addLost(lostPaperOwnership);
} else {
outcome.anteResult.put(registered, GameOutcome.AnteResult.lost(lostPaperOwnership));
}
outcome.addAnteLost(registered, lostPaperOwnership);
}
if (!gainedOwnership.isEmpty()) {
@@ -349,12 +360,7 @@ public class Match {
for(Card c : gainedOwnership) {
gainedPaperOwnership.add((PaperCard)c.getPaperCard());
}
if (outcome.anteResult.containsKey(registered)) {
outcome.anteResult.get(registered).addWon(gainedPaperOwnership);
}
else {
outcome.anteResult.put(registered, GameOutcome.AnteResult.won(gainedPaperOwnership));
}
outcome.addAnteWon(registered, gainedPaperOwnership);
}
if (outcome.isDraw()) {
@@ -377,24 +383,14 @@ public class Match {
losses.add(toRemove);
}
if (outcome.anteResult.containsKey(registered)) {
outcome.anteResult.get(registered).addLost(personalLosses);
}
else {
outcome.anteResult.put(registered, GameOutcome.AnteResult.lost(personalLosses));
}
outcome.addAnteLost(registered, personalLosses);
}
if (iWinner >= 0) {
// Winner gains these cards always
Player fromGame = lastGame.getRegisteredPlayers().get(iWinner);
RegisteredPlayer registered = fromGame.getRegisteredPlayer();
if (outcome.anteResult.containsKey(registered)) {
outcome.anteResult.get(registered).addWon(losses);
}
else {
outcome.anteResult.put(registered, GameOutcome.AnteResult.won(losses));
}
outcome.addAnteWon(registered, losses);
if (rules.getGameType().canAddWonCardsMidGame()) {
// But only certain game types lets you swap midgame

View File

@@ -2,13 +2,13 @@ package forge.game.event;
import forge.game.GameOutcome;
import java.util.List;
import java.util.Collection;
public class GameEventGameOutcome extends GameEvent {
public final GameOutcome result;
public final List<GameOutcome> history;
public final Collection<GameOutcome> history;
public GameEventGameOutcome(GameOutcome lastOne, List<GameOutcome> history) {
public GameEventGameOutcome(GameOutcome lastOne, Collection<GameOutcome> history) {
this.result = lastOne;
this.history = history;
}

View File

@@ -22,6 +22,7 @@ import forge.game.GameEntity;
import forge.game.GameObject;
import forge.game.GameOutcome.AnteResult;
import forge.game.GameType;
import forge.game.GameView;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CardCollectionView;
@@ -73,13 +74,13 @@ public abstract class PlayerController {
AddOrRemove,
}
protected final Game game;
protected final GameView gameView;
protected final Player player;
protected final LobbyPlayer lobbyPlayer;
public PlayerController(Game game0, Player p, LobbyPlayer lp) {
game = game0;
gameView = game0.getView();
player = p;
lobbyPlayer = lp;
}
@@ -88,7 +89,7 @@ public abstract class PlayerController {
return false;
}
public Game getGame() { return game; }
public Game getGame() { return gameView.getGame(); }
public Player getPlayer() { return player; }
public LobbyPlayer getLobbyPlayer() { return lobbyPlayer; }
@@ -280,7 +281,7 @@ public abstract class PlayerController {
}
public AnteResult getAnteResult() {
return game.getOutcome().anteResult.get(player.getRegisteredPlayer());
return gameView.getAnteResult(player.getView());
}
public abstract List<OptionalCostValue> chooseOptionalCosts(SpellAbility choosen, List<OptionalCostValue> optionalCostValues);

View File

@@ -128,6 +128,7 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
wantUnique = true;
break;
default:
}
catalogManager = new CardManager(getCDetailPicture(), wantUnique, false);
@@ -163,6 +164,7 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
case TinyLeaders:
this.controller = new DeckController<>(FModel.getDecks().getTinyLeaders(), this, newCreator);
break;
default:
}
getBtnAddBasicLands().setCommand(new UiCommand() {
@@ -189,6 +191,7 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
case TinyLeaders:
case Brawl:
return CardLimit.Singleton;
default:
}
}
return CardLimit.None; //if not enforcing deck legality, don't enforce default limit
@@ -488,6 +491,7 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
default:
break;
}
default:
}
this.sectionMode = sectionMode;
@@ -508,7 +512,6 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
/* (non-Javadoc)
* @see forge.gui.deckeditor.ACEditorBase#show(forge.Command)
*/
@SuppressWarnings("serial")
@Override
public void update() {
this.getCatalogManager().setup(ItemManagerConfig.CARD_CATALOG);

View File

@@ -60,7 +60,7 @@ public enum CSubmenuQuestPrefs implements ICDoc {
|| QPref.WILD_OPPONENTS_MULTIPLIER.equals(i0.getQPref())) {
Double val = null;
try {
val = new Double(i0.getText());
val = Double.valueOf(i0.getText());
} catch (Exception e) {
}
validationError = val == null ? localizer.getMessage("lblEnteraDecimal") : null;

View File

@@ -271,7 +271,7 @@ public final class CMatchUI
if (!isInGame()) {
return;
}
final Deck deck = getGameView().getDeck(getCurrentPlayer().getLobbyPlayerName());
final Deck deck = getGameView().getDeck(getCurrentPlayer());
if (deck != null) {
FDeckViewer.show(deck);
}

View File

@@ -85,6 +85,7 @@ public final class Main {
System.exit(0);
}
@SuppressWarnings("deprecation")
@Override
protected void finalize() throws Throwable {
try {

View File

@@ -84,10 +84,6 @@ public class PlayerControllerForTests extends PlayerController {
return player;
}
public Game getGame() {
return game;
}
@Override
public void playSpellAbilityForFree(SpellAbility copySA, boolean mayChoseNewTargets) {
throw new IllegalStateException("Callers of this method currently assume that it performs extra functionality!");
@@ -202,7 +198,7 @@ public class PlayerControllerForTests extends PlayerController {
}
@Override
public Player chooseStartingPlayer(boolean isFirstGame) {
public Player chooseStartingPlayer(boolean isFirstgame) {
return this.player;
}
@@ -320,7 +316,7 @@ public class PlayerControllerForTests extends PlayerController {
if (playerActions == null) {
return;
}
DeclareAttackersAction declareAttackers = playerActions.getNextActionIfApplicable(player, game, DeclareAttackersAction.class);
DeclareAttackersAction declareAttackers = playerActions.getNextActionIfApplicable(player, getGame(), DeclareAttackersAction.class);
if (declareAttackers == null) {
return;
}
@@ -330,11 +326,11 @@ public class PlayerControllerForTests extends PlayerController {
//TODO: banding (don't really care at the moment...)
for (Map.Entry<CardSpecification, PlayerSpecification> playerAttackAssignment : declareAttackers.getPlayerAttackAssignments().entrySet()) {
Player defender = getPlayerBeingAttacked(game, player, playerAttackAssignment.getValue());
Player defender = getPlayerBeingAttacked(getGame(), player, playerAttackAssignment.getValue());
attack(combat, playerAttackAssignment.getKey(), defender);
}
for (Map.Entry<CardSpecification, CardSpecification> planeswalkerAttackAssignment: declareAttackers.getPlaneswalkerAttackAssignments().entrySet()) {
Card defender = CardSpecificationHandler.INSTANCE.find(game.getCardsInGame(), planeswalkerAttackAssignment.getKey());
Card defender = CardSpecificationHandler.INSTANCE.find(getGame().getCardsInGame(), planeswalkerAttackAssignment.getKey());
attack(combat, planeswalkerAttackAssignment.getKey(), defender);
}
@@ -345,12 +341,12 @@ public class PlayerControllerForTests extends PlayerController {
private Player getPlayerBeingAttacked(Game game, Player attacker, PlayerSpecification defenderSpecification) {
if (defenderSpecification != null) {
return PlayerSpecificationHandler.INSTANCE.find(game.getPlayers(), defenderSpecification);
return PlayerSpecificationHandler.INSTANCE.find(getGame().getPlayers(), defenderSpecification);
}
if (game.getPlayers().size() != 2) {
if (getGame().getPlayers().size() != 2) {
throw new IllegalStateException("Can't use implicit defender specification in this situation!");
}
for (Player player : game.getPlayers()) {
for (Player player : getGame().getPlayers()) {
if (!attacker.equals(player)) {
return player;
}
@@ -372,7 +368,7 @@ public class PlayerControllerForTests extends PlayerController {
if (playerActions == null) {
return;
}
DeclareBlockersAction declareBlockers = playerActions.getNextActionIfApplicable(player, game, DeclareBlockersAction.class);
DeclareBlockersAction declareBlockers = playerActions.getNextActionIfApplicable(player, getGame(), DeclareBlockersAction.class);
if (declareBlockers == null) {
return;
}
@@ -384,7 +380,7 @@ public class PlayerControllerForTests extends PlayerController {
for (Map.Entry<CardSpecification, Collection<CardSpecification>> blockingAssignment : declareBlockers.getBlockingAssignments().asMap().entrySet()) {
Card attacker = CardSpecificationHandler.INSTANCE.find(combat.getAttackers(), blockingAssignment.getKey());
for (CardSpecification blockerSpecification : blockingAssignment.getValue()) {
Card blocker = CardSpecificationHandler.INSTANCE.find(game, blockerSpecification);
Card blocker = CardSpecificationHandler.INSTANCE.find(getGame(), blockerSpecification);
if (!CombatUtil.canBlock(attacker, blocker)) {
throw new IllegalStateException(blocker + " can't block " + blocker);
}
@@ -402,14 +398,14 @@ public class PlayerControllerForTests extends PlayerController {
//TODO: This method has to return the spellability chosen by player
// It should not play the sa right from here. The code has been left as it is to quickly adapt to changed playercontroller interface
if (playerActions != null) {
CastSpellFromHandAction castSpellFromHand = playerActions.getNextActionIfApplicable(player, game, CastSpellFromHandAction.class);
CastSpellFromHandAction castSpellFromHand = playerActions.getNextActionIfApplicable(player, getGame(), CastSpellFromHandAction.class);
if (castSpellFromHand != null) {
castSpellFromHand.castSpellFromHand(player, game);
castSpellFromHand.castSpellFromHand(player, getGame());
}
ActivateAbilityAction activateAbilityAction = playerActions.getNextActionIfApplicable(player, game, ActivateAbilityAction.class);
ActivateAbilityAction activateAbilityAction = playerActions.getNextActionIfApplicable(player, getGame(), ActivateAbilityAction.class);
if (activateAbilityAction != null) {
activateAbilityAction.activateAbility(player, game);
activateAbilityAction.activateAbility(player, getGame());
}
}
return null;
@@ -526,7 +522,7 @@ public class PlayerControllerForTests extends PlayerController {
public void orderAndPlaySimultaneousSa(List<SpellAbility> activePlayerSAs) {
for (final SpellAbility sa : activePlayerSAs) {
prepareSingleSa(sa.getHostCard(),sa,true);
ComputerUtil.playStack(sa, player, game);
ComputerUtil.playStack(sa, player, getGame());
}
}
@@ -544,7 +540,7 @@ public class PlayerControllerForTests extends PlayerController {
@Override
public void playTrigger(Card host, WrappedAbility wrapperAbility, boolean isMandatory) {
prepareSingleSa(host, wrapperAbility, isMandatory);
ComputerUtil.playNoStack(wrapperAbility.getActivatingPlayer(), wrapperAbility, game);
ComputerUtil.playNoStack(wrapperAbility.getActivatingPlayer(), wrapperAbility, getGame());
}
@Override
@@ -557,9 +553,9 @@ public class PlayerControllerForTests extends PlayerController {
// if (spell.canPlayFromEffectAI(player, !optional, noManaCost) || !optional) { -- could not save this part
if (spell.canPlay() || !optional) {
if (noManaCost) {
ComputerUtil.playSpellAbilityWithoutPayingManaCost(player, tgtSA, game);
ComputerUtil.playSpellAbilityWithoutPayingManaCost(player, tgtSA, getGame());
} else {
ComputerUtil.playStack(tgtSA, player, game);
ComputerUtil.playStack(tgtSA, player, getGame());
}
} else
return false; // didn't play spell

View File

@@ -213,7 +213,7 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
if(FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.FILTERED_HANDS)){
baseLandParameter--;
}
landsNeeded = new Double((baseLandParameter + 3.14f * avCMC) * targetSize/60f).intValue();
landsNeeded = Double.valueOf((baseLandParameter + 3.14f * avCMC) * targetSize/60f).intValue();
if (logToConsole) {
System.out.println("Required lands from linear regression : " + avCMC + " cmc, needed: " + landsNeeded);
}
@@ -425,8 +425,6 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
@Override
public boolean apply(CardRules subject) {
ManaCost mc = subject.getManaCost();
boolean generic = mc.isPureGeneric();
return ((allowedColor.containsAllColorsFrom(subject.getColorIdentity().getColor())));
}
}

View File

@@ -149,7 +149,7 @@ public class HostedMatch {
if (game.getRules().getGameType() == GameType.Quest) {
final QuestController qc = FModel.getQuest();
// Reset new list when the Match round starts, not when each game starts
if (game.getMatch().getPlayedGames().isEmpty()) {
if (game.getMatch().getOutcomes().isEmpty()) {
qc.getCards().resetNewList();
}
game.subscribeToEvents(qc); // this one listens to player's mulligans ATM

View File

@@ -4,7 +4,6 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import forge.FThreads;
import forge.game.Game;
import forge.game.card.Card;
import forge.game.player.Player;
import forge.game.player.PlayerView;
@@ -17,10 +16,8 @@ public class InputLockUI implements Input {
private final AtomicInteger iCall = new AtomicInteger();
private final InputQueue inputQueue;
private final Game game;
private final PlayerControllerHuman controller;
public InputLockUI(final Game game0, final InputQueue inputQueue0, final PlayerControllerHuman controller) {
game = game0;
public InputLockUI(final InputQueue inputQueue0, final PlayerControllerHuman controller) {
inputQueue = inputQueue0;
this.controller = controller;
}
@@ -90,7 +87,7 @@ public class InputLockUI implements Input {
@Override
public void selectButtonCancel() {
//cancel auto pass for all players
for (final Player player : game.getPlayers()) {
for (final Player player : controller.getGame().getPlayers()) {
player.getController().autoPassCancel();
}
}

View File

@@ -21,7 +21,7 @@ import java.util.Observable;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import forge.game.Game;
import forge.game.GameView;
import forge.player.PlayerControllerHuman;
/**
@@ -34,10 +34,10 @@ import forge.player.PlayerControllerHuman;
*/
public class InputQueue extends Observable {
private final BlockingDeque<InputSynchronized> inputStack = new LinkedBlockingDeque<>();
private final Game game;
private final GameView gameView;
public InputQueue(final Game game, final InputProxy inputProxy) {
this.game = game;
public InputQueue(final GameView gameView, final InputProxy inputProxy) {
this.gameView = gameView;
addObserver(inputProxy);
}
@@ -64,10 +64,10 @@ public class InputQueue extends Observable {
public final Input getActualInput(final PlayerControllerHuman controller) {
final Input topMost = inputStack.peek(); // incoming input to Control
if (topMost != null && !game.isGameOver()) {
if (topMost != null && !gameView.isGameOver()) {
return topMost;
}
return new InputLockUI(game, this, controller);
return new InputLockUI(this, controller);
} // getInput()
// only for debug purposes

View File

@@ -5,6 +5,8 @@ import java.util.*;
import java.util.Map.Entry;
import forge.game.ability.AbilityUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.Range;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
@@ -108,7 +110,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
public PlayerControllerHuman(final Game game0, final Player p, final LobbyPlayer lp) {
super(game0, p, lp);
inputProxy = new InputProxy(this);
inputQueue = new InputQueue(game, inputProxy);
inputQueue = new InputQueue(game0.getView(), inputProxy);
}
public PlayerControllerHuman(final Player p, final LobbyPlayer lp, final PlayerControllerHuman owner) {
@@ -268,19 +270,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
// Sideboard rules have changed for M14, just need to consider min
// maindeck and max sideboard sizes
// No longer need 1:1 sideboarding in non-limited formats
Object resp = getGui().sideboard(sideboard, main, message);
if (resp instanceof List<?> &&
!((List) resp).isEmpty() &&
((List) resp).get(0) instanceof PaperCard) {
newMain = (List) resp;
} else if (resp == null) {
// if we got here, the user took too long to reply
newMain = main.toFlatList();
} else {
System.err.println("PlayerControllerHuman.sideboard -- FAILED!");
System.err.println("resp instanceof " + resp.getClass().toString());
System.err.println("resp = " + resp.toString());
}
List<PaperCard> resp = getGui().sideboard(sideboard, main, message);
newMain = ObjectUtils.defaultIfNull(resp, main.toFlatList());
} while (conform && (newMain.size() < deckMinSize || combinedDeckSize - newMain.size() > sbMax));
return newMain;
@@ -667,8 +658,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
}
if (tos.containsKey(AbilityKey.Card)) {
final Card card = (Card) tos.get(AbilityKey.Card);
if (card != null && (card.getController() == player || game.getZoneOf(card) == null
|| game.getZoneOf(card).getZoneType().isKnown())) {
if (card != null && (card.getController() == player || getGame().getZoneOf(card) == null
|| getGame().getZoneOf(card).getZoneType().isKnown())) {
buildQuestion.append("\n").append(localizer.getMessage("lblTriggeredby")).append(": ").append(tos.get(AbilityKey.Card));
}
}
@@ -680,7 +671,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
@Override
public Player chooseStartingPlayer(final boolean isFirstGame) {
if (game.getPlayers().size() == 2) {
if (getGame().getPlayers().size() == 2) {
String prompt = null;
if (isFirstGame) {
prompt = localizer.getMessage("lblYouHaveWonTheCoinToss", player.getName());
@@ -702,7 +693,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
}
prompt += "\n\n" + localizer.getMessage("lblWhoWouldYouLiketoStartthisGame");
final InputSelectEntitiesFromList<Player> input = new InputSelectEntitiesFromList<>(this, 1, 1,
new FCollection<>(game.getPlayersInTurnOrder()));
new FCollection<>(getGame().getPlayersInTurnOrder()));
input.setMessage(prompt);
input.showAndWait();
return input.getFirstSelected();
@@ -922,7 +913,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
return cards;
case ForgeConstants.GRAVEYARD_ORDERING_OWN_CARDS:
// Order only if the relevant cards controlled by the player determine the potential necessity for it
if (!game.isGraveyardOrdered(player)) {
if (!getGame().isGraveyardOrdered(player)) {
return cards;
}
break;
@@ -1286,7 +1277,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
@Override
public List<SpellAbility> chooseSpellAbilityToPlay() {
final MagicStack stack = game.getStack();
final MagicStack stack = getGame().getStack();
if (mayAutoPass()) {
// avoid prompting for input if current phase is set to be
@@ -1297,8 +1288,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
if (stack.isEmpty()) {
// make sure to briefly pause at phases you're not set up to
// skip
if (!getGui().isUiSetToSkipPhase(game.getPhaseHandler().getPlayerTurn().getView(),
game.getPhaseHandler().getPhase())) {
if (!getGui().isUiSetToSkipPhase(getGame().getPhaseHandler().getPlayerTurn().getView(),
getGame().getPhaseHandler().getPhase())) {
delay = FControlGamePlayback.phasesDelay;
}
} else {
@@ -1317,8 +1308,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
}
if (stack.isEmpty()) {
if (getGui().isUiSetToSkipPhase(game.getPhaseHandler().getPlayerTurn().getView(),
game.getPhaseHandler().getPhase())) {
if (getGui().isUiSetToSkipPhase(getGame().getPhaseHandler().getPlayerTurn().getView(),
getGame().getPhaseHandler().getPhase())) {
return null; // avoid prompt for input if stack is empty and
// player is set to skip the current phase
}
@@ -1504,7 +1495,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
public void notifyOfValue(final SpellAbility sa, final GameObject realtedTarget, final String value) {
final String message = MessageUtil.formatNotificationMessage(sa, player, realtedTarget, value);
if (sa != null && sa.isManaAbility()) {
game.getGameLog().add(GameLogEntryType.LAND, message);
getGame().getGameLog().add(GameLogEntryType.LAND, message);
} else {
getGui().message(message,
sa == null || sa.getHostCard() == null ? "" : CardView.get(sa.getHostCard()).toString());
@@ -1522,14 +1513,14 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
@Override
public List<AbilitySub> chooseModeForAbility(final SpellAbility sa, List<AbilitySub> possible, final int min, final int num,
boolean allowRepeat) {
boolean trackerFrozen = game.getTracker().isFrozen();
boolean trackerFrozen = getGame().getTracker().isFrozen();
if (trackerFrozen) {
// The view tracker needs to be unfrozen to update the SpellAbilityViews at this point, or it may crash
game.getTracker().unfreeze();
getGame().getTracker().unfreeze();
}
Map<SpellAbilityView, AbilitySub> spellViewCache = SpellAbilityView.getMap(possible);
if (trackerFrozen) {
game.getTracker().freeze(); // refreeze if the tracker was frozen prior to this update
getGame().getTracker().freeze(); // refreeze if the tracker was frozen prior to this update
}
final List<SpellAbilityView> choices = Lists.newArrayList(spellViewCache.keySet());
final String modeTitle = localizer.getMessage("lblPlayerActivatedCardChooseMode", sa.getActivatingPlayer().toString(), CardTranslation.getTranslatedName(sa.getHostCard().getName()));
@@ -1894,10 +1885,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
}
public boolean canUndoLastAction() {
if (!game.stack.canUndo(player)) {
if (!getGame().stack.canUndo(player)) {
return false;
}
final Player priorityPlayer = game.getPhaseHandler().getPriorityPlayer();
final Player priorityPlayer = getGame().getPhaseHandler().getPriorityPlayer();
return priorityPlayer != null && priorityPlayer == player;
}
@@ -1911,7 +1902,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
return false;
}
if (game.getStack().undo()) {
if (getGame().getStack().undo()) {
final Input currentInput = inputQueue.getInput();
if (currentInput instanceof InputPassPriority) {
// ensure prompt updated if needed
@@ -2057,7 +2048,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
@Override
public void setViewAllCards(final boolean canViewAll) {
mayLookAtAllCards = canViewAll;
for (final Player p : game.getPlayers()) {
for (final Player p : getGame().getPlayers()) {
getGui().updateCards(CardView.getCollection(p.getAllCards()));
}
}
@@ -2069,18 +2060,18 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
*/
@Override
public void generateMana() {
final Player pPriority = game.getPhaseHandler().getPriorityPlayer();
final Player pPriority = getGame().getPhaseHandler().getPriorityPlayer();
if (pPriority == null) {
getGui().message(localizer.getMessage("lblNoPlayerHasPriorityCannotAddedManaToPool"));
return;
}
final Card dummy = new Card(-777777, game);
final Card dummy = new Card(-777777, getGame());
dummy.setOwner(pPriority);
final Map<String, String> produced = Maps.newHashMap();
produced.put("Produced", "W W W W W W W U U U U U U U B B B B B B B G G G G G G G R R R R R R R 7");
final AbilityManaPart abMana = new AbilityManaPart(dummy, produced);
game.getAction().invoke(new Runnable() {
getGame().getAction().invoke(new Runnable() {
@Override
public void run() {
abMana.produceMana(null);
@@ -2106,7 +2097,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
public void dumpGameState() {
final GameState state = createGameStateObject();
try {
state.initFromGame(game);
state.initFromGame(getGame());
final File f = GuiBase.getInterface().getSaveFile(new File(ForgeConstants.USER_GAMES_DIR, "state.txt"));
if (f != null
&& (!f.exists() || getGui().showConfirmDialog(localizer.getMessage("lblOverwriteExistFileConfirm"), localizer.getMessage("lblFileExists")))) {
@@ -2156,12 +2147,12 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
return;
}
final Player pPriority = game.getPhaseHandler().getPriorityPlayer();
final Player pPriority = getGame().getPhaseHandler().getPriorityPlayer();
if (pPriority == null) {
getGui().message(localizer.getMessage("lblNoPlayerPriorityGameStateCannotBeSetup"));
return;
}
state.applyToGame(game);
state.applyToGame(getGame());
}
/*
@@ -2171,7 +2162,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
*/
@Override
public void tutorForCard() {
final Player pPriority = game.getPhaseHandler().getPriorityPlayer();
final Player pPriority = getGame().getPhaseHandler().getPriorityPlayer();
if (pPriority == null) {
getGui().message(localizer.getMessage("lblNoPlayerPriorityDeckCantBeTutoredFrom"));
return;
@@ -2180,17 +2171,17 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
final CardCollection lib = (CardCollection) pPriority.getCardsIn(ZoneType.Library);
final List<ZoneType> origin = Lists.newArrayList();
origin.add(ZoneType.Library);
final SpellAbility sa = new SpellAbility.EmptySa(new Card(-1, game));
final SpellAbility sa = new SpellAbility.EmptySa(new Card(-1, getGame()));
final Card card = chooseSingleCardForZoneChange(ZoneType.Hand, origin, sa, lib, null, localizer.getMessage("lblChooseaCard"), true,
pPriority);
if (card == null) {
return;
}
game.getAction().invoke(new Runnable() {
getGame().getAction().invoke(new Runnable() {
@Override
public void run() {
game.getAction().moveToHand(card, null);
getGame().getAction().moveToHand(card, null);
}
});
}
@@ -2218,7 +2209,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
public void modifyCountersOnPermanent(boolean subtract) {
final String titleMsg = subtract ? localizer.getMessage("lblRemoveCountersFromWhichCard") : localizer.getMessage("lblAddCountersToWhichCard");
GameEntityViewMap<Card, CardView> gameCacheCounters = GameEntityView.getMap(game.getCardsIn(ZoneType.Battlefield));
GameEntityViewMap<Card, CardView> gameCacheCounters = GameEntityView.getMap(getGame().getCardsIn(ZoneType.Battlefield));
final CardView cv = getGui().oneOrNone(titleMsg, gameCacheCounters.getTrackableKeys());
if (cv == null || !gameCacheCounters.containsKey(cv)) {
@@ -2259,10 +2250,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
*/
@Override
public void tapPermanents() {
game.getAction().invoke(new Runnable() {
getGame().getAction().invoke(new Runnable() {
@Override
public void run() {
final CardCollectionView untapped = CardLists.filter(game.getCardsIn(ZoneType.Battlefield),
final CardCollectionView untapped = CardLists.filter(getGame().getCardsIn(ZoneType.Battlefield),
Predicates.not(CardPredicates.Presets.TAPPED));
final InputSelectCardsFromList inp = new InputSelectCardsFromList(PlayerControllerHuman.this, 0,
Integer.MAX_VALUE, untapped);
@@ -2285,10 +2276,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
*/
@Override
public void untapPermanents() {
game.getAction().invoke(new Runnable() {
getGame().getAction().invoke(new Runnable() {
@Override
public void run() {
final CardCollectionView tapped = CardLists.filter(game.getCardsIn(ZoneType.Battlefield),
final CardCollectionView tapped = CardLists.filter(getGame().getCardsIn(ZoneType.Battlefield),
CardPredicates.Presets.TAPPED);
final InputSelectCardsFromList inp = new InputSelectCardsFromList(PlayerControllerHuman.this, 0,
Integer.MAX_VALUE, tapped);
@@ -2312,7 +2303,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
@Override
public void setPlayerLife() {
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(game.getPlayers());
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(getGame().getPlayers());
final PlayerView pv = getGui().oneOrNone(localizer.getMessage("lblSetLifeforWhichPlayer"), gameCachePlayer.getTrackableKeys());
if (pv == null || !gameCachePlayer.containsKey(pv)) {
@@ -2343,7 +2334,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
// set life of all other players to 0
final LobbyPlayer guiPlayer = getLobbyPlayer();
final FCollectionView<Player> players = game.getPlayers();
final FCollectionView<Player> players = getGame().getPlayers();
for (final Player player : players) {
if (player.getLobbyPlayer() != guiPlayer) {
player.setLife(0, null);
@@ -2448,7 +2439,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
return;
}
} else {
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(game.getPlayers());
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(getGame().getPlayers());
PlayerView pv = getGui().oneOrNone(message, gameCachePlayer.getTrackableKeys());
if (pv == null || !gameCachePlayer.containsKey(pv)) {
return;
@@ -2470,9 +2461,9 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
final PaperCard c = carddb.getUniqueByName(f.getName());
final Card forgeCard = Card.fromPaperCard(c, p);
forgeCard.setTimestamp(game.getNextTimestamp());
forgeCard.setTimestamp(getGame().getNextTimestamp());
game.getAction().invoke(new Runnable() {
getGame().getAction().invoke(new Runnable() {
@Override
public void run() {
if (targetZone == ZoneType.Battlefield) {
@@ -2488,7 +2479,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
}
}
}
game.getAction().moveTo(targetZone, forgeCard, null);
getGame().getAction().moveTo(targetZone, forgeCard, null);
if (forgeCard.isCreature()) {
forgeCard.setSickness(lastSummoningSickness);
}
@@ -2499,10 +2490,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
} else {
if (c.getRules().getType().isLand()) {
// this is needed to ensure land abilities fire
game.getAction().moveToHand(forgeCard, null);
game.getAction().moveToPlay(forgeCard, null);
getGame().getAction().moveToHand(forgeCard, null);
getGame().getAction().moveToPlay(forgeCard, null);
// ensure triggered abilities fire
game.getTriggerHandler().runWaitingTriggers();
getGame().getTriggerHandler().runWaitingTriggers();
} else {
final FCollectionView<SpellAbility> choices = forgeCard.getBasicSpells();
if (choices.isEmpty()) {
@@ -2522,14 +2513,14 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
lastAddedSA = sa;
// this is really needed (for rollbacks at least)
game.getAction().moveToHand(forgeCard, null);
getGame().getAction().moveToHand(forgeCard, null);
// Human player is choosing targets for an ability
// controlled by chosen player.
sa.setActivatingPlayer(p);
HumanPlay.playSaWithoutPayingManaCost(PlayerControllerHuman.this, game, sa, true);
HumanPlay.playSaWithoutPayingManaCost(PlayerControllerHuman.this, getGame(), sa, true);
}
// playSa could fire some triggers
game.getStack().addAllTriggeredAbilitiesToStack();
getGame().getStack().addAllTriggeredAbilitiesToStack();
}
} else if (targetZone == ZoneType.Library) {
if (!repeatLast) {
@@ -2537,12 +2528,12 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
true, Arrays.asList(localizer.getMessage("lblTop"), localizer.getMessage("lblBottom")));
}
if (lastTopOfTheLibrary) {
game.getAction().moveToLibrary(forgeCard, null);
getGame().getAction().moveToLibrary(forgeCard, null);
} else {
game.getAction().moveToBottomOfLibrary(forgeCard, null);
getGame().getAction().moveToBottomOfLibrary(forgeCard, null);
}
} else {
game.getAction().moveTo(targetZone, forgeCard, null);
getGame().getAction().moveTo(targetZone, forgeCard, null);
}
lastAdded = f;
@@ -2560,7 +2551,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
*/
@Override
public void exileCardsFromHand() {
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(game.getPlayers());
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(getGame().getPlayers());
final PlayerView pv = getGui().oneOrNone(localizer.getMessage("lblExileCardsFromPlayerHandConfirm"),
gameCachePlayer.getTrackableKeys());
@@ -2581,12 +2572,12 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
if (c == null) {
continue;
}
if (game.getAction().moveTo(ZoneType.Exile, c, null) != null) {
if (getGame().getAction().moveTo(ZoneType.Exile, c, null) != null) {
StringBuilder sb = new StringBuilder();
sb.append(p).append(" exiles ").append(c).append(" due to Dev Cheats.");
game.getGameLog().add(GameLogEntryType.DISCARD, sb.toString());
getGame().getGameLog().add(GameLogEntryType.DISCARD, sb.toString());
} else {
game.getGameLog().add(GameLogEntryType.INFORMATION, "DISCARD CHEAT ERROR");
getGame().getGameLog().add(GameLogEntryType.INFORMATION, "DISCARD CHEAT ERROR");
}
}
}
@@ -2598,7 +2589,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
*/
@Override
public void exileCardsFromBattlefield() {
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(game.getPlayers());
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(getGame().getPlayers());
final PlayerView pv = getGui().oneOrNone(localizer.getMessage("lblExileCardsFromPlayerBattlefieldConfirm"),
gameCachePlayer.getTrackableKeys());
@@ -2619,12 +2610,12 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
if (c == null) {
continue;
}
if (game.getAction().moveTo(ZoneType.Exile, c, null) != null) {
if (getGame().getAction().moveTo(ZoneType.Exile, c, null) != null) {
StringBuilder sb = new StringBuilder();
sb.append(p).append(" exiles ").append(c).append(" due to Dev Cheats.");
game.getGameLog().add(GameLogEntryType.ZONE_CHANGE, sb.toString());
getGame().getGameLog().add(GameLogEntryType.ZONE_CHANGE, sb.toString());
} else {
game.getGameLog().add(GameLogEntryType.INFORMATION, "EXILE FROM PLAY CHEAT ERROR");
getGame().getGameLog().add(GameLogEntryType.INFORMATION, "EXILE FROM PLAY CHEAT ERROR");
}
}
}
@@ -2636,7 +2627,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
*/
@Override
public void removeCardsFromGame() {
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(game.getPlayers());
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(getGame().getPlayers());
final PlayerView pv = getGui().oneOrNone(localizer.getMessage("lblRemoveCardBelongingWitchPlayer"),
gameCachePlayer.getTrackableKeys());
@@ -2665,7 +2656,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
StringBuilder sb = new StringBuilder();
sb.append(p).append(" removes ").append(c).append(" from game due to Dev Cheats.");
game.getGameLog().add(GameLogEntryType.ZONE_CHANGE, sb.toString());
getGame().getGameLog().add(GameLogEntryType.ZONE_CHANGE, sb.toString());
}
}
@@ -2676,7 +2667,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
*/
@Override
public void riggedPlanarRoll() {
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(game.getPlayers());
GameEntityViewMap<Player, PlayerView> gameCachePlayer = GameEntityView.getMap(getGame().getPlayers());
final PlayerView pv = getGui().oneOrNone(localizer.getMessage("lblWhichPlayerShouldRoll"), gameCachePlayer.getTrackableKeys());
if (pv == null || !gameCachePlayer.containsKey(pv)) {
@@ -2691,7 +2682,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
System.out.println("Rigging planar dice roll: " + res.toString());
game.getAction().invoke(new Runnable() {
getGame().getAction().invoke(new Runnable() {
@Override
public void run() {
PlanarDice.roll(player, res);
@@ -2706,10 +2697,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
*/
@Override
public void planeswalkTo() {
if (!game.getRules().hasAppliedVariant(GameType.Planechase)) {
if (!getGame().getRules().hasAppliedVariant(GameType.Planechase)) {
return;
}
final Player p = game.getPhaseHandler().getPlayerTurn();
final Player p = getGame().getPhaseHandler().getPlayerTurn();
final List<PaperCard> allPlanars = Lists.newArrayList();
for (final PaperCard c : FModel.getMagicDb().getVariantCards().getAllCards()) {
@@ -2727,10 +2718,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
final Card forgeCard = Card.fromPaperCard(c, p);
forgeCard.setOwner(p);
game.getAction().invoke(new Runnable() {
getGame().getAction().invoke(new Runnable() {
@Override
public void run() {
game.getAction().changeZone(null, p.getZone(ZoneType.PlanarDeck), forgeCard, 0, null);
getGame().getAction().changeZone(null, p.getZone(ZoneType.PlanarDeck), forgeCard, 0, null);
PlanarDice.roll(p, PlanarDice.Planeswalk);
}
});
@@ -2781,7 +2772,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
// the parsing
// process, and this implementation is still a "proof of concept".
int opponentID = 0;
for (final Player player : game.getPlayers()) {
for (final Player player : getGame().getPlayers()) {
if (player.getId() != playerID) {
opponentID = player.getId();
break;
@@ -2842,14 +2833,14 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
// Fetch cards and players specified by the user input
final ZoneType[] zones = { ZoneType.Battlefield, ZoneType.Hand, ZoneType.Graveyard, ZoneType.Exile,
ZoneType.Command };
final CardCollectionView cards = game.getCardsIn(Arrays.asList(zones));
final CardCollectionView cards = getGame().getCardsIn(Arrays.asList(zones));
for (final Pair<Integer, Boolean> entity : entityInfo) {
boolean found = false;
// Nested loops are no fun; however, seems there's no better way
// to get stuff by ID
boolean isPlayer = entity.getValue();
if (isPlayer) {
for (final Player player : game.getPlayers()) {
for (final Player player : getGame().getPlayers()) {
if (player.getId() == entity.getKey()) {
found = true;
rememberedActions.add(Pair.of(player.getView(), true));
@@ -2945,8 +2936,12 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
@Override
public void nextGameDecision(final NextGameDecision decision) {
Game game = getGame();
// in case the game ended before the button is pressed, then match doesn't remember the game anymore
if (game != null) {
game.fireEvent(new UiEventNextGameDecision(this, decision));
}
}
@Override
public String getActivateDescription(final CardView card) {