diff --git a/.gitattributes b/.gitattributes index ebf77642c7f..4948c27d2b9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -280,6 +280,7 @@ forge-game/src/main/java/forge/game/GameAction.java svneol=native#text/plain forge-game/src/main/java/forge/game/GameActionUtil.java svneol=native#text/plain forge-game/src/main/java/forge/game/GameEndReason.java -text forge-game/src/main/java/forge/game/GameEntity.java -text +forge-game/src/main/java/forge/game/GameEntityCache.java -text forge-game/src/main/java/forge/game/GameEntityView.java -text forge-game/src/main/java/forge/game/GameFormat.java -text forge-game/src/main/java/forge/game/GameLog.java -text diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index 44d0316e081..9f1a6726c80 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -53,6 +53,7 @@ import forge.game.phase.Untap; import forge.game.phase.Upkeep; import forge.game.player.IGameEntitiesFactory; import forge.game.player.Player; +import forge.game.player.PlayerView; import forge.game.player.RegisteredPlayer; import forge.game.replacement.ReplacementHandler; import forge.game.spellability.SpellAbility; @@ -102,9 +103,16 @@ public class Game { private final GameView view; + private GameEntityCache playerCache = new GameEntityCache<>(); + public Player getPlayer(PlayerView playerView) { + return playerCache.get(playerView); + } + public void addPlayer(Integer id, Player player) { + playerCache.put(id, player); + } + public Game(List players0, GameRules rules0, Match match0) { /* no more zones to map here */ Card.clearCache(); - Player.clearCache(); rules = rules0; match = match0; diff --git a/forge-game/src/main/java/forge/game/GameEntity.java b/forge-game/src/main/java/forge/game/GameEntity.java index 012c98f1f4d..350c9f01a97 100644 --- a/forge-game/src/main/java/forge/game/GameEntity.java +++ b/forge-game/src/main/java/forge/game/GameEntity.java @@ -19,28 +19,15 @@ package forge.game; import forge.game.card.Card; import forge.game.card.CardCollection; -import forge.game.card.CardView; import forge.game.card.CardCollectionView; import forge.game.event.GameEventCardAttachment; import forge.game.event.GameEventCardAttachment.AttachMethod; -import forge.game.player.Player; -import forge.game.player.PlayerView; import java.util.Map; import java.util.TreeMap; public abstract class GameEntity extends GameObject implements IIdentifiable { - public static GameEntity get(GameEntityView gameEntityView) { - if (gameEntityView instanceof CardView) { - return Card.get((CardView)gameEntityView); - } - if (gameEntityView instanceof PlayerView) { - return Player.get((PlayerView)gameEntityView); - } - return null; - } - protected final int id; private String name = ""; private int preventNextDamage = 0; diff --git a/forge-game/src/main/java/forge/game/GameEntityCache.java b/forge-game/src/main/java/forge/game/GameEntityCache.java new file mode 100644 index 00000000000..57867b7bd08 --- /dev/null +++ b/forge-game/src/main/java/forge/game/GameEntityCache.java @@ -0,0 +1,33 @@ +package forge.game; + +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; + +public class GameEntityCache { + private HashMap entityCache = new HashMap(); + + public void put(Integer id, Entity entity) { + entityCache.put(id, entity); + } + + public Entity get(View entityView) { + if (entityView == null) { return null; } + return entityCache.get(entityView.getId()); + } + + public void addToList(Iterable views, List list) { + for (View view : views) { + Entity entity = get(view); + if (entity != null) { + list.add(entity); + } + } + } + + public List getList(Iterable views) { + List list = new ArrayList(); + addToList(views, list); + return list; + } +} diff --git a/forge-game/src/main/java/forge/game/GameView.java b/forge-game/src/main/java/forge/game/GameView.java index bd60785ba66..16244ded50f 100644 --- a/forge-game/src/main/java/forge/game/GameView.java +++ b/forge-game/src/main/java/forge/game/GameView.java @@ -209,6 +209,6 @@ public class GameView extends TrackableObject { } public AnteResult getAnteResult(PlayerView player) { - return game.getOutcome().anteResult.get(Player.get(player)); + return game.getOutcome().anteResult.get(game.getPlayer(player)); } } diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index 40bc342d466..6757d7401c9 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -82,25 +82,6 @@ public class Player extends GameEntity implements Comparable { ZoneType.Library, ZoneType.Graveyard, ZoneType.Hand, ZoneType.Exile, ZoneType.Command, ZoneType.Ante, ZoneType.Sideboard, ZoneType.PlanarDeck, ZoneType.SchemeDeck)); - private static HashMap playerCache = new HashMap(); - public static Player get(PlayerView playerView) { - if (playerView == null) { return null; } - return playerCache.get(playerView.getId()); - } - public static List getList(Iterable playerViews) { - List list = new ArrayList(); - for (PlayerView pv : playerViews) { - Player p = get(pv); - if (p != null) { - list.add(p); - } - } - return list; - } - public static void clearCache() { - playerCache.clear(); - } - private final Map commanderDamage = new HashMap(); private int poisonCounters = 0; @@ -174,7 +155,7 @@ public class Player extends GameEntity implements Comparable { view.updateKeywords(this); setName(chooseName(name0)); if (id0 >= 0) { - playerCache.put(id0, this); + game.addPlayer(id, this); } } @@ -2214,6 +2195,8 @@ public class Player extends GameEntity implements Comparable { controllerCreator = ctrlr; controller = ctrlr; view.updateAvatarIndex(this); + view.updateIsAI(this); + view.updateLobbyPlayerName(this); } /** diff --git a/forge-game/src/main/java/forge/game/player/PlayerView.java b/forge-game/src/main/java/forge/game/player/PlayerView.java index cf933bfd63a..f455e04bb66 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerView.java +++ b/forge-game/src/main/java/forge/game/player/PlayerView.java @@ -41,6 +41,23 @@ public class PlayerView extends GameEntityView { set(TrackableProperty.Mana, Maps.newHashMapWithExpectedSize(MagicColor.NUMBER_OR_COLORS + 1)); } + public boolean isAI() { + return get(TrackableProperty.IsAI); + } + void updateIsAI(Player p) { + set(TrackableProperty.IsAI, p.getController().isAI()); + } + + public String getLobbyPlayerName() { + return get(TrackableProperty.LobbyPlayerName); + } + void updateLobbyPlayerName(Player p) { + set(TrackableProperty.LobbyPlayerName, p.getLobbyPlayer().getName()); + } + public boolean isLobbyPlayer(LobbyPlayer p) { + return getLobbyPlayerName().equals(p.getName()); + } + public int getAvatarIndex() { return get(TrackableProperty.AvatarIndex); } @@ -257,9 +274,4 @@ public class PlayerView extends GameEntityView { } set(TrackableProperty.Mana, mana); } - - //TODO: Find better way to do this - public LobbyPlayer getLobbyPlayer() { - return Player.get(this).getLobbyPlayer(); - } } \ No newline at end of file diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index 219cb27d7d0..469024a7b63 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -85,6 +85,8 @@ public enum TrackableProperty { FoilIndex(TrackableTypes.IntegerType), //Player + IsAI(TrackableTypes.BooleanType), + LobbyPlayerName(TrackableTypes.StringType), AvatarIndex(TrackableTypes.IntegerType), Opponents(TrackableTypes.PlayerViewCollectionType), Life(TrackableTypes.IntegerType), diff --git a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java index 1ed9a839321..242c6f8975d 100644 --- a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java +++ b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java @@ -304,6 +304,6 @@ public class GuiDesktop implements IGuiBase { @Override public void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi) { - CMatchUI.SINGLETON_INSTANCE.avatarImages.put(player, ihi.getIconImageKey()); + CMatchUI.SINGLETON_INSTANCE.avatarImages.put(player.getName(), ihi.getIconImageKey()); } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java index d0915e90a92..561e43854b8 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java @@ -66,7 +66,6 @@ import forge.match.IMatchController; import forge.match.MatchUtil; import forge.menus.IMenuProvider; import forge.model.FModel; -import forge.player.LobbyPlayerHuman; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; import forge.screens.match.controllers.CAntes; @@ -110,11 +109,11 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { private boolean showOverlay = true; private IVDoc selectedDocBeforeCombat; - public final Map avatarImages = new HashMap(); - - private SkinImage getPlayerAvatar(final LobbyPlayer p, final int defaultIndex) { - if (avatarImages.containsKey(p)) { - return ImageCache.getIcon(avatarImages.get(p)); + public final Map avatarImages = new HashMap(); + + private SkinImage getPlayerAvatar(final PlayerView p, final int defaultIndex) { + if (avatarImages.containsKey(p.getLobbyPlayerName())) { + return ImageCache.getIcon(avatarImages.get(p.getLobbyPlayerName())); } int avatarIdx = p.getAvatarIndex(); @@ -147,7 +146,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { commands.add(c); //setAvatar(f, new ImageIcon(FSkin.getAvatars().get())); - setAvatar(f, getPlayerAvatar(p.getLobbyPlayer(), Integer.parseInt(indices[i > 2 ? 1 : 0]))); + setAvatar(f, getPlayerAvatar(p, Integer.parseInt(indices[i > 2 ? 1 : 0]))); f.getLayoutControl().initialize(); c.getLayoutControl().initialize(); i++; @@ -167,7 +166,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { int i = 0; for (final PlayerView p : sortedPlayers) { - if (allHands || p.getLobbyPlayer() instanceof LobbyPlayerHuman || CardView.mayViewAny(p.getHand(), p)) { + if (allHands || !p.isAI() || CardView.mayViewAny(p.getHand(), p)) { VHand newHand = new VHand(EDocID.Hands[i], p); newHand.getLayoutControl().initialize(); hands.add(newHand); diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java b/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java index b0697c74188..62d86d3fa73 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java @@ -80,7 +80,7 @@ public class QuestDraftWinLose extends ControlWinLose { final Iterable players = lastGame.getPlayers(); boolean gameHadHumanPlayer = false; for (final PlayerView p : players) { - if (p.getLobbyPlayer().equals(questLobbyPlayer)) { + if (p.isLobbyPlayer(questLobbyPlayer)) { gameHadHumanPlayer = true; break; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java b/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java index 752fbeae359..99b66e4af27 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java @@ -199,7 +199,7 @@ public class VAssignDamage { } else if (defender instanceof PlayerView) { final PlayerView p = (PlayerView)defender; - fakeCard = new CardView(-1, defender.toString(), p, CMatchUI.SINGLETON_INSTANCE.avatarImages.get(p.getLobbyPlayer())); + fakeCard = new CardView(-1, defender.toString(), p, CMatchUI.SINGLETON_INSTANCE.avatarImages.get(p.getLobbyPlayerName())); } addPanelForDefender(pnlDefenders, fakeCard); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java index 0ab91a92e9a..5a5a008177f 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java @@ -69,7 +69,7 @@ public class CField implements ICDoc { Function manaAction = new Function() { public Boolean apply(Byte colorCode) { - if (CField.this.player.getLobbyPlayer() == Singletons.getControl().getGuiPlayer()) { + if (CField.this.player.isLobbyPlayer(Singletons.getControl().getGuiPlayer())) { return MatchUtil.getHumanController().useMana(colorCode.byteValue()); } return false; diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java index b704c14c1d6..f767fac2d2f 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java @@ -20,7 +20,6 @@ package forge.view.arcane; import forge.Singletons; import forge.assets.FSkinProp; import forge.game.card.CardView; -import forge.game.player.Player; import forge.game.player.PlayerView; import forge.game.zone.ZoneType; import forge.gui.framework.SDisplayUtil; @@ -169,7 +168,7 @@ public class FloatingCardArea extends CardArea { player = player0; title = Lang.getPossessedObject(player0.getName(), zone.name()) + " (%d)"; - boolean isAi = Player.get(player0).getController().isAI(); + boolean isAi = player0.isAI(); switch (zone) { case Exile: locPref = isAi ? FPref.ZONE_LOC_AI_EXILE : FPref.ZONE_LOC_HUMAN_EXILE; diff --git a/forge-gui/src/main/java/forge/match/input/InputProxy.java b/forge-gui/src/main/java/forge/match/input/InputProxy.java index c0b1881da13..23014002521 100644 --- a/forge-gui/src/main/java/forge/match/input/InputProxy.java +++ b/forge-gui/src/main/java/forge/match/input/InputProxy.java @@ -100,7 +100,7 @@ public class InputProxy implements Observer { public final void selectPlayer(final PlayerView playerView, final ITriggerEvent triggerEvent) { final Input inp = getInput(); if (inp != null) { - final Player player = Player.get(playerView); + final Player player = controller.getGame().getPlayer(playerView); if (player != null) { inp.selectPlayer(player, triggerEvent); } diff --git a/forge-gui/src/main/java/forge/match/input/InputQueue.java b/forge-gui/src/main/java/forge/match/input/InputQueue.java index a9ef3c48dbf..d8975c16355 100644 --- a/forge-gui/src/main/java/forge/match/input/InputQueue.java +++ b/forge-gui/src/main/java/forge/match/input/InputQueue.java @@ -22,7 +22,6 @@ import java.util.concurrent.BlockingDeque; import java.util.concurrent.LinkedBlockingDeque; import forge.game.Game; -import forge.game.player.Player; import forge.match.MatchUtil; import forge.player.PlayerControllerHuman; @@ -37,9 +36,11 @@ import forge.player.PlayerControllerHuman; public class InputQueue extends Observable { private final BlockingDeque inputStack = new LinkedBlockingDeque(); private final InputLockUI inputLock; + private final Game game; public InputQueue(final Game game, final InputProxy inputProxy) { inputLock = new InputLockUI(game, this); + this.game = game; addObserver(inputProxy); } @@ -76,7 +77,7 @@ public class InputQueue extends Observable { public void setInput(final InputSynchronized input) { if (MatchUtil.getHumanCount() > 1) { //update current player if needed - MatchUtil.setCurrentPlayer(Player.get(input.getOwner())); + MatchUtil.setCurrentPlayer(game.getPlayer(input.getOwner())); } inputStack.push(input); InputBase.waitForOtherPlayer(); diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index dd1d2be370c..e855fd08c4a 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -297,7 +297,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { if (nNeeded == 0) { return PaymentDecision.number(0); } - final Player p = Player.get(SGuiChoose.oneOrNone(String.format("Exile from whose %s?", cost.getFrom()), PlayerView.getCollection(payableZone))); + final Player p = controller.getGame().getPlayer(SGuiChoose.oneOrNone(String.format("Exile from whose %s?", cost.getFrom()), PlayerView.getCollection(payableZone))); if (p == null) { return null; } @@ -489,7 +489,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { final StringBuilder sb = new StringBuilder(); sb.append(source.getName()).append(" - Choose an opponent to gain ").append(c).append(" life:"); - final Player chosenToGain = Player.get(SGuiChoose.oneOrNone(sb.toString(), PlayerView.getCollection(oppsThatCanGainLife))); + final Player chosenToGain = controller.getGame().getPlayer(SGuiChoose.oneOrNone(sb.toString(), PlayerView.getCollection(oppsThatCanGainLife))); if (chosenToGain == null) { return null; } @@ -614,7 +614,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { return PaymentDecision.number(0); } - final Player p = Player.get(SGuiChoose.oneOrNone(String.format("Put cards from whose %s?", fromZone), PlayerView.getCollection(payableZone))); + final Player p = controller.getGame().getPlayer(SGuiChoose.oneOrNone(String.format("Put cards from whose %s?", fromZone), PlayerView.getCollection(payableZone))); if (p == null) { return null; } diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index 3fdb56253e5..594b492f820 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -524,7 +524,7 @@ public class HumanPlay { payableZone.add(player); } } - Player chosen = Player.get(SGuiChoose.oneOrNone(String.format("Put cards from whose %s?", from), PlayerView.getCollection(payableZone))); + Player chosen = controller.getGame().getPlayer(SGuiChoose.oneOrNone(String.format("Put cards from whose %s?", from), PlayerView.getCollection(payableZone))); if (chosen == null) { return false; } diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 0a1f2e8eee0..973da3ebf31 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -418,7 +418,13 @@ public class PlayerControllerHuman extends PlayerController { final GameEntityView result = GuiBase.getInterface().chooseSingleEntityForEffect(title, optionList, delayedReveal, isOptional, this); endTempShowCards(); //assume tempShow called by GuiBase.getInterface().chooseSingleEntityForEffect - return (T) GameEntity.get(result); + if (result instanceof CardView) { + return (T) Card.get((CardView)result); + } + if (result instanceof PlayerView) { + return (T) game.getPlayer((PlayerView)result); + } + return null; } @Override @@ -1539,7 +1545,7 @@ public class PlayerControllerHuman extends PlayerController { } public void setPlayerLife() { - final Player player = Player.get(SGuiChoose.oneOrNone("Set life for which player?", PlayerView.getCollection(game.getPlayers()))); + final Player player = game.getPlayer(SGuiChoose.oneOrNone("Set life for which player?", PlayerView.getCollection(game.getPlayers()))); if (player == null) { return; } final Integer life = SGuiChoose.getInteger("Set life to what?", 0); @@ -1569,7 +1575,7 @@ public class PlayerControllerHuman extends PlayerController { } public void addCardToHand() { - final Player p = Player.get(SGuiChoose.oneOrNone("Put card in hand for which player?", PlayerView.getCollection(game.getPlayers()))); + final Player p = game.getPlayer(SGuiChoose.oneOrNone("Put card in hand for which player?", PlayerView.getCollection(game.getPlayers()))); if (p == null) { return; } @@ -1589,7 +1595,7 @@ public class PlayerControllerHuman extends PlayerController { } public void addCardToBattlefield() { - final Player p = Player.get(SGuiChoose.oneOrNone("Put card in play for which player?", PlayerView.getCollection(game.getPlayers()))); + final Player p = game.getPlayer(SGuiChoose.oneOrNone("Put card in play for which player?", PlayerView.getCollection(game.getPlayers()))); if (p == null) { return; } @@ -1637,7 +1643,7 @@ public class PlayerControllerHuman extends PlayerController { } public void riggedPlanarRoll() { - final Player player = Player.get(SGuiChoose.oneOrNone("Which player should roll?", PlayerView.getCollection(game.getPlayers()))); + final Player player = game.getPlayer(SGuiChoose.oneOrNone("Which player should roll?", PlayerView.getCollection(game.getPlayers()))); if (player == null) { return; } final PlanarDice res = SGuiChoose.oneOrNone("Choose result", PlanarDice.values()); diff --git a/forge-gui/src/main/java/forge/quest/QuestWinLoseController.java b/forge-gui/src/main/java/forge/quest/QuestWinLoseController.java index 9a3d959fae4..f52ef8bfba6 100644 --- a/forge-gui/src/main/java/forge/quest/QuestWinLoseController.java +++ b/forge-gui/src/main/java/forge/quest/QuestWinLoseController.java @@ -63,7 +63,7 @@ public class QuestWinLoseController { final LobbyPlayer questLobbyPlayer = GamePlayerUtil.getQuestPlayer(); PlayerView player = null; for (final PlayerView p : lastGame.getPlayers()) { - if (p.getLobbyPlayer().equals(questLobbyPlayer)) { + if (p.isLobbyPlayer(questLobbyPlayer)) { player = p; } } @@ -97,7 +97,7 @@ public class QuestWinLoseController { if (anteResult.lostCards != null) { qc.getCards().loseCards(anteResult.lostCards); } - anteReport(anteResult.wonCards, anteResult.lostCards, questPlayer.getLobbyPlayer().equals(lastGame.getWinningPlayer())); + anteReport(anteResult.wonCards, anteResult.lostCards, questPlayer.isLobbyPlayer(lastGame.getWinningPlayer())); } }