diff --git a/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java b/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java index cd99a5a6d94..903f6e474a9 100644 --- a/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java +++ b/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java @@ -125,8 +125,6 @@ public class GameCopier { } } } - origGame.validateSpabCache(); - newGame.validateSpabCache(); // Undo effects first before calculating them below, to avoid them applying twice. for (StaticEffect effect : origGame.getStaticEffects().getEffects()) { diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index 75df1aa51f2..fd4f935ca3c 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -40,7 +40,6 @@ import forge.game.player.*; import forge.game.replacement.ReplacementHandler; import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityStackInstance; -import forge.game.spellability.SpellAbilityView; import forge.game.trigger.TriggerHandler; import forge.game.trigger.TriggerType; import forge.game.zone.CostPaymentStack; @@ -209,27 +208,6 @@ public class Game { changeZoneLKIInfo.clear(); } - private final GameEntityCache spabCache = new GameEntityCache<>(); - public SpellAbility getSpellAbility(final SpellAbilityView view) { - return spabCache.get(view); - } - public void addSpellAbility(SpellAbility spellAbility) { - spabCache.put(spellAbility.getId(), spellAbility); - } - public void removeSpellAbility(SpellAbility spellAbility) { - spabCache.remove(spellAbility.getId()); - } - public void validateSpabCache() { - for (SpellAbility sa : spabCache.getValues()) { - if (sa.getHostCard() != null && sa.getHostCard().getGame() != this) { - throw new RuntimeException(); - } - if (sa.getActivatingPlayer() != null && sa.getActivatingPlayer().getGame() != this) { - throw new RuntimeException(); - } - } - } - public Game(List players0, GameRules rules0, Match match0) { /* no more zones to map here */ rules = rules0; match = match0; @@ -896,7 +874,6 @@ public class Game { } public void clearCaches() { - spabCache.clear(); cardCache.clear(); lastStateBattlefield.clear(); diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 81ceddeab56..20163be99d5 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -192,9 +192,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit view0 = new SpellAbilityView(this); } view = view0; - if (hostCard != null && hostCard.getGame() != null) { - hostCard.getGame().addSpellAbility(this); - } } @Override @@ -213,13 +210,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit @Override public void setHostCard(final Card c) { if (hostCard == c) { return; } - Game oldGame = hostCard != null ? hostCard.getGame() : null; - Game newGame = c != null ? c.getGame() : null; super.setHostCard(c); - if (oldGame != newGame) { - if (oldGame != null) { oldGame.removeSpellAbility(this); } - if (newGame != null) { newGame.addSpellAbility(this); } - } if (manaPart != null) { manaPart.setSourceCard(c); @@ -892,9 +883,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit // dont use setHostCard to not trigger the not copied parts yet copyHelper(clone, host); - if (!lki && host != null && host.getGame() != null) { - host.getGame().addSpellAbility(clone); - } clone.triggeringObjects = AbilityKey.newMap(this.triggeringObjects); @@ -1996,24 +1984,4 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit public void setXManaCostPaid(final Integer n) { xManaCostPaid = n; } - - public void removeFromGame() { - if (getHostCard() == null) { - return; - } - - getHostCard().getGame().removeSpellAbility(this); - - if (subAbility != null) { - subAbility.removeFromGame(); - } - for (AbilitySub sa : additionalAbilities.values()) { - sa.removeFromGame(); - } - for (List list : additionalAbilityLists.values()) { - for (AbilitySub sa : list) { - sa.removeFromGame(); - } - } - } } diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityView.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityView.java index 20e3d91e522..a8724b54c0e 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityView.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityView.java @@ -1,8 +1,11 @@ package forge.game.spellability; +import java.util.Map; + +import com.google.common.collect.Maps; + import forge.game.card.CardView; import forge.game.card.IHasCardView; -import forge.trackable.TrackableCollection; import forge.trackable.TrackableObject; import forge.trackable.TrackableProperty; @@ -13,15 +16,12 @@ public class SpellAbilityView extends TrackableObject implements IHasCardView { return spab == null ? null : spab.getView(); } - public static TrackableCollection getCollection(Iterable spabs) { - if (spabs == null) { - return null; + public static Map getMap(Iterable spabs) { + Map spellViewCache = Maps.newLinkedHashMap(); + for (T spellAbility : spabs) { + spellViewCache.put(spellAbility.getView(), spellAbility); } - TrackableCollection collection = new TrackableCollection<>(); - for (SpellAbility spab : spabs) { - collection.add(spab.getView()); - } - return collection; + return spellViewCache; } SpellAbilityView(final SpellAbility sa) { diff --git a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java index ce5fc31cfcb..55532468591 100644 --- a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java +++ b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java @@ -563,10 +563,4 @@ public class WrappedAbility extends Ability { public void setXManaCostPaid(final Integer n) { sa.setXManaCostPaid(n); } - - @Override - public void removeFromGame() { - super.removeFromGame(); - getHostCard().getGame().removeSpellAbility(this.getWrappedAbility()); - } } \ No newline at end of file diff --git a/forge-game/src/main/java/forge/game/zone/MagicStack.java b/forge-game/src/main/java/forge/game/zone/MagicStack.java index 5755bad881d..c5847d757c3 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -640,10 +640,6 @@ public class MagicStack /* extends MyObservable */ implements Iterable spellViewCache = null; + public PlayerControllerHuman(final Game game0, final Player p, final LobbyPlayer lp) { super(game0, p, lp); inputProxy = new InputProxy(this); @@ -200,9 +201,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont @Override public SpellAbility getAbilityToPlay(final Card hostCard, final List abilities, final ITriggerEvent triggerEvent) { + spellViewCache = SpellAbilityView.getMap(abilities); final SpellAbilityView resultView = getGui().getAbilityToPlay(CardView.get(hostCard), - SpellAbilityView.getCollection(abilities), triggerEvent); - return getGame().getSpellAbility(resultView); + Lists.newArrayList(spellViewCache.keySet()), triggerEvent); + return resultView == null ? null : spellViewCache.get(resultView); } @Override @@ -547,12 +549,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont getGui().setCard(CardView.get(sa.getHostCard())); // create a mapping between a spell's view and the spell itself - HashMap spellViewCache = new HashMap<>(); - for (SpellAbility spellAbility : spells) { - spellViewCache.put(spellAbility.getView(), spellAbility); - } - List choices = new ArrayList<>(spellViewCache.keySet()); - Object choice = getGui().one(title, choices); + Map spellViewCache = SpellAbilityView.getMap(spells); + Object choice = getGui().one(title, Lists.newArrayList(spellViewCache.keySet())); // Human is supposed to read the message and understand from it what to // choose @@ -1489,14 +1487,11 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont game.getTracker().unfreeze(); } final List possible = CharmEffect.makePossibleOptions(sa); - LinkedHashMap spellViewCache = new LinkedHashMap<>(); - for (AbilitySub spellAbility : possible) { - spellViewCache.put(spellAbility.getView(), spellAbility); - } + Map spellViewCache = SpellAbilityView.getMap(possible); if (trackerFrozen) { game.getTracker().freeze(); // refreeze if the tracker was frozen prior to this update } - final List choices = new ArrayList<>(spellViewCache.keySet()); + final List choices = Lists.newArrayList(spellViewCache.keySet()); final String modeTitle = localizer.getMessage("lblPlayerActivatedCardChooseMode", sa.getActivatingPlayer().toString(), CardTranslation.getTranslatedName(sa.getHostCard().getName())); final List chosen = Lists.newArrayListWithCapacity(num); for (int i = 0; i < num; i++) { @@ -1666,10 +1661,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont List orderedSAVs = Lists.newArrayList(); // create a mapping between a spell's view and the spell itself - HashMap spellViewCache = new HashMap<>(); - for (SpellAbility spellAbility : orderedSAs) { - spellViewCache.put(spellAbility.getView(), spellAbility); - } + Map spellViewCache = SpellAbilityView.getMap(orderedSAs); if (savedOrder != null) { orderedSAVs = Lists.newArrayList(); @@ -1937,7 +1929,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont @Override public void selectAbility(final SpellAbilityView sa) { - inputProxy.selectAbility(getGame().getSpellAbility(sa)); + if (spellViewCache == null || spellViewCache.isEmpty()) { + return; + } + inputProxy.selectAbility(spellViewCache.get(sa)); } @Override