From 60fb7d880944518cf17dd09dd95a3454da6b3c2e Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Tue, 24 Sep 2019 22:03:09 -0600 Subject: [PATCH 01/17] add myself to `CONTRIBUTORS.txt` --- forge-gui/release-files/CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/forge-gui/release-files/CONTRIBUTORS.txt b/forge-gui/release-files/CONTRIBUTORS.txt index 2ff5c065a82..e629c816105 100644 --- a/forge-gui/release-files/CONTRIBUTORS.txt +++ b/forge-gui/release-files/CONTRIBUTORS.txt @@ -19,6 +19,7 @@ Myrd nefigah OgreBattlecruiser pfps +Ryan1729 Seravy Sirspud Sloth From 6da178c8ae0b0be50968a37b0f928cb49e0bb04b Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Tue, 24 Sep 2019 22:31:46 -0600 Subject: [PATCH 02/17] use the same `methodNameOld` trick as before with `runTrigger` --- .../src/main/java/forge/game/GameAction.java | 4 +- .../src/main/java/forge/game/GameEntity.java | 4 +- .../game/ability/effects/CounterEffect.java | 2 +- .../ability/effects/ReplaceDamageEffect.java | 2 +- .../game/ability/effects/ReplaceEffect.java | 2 +- .../effects/ReplaceSplitDamageEffect.java | 2 +- .../src/main/java/forge/game/card/Card.java | 6 +- .../java/forge/game/card/token/TokenInfo.java | 2 +- .../main/java/forge/game/player/Player.java | 16 ++--- .../game/replacement/ReplacementHandler.java | 66 +++++++++++-------- .../game/spellability/AbilityManaPart.java | 2 +- 11 files changed, 60 insertions(+), 48 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 9e3aeb0c06c..4661f40d5dc 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -303,7 +303,7 @@ public class GameAction { repParams.putAll(params); } - ReplacementResult repres = game.getReplacementHandler().run(ReplacementType.Moved, toStringMap(repParams)); + ReplacementResult repres = game.getReplacementHandler().runOld(ReplacementType.Moved, toStringMap(repParams)); if (repres != ReplacementResult.NotReplaced) { // reset failed manifested Cards back to original if (c.isManifested()) { @@ -1404,7 +1404,7 @@ public class GameAction { repRunParams.put("Affected", c); repRunParams.put("Regeneration", regenerate); - if (game.getReplacementHandler().run(ReplacementType.Destroy, repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().runOld(ReplacementType.Destroy, repRunParams) != ReplacementResult.NotReplaced) { return false; } diff --git a/forge-game/src/main/java/forge/game/GameEntity.java b/forge-game/src/main/java/forge/game/GameEntity.java index c8a82cbf8d2..d856722e2b7 100644 --- a/forge-game/src/main/java/forge/game/GameEntity.java +++ b/forge-game/src/main/java/forge/game/GameEntity.java @@ -128,7 +128,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { repParams.put("Cause", cause); } - switch (getGame().getReplacementHandler().run(ReplacementType.DamageDone, repParams)) { + switch (getGame().getReplacementHandler().runOld(ReplacementType.DamageDone, repParams)) { case NotReplaced: return damage; case Updated: @@ -181,7 +181,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { repParams.put("Cause", cause); } - switch (getGame().getReplacementHandler().run(ReplacementType.DamageDone, repParams)) { + switch (getGame().getReplacementHandler().runOld(ReplacementType.DamageDone, repParams)) { case NotReplaced: restDamage = damage; break; diff --git a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java index 1c072cf3dba..f26a9bda9e0 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java @@ -159,7 +159,7 @@ public class CounterEffect extends SpellAbilityEffect { repParams.put("TgtSA", tgtSA); repParams.put("Affected", tgtSA.getHostCard()); repParams.put("Cause", srcSA.getHostCard()); - if (game.getReplacementHandler().run(ReplacementType.Counter, repParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().runOld(ReplacementType.Counter, repParams) != ReplacementResult.NotReplaced) { return; } game.getStack().remove(si); diff --git a/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java index 6620b89c346..5c0786596d7 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java @@ -61,7 +61,7 @@ public class ReplaceDamageEffect extends SpellAbilityEffect { //try to call replacementHandler with new Params - ReplacementResult result = game.getReplacementHandler().run(event, params); + ReplacementResult result = game.getReplacementHandler().runOld(event, params); switch (result) { case NotReplaced: case Updated: { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java index 260eb307491..168faea6fc6 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java @@ -61,7 +61,7 @@ public class ReplaceEffect extends SpellAbilityEffect { } //try to call replacementHandler with new Params - ReplacementResult result = game.getReplacementHandler().run(retype, params); + ReplacementResult result = game.getReplacementHandler().runOld(retype, params); switch (result) { case NotReplaced: case Updated: { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java index 4d504b97c28..3ec56f5b801 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java @@ -80,7 +80,7 @@ public class ReplaceSplitDamageEffect extends SpellAbilityEffect { params.put("DamageAmount", dmg); //try to call replacementHandler with new Params - ReplacementResult result = game.getReplacementHandler().run(event, params); + ReplacementResult result = game.getReplacementHandler().runOld(event, params); switch (result) { case NotReplaced: case Updated: { diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index f1925b5d307..a2048b02963 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -689,7 +689,7 @@ public class Card extends GameEntity implements Comparable { // Run replacement effects Map repParams = Maps.newHashMap(); repParams.put("Affected", this); - getGame().getReplacementHandler().run(ReplacementType.TurnFaceUp, repParams); + getGame().getReplacementHandler().runOld(ReplacementType.TurnFaceUp, repParams); // Run triggers getGame().getTriggerHandler().registerActiveTrigger(this, false); @@ -1240,7 +1240,7 @@ public class Card extends GameEntity implements Comparable { repParams.put("CounterNum", addAmount); repParams.put("EffectOnly", applyMultiplier); - switch (getGame().getReplacementHandler().run(ReplacementType.AddCounter, repParams)) { + switch (getGame().getReplacementHandler().runOld(ReplacementType.AddCounter, repParams)) { case NotReplaced: break; case Updated: { @@ -3575,7 +3575,7 @@ public class Card extends GameEntity implements Comparable { final Map repRunParams = Maps.newHashMap(); repRunParams.put("Affected", this); - if (getGame().getReplacementHandler().run(ReplacementType.Untap, repRunParams) != ReplacementResult.NotReplaced) { + if (getGame().getReplacementHandler().runOld(ReplacementType.Untap, repRunParams) != ReplacementResult.NotReplaced) { return; } diff --git a/forge-game/src/main/java/forge/game/card/token/TokenInfo.java b/forge-game/src/main/java/forge/game/card/token/TokenInfo.java index 59000cb3b8f..9ce07d63e13 100644 --- a/forge-game/src/main/java/forge/game/card/token/TokenInfo.java +++ b/forge-game/src/main/java/forge/game/card/token/TokenInfo.java @@ -172,7 +172,7 @@ public class TokenInfo { repParams.put("TokenNum", multiplier); repParams.put("EffectOnly", applyMultiplier); - switch (game.getReplacementHandler().run(ReplacementType.CreateToken, repParams)) { + switch (game.getReplacementHandler().runOld(ReplacementType.CreateToken, repParams)) { case NotReplaced: break; case Updated: { 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 02b148414e7..ca6ef357618 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -238,7 +238,7 @@ public class Player extends GameEntity implements Comparable { final Map repRunParams = Maps.newHashMap(); repRunParams.put("Affected", this); - if (game.getReplacementHandler().run(ReplacementType.SetInMotion, repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().runOld(ReplacementType.SetInMotion, repRunParams) != ReplacementResult.NotReplaced) { return; } @@ -412,7 +412,7 @@ public class Player extends GameEntity implements Comparable { return false; } - switch (getGame().getReplacementHandler().run(ReplacementType.GainLife, repParams)) { + switch (getGame().getReplacementHandler().runOld(ReplacementType.GainLife, repParams)) { case NotReplaced: break; case Updated: @@ -921,7 +921,7 @@ public class Player extends GameEntity implements Comparable { repParams.put("CounterNum", addAmount); repParams.put("EffectOnly", applyMultiplier); - switch (getGame().getReplacementHandler().run(ReplacementType.AddCounter, repParams)) { + switch (getGame().getReplacementHandler().runOld(ReplacementType.AddCounter, repParams)) { case NotReplaced: break; case Updated: { @@ -1281,7 +1281,7 @@ public class Player extends GameEntity implements Comparable { repParams.put("Source", cause); repParams.put("SurveilNum", num); - switch (getGame().getReplacementHandler().run(ReplacementType.Surveil, repParams)) { + switch (getGame().getReplacementHandler().runOld(ReplacementType.Surveil, repParams)) { case NotReplaced: break; case Updated: { @@ -1350,7 +1350,7 @@ public class Player extends GameEntity implements Comparable { repRunParams.put("Affected", this); repRunParams.put("Number", n); - if (game.getReplacementHandler().run(ReplacementType.DrawCards, repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().runOld(ReplacementType.DrawCards, repRunParams) != ReplacementResult.NotReplaced) { return drawn; } @@ -1381,7 +1381,7 @@ public class Player extends GameEntity implements Comparable { final Map repRunParams = Maps.newHashMap(); repRunParams.put("Affected", this); - if (game.getReplacementHandler().run(ReplacementType.Draw, repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().runOld(ReplacementType.Draw, repRunParams) != ReplacementResult.NotReplaced) { return drawn; } @@ -1561,7 +1561,7 @@ public class Player extends GameEntity implements Comparable { repRunParams.put("Source", source); repRunParams.put("Affected", this); - if (game.getReplacementHandler().run(ReplacementType.Discard, repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().runOld(ReplacementType.Discard, repRunParams) != ReplacementResult.NotReplaced) { return null; } } @@ -1864,7 +1864,7 @@ public class Player extends GameEntity implements Comparable { final Map runParams = Maps.newHashMap(); runParams.put("Affected", this); - if (game.getReplacementHandler().run(ReplacementType.GameLoss, runParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().runOld(ReplacementType.GameLoss, runParams) != ReplacementResult.NotReplaced) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java index 272388ef303..eec2171b2d4 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -21,6 +21,7 @@ import forge.card.MagicColor; import forge.game.Game; import forge.game.GameLogEntryType; import forge.game.ability.AbilityFactory; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.card.CardCollection; @@ -40,6 +41,8 @@ import com.google.common.collect.Sets; import java.util.*; +import static forge.util.EnumMapUtil.toStringMap; + public class ReplacementHandler { private final Game game; /** @@ -52,30 +55,6 @@ public class ReplacementHandler { //private final List tmpEffects = new ArrayList(); - public ReplacementResult run(ReplacementType event, final Map runParams) { - final Object affected = runParams.get("Affected"); - Player decider = null; - - // Figure out who decides which of multiple replacements to apply - // as well as whether or not to apply optional replacements. - if (affected instanceof Player) { - decider = (Player) affected; - } else { - decider = ((Card) affected).getController(); - } - - // try out all layer - for (ReplacementLayer layer : ReplacementLayer.values()) { - ReplacementResult res = run(event, runParams, layer, decider); - if (res != ReplacementResult.NotReplaced) { - return res; - } - } - - return ReplacementResult.NotReplaced; - - } - public List getReplacementList(final ReplacementType event, final Map runParams, final ReplacementLayer layer) { final CardCollection preList = new CardCollection(); @@ -171,9 +150,42 @@ public class ReplacementHandler { * * @param runParams * the run params,same as for triggers. - * @return true if the event was replaced. + * @return ReplacementResult, an enum that represents what happened to the replacement effect. */ - public ReplacementResult run(final ReplacementType event, final Map runParams, final ReplacementLayer layer, final Player decider) { + public ReplacementResult run(ReplacementType event, final Map runParams) { + return runOld(event, toStringMap(runParams)); + } + + // The plan is to slowly refactor any usages of runOld to use run. Then we can just inline + // runOld into run and change the code inside to just always use a Map. + // The reason we can't just call them both run is because we get a same erasure compile error if we do. + @Deprecated + public ReplacementResult runOld(ReplacementType event, final Map runParams) { + final Object affected = runParams.get("Affected"); + Player decider = null; + + // Figure out who decides which of multiple replacements to apply + // as well as whether or not to apply optional replacements. + if (affected instanceof Player) { + decider = (Player) affected; + } else { + decider = ((Card) affected).getController(); + } + + // try out all layer + for (ReplacementLayer layer : ReplacementLayer.values()) { + ReplacementResult res = run(event, runParams, layer, decider); + if (res != ReplacementResult.NotReplaced) { + return res; + } + } + + return ReplacementResult.NotReplaced; + + } + + @Deprecated + private ReplacementResult run(final ReplacementType event, final Map runParams, final ReplacementLayer layer, final Player decider) { final List possibleReplacers = getReplacementList(event, runParams, layer); if (possibleReplacers.isEmpty()) { @@ -189,7 +201,7 @@ public class ReplacementHandler { ReplacementResult res = executeReplacement(runParams, chosenRE, decider, game); if (res == ReplacementResult.NotReplaced) { if (!possibleReplacers.isEmpty()) { - res = run(event, runParams); + res = runOld(event, runParams); } chosenRE.setHasRun(false); chosenRE.setOtherChoices(null); diff --git a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java index 8d1cd6db131..e409f24961d 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java @@ -133,7 +133,7 @@ public class AbilityManaPart implements java.io.Serializable { repParams.put("Affected", source); repParams.put("Player", player); repParams.put("AbilityMana", sa); - if (player.getGame().getReplacementHandler().run(ReplacementType.ProduceMana, repParams) != ReplacementResult.NotReplaced) { + if (player.getGame().getReplacementHandler().runOld(ReplacementType.ProduceMana, repParams) != ReplacementResult.NotReplaced) { return; } //clear lastProduced From 5298b8666d9a5b4c2f9b85e4f77b905312be5714 Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Wed, 25 Sep 2019 00:04:28 -0600 Subject: [PATCH 03/17] refactor `getReplacementList` to use `AbiltyKey` as much as currently possible --- .../src/main/java/forge/ai/ComputerUtil.java | 24 ++++++++++--------- .../java/forge/ai/ComputerUtilCombat.java | 14 +++++------ .../java/forge/ai/ability/ManifestAi.java | 11 +++++---- .../java/forge/game/ability/AbilityKey.java | 5 +++- .../game/replacement/ReplacementHandler.java | 10 ++++++-- 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index f8550ba8066..102e6ccc4ea 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -29,6 +29,7 @@ import forge.card.MagicColor; import forge.card.mana.ManaCostShard; import forge.game.*; import forge.game.ability.AbilityFactory; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.ability.effects.CharmEffect; @@ -2849,10 +2850,10 @@ public class ComputerUtil { } // Run any applicable replacement effects. - final Map repParams = Maps.newHashMap(); - repParams.put("Affected", player); - repParams.put("LifeGained", 1); - repParams.put("Source", source); + final Map repParams = AbilityKey.newMap(); + repParams.put(AbilityKey.Affected, player); + repParams.put(AbilityKey.LifeGained, 1); + repParams.put(AbilityKey.Source, source); List list = player.getGame().getReplacementHandler().getReplacementList( ReplacementType.GainLife, @@ -2880,15 +2881,16 @@ public class ComputerUtil { } // Run any applicable replacement effects. - final Map repParams = Maps.newHashMap(); - repParams.put("Affected", player); - repParams.put("LifeGained", n); - repParams.put("Source", source); + final Map repParams = AbilityKey.newMap(); + repParams.put(AbilityKey.Affected, player); + repParams.put(AbilityKey.LifeGained, n); + repParams.put(AbilityKey.Source, source); List list = player.getGame().getReplacementHandler().getReplacementList( - ReplacementType.GainLife, - repParams, - ReplacementLayer.Other); + ReplacementType.GainLife, + repParams, + ReplacementLayer.Other + ); if (Iterables.any(list, CardTraitPredicates.hasParam("AiLogic", "NoLife"))) { // no life gain is not negative diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index d1616e3ab7f..7f90ba83941 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -30,6 +30,7 @@ import forge.game.Game; import forge.game.GameEntity; import forge.game.GlobalRuleChange; import forge.game.ability.AbilityFactory; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.card.*; @@ -2583,13 +2584,12 @@ public class ComputerUtilCombat { final Game game = attacker.getGame(); // first try to replace the damage - final Map repParams = Maps.newHashMap(); - repParams.put("Affected", target); - repParams.put("DamageSource", attacker); - repParams.put("DamageAmount", damage); - repParams.put("IsCombat", true); - repParams.put("Prevention", true); - // repParams.put("PreventMap", preventMap); + final Map repParams = AbilityKey.newMap(); + repParams.put(AbilityKey.Affected, target); + repParams.put(AbilityKey.DamageSource, attacker); + repParams.put(AbilityKey.DamageAmount, damage); + repParams.put(AbilityKey.IsCombat, true); + repParams.put(AbilityKey.Prevention, true); List list = game.getReplacementHandler().getReplacementList( ReplacementType.DamageDone, repParams, ReplacementLayer.Other); diff --git a/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java b/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java index f98cd0bd02e..e913008e014 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java @@ -8,6 +8,7 @@ import forge.ai.ComputerUtilCard; import forge.ai.ComputerUtilMana; import forge.ai.SpellAbilityAi; import forge.game.Game; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.card.CardCollection; import forge.game.card.CardCollectionView; @@ -97,11 +98,11 @@ public class ManifestAi extends SpellAbilityAi { topCopy.turnFaceDownNoUpdate(); topCopy.setManifested(true); - final Map repParams = Maps.newHashMap(); - repParams.put("Affected", topCopy); - repParams.put("Origin", card.getZone().getZoneType()); - repParams.put("Destination", ZoneType.Battlefield); - repParams.put("Source", sa.getHostCard()); + final Map repParams = AbilityKey.newMap(); + repParams.put(AbilityKey.Affected, topCopy); + repParams.put(AbilityKey.Origin, card.getZone().getZoneType()); + repParams.put(AbilityKey.Destination, ZoneType.Battlefield); + repParams.put(AbilityKey.Source, sa.getHostCard()); List list = game.getReplacementHandler().getReplacementList(ReplacementType.Moved, repParams, ReplacementLayer.Other); if (!list.isEmpty()) { return false; diff --git a/forge-game/src/main/java/forge/game/ability/AbilityKey.java b/forge-game/src/main/java/forge/game/ability/AbilityKey.java index a33cd8e8f3e..f97a215bd31 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityKey.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityKey.java @@ -59,10 +59,12 @@ public enum AbilityKey { Fighter("Fighter"), FirstTime("FirstTime"), Fizzle("Fizzle"), + IsCombat("IsCombat"), // TODO confirm that this and IsCombatDamage can be merged IsCombatDamage("IsCombatDamage"), IndividualCostPaymentInstance("IndividualCostPaymentInstance"), IsMadness("IsMadness"), - LifeAmount("LifeAmount"), + LifeAmount("LifeAmount"), //TODO confirm that this and LifeGained can be merged + LifeGained("LifeGained"), MonstrosityAmount("MonstrosityAmount"), NewCounterAmount("NewCounterAmount"), Num("Num"), // TODO confirm that this and NumThisTurn can be merged @@ -79,6 +81,7 @@ public enum AbilityKey { PayingMana("PayingMana"), Phase("Phase"), Player("Player"), + Prevention("Prevention"), Produced("Produced"), Result("Result"), Scheme("Scheme"), diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java index eec2171b2d4..e33cebcdb25 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -55,7 +55,13 @@ public class ReplacementHandler { //private final List tmpEffects = new ArrayList(); - public List getReplacementList(final ReplacementType event, final Map runParams, final ReplacementLayer layer) { + public List getReplacementList(final ReplacementType event, final Map runParams, final ReplacementLayer layer) { + return getReplacementListOld(event, toStringMap(runParams), layer); + } + // The plan is to slowly refactor any usages of getReplacementListOld to use getReplacementList. Then we can just inline + // getReplacementListOld into getReplacementList and change the code inside to just always use a Map. + // The reason we can't just call them both getReplacementList is because we get a same erasure compile error if we do. + private List getReplacementListOld(final ReplacementType event, final Map runParams, final ReplacementLayer layer) { final CardCollection preList = new CardCollection(); boolean checkAgain = false; @@ -186,7 +192,7 @@ public class ReplacementHandler { @Deprecated private ReplacementResult run(final ReplacementType event, final Map runParams, final ReplacementLayer layer, final Player decider) { - final List possibleReplacers = getReplacementList(event, runParams, layer); + final List possibleReplacers = getReplacementListOld(event, runParams, layer); if (possibleReplacers.isEmpty()) { return ReplacementResult.NotReplaced; From 94b39d726117c2147755336f9100ea5e657449a2 Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Wed, 25 Sep 2019 00:17:14 -0600 Subject: [PATCH 04/17] do the first couple `runOld` to `run refactors --- forge-game/src/main/java/forge/game/GameAction.java | 2 +- forge-game/src/main/java/forge/game/card/Card.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 4661f40d5dc..a7e6ac0045e 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -303,7 +303,7 @@ public class GameAction { repParams.putAll(params); } - ReplacementResult repres = game.getReplacementHandler().runOld(ReplacementType.Moved, toStringMap(repParams)); + ReplacementResult repres = game.getReplacementHandler().run(ReplacementType.Moved, repParams); if (repres != ReplacementResult.NotReplaced) { // reset failed manifested Cards back to original if (c.isManifested()) { diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index a2048b02963..85928cf97c5 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -687,9 +687,9 @@ public class Card extends GameEntity implements Comparable { if (result && runTriggers) { // Run replacement effects - Map repParams = Maps.newHashMap(); - repParams.put("Affected", this); - getGame().getReplacementHandler().runOld(ReplacementType.TurnFaceUp, repParams); + Map repParams = AbilityKey.newMap(); + repParams.put(AbilityKey.Affected, this); + getGame().getReplacementHandler().run(ReplacementType.TurnFaceUp, repParams); // Run triggers getGame().getTriggerHandler().registerActiveTrigger(this, false); From 9d39ce5dda25aa3254dae7180007343594ce6f78 Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Wed, 25 Sep 2019 00:31:35 -0600 Subject: [PATCH 05/17] remove unused import --- forge-game/src/main/java/forge/game/GameAction.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index a7e6ac0045e..165c9247d79 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -55,8 +55,6 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import java.util.*; -import static forge.util.EnumMapUtil.toStringMap; - /** * Methods for common actions performed during a game. * From 15e5d68520eb37437ea53394bfeda7644e50e5eb Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Wed, 25 Sep 2019 08:03:32 +0000 Subject: [PATCH 06/17] Update ManifestAi: unused import --- forge-ai/src/main/java/forge/ai/ability/ManifestAi.java | 1 - 1 file changed, 1 deletion(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java b/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java index e913008e014..f5b399102a3 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java @@ -2,7 +2,6 @@ package forge.ai.ability; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; import forge.ai.ComputerUtil; import forge.ai.ComputerUtilCard; import forge.ai.ComputerUtilMana; From c9b66d974320e832694fa005b691dfae0f62da99 Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Wed, 25 Sep 2019 19:50:00 -0600 Subject: [PATCH 07/17] add `mapFromAffected` convenience function --- forge-ai/src/main/java/forge/ai/ComputerUtil.java | 6 ++---- forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java | 3 +-- forge-ai/src/main/java/forge/ai/ability/ManifestAi.java | 3 +-- forge-game/src/main/java/forge/game/GameAction.java | 3 +-- .../src/main/java/forge/game/ability/AbilityKey.java | 8 ++++++++ forge-game/src/main/java/forge/game/card/Card.java | 4 +--- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index 102e6ccc4ea..f6c451b0668 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -2850,8 +2850,7 @@ public class ComputerUtil { } // Run any applicable replacement effects. - final Map repParams = AbilityKey.newMap(); - repParams.put(AbilityKey.Affected, player); + final Map repParams = AbilityKey.mapFromAffected(player); repParams.put(AbilityKey.LifeGained, 1); repParams.put(AbilityKey.Source, source); @@ -2881,8 +2880,7 @@ public class ComputerUtil { } // Run any applicable replacement effects. - final Map repParams = AbilityKey.newMap(); - repParams.put(AbilityKey.Affected, player); + final Map repParams = AbilityKey.mapFromAffected(player); repParams.put(AbilityKey.LifeGained, n); repParams.put(AbilityKey.Source, source); diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index 7f90ba83941..a81da13c9ba 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -2584,8 +2584,7 @@ public class ComputerUtilCombat { final Game game = attacker.getGame(); // first try to replace the damage - final Map repParams = AbilityKey.newMap(); - repParams.put(AbilityKey.Affected, target); + final Map repParams = AbilityKey.mapFromAffected(target); repParams.put(AbilityKey.DamageSource, attacker); repParams.put(AbilityKey.DamageAmount, damage); repParams.put(AbilityKey.IsCombat, true); diff --git a/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java b/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java index e913008e014..6983e70b096 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java @@ -98,8 +98,7 @@ public class ManifestAi extends SpellAbilityAi { topCopy.turnFaceDownNoUpdate(); topCopy.setManifested(true); - final Map repParams = AbilityKey.newMap(); - repParams.put(AbilityKey.Affected, topCopy); + final Map repParams = AbilityKey.mapFromAffected(topCopy); repParams.put(AbilityKey.Origin, card.getZone().getZoneType()); repParams.put(AbilityKey.Destination, ZoneType.Battlefield); repParams.put(AbilityKey.Source, sa.getHostCard()); diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 165c9247d79..6311663807c 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -290,8 +290,7 @@ public class GameAction { copied.getOwner().addInboundToken(copied); } - Map repParams = AbilityKey.newMap(); - repParams.put(AbilityKey.Affected, copied); + Map repParams = AbilityKey.mapFromAffected(copied); repParams.put(AbilityKey.CardLKI, lastKnownInfo); repParams.put(AbilityKey.Cause, cause); repParams.put(AbilityKey.Origin, zoneFrom != null ? zoneFrom.getZoneType() : null); diff --git a/forge-game/src/main/java/forge/game/ability/AbilityKey.java b/forge-game/src/main/java/forge/game/ability/AbilityKey.java index f97a215bd31..8307cb95cbd 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityKey.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityKey.java @@ -3,6 +3,7 @@ package forge.game.ability; import java.util.EnumMap; import java.util.Map; +import forge.game.GameEntity; import forge.game.card.Card; /** @@ -144,4 +145,11 @@ public enum AbilityKey { runParams.put(Card, card); return runParams; } + + public static Map mapFromAffected(GameEntity gameEntity) { + final Map runParams = newMap(); + + runParams.put(Affected, gameEntity); + return runParams; + } } diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 85928cf97c5..4beb976b28c 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -687,9 +687,7 @@ public class Card extends GameEntity implements Comparable { if (result && runTriggers) { // Run replacement effects - Map repParams = AbilityKey.newMap(); - repParams.put(AbilityKey.Affected, this); - getGame().getReplacementHandler().run(ReplacementType.TurnFaceUp, repParams); + getGame().getReplacementHandler().run(ReplacementType.TurnFaceUp, AbilityKey.mapFromAffected(this)); // Run triggers getGame().getTriggerHandler().registerActiveTrigger(this, false); From a9e97d65085edfdf63836332a383bb1b88134b87 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Thu, 26 Sep 2019 12:29:52 +0000 Subject: [PATCH 08/17] Update Player: use some mapFromAffected --- .../src/main/java/forge/game/player/Player.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) 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 ca6ef357618..898ef9d1b3e 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -235,10 +235,7 @@ public class Player extends GameEntity implements Comparable { } // Replacement effects - final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Affected", this); - - if (game.getReplacementHandler().runOld(ReplacementType.SetInMotion, repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(ReplacementType.SetInMotion, AbilityKey.mapFromAffected(this)) != ReplacementResult.NotReplaced) { return; } @@ -1378,10 +1375,7 @@ public class Player extends GameEntity implements Comparable { final PlayerZone library = getZone(ZoneType.Library); // Replacement effects - final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Affected", this); - - if (game.getReplacementHandler().runOld(ReplacementType.Draw, repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(ReplacementType.Draw, AbilityKey.mapFromAffected(this)) != ReplacementResult.NotReplaced) { return drawn; } @@ -1861,10 +1855,7 @@ public class Player extends GameEntity implements Comparable { } // Replacement effects - final Map runParams = Maps.newHashMap(); - runParams.put("Affected", this); - - if (game.getReplacementHandler().runOld(ReplacementType.GameLoss, runParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(ReplacementType.GameLoss, AbilityKey.mapFromAffected(this)) != ReplacementResult.NotReplaced) { return false; } } From a3b0d8ac3cd4bcda83eb50c71d5ce76c98fd0685 Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Fri, 27 Sep 2019 01:25:04 -0600 Subject: [PATCH 09/17] do the remaining easy `repRunParams` changeovers --- .../src/main/java/forge/game/GameAction.java | 11 ++-- .../src/main/java/forge/game/GameEntity.java | 44 +++++++-------- .../java/forge/game/ability/AbilityKey.java | 12 ++++ .../game/ability/effects/CounterEffect.java | 9 ++- .../src/main/java/forge/game/card/Card.java | 20 +++---- .../java/forge/game/card/token/TokenInfo.java | 18 +++--- .../main/java/forge/game/player/Player.java | 55 +++++++++---------- .../game/spellability/AbilityManaPart.java | 11 ++-- 8 files changed, 89 insertions(+), 91 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 6311663807c..8760379783a 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -1395,13 +1395,12 @@ public class GameAction { } // Replacement effects - final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Source", sa); - repRunParams.put("Card", c); - repRunParams.put("Affected", c); - repRunParams.put("Regeneration", regenerate); + final Map repRunParams = AbilityKey.mapFromCard(c); + repRunParams.put(AbilityKey.Source, sa); + repRunParams.put(AbilityKey.Affected, c); + repRunParams.put(AbilityKey.Regeneration, regenerate); - if (game.getReplacementHandler().runOld(ReplacementType.Destroy, repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(ReplacementType.Destroy, repRunParams) != ReplacementResult.NotReplaced) { return false; } diff --git a/forge-game/src/main/java/forge/game/GameEntity.java b/forge-game/src/main/java/forge/game/GameEntity.java index d856722e2b7..9c9bbd46c3d 100644 --- a/forge-game/src/main/java/forge/game/GameEntity.java +++ b/forge-game/src/main/java/forge/game/GameEntity.java @@ -115,25 +115,24 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { public int replaceDamage(final int damage, final Card source, final boolean isCombat, final boolean prevention, final CardDamageMap damageMap, final CardDamageMap preventMap, GameEntityCounterTable counterTable, final SpellAbility cause) { // Replacement effects - final Map repParams = Maps.newHashMap(); - repParams.put("Affected", this); - repParams.put("DamageSource", source); - repParams.put("DamageAmount", damage); - repParams.put("IsCombat", isCombat); - repParams.put("NoPreventDamage", !prevention); - repParams.put("DamageMap", damageMap); - repParams.put("PreventMap", preventMap); - repParams.put("CounterTable", counterTable); + final Map repParams = AbilityKey.mapFromAffected(this); + repParams.put(AbilityKey.DamageSource, source); + repParams.put(AbilityKey.DamageAmount, damage); + repParams.put(AbilityKey.IsCombat, isCombat); + repParams.put(AbilityKey.NoPreventDamage, !prevention); + repParams.put(AbilityKey.DamageMap, damageMap); + repParams.put(AbilityKey.PreventMap, preventMap); + repParams.put(AbilityKey.CounterTable, counterTable); if (cause != null) { - repParams.put("Cause", cause); + repParams.put(AbilityKey.Cause, cause); } - switch (getGame().getReplacementHandler().runOld(ReplacementType.DamageDone, repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.DamageDone, repParams)) { case NotReplaced: return damage; case Updated: - int newDamage = (int) repParams.get("DamageAmount"); - GameEntity newTarget = (GameEntity) repParams.get("Affected"); + int newDamage = (int) repParams.get(AbilityKey.DamageAmount); + GameEntity newTarget = (GameEntity) repParams.get(AbilityKey.Affected); // check if this is still the affected card or player if (this.equals(newTarget)) { return newDamage; @@ -170,23 +169,22 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { int restDamage = damage; // first try to replace the damage - final Map repParams = Maps.newHashMap(); - repParams.put("Affected", this); - repParams.put("DamageSource", source); - repParams.put("DamageAmount", damage); - repParams.put("IsCombat", isCombat); - repParams.put("Prevention", true); - repParams.put("PreventMap", preventMap); + final Map repParams = AbilityKey.mapFromAffected(this); + repParams.put(AbilityKey.DamageSource, source); + repParams.put(AbilityKey.DamageAmount, damage); + repParams.put(AbilityKey.IsCombat, isCombat); + repParams.put(AbilityKey.Prevention, true); + repParams.put(AbilityKey.PreventMap, preventMap); if (cause != null) { - repParams.put("Cause", cause); + repParams.put(AbilityKey.Cause, cause); } - switch (getGame().getReplacementHandler().runOld(ReplacementType.DamageDone, repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.DamageDone, repParams)) { case NotReplaced: restDamage = damage; break; case Updated: - restDamage = (int) repParams.get("DamageAmount"); + restDamage = (int) repParams.get(AbilityKey.DamageAmount); break; default: restDamage = 0; diff --git a/forge-game/src/main/java/forge/game/ability/AbilityKey.java b/forge-game/src/main/java/forge/game/ability/AbilityKey.java index 8307cb95cbd..c2ce43ef6e3 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityKey.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityKey.java @@ -38,12 +38,15 @@ public enum AbilityKey { CostStack("CostStack"), CounterAmount("CounterAmount"), CounteredSA("CounteredSA"), + CounterNum("CounterNum"), + CounterTable("CounterTable"), CounterType("CounterType"), Crew("Crew"), CumulativeUpkeepPaid("CumulativeUpkeepPaid"), CurrentCastSpells("CurrentCastSpells"), CurrentStormCount("CurrentStormCount"), DamageAmount("DamageAmount"), + DamageMap("DamageMap"), DamageSource("DamageSource"), DamageSources("DamageSources"), DamageTarget("DamageTarget"), @@ -54,6 +57,7 @@ public enum AbilityKey { Destination("Destination"), Devoured("Devoured"), EchoPaid("EchoPaid"), + EffectOnly("EffectOnly"), Exploited("Exploited"), Explorer("Explorer"), Event("Event"), @@ -66,8 +70,10 @@ public enum AbilityKey { IsMadness("IsMadness"), LifeAmount("LifeAmount"), //TODO confirm that this and LifeGained can be merged LifeGained("LifeGained"), + Mana("Mana"), MonstrosityAmount("MonstrosityAmount"), NewCounterAmount("NewCounterAmount"), + NoPreventDamage("NoPreventDamage"), Num("Num"), // TODO confirm that this and NumThisTurn can be merged NumBlockers("NumBlockers"), NumThisTurn("NumThisTurn"), @@ -82,8 +88,10 @@ public enum AbilityKey { PayingMana("PayingMana"), Phase("Phase"), Player("Player"), + PreventMap("PreventMap"), Prevention("Prevention"), Produced("Produced"), + Regeneration("Regeneration"), Result("Result"), Scheme("Scheme"), Source("Source"), @@ -95,8 +103,12 @@ public enum AbilityKey { StackInstance("StackInstance"), StackSa("StackSa"), StackSi("StackSi"), + SurveilNum("SurveilNum"), Target("Target"), Targets("Targets"), + TgtSA("TgtSA"), + Token("Token"), + TokenNum("TokenNum"), Transformer("Transformer"), Vehicle("Vehicle"), Won("Won"); diff --git a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java index f26a9bda9e0..2b05fa8f0d0 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java @@ -155,11 +155,10 @@ public class CounterEffect extends SpellAbilityEffect { final SpellAbility srcSA, final SpellAbilityStackInstance si) { final Game game = tgtSA.getActivatingPlayer().getGame(); // Run any applicable replacement effects. - final Map repParams = Maps.newHashMap(); - repParams.put("TgtSA", tgtSA); - repParams.put("Affected", tgtSA.getHostCard()); - repParams.put("Cause", srcSA.getHostCard()); - if (game.getReplacementHandler().runOld(ReplacementType.Counter, repParams) != ReplacementResult.NotReplaced) { + final Map repParams = AbilityKey.mapFromAffected(tgtSA.getHostCard()); + repParams.put(AbilityKey.TgtSA, tgtSA); + repParams.put(AbilityKey.Cause, srcSA.getHostCard()); + if (game.getReplacementHandler().run(ReplacementType.Counter, repParams) != ReplacementResult.NotReplaced) { return; } game.getStack().remove(si); diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 4beb976b28c..f242d4fd4e1 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1231,18 +1231,17 @@ public class Card extends GameEntity implements Comparable { addAmount = 0; // As per rule 107.1b return 0; } - final Map repParams = Maps.newHashMap(); - repParams.put("Affected", this); - repParams.put("Source", source); - repParams.put("CounterType", counterType); - repParams.put("CounterNum", addAmount); - repParams.put("EffectOnly", applyMultiplier); + final Map repParams = AbilityKey.mapFromAffected(this); + repParams.put(AbilityKey.Source, source); + repParams.put(AbilityKey.CounterType, counterType); + repParams.put(AbilityKey.CounterNum, addAmount); + repParams.put(AbilityKey.EffectOnly, applyMultiplier); - switch (getGame().getReplacementHandler().runOld(ReplacementType.AddCounter, repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.AddCounter, repParams)) { case NotReplaced: break; case Updated: { - addAmount = (int) repParams.get("CounterNum"); + addAmount = (int) repParams.get(AbilityKey.CounterNum); break; } default: @@ -3570,10 +3569,7 @@ public class Card extends GameEntity implements Comparable { if (!tapped) { return; } // Run Replacement effects - final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Affected", this); - - if (getGame().getReplacementHandler().runOld(ReplacementType.Untap, repRunParams) != ReplacementResult.NotReplaced) { + if (getGame().getReplacementHandler().run(ReplacementType.Untap, AbilityKey.mapFromAffected(this)) != ReplacementResult.NotReplaced) { return; } diff --git a/forge-game/src/main/java/forge/game/card/token/TokenInfo.java b/forge-game/src/main/java/forge/game/card/token/TokenInfo.java index 9ce07d63e13..9018ea93840 100644 --- a/forge-game/src/main/java/forge/game/card/token/TokenInfo.java +++ b/forge-game/src/main/java/forge/game/card/token/TokenInfo.java @@ -9,6 +9,7 @@ import forge.StaticData; import forge.card.CardType; import forge.card.MagicColor; import forge.game.Game; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.card.CardFactory; @@ -166,19 +167,18 @@ public class TokenInfo { Player player = controller; Card proto = prototype; - final Map repParams = Maps.newHashMap(); - repParams.put("Affected", player); - repParams.put("Token", prototype); - repParams.put("TokenNum", multiplier); - repParams.put("EffectOnly", applyMultiplier); + final Map repParams = AbilityKey.mapFromAffected(player); + repParams.put(AbilityKey.Token, prototype); + repParams.put(AbilityKey.TokenNum, multiplier); + repParams.put(AbilityKey.EffectOnly, applyMultiplier); - switch (game.getReplacementHandler().runOld(ReplacementType.CreateToken, repParams)) { + switch (game.getReplacementHandler().run(ReplacementType.CreateToken, repParams)) { case NotReplaced: break; case Updated: { - multiplier = (int) repParams.get("TokenNum"); - player = (Player) repParams.get("Affected"); - proto = (Card) repParams.get("Token"); + multiplier = (int) repParams.get(AbilityKey.TokenNum); + player = (Player) repParams.get(AbilityKey.Affected); + proto = (Card) repParams.get(AbilityKey.Token); break; } default: 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 898ef9d1b3e..65e2d8702b7 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -400,22 +400,21 @@ public class Player extends GameEntity implements Comparable { public final boolean gainLife(int lifeGain, final Card source, final SpellAbility sa) { // Run any applicable replacement effects. - final Map repParams = Maps.newHashMap(); - repParams.put("Affected", this); - repParams.put("LifeGained", lifeGain); - repParams.put("Source", source); + final Map repParams = AbilityKey.mapFromAffected(this); + repParams.put(AbilityKey.LifeGained, lifeGain); + repParams.put(AbilityKey.Source, source); if (!canGainLife()) { return false; } - switch (getGame().getReplacementHandler().runOld(ReplacementType.GainLife, repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.GainLife, repParams)) { case NotReplaced: break; case Updated: // check if this is still the affected player - if (this.equals(repParams.get("Affected"))) { - lifeGain = (int) repParams.get("LifeGained"); + if (this.equals(repParams.get(AbilityKey.Affected))) { + lifeGain = (int) repParams.get(AbilityKey.LifeGained); // negative update means life loss if (lifeGain < 0) { this.loseLife(-lifeGain); @@ -911,18 +910,17 @@ public class Player extends GameEntity implements Comparable { return 0; } - final Map repParams = Maps.newHashMap(); - repParams.put("Affected", this); - repParams.put("Source", source); - repParams.put("CounterType", counterType); - repParams.put("CounterNum", addAmount); - repParams.put("EffectOnly", applyMultiplier); + final Map repParams = AbilityKey.mapFromAffected(this); + repParams.put(AbilityKey.Source, source); + repParams.put(AbilityKey.CounterType, counterType); + repParams.put(AbilityKey.CounterNum, addAmount); + repParams.put(AbilityKey.EffectOnly, applyMultiplier); - switch (getGame().getReplacementHandler().runOld(ReplacementType.AddCounter, repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.AddCounter, repParams)) { case NotReplaced: break; case Updated: { - addAmount = (int) repParams.get("CounterNum"); + addAmount = (int) repParams.get(AbilityKey.CounterNum); break; } default: @@ -1273,16 +1271,15 @@ public class Player extends GameEntity implements Comparable { public void surveil(int num, SpellAbility cause) { - final Map repParams = Maps.newHashMap(); - repParams.put("Affected", this); - repParams.put("Source", cause); - repParams.put("SurveilNum", num); + final Map repParams = AbilityKey.mapFromAffected(this); + repParams.put(AbilityKey.Source, cause); + repParams.put(AbilityKey.SurveilNum, num); - switch (getGame().getReplacementHandler().runOld(ReplacementType.Surveil, repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.Surveil, repParams)) { case NotReplaced: break; case Updated: { - num = (int) repParams.get("SurveilNum"); + num = (int) repParams.get(AbilityKey.SurveilNum); break; } default: @@ -1343,11 +1340,10 @@ public class Player extends GameEntity implements Comparable { final CardCollection toReveal = new CardCollection(); // Replacement effects - final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Affected", this); - repRunParams.put("Number", n); + final Map repRunParams = AbilityKey.mapFromAffected(this); + repRunParams.put(AbilityKey.Number, n); - if (game.getReplacementHandler().runOld(ReplacementType.DrawCards, repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(ReplacementType.DrawCards, repRunParams) != ReplacementResult.NotReplaced) { return drawn; } @@ -1550,12 +1546,11 @@ public class Player extends GameEntity implements Comparable { // that should not trigger other Replacement again if (!discardToTopOfLibrary && !discardMadness) { // Replacement effects - final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Card", c); - repRunParams.put("Source", source); - repRunParams.put("Affected", this); + final Map repRunParams = AbilityKey.mapFromCard(c); + repRunParams.put(AbilityKey.Source, source); + repRunParams.put(AbilityKey.Affected, this); - if (game.getReplacementHandler().runOld(ReplacementType.Discard, repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(ReplacementType.Discard, repRunParams) != ReplacementResult.NotReplaced) { return null; } } diff --git a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java index e409f24961d..9dfae9446b8 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java @@ -128,12 +128,11 @@ public class AbilityManaPart implements java.io.Serializable { final Card source = this.getSourceCard(); final ManaPool manaPool = player.getManaPool(); String afterReplace = applyManaReplacement(sa, produced); - final Map repParams = Maps.newHashMap(); - repParams.put("Mana", afterReplace); - repParams.put("Affected", source); - repParams.put("Player", player); - repParams.put("AbilityMana", sa); - if (player.getGame().getReplacementHandler().runOld(ReplacementType.ProduceMana, repParams) != ReplacementResult.NotReplaced) { + final Map repParams = AbilityKey.mapFromAffected(source); + repParams.put(AbilityKey.Mana, afterReplace); + repParams.put(AbilityKey.Player, player); + repParams.put(AbilityKey.AbilityMana, sa); + if (player.getGame().getReplacementHandler().run(ReplacementType.ProduceMana, repParams) != ReplacementResult.NotReplaced) { return; } //clear lastProduced From df4b0b03b97060402ff14d3b9a1c7d3c3f74a0a7 Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Fri, 27 Sep 2019 17:13:44 -0600 Subject: [PATCH 10/17] remove `runOld` and `getReplacementListOld` --- .../src/main/java/forge/ai/AiController.java | 3 +- .../java/forge/ai/PlayerControllerAi.java | 4 +- .../java/forge/ai/ability/ChangeZoneAi.java | 5 +- .../java/forge/game/ability/AbilityKey.java | 2 + .../ability/effects/ReplaceDamageEffect.java | 19 +++--- .../game/ability/effects/ReplaceEffect.java | 19 +++--- .../effects/ReplaceSplitDamageEffect.java | 33 ++++++----- .../forge/game/player/PlayerController.java | 2 +- .../game/replacement/ReplacementHandler.java | 59 +++++++------------ .../forge/game/spellability/SpellAbility.java | 12 ++++ .../util/PlayerControllerForTests.java | 2 +- .../forge/player/PlayerControllerHuman.java | 2 +- 12 files changed, 82 insertions(+), 80 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index 4add78baf31..391d83cdcdd 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -2079,8 +2079,7 @@ public class AiController { return true; } - public ReplacementEffect chooseSingleReplacementEffect(List list, - Map runParams) { + public ReplacementEffect chooseSingleReplacementEffect(List list) { // no need to choose anything if (list.size() <= 1) { return Iterables.getFirst(list, null); diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index 3f461395650..d7042d89276 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -866,8 +866,8 @@ public class PlayerControllerAi extends PlayerController { } @Override - public ReplacementEffect chooseSingleReplacementEffect(String prompt, List possibleReplacers, Map runParams) { - return brains.chooseSingleReplacementEffect(possibleReplacers, runParams); + public ReplacementEffect chooseSingleReplacementEffect(String prompt, List possibleReplacers) { + return brains.chooseSingleReplacementEffect(possibleReplacers); } @Override diff --git a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java index 0a747747895..ecaa91b27d0 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java @@ -10,6 +10,7 @@ import forge.card.MagicColor; import forge.game.Game; import forge.game.GameObject; import forge.game.GlobalRuleChange; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.card.*; @@ -1789,8 +1790,8 @@ public class ChangeZoneAi extends SpellAbilityAi { } public boolean doReturnCommanderLogic(SpellAbility sa, Player aiPlayer) { - Map originalParams = (Map)sa.getReplacingObject("OriginalParams"); - SpellAbility causeSa = (SpellAbility)originalParams.get("Cause"); + Map originalParams = (Map)sa.getReplacingObject(AbilityKey.OriginalParams); + SpellAbility causeSa = (SpellAbility)originalParams.get(AbilityKey.Cause); SpellAbility causeSub = null; // Squee, the Immortal: easier to recast it (the call below has to be "contains" since SA is an intrinsic effect) diff --git a/forge-game/src/main/java/forge/game/ability/AbilityKey.java b/forge-game/src/main/java/forge/game/ability/AbilityKey.java index c2ce43ef6e3..4821b088c8a 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityKey.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityKey.java @@ -85,6 +85,7 @@ public enum AbilityKey { Origin("Origin"), OriginalController("OriginalController"), OriginalDefender("OriginalDefender"), + OriginalParams("OriginalParams"), PayingMana("PayingMana"), Phase("Phase"), Player("Player"), @@ -92,6 +93,7 @@ public enum AbilityKey { Prevention("Prevention"), Produced("Produced"), Regeneration("Regeneration"), + ReplacementResult("ReplacementResult"), Result("Result"), Scheme("Scheme"), Source("Source"), diff --git a/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java index 5c0786596d7..e8ea9c504f9 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java @@ -2,6 +2,7 @@ package forge.game.ability.effects; import java.util.Map; +import forge.game.ability.AbilityKey; import org.apache.commons.lang3.StringUtils; import com.google.common.collect.Maps; @@ -31,10 +32,10 @@ public class ReplaceDamageEffect extends SpellAbilityEffect { String varValue = sa.getParamOrDefault("VarName", "1"); @SuppressWarnings("unchecked") - Map originalParams = (Map) sa.getReplacingObject("OriginalParams"); - Map params = Maps.newHashMap(originalParams); + Map originalParams = (Map) sa.getReplacingObject(AbilityKey.OriginalParams); + Map params = AbilityKey.newMap(originalParams); - Integer dmg = (Integer) sa.getReplacingObject("DamageAmount"); + Integer dmg = (Integer) sa.getReplacingObject(AbilityKey.DamageAmount); int prevent = AbilityUtils.calculateAmount(card, varValue, sa); @@ -54,27 +55,27 @@ public class ReplaceDamageEffect extends SpellAbilityEffect { // no damage for original target anymore if (dmg <= 0) { - originalParams.put("ReplacementResult", ReplacementResult.Replaced); + originalParams.put(AbilityKey.ReplacementResult, ReplacementResult.Replaced); return; } - params.put("DamageAmount", dmg); + params.put(AbilityKey.DamageAmount, dmg); //try to call replacementHandler with new Params - ReplacementResult result = game.getReplacementHandler().runOld(event, params); + ReplacementResult result = game.getReplacementHandler().run(event, params); switch (result) { case NotReplaced: case Updated: { - for (Map.Entry e : params.entrySet()) { + for (Map.Entry e : params.entrySet()) { originalParams.put(e.getKey(), e.getValue()); } // effect was updated - originalParams.put("ReplacementResult", ReplacementResult.Updated); + originalParams.put(AbilityKey.ReplacementResult, ReplacementResult.Updated); break; } default: // effect was replaced with something else - originalParams.put("ReplacementResult", result); + originalParams.put(AbilityKey.ReplacementResult, result); break; } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java index 168faea6fc6..af761de13fb 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java @@ -7,6 +7,7 @@ import com.google.common.collect.Maps; import forge.game.Game; import forge.game.GameObject; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; @@ -23,14 +24,14 @@ public class ReplaceEffect extends SpellAbilityEffect { final Card card = sa.getHostCard(); final Game game = card.getGame(); - final String varName = sa.getParam("VarName"); + final AbilityKey varName = AbilityKey.fromString(sa.getParam("VarName")); final String varValue = sa.getParam("VarValue"); final String type = sa.getParamOrDefault("VarType", "amount"); final ReplacementType retype = sa.getReplacementEffect().getMode(); @SuppressWarnings("unchecked") - Map originalParams = (Map) sa.getReplacingObject("OriginalParams"); - Map params = Maps.newHashMap(originalParams); + Map originalParams = (Map) sa.getReplacingObject(AbilityKey.OriginalParams); + Map params = Maps.newHashMap(originalParams); if ("Card".equals(type)) { List list = AbilityUtils.getDefinedCards(card, varValue, sa); @@ -56,25 +57,25 @@ public class ReplaceEffect extends SpellAbilityEffect { params.put(varName, AbilityUtils.calculateAmount(card, varValue, sa)); } - if (params.containsKey("EffectOnly")) { - params.put("EffectOnly", true); + if (params.containsKey(AbilityKey.EffectOnly)) { + params.put(AbilityKey.EffectOnly, true); } //try to call replacementHandler with new Params - ReplacementResult result = game.getReplacementHandler().runOld(retype, params); + ReplacementResult result = game.getReplacementHandler().run(retype, params); switch (result) { case NotReplaced: case Updated: { - for (Map.Entry e : params.entrySet()) { + for (Map.Entry e : params.entrySet()) { originalParams.put(e.getKey(), e.getValue()); } // effect was updated - originalParams.put("ReplacementResult", ReplacementResult.Updated); + originalParams.put(AbilityKey.ReplacementResult, ReplacementResult.Updated); break; } default: // effect was replaced with something else - originalParams.put("ReplacementResult", result); + originalParams.put(AbilityKey.ReplacementResult, result); break; } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java index 3ec56f5b801..f97e17b1612 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java @@ -3,6 +3,7 @@ package forge.game.ability.effects; import java.util.List; import java.util.Map; +import forge.game.ability.AbilityKey; import org.apache.commons.lang3.StringUtils; import com.google.common.collect.Maps; @@ -36,10 +37,10 @@ public class ReplaceSplitDamageEffect extends SpellAbilityEffect { String varValue = sa.getParamOrDefault("VarName", "1"); @SuppressWarnings("unchecked") - Map originalParams = (Map) sa.getReplacingObject("OriginalParams"); - Map params = Maps.newHashMap(originalParams); + Map originalParams = (Map) sa.getReplacingObject(AbilityKey.OriginalParams); + Map params = AbilityKey.newMap(originalParams); - Integer dmg = (Integer) sa.getReplacingObject("DamageAmount"); + Integer dmg = (Integer) sa.getReplacingObject(AbilityKey.DamageAmount); int prevent = AbilityUtils.calculateAmount(card, varValue, sa); @@ -57,15 +58,15 @@ public class ReplaceSplitDamageEffect extends SpellAbilityEffect { card.setSVar(varValue, "Number$" + prevent); } - Card sourceLKI = (Card) sa.getReplacingObject("Source"); + Card sourceLKI = (Card) sa.getReplacingObject(AbilityKey.Source); - CardDamageMap damageMap = (CardDamageMap) originalParams.get("DamageMap"); - CardDamageMap preventMap = (CardDamageMap) originalParams.get("PreventMap"); - GameEntityCounterTable counterTable = (GameEntityCounterTable) originalParams.get("CounterTable"); - SpellAbility cause = (SpellAbility) originalParams.get("Cause"); + CardDamageMap damageMap = (CardDamageMap) originalParams.get(AbilityKey.DamageMap); + CardDamageMap preventMap = (CardDamageMap) originalParams.get(AbilityKey.PreventMap); + GameEntityCounterTable counterTable = (GameEntityCounterTable) originalParams.get(AbilityKey.CounterTable); + SpellAbility cause = (SpellAbility) originalParams.get(AbilityKey.Cause); - boolean isCombat = (Boolean) originalParams.get("IsCombat"); - boolean noPrevention = (Boolean) originalParams.get("NoPreventDamage"); + boolean isCombat = (Boolean) originalParams.get(AbilityKey.IsCombat); + boolean noPrevention = (Boolean) originalParams.get(AbilityKey.NoPreventDamage); GameEntity obj = (GameEntity) list.get(0); @@ -74,26 +75,26 @@ public class ReplaceSplitDamageEffect extends SpellAbilityEffect { // no damage for original target anymore if (dmg <= 0) { - originalParams.put("ReplacementResult", ReplacementResult.Replaced); + originalParams.put(AbilityKey.ReplacementResult, ReplacementResult.Replaced); return; } - params.put("DamageAmount", dmg); + params.put(AbilityKey.DamageAmount, dmg); //try to call replacementHandler with new Params - ReplacementResult result = game.getReplacementHandler().runOld(event, params); + ReplacementResult result = game.getReplacementHandler().run(event, params); switch (result) { case NotReplaced: case Updated: { - for (Map.Entry e : params.entrySet()) { + for (Map.Entry e : params.entrySet()) { originalParams.put(e.getKey(), e.getValue()); } // effect was updated - originalParams.put("ReplacementResult", ReplacementResult.Updated); + originalParams.put(AbilityKey.ReplacementResult, ReplacementResult.Updated); break; } default: // effect was replaced with something else - originalParams.put("ReplacementResult", result); + originalParams.put(AbilityKey.ReplacementResult, result); break; } } diff --git a/forge-game/src/main/java/forge/game/player/PlayerController.java b/forge-game/src/main/java/forge/game/player/PlayerController.java index ecea26174d9..d5cef95818b 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerController.java +++ b/forge-game/src/main/java/forge/game/player/PlayerController.java @@ -211,7 +211,7 @@ public abstract class PlayerController { Map params); public abstract boolean confirmPayment(CostPart costPart, String string, SpellAbility sa); - public abstract ReplacementEffect chooseSingleReplacementEffect(String prompt, List possibleReplacers, Map runParams); + public abstract ReplacementEffect chooseSingleReplacementEffect(String prompt, List possibleReplacers); public abstract String chooseProtectionType(String string, SpellAbility sa, List choices); // these 4 need some refining. diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java index e33cebcdb25..d2273e35e2a 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -56,22 +56,16 @@ public class ReplacementHandler { //private final List tmpEffects = new ArrayList(); public List getReplacementList(final ReplacementType event, final Map runParams, final ReplacementLayer layer) { - return getReplacementListOld(event, toStringMap(runParams), layer); - } - // The plan is to slowly refactor any usages of getReplacementListOld to use getReplacementList. Then we can just inline - // getReplacementListOld into getReplacementList and change the code inside to just always use a Map. - // The reason we can't just call them both getReplacementList is because we get a same erasure compile error if we do. - private List getReplacementListOld(final ReplacementType event, final Map runParams, final ReplacementLayer layer) { final CardCollection preList = new CardCollection(); boolean checkAgain = false; Card affectedLKI = null; Card affectedCard = null; - if (ReplacementType.Moved.equals(event) && ZoneType.Battlefield.equals(runParams.get("Destination"))) { + if (ReplacementType.Moved.equals(event) && ZoneType.Battlefield.equals(runParams.get(AbilityKey.Destination))) { // if it was caused by an replacement effect, use the already calculated RE list // otherwise the RIOT card would cause a StackError - SpellAbility cause = (SpellAbility) runParams.get("Cause"); + SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause); if (cause != null && cause.isReplacementAbility()) { final ReplacementEffect re = cause.getReplacementEffect(); // only return for same layer @@ -81,13 +75,13 @@ public class ReplacementHandler { } // Rule 614.12 Enter the Battlefield Replacement Effects look at what the card would be on the battlefield - affectedCard = (Card) runParams.get("Affected"); + affectedCard = (Card) runParams.get(AbilityKey.Affected); affectedLKI = CardUtil.getLKICopy(affectedCard); affectedLKI.setLastKnownZone(affectedCard.getController().getZone(ZoneType.Battlefield)); preList.add(affectedLKI); game.getAction().checkStaticAbilities(false, Sets.newHashSet(affectedLKI), preList); checkAgain = true; - runParams.put("Affected", affectedLKI); + runParams.put(AbilityKey.Affected, affectedLKI); } final List possibleReplacers = Lists.newArrayList(); @@ -124,7 +118,7 @@ public class ReplacementHandler { && (layer == null || replacementEffect.getLayer() == layer) && event.equals(replacementEffect.getMode()) && replacementEffect.requirementsCheck(game) - && replacementEffect.canReplace(runParams) + && replacementEffect.canReplace(toStringMap(runParams)) && !possibleReplacers.contains(replacementEffect) && replacementEffect.zonesCheck(cardZone)) { possibleReplacers.add(replacementEffect); @@ -142,7 +136,7 @@ public class ReplacementHandler { for (final ReplacementEffect re : affectedLKI.getReplacementEffects()) { re.setHostCard(affectedCard); } - runParams.put("Affected", affectedCard); + runParams.put(AbilityKey.Affected, affectedCard); } game.getAction().checkStaticAbilities(false); } @@ -159,15 +153,7 @@ public class ReplacementHandler { * @return ReplacementResult, an enum that represents what happened to the replacement effect. */ public ReplacementResult run(ReplacementType event, final Map runParams) { - return runOld(event, toStringMap(runParams)); - } - - // The plan is to slowly refactor any usages of runOld to use run. Then we can just inline - // runOld into run and change the code inside to just always use a Map. - // The reason we can't just call them both run is because we get a same erasure compile error if we do. - @Deprecated - public ReplacementResult runOld(ReplacementType event, final Map runParams) { - final Object affected = runParams.get("Affected"); + final Object affected = runParams.get(AbilityKey.Affected); Player decider = null; // Figure out who decides which of multiple replacements to apply @@ -190,15 +176,14 @@ public class ReplacementHandler { } - @Deprecated - private ReplacementResult run(final ReplacementType event, final Map runParams, final ReplacementLayer layer, final Player decider) { - final List possibleReplacers = getReplacementListOld(event, runParams, layer); + private ReplacementResult run(final ReplacementType event, final Map runParams, final ReplacementLayer layer, final Player decider) { + final List possibleReplacers = getReplacementList(event, runParams, layer); if (possibleReplacers.isEmpty()) { return ReplacementResult.NotReplaced; } - ReplacementEffect chosenRE = decider.getController().chooseSingleReplacementEffect("Choose a replacement effect to apply first.", possibleReplacers, runParams); + ReplacementEffect chosenRE = decider.getController().chooseSingleReplacementEffect("Choose a replacement effect to apply first.", possibleReplacers); possibleReplacers.remove(chosenRE); @@ -207,7 +192,7 @@ public class ReplacementHandler { ReplacementResult res = executeReplacement(runParams, chosenRE, decider, game); if (res == ReplacementResult.NotReplaced) { if (!possibleReplacers.isEmpty()) { - res = runOld(event, runParams); + res = run(event, runParams); } chosenRE.setHasRun(false); chosenRE.setOtherChoices(null); @@ -231,7 +216,7 @@ public class ReplacementHandler { * @param replacementEffect * the replacement effect to run */ - private ReplacementResult executeReplacement(final Map runParams, + private ReplacementResult executeReplacement(final Map runParams, final ReplacementEffect replacementEffect, final Player decider, final Game game) { final Map mapParams = replacementEffect.getMapParams(); @@ -253,9 +238,9 @@ public class ReplacementHandler { SpellAbility tailend = effectSA; do { - replacementEffect.setReplacingObjects(runParams, tailend); + replacementEffect.setReplacingObjects(toStringMap(runParams), tailend); //set original Params to update them later - tailend.setReplacingObject("OriginalParams", runParams); + tailend.setReplacingObject(AbilityKey.OriginalParams, runParams); tailend = tailend.getSubAbility(); } while(tailend != null); @@ -264,9 +249,9 @@ public class ReplacementHandler { effectSA = replacementEffect.getOverridingAbility(); SpellAbility tailend = effectSA; do { - replacementEffect.setReplacingObjects(runParams, tailend); + replacementEffect.setReplacingObjects(toStringMap(runParams), tailend); //set original Params to update them later - tailend.setReplacingObject("OriginalParams", runParams); + tailend.setReplacingObject(AbilityKey.OriginalParams, runParams); tailend = tailend.getSubAbility(); } while(tailend != null); } @@ -293,7 +278,7 @@ public class ReplacementHandler { Card cardForUi = host.getCardForUi(); String effectDesc = TextUtil.fastReplace(replacementEffect.toString(), "CARDNAME", cardForUi.getName()); final String question = replacementEffect instanceof ReplaceDiscard - ? TextUtil.concatWithSpace("Apply replacement effect of", cardForUi.toString(), "to", TextUtil.addSuffix(runParams.get("Card").toString(),"?\r\n"), TextUtil.enclosedParen(effectDesc)) + ? TextUtil.concatWithSpace("Apply replacement effect of", cardForUi.toString(), "to", TextUtil.addSuffix(runParams.get(AbilityKey.Card).toString(),"?\r\n"), TextUtil.enclosedParen(effectDesc)) : TextUtil.concatWithSpace("Apply replacement effect of", TextUtil.addSuffix(cardForUi.toString(),"?\r\n"), TextUtil.enclosedParen(effectDesc)); boolean confirmed = optDecider.getController().confirmReplacementEffect(replacementEffect, effectSA, question); if (!confirmed) { @@ -310,9 +295,9 @@ public class ReplacementHandler { Player player = host.getController(); if (mapParams.containsKey("ManaReplacement")) { - final SpellAbility manaAb = (SpellAbility) runParams.get("AbilityMana"); - final Player player1 = (Player) runParams.get("Player"); - final String rep = (String) runParams.get("Mana"); + final SpellAbility manaAb = (SpellAbility) runParams.get(AbilityKey.AbilityMana); + final Player player1 = (Player) runParams.get(AbilityKey.Player); + final String rep = (String) runParams.get(AbilityKey.Mana); // Replaced mana type final Card repHost = host; String repType = repHost.getSVar(mapParams.get("ManaReplacement")); @@ -325,8 +310,8 @@ public class ReplacementHandler { player.getController().playSpellAbilityNoStack(effectSA, true); // if the spellability is a replace effect then its some new logic // if ReplacementResult is set in run params use that instead - if (runParams.containsKey("ReplacementResult")) { - return (ReplacementResult) runParams.get("ReplacementResult"); + if (runParams.containsKey(AbilityKey.ReplacementResult)) { + return (ReplacementResult) runParams.get(AbilityKey.ReplacementResult); } } 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 e27af7b79bb..ea335a7df7d 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -599,10 +599,22 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit public boolean hasReplacingObject(final String type) { return replacingObjects.containsKey(type); } + public Object getReplacingObject(final AbilityKey type) { + return getReplacingObject(type.toString()); + } + // Eventually we want to switch the internal map to be a `Map` instead of a + // `Map`. + @Deprecated public Object getReplacingObject(final String type) { final Object res = replacingObjects.get(type); return res; } + public void setReplacingObject(final AbilityKey type, final Object o) { + setReplacingObject(type.toString(), o); + } + // Eventually we want to switch the internal map to be a `Map` instead of a + // `Map`. + @Deprecated public void setReplacingObject(final String type, final Object o) { replacingObjects.put(type, o); } diff --git a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java index 4e3b48f2917..f1906ebdb0f 100644 --- a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java +++ b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java @@ -506,7 +506,7 @@ public class PlayerControllerForTests extends PlayerController { } @Override - public ReplacementEffect chooseSingleReplacementEffect(String prompt, List possibleReplacers, Map runParams) { + public ReplacementEffect chooseSingleReplacementEffect(String prompt, List possibleReplacers) { // TODO Auto-generated method stub return Iterables.getFirst(possibleReplacers, null); } diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 267eae1e1a9..36dd6de0d00 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -1587,7 +1587,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont @Override public ReplacementEffect chooseSingleReplacementEffect(final String prompt, - final List possibleReplacers, final Map runParams) { + final List possibleReplacers) { final ReplacementEffect first = possibleReplacers.get(0); if (possibleReplacers.size() == 1) { return first; From a3355ba05a38e7a766f136f6c8377c2e660dadd2 Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Fri, 27 Sep 2019 17:27:36 -0600 Subject: [PATCH 11/17] remove imports --- .../src/main/java/forge/game/ability/effects/CounterEffect.java | 1 - .../java/forge/game/ability/effects/ReplaceDamageEffect.java | 2 -- .../forge/game/ability/effects/ReplaceSplitDamageEffect.java | 2 -- forge-game/src/main/java/forge/game/card/token/TokenInfo.java | 1 - 4 files changed, 6 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java index 2b05fa8f0d0..f82231f20b4 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java @@ -18,7 +18,6 @@ import java.util.List; import java.util.Map; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; public class CounterEffect extends SpellAbilityEffect { @Override diff --git a/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java index e8ea9c504f9..6261fac4440 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java @@ -5,8 +5,6 @@ import java.util.Map; import forge.game.ability.AbilityKey; import org.apache.commons.lang3.StringUtils; -import com.google.common.collect.Maps; - import forge.game.Game; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; diff --git a/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java index f97e17b1612..048d41e1c17 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ReplaceSplitDamageEffect.java @@ -6,8 +6,6 @@ import java.util.Map; import forge.game.ability.AbilityKey; import org.apache.commons.lang3.StringUtils; -import com.google.common.collect.Maps; - import forge.game.Game; import forge.game.GameEntity; import forge.game.GameEntityCounterTable; diff --git a/forge-game/src/main/java/forge/game/card/token/TokenInfo.java b/forge-game/src/main/java/forge/game/card/token/TokenInfo.java index 9018ea93840..c540ad0b56a 100644 --- a/forge-game/src/main/java/forge/game/card/token/TokenInfo.java +++ b/forge-game/src/main/java/forge/game/card/token/TokenInfo.java @@ -3,7 +3,6 @@ package forge.game.card.token; import com.google.common.base.Joiner; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import forge.ImageKeys; import forge.StaticData; import forge.card.CardType; From f95cdd6ab4913dd7eba5658a69f8c300a34cbbfa Mon Sep 17 00:00:00 2001 From: Agetian Date: Sat, 5 Oct 2019 10:51:34 +0300 Subject: [PATCH 12/17] - Added puzzle PS_ELD0. --- forge-gui/res/puzzle/PS_ELD0.pzl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 forge-gui/res/puzzle/PS_ELD0.pzl diff --git a/forge-gui/res/puzzle/PS_ELD0.pzl b/forge-gui/res/puzzle/PS_ELD0.pzl new file mode 100644 index 00000000000..d54fe40165b --- /dev/null +++ b/forge-gui/res/puzzle/PS_ELD0.pzl @@ -0,0 +1,17 @@ +[metadata] +Name:Possibility Storm - Throne of Eldraine #00 (Pre-release Puzzle) +URL:http://www.possibilitystorm.com/wp-content/uploads/2019/10/130.-ELD001.jpg +Goal:Win +Turns:1 +Difficulty:Uncommon +Description:Win this turn. +[state] +humanlife=20 +ailife=12 +turn=1 +activeplayer=human +activephase=MAIN1 +humanhand=Giant Opportunity;Mirrormade;Curious Pair;Frogify +humanbattlefield=Witch's Oven;Wicked Wolf;Maraleaf Rider;Oko, Thief of Crowns|Counters:LOYALTY=6;Forest;Forest;Forest;Island;Island;Island +aibattlefield=Wojek Bodyguard;Loyal Pegasus +humanprecast=Oko, Thief of Crowns:1 From 937521632dd3fbb6219eaaff42cdb97c2b8bab14 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Sat, 5 Oct 2019 11:37:29 +0000 Subject: [PATCH 13/17] GameAction: better ZoneCheck for Adventure --- forge-game/src/main/java/forge/game/GameAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index aed8d191d9c..8df103f9c77 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -148,7 +148,7 @@ public class GameAction { } // if an adventureCard is put from Stack somewhere else, need to reset to Original State - if (c.isAdventureCard() && (ZoneType.Stack.equals(zoneFrom) || !ZoneType.Stack.equals(zoneTo))) { //fix NPE momir + if (c.isAdventureCard() && ((zoneFrom != null && zoneFrom.is(ZoneType.Stack)) || !zoneTo.is(ZoneType.Stack))) { c.setState(CardStateName.Original, true); } From f32a8d7bb83d6c1eb06d58458c2df078ce499289 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Sat, 5 Oct 2019 19:59:28 +0000 Subject: [PATCH 14/17] Card: CardTraits are now not added to Card/State anymore but uses timestamp --- .../src/main/java/forge/ai/ComputerUtil.java | 2 +- .../main/java/forge/ai/ComputerUtilCard.java | 4 +- .../main/java/forge/ai/ability/AnimateAi.java | 81 ++--- .../main/java/forge/game/CardTraitBase.java | 38 --- .../src/main/java/forge/game/GameAction.java | 10 +- .../main/java/forge/game/StaticEffect.java | 24 +- .../main/java/forge/game/StaticEffects.java | 9 + .../ability/effects/AnimateAllEffect.java | 80 +---- .../game/ability/effects/AnimateEffect.java | 123 ++------ .../ability/effects/AnimateEffectBase.java | 32 +- .../ability/effects/RegenerateBaseEffect.java | 2 +- .../ability/effects/RestartGameEffect.java | 1 - .../src/main/java/forge/game/card/Card.java | 186 ++++++++---- .../java/forge/game/card/CardFactoryUtil.java | 59 ---- .../forge/game/card/CardTraitChanges.java | 129 ++++++++ .../main/java/forge/game/card/CardUtil.java | 20 +- .../main/java/forge/game/player/Player.java | 2 +- .../game/replacement/ReplacementEffect.java | 1 - .../game/replacement/ReplacementHandler.java | 27 -- .../spellability/SpellAbilityPredicates.java | 9 + .../game/staticability/StaticAbility.java | 20 +- .../StaticAbilityContinuous.java | 277 ++++++++---------- .../staticability/StaticAbilityLayer.java | 9 +- .../main/java/forge/game/trigger/Trigger.java | 1 - .../forge/game/trigger/TriggerHandler.java | 39 --- 25 files changed, 487 insertions(+), 698 deletions(-) create mode 100644 forge-game/src/main/java/forge/game/card/CardTraitChanges.java diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index f8550ba8066..fd96b4a1bfb 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -1266,7 +1266,7 @@ public class ComputerUtil { public static boolean preventRunAwayActivations(final SpellAbility sa) { int activations = sa.getActivationsThisTurn(); - if (sa.isTemporary()) { + if (!sa.isIntrinsic()) { return MyRandom.getRandom().nextFloat() >= .95; // Abilities created by static abilities have no memory } diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java index a56e032dc87..2dbce19187d 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java @@ -1128,14 +1128,14 @@ public class ComputerUtilCard { // assume it either benefits the player or disrupts the opponent for (final StaticAbility stAb : c.getStaticAbilities()) { final Map params = stAb.getMapParams(); - if (params.get("Mode").equals("Continuous") && stAb.isIntrinsic() && !stAb.isTemporary()) { + if (params.get("Mode").equals("Continuous") && stAb.isIntrinsic()) { priority = true; break; } } if (!priority) { for (final Trigger t : c.getTriggers()) { - if (t.isIntrinsic() && !t.isTemporary()) { + if (t.isIntrinsic()) { // has a triggered ability, could be benefitting the opponent or disrupting the AI priority = true; break; diff --git a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java index 4f479d60678..baa0d00b7c5 100644 --- a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java @@ -467,26 +467,19 @@ public class AnimateAi extends SpellAbilityAi { AnimateEffectBase.doAnimate(card, sa, power, toughness, types, removeTypes, finalDesc, keywords, removeKeywords, hiddenKeywords, timestamp); - // back to duplicating AnimateEffect.resolve - // TODO will all these abilities/triggers/replacements/etc. lead to - // memory leaks or unintended effects? + // remove abilities final List removedAbilities = Lists.newArrayList(); - boolean clearAbilities = sa.hasParam("OverwriteAbilities"); boolean clearSpells = sa.hasParam("OverwriteSpells"); boolean removeAll = sa.hasParam("RemoveAllAbilities"); boolean removeIntrinsic = sa.hasParam("RemoveIntrinsicAbilities"); - if (clearAbilities || clearSpells || removeAll) { - for (final SpellAbility ab : card.getSpellAbilities()) { - if (removeAll - || (ab.isIntrinsic() && removeIntrinsic && !ab.isBasicLandAbility()) - || (ab.isAbility() && clearAbilities) - || (ab.isSpell() && clearSpells)) { - card.removeSpellAbility(ab); - removedAbilities.add(ab); - } - } + if (clearSpells) { + removedAbilities.addAll(Lists.newArrayList(card.getSpells())); + } + + if (sa.hasParam("RemoveThisAbility") && !removedAbilities.contains(sa)) { + removedAbilities.add(sa); } // give abilities @@ -494,9 +487,7 @@ public class AnimateAi extends SpellAbilityAi { if (abilities.size() > 0) { for (final String s : abilities) { final String actualAbility = source.getSVar(s); - final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, source); - addedAbilities.add(grantedAbility); - card.addSpellAbility(grantedAbility); + addedAbilities.add(AbilityFactory.getAbility(actualAbility, card)); } } @@ -505,8 +496,8 @@ public class AnimateAi extends SpellAbilityAi { if (triggers.size() > 0) { for (final String s : triggers) { final String actualTrigger = source.getSVar(s); - final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, source, false); - addedTriggers.add(card.addTrigger(parsedTrigger)); + final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, card, false); + addedTriggers.add(parsedTrigger); } } @@ -515,24 +506,28 @@ public class AnimateAi extends SpellAbilityAi { if (replacements.size() > 0) { for (final String s : replacements) { final String actualReplacement = source.getSVar(s); - final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, - source, false); - addedReplacements.add(card.addReplacementEffect(parsedReplacement)); + final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, card, false); + addedReplacements.add(parsedReplacement); } } - // suppress triggers from the animated card - final List removedTriggers = Lists.newArrayList(); - if (sa.hasParam("OverwriteTriggers") || removeAll || removeIntrinsic) { - for (final Trigger trigger : card.getTriggers()) { - if (removeIntrinsic && !trigger.isIntrinsic()) { - continue; - } - trigger.setSuppressed(true); - removedTriggers.add(trigger); + // give static abilities (should only be used by cards to give + // itself a static ability) + final List addedStaticAbilities = Lists.newArrayList(); + if (stAbs.size() > 0) { + for (final String s : stAbs) { + final String actualAbility = source.getSVar(s); + addedStaticAbilities.add(new StaticAbility(actualAbility, card)); } } + if (removeAll || removeIntrinsic + || !addedAbilities.isEmpty() || !removedAbilities.isEmpty() || !addedTriggers.isEmpty() + || !addedReplacements.isEmpty() || !addedStaticAbilities.isEmpty()) { + card.addChangedCardTraits(addedAbilities, removedAbilities, addedTriggers, addedReplacements, + addedStaticAbilities, removeAll, false, removeIntrinsic, timestamp); + } + // give static abilities (should only be used by cards to give // itself a static ability) if (stAbs.size() > 0) { @@ -560,30 +555,6 @@ public class AnimateAi extends SpellAbilityAi { card.setSVar(name, actualsVar); } } - - // suppress static abilities from the animated card - final List removedStatics = Lists.newArrayList(); - if (sa.hasParam("OverwriteStatics") || removeAll || removeIntrinsic) { - for (final StaticAbility stAb : card.getStaticAbilities()) { - if (removeIntrinsic && !stAb.isIntrinsic()) { - continue; - } - stAb.setTemporarilySuppressed(true); - removedStatics.add(stAb); - } - } - - // suppress static abilities from the animated card - final List removedReplacements = Lists.newArrayList(); - if (sa.hasParam("OverwriteReplacements") || removeAll || removeIntrinsic) { - for (final ReplacementEffect re : card.getReplacementEffects()) { - if (removeIntrinsic && !re.isIntrinsic()) { - continue; - } - re.setTemporarilySuppressed(true); - removedReplacements.add(re); - } - } ComputerUtilCard.applyStaticContPT(game, card, null); } diff --git a/forge-game/src/main/java/forge/game/CardTraitBase.java b/forge-game/src/main/java/forge/game/CardTraitBase.java index 1c72d72fe38..34c2a77edf5 100644 --- a/forge-game/src/main/java/forge/game/CardTraitBase.java +++ b/forge-game/src/main/java/forge/game/CardTraitBase.java @@ -38,15 +38,9 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView { /** The is intrinsic. */ protected boolean intrinsic; - /** The temporary. */ - protected boolean temporary = false; - /** The suppressed. */ protected boolean suppressed = false; - /** The temporarily suppressed. */ - protected boolean temporarilySuppressed = false; - protected Map sVars = Maps.newHashMap(); protected Map intrinsicChangedTextColors = Maps.newHashMap(); @@ -66,24 +60,6 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView { */ private static final ImmutableList noChangeKeys = ImmutableList.builder() .add("TokenScript", "LegacyImage", "TokenImage", "NewName").build(); - /** - * Sets the temporary. - * - * @param temp - * the new temporary - */ - public final void setTemporary(final boolean temp) { - this.temporary = temp; - } - - /** - * Checks if is temporary. - * - * @return true, if is temporary - */ - public final boolean isTemporary() { - return this.temporary; - } /** *

@@ -196,26 +172,12 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView { this.suppressed = supp; } - /** - * Sets the temporarily suppressed. - * - * @param supp - * the new temporarily suppressed - */ - public final void setTemporarilySuppressed(final boolean supp) { - this.temporarilySuppressed = supp; - } - /** * Checks if is suppressed. * * @return true, if is suppressed */ public final boolean isSuppressed() { - return (this.suppressed || this.temporarilySuppressed); - } - - protected final boolean isNonTempSuppressed() { return this.suppressed; } diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 8df103f9c77..e7fb4887257 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -760,8 +760,6 @@ public class GameAction { // remove old effects game.getStaticEffects().clearStaticEffects(affectedCards); - game.getTriggerHandler().cleanUpTemporaryTriggers(); - game.getReplacementHandler().cleanUpTemporaryReplacements(); for (final Player p : game.getPlayers()) { if (!game.getStack().isFrozen()) { @@ -779,17 +777,11 @@ public class GameAction { public boolean visit(final Card c) { // need to get Card from preList if able final Card co = preList.get(c); - List toRemove = Lists.newArrayList(); for (StaticAbility stAb : co.getStaticAbilities()) { - if (stAb.isTemporary()) { - toRemove.add(stAb); - } else if (stAb.getParam("Mode").equals("Continuous")) { + if (stAb.getParam("Mode").equals("Continuous")) { staticAbilities.add(stAb); } } - for (StaticAbility stAb : toRemove) { - co.removeStaticAbility(stAb); - } if (!co.getStaticCommandList().isEmpty()) { staticList.add(co); } diff --git a/forge-game/src/main/java/forge/game/StaticEffect.java b/forge-game/src/main/java/forge/game/StaticEffect.java index d315c1d06e4..76cb288b920 100644 --- a/forge-game/src/main/java/forge/game/StaticEffect.java +++ b/forge-game/src/main/java/forge/game/StaticEffect.java @@ -23,8 +23,6 @@ import forge.game.card.CardCollection; import forge.game.card.CardCollectionView; import forge.game.card.CardUtil; import forge.game.player.Player; -import forge.game.spellability.AbilityStatic; -import forge.game.spellability.SpellAbility; import forge.game.staticability.StaticAbility; import java.util.ArrayList; @@ -236,11 +234,7 @@ public class StaticEffect { } if (hasParam("IgnoreEffectCost")) { - for (final SpellAbility s : getSource().getSpellAbilities()) { - if (s instanceof AbilityStatic && s.isTemporary()) { - getSource().removeSpellAbility(s); - } - } + getSource().removeChangedCardTraits(getTimestamp()); } // modify players @@ -273,22 +267,12 @@ public class StaticEffect { // the view is updated in GameAction#checkStaticAbilities to avoid flickering // remove keywords - // TODO regular keywords currently don't try to use keyword multiplier // (Although nothing uses it at this time) if (hasParam("AddKeyword") || hasParam("RemoveKeyword") || hasParam("RemoveAllAbilities")) { affectedCard.removeChangedCardKeywords(getTimestamp()); } - // remove abilities - if (hasParam("AddAbility") || hasParam("GainsAbilitiesOf")) { - for (final SpellAbility s : affectedCard.getSpellAbilities().threadSafeIterable()) { - if (s.isTemporary()) { - affectedCard.removeSpellAbility(s, false); - } - } - } - if (addHiddenKeywords != null) { for (final String k : addHiddenKeywords) { affectedCard.removeHiddenExtrinsicKeyword(k); @@ -296,8 +280,10 @@ public class StaticEffect { } // remove abilities - if (hasParam("RemoveAllAbilities") || hasParam("RemoveIntrinsicAbilities")) { - affectedCard.unSuppressCardTraits(); + if (hasParam("AddAbility") || hasParam("GainsAbilitiesOf") + || hasParam("AddTrigger") || hasParam("AddStaticAbility") || hasParam("AddReplacementEffects") + || hasParam("RemoveAllAbilities") || hasParam("RemoveIntrinsicAbilities")) { + affectedCard.removeChangedCardTraits(getTimestamp()); } // remove Types diff --git a/forge-game/src/main/java/forge/game/StaticEffects.java b/forge-game/src/main/java/forge/game/StaticEffects.java index 9bba9d9b0d9..af677db1a3f 100644 --- a/forge-game/src/main/java/forge/game/StaticEffects.java +++ b/forge-game/src/main/java/forge/game/StaticEffects.java @@ -80,4 +80,13 @@ public class StaticEffects { public Iterable getEffects() { return staticEffects.values(); } + + public boolean removeStaticEffect(final StaticAbility staticAbility) { + final StaticEffect currentEffect = staticEffects.remove(staticAbility); + if (currentEffect == null) { + return false; + } + currentEffect.remove(); + return true; + } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java index 623a727ed55..9e23a7a7183 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java @@ -14,19 +14,15 @@ import forge.game.player.Player; import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementHandler; import forge.game.spellability.SpellAbility; -import forge.game.staticability.StaticAbility; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerHandler; import forge.game.zone.ZoneType; -import forge.util.collect.FCollectionView; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; -import com.google.common.collect.ImmutableList; - public class AnimateAllEffect extends AnimateEffectBase { @Override @@ -160,30 +156,16 @@ public class AnimateAllEffect extends AnimateEffectBase { final String actualAbility = host.getSVar(s); final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c); addedAbilities.add(grantedAbility); - c.addSpellAbility(grantedAbility); } } - // remove abilities - final List removedAbilities = new ArrayList<>(); - if (sa.hasParam("OverwriteAbilities") || removeAll || removeIntrinsic) { - for (final SpellAbility ab : c.getSpellAbilities()) { - if (ab.isAbility()) { - if (removeAll - || (ab.isIntrinsic() && removeIntrinsic && !ab.isBasicLandAbility())) { - ab.setTemporarilySuppressed(true); - removedAbilities.add(ab); - } - } - } - } // give replacement effects final List addedReplacements = new ArrayList<>(); if (replacements.size() > 0) { for (final String s : replacements) { final String actualReplacement = host.getSVar(s); final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, c, false); - addedReplacements.add(c.addReplacementEffect(parsedReplacement)); + addedReplacements.add(parsedReplacement); } } // Grant triggers @@ -192,45 +174,12 @@ public class AnimateAllEffect extends AnimateEffectBase { for (final String s : triggers) { final String actualTrigger = host.getSVar(s); final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, c, false); - addedTriggers.add(c.addTrigger(parsedTrigger)); + addedTriggers.add(parsedTrigger); } } - // suppress triggers from the animated card - final List removedTriggers = new ArrayList<>(); - if (sa.hasParam("OverwriteTriggers") || removeAll || removeIntrinsic) { - final FCollectionView triggersToRemove = c.getTriggers(); - for (final Trigger trigger : triggersToRemove) { - if (removeIntrinsic && !trigger.isIntrinsic()) { - continue; - } - trigger.setSuppressed(true); // why this not TemporarilySuppressed? - removedTriggers.add(trigger); - } - } - - // suppress static abilities from the animated card - final List removedStatics = new ArrayList<>(); - if (sa.hasParam("OverwriteStatics") || removeAll || removeIntrinsic) { - for (final StaticAbility stAb : c.getStaticAbilities()) { - if (removeIntrinsic && !stAb.isIntrinsic()) { - continue; - } - stAb.setTemporarilySuppressed(true); - removedStatics.add(stAb); - } - } - - // suppress static abilities from the animated card - final List removedReplacements = new ArrayList<>(); - if (sa.hasParam("OverwriteReplacements") || removeAll || removeIntrinsic) { - for (final ReplacementEffect re : c.getReplacementEffects()) { - if (removeIntrinsic && !re.isIntrinsic()) { - continue; - } - re.setTemporarilySuppressed(true); - removedReplacements.add(re); - } + if (!addedAbilities.isEmpty() || !addedTriggers.isEmpty() || !addedReplacements.isEmpty()) { + c.addChangedCardTraits(addedAbilities, null, addedTriggers, addedReplacements, null, removeAll, false, removeIntrinsic, timestamp); } // give sVars @@ -247,27 +196,8 @@ public class AnimateAllEffect extends AnimateEffectBase { @Override public void run() { - doUnanimate(c, sa, finalDesc, hiddenKeywords, - addedAbilities, addedTriggers, addedReplacements, - ImmutableList.of(), timestamp); + doUnanimate(c, sa, hiddenKeywords, timestamp); - for (final SpellAbility sa : removedAbilities) { - sa.setTemporarilySuppressed(false); - } - // give back suppressed triggers - for (final Trigger t : removedTriggers) { - t.setSuppressed(false); - } - - // give back suppressed static abilities - for (final StaticAbility s : removedStatics) { - s.setTemporarilySuppressed(false); - } - - // give back suppressed replacement effects - for (final ReplacementEffect re : removedReplacements) { - re.setTemporarilySuppressed(false); - } game.fireEvent(new GameEventCardStatsChanged(c)); } }; diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java index 7f0fa438ebc..b319e84f37f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java @@ -162,25 +162,15 @@ public class AnimateEffect extends AnimateEffectBase { // remove abilities final List removedAbilities = Lists.newArrayList(); - boolean clearAbilities = sa.hasParam("OverwriteAbilities"); boolean clearSpells = sa.hasParam("OverwriteSpells"); boolean removeAll = sa.hasParam("RemoveAllAbilities"); boolean removeIntrinsic = sa.hasParam("RemoveIntrinsicAbilities"); - if (clearAbilities || clearSpells || removeAll) { - for (final SpellAbility ab : c.getSpellAbilities()) { - if (removeAll - || (ab.isIntrinsic() && removeIntrinsic && !ab.isBasicLandAbility()) - || (ab.isAbility() && clearAbilities) - || (ab.isSpell() && clearSpells)) { - ab.setTemporarilySuppressed(true); - removedAbilities.add(ab); - } - } + if (clearSpells) { + removedAbilities.addAll(Lists.newArrayList(c.getSpells())); } if (sa.hasParam("RemoveThisAbility") && !removedAbilities.contains(sa)) { - c.removeSpellAbility(sa); removedAbilities.add(sa); } @@ -189,9 +179,7 @@ public class AnimateEffect extends AnimateEffectBase { if (abilities.size() > 0) { for (final String s : abilities) { final String actualAbility = source.getSVar(s); - final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c); - addedAbilities.add(grantedAbility); - c.addSpellAbility(grantedAbility); + addedAbilities.add(AbilityFactory.getAbility(actualAbility, c)); } } @@ -201,7 +189,7 @@ public class AnimateEffect extends AnimateEffectBase { for (final String s : triggers) { final String actualTrigger = source.getSVar(s); final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, c, false); - addedTriggers.add(c.addTrigger(parsedTrigger)); + addedTriggers.add(parsedTrigger); } } @@ -211,19 +199,7 @@ public class AnimateEffect extends AnimateEffectBase { for (final String s : replacements) { final String actualReplacement = source.getSVar(s); final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, c, false); - addedReplacements.add(c.addReplacementEffect(parsedReplacement)); - } - } - - // suppress triggers from the animated card - final List removedTriggers = Lists.newArrayList(); - if (sa.hasParam("OverwriteTriggers") || removeAll || removeIntrinsic) { - for (final Trigger trigger : c.getTriggers()) { - if (removeIntrinsic && !trigger.isIntrinsic()) { - continue; - } - trigger.setSuppressed(true); // why this not TemporarilySuppressed? - removedTriggers.add(trigger); + addedReplacements.add(parsedReplacement); } } @@ -233,7 +209,7 @@ public class AnimateEffect extends AnimateEffectBase { if (stAbs.size() > 0) { for (final String s : stAbs) { final String actualAbility = source.getSVar(s); - addedStaticAbilities.add(c.addStaticAbility(actualAbility)); + addedStaticAbilities.add(new StaticAbility(actualAbility, c)); } } @@ -251,30 +227,6 @@ public class AnimateEffect extends AnimateEffectBase { } } - // suppress static abilities from the animated card - final List removedStatics = Lists.newArrayList(); - if (sa.hasParam("OverwriteStatics") || removeAll || removeIntrinsic) { - for (final StaticAbility stAb : c.getStaticAbilities()) { - if (removeIntrinsic && !stAb.isIntrinsic()) { - continue; - } - stAb.setTemporarilySuppressed(true); - removedStatics.add(stAb); - } - } - - // suppress static abilities from the animated card - final List removedReplacements = Lists.newArrayList(); - if (sa.hasParam("OverwriteReplacements") || removeAll || removeIntrinsic) { - for (final ReplacementEffect re : c.getReplacementEffects()) { - if (removeIntrinsic && !re.isIntrinsic()) { - continue; - } - re.setTemporarilySuppressed(true); - removedReplacements.add(re); - } - } - // give Remembered if (animateRemembered != null) { for (final Object o : AbilityUtils.getDefinedObjects(source, animateRemembered, sa)) { @@ -287,35 +239,40 @@ public class AnimateEffect extends AnimateEffectBase { @Override public void run() { - doUnanimate(c, sa, finalDesc, hiddenKeywords, - addedAbilities, addedTriggers, addedReplacements, - addedStaticAbilities, timestamp); + doUnanimate(c, sa, hiddenKeywords, timestamp); c.removeChangedName(timestamp); c.updateStateForView(); game.fireEvent(new GameEventCardStatsChanged(c)); - - for (final SpellAbility sa : removedAbilities) { - sa.setTemporarilySuppressed(false); - } - // give back suppressed triggers - for (final Trigger t : removedTriggers) { - t.setSuppressed(false); - } - - // give back suppressed static abilities - for (final StaticAbility s : removedStatics) { - s.setTemporarilySuppressed(false); - } - - // give back suppressed replacement effects - for (final ReplacementEffect re : removedReplacements) { - re.setTemporarilySuppressed(false); - } } }; + + if (sa.hasParam("RevertCost")) { + final ManaCost cost = new ManaCost(new ManaCostParser(sa.getParam("RevertCost"))); + final String desc = this.getStackDescription(sa); + final SpellAbility revertSA = new AbilityStatic(c, cost) { + @Override + public void resolve() { + unanimate.run(); + } + @Override + public String getDescription() { + return cost + ": End Effect: " + desc; + } + }; + addedAbilities.add(revertSA); + } + + // after unanimate to add RevertCost + if (removeAll || removeIntrinsic + || !addedAbilities.isEmpty() || !removedAbilities.isEmpty() || !addedTriggers.isEmpty() + || !addedReplacements.isEmpty() || !addedStaticAbilities.isEmpty()) { + c.addChangedCardTraits(addedAbilities, removedAbilities, addedTriggers, addedReplacements, + addedStaticAbilities, removeAll, false, removeIntrinsic, timestamp); + } + if (!permanent) { if (sa.hasParam("UntilEndOfCombat")) { game.getEndOfCombat().addUntil(unanimate); @@ -343,22 +300,6 @@ public class AnimateEffect extends AnimateEffectBase { } } - if (sa.hasParam("RevertCost")) { - final ManaCost cost = new ManaCost(new ManaCostParser(sa.getParam("RevertCost"))); - final String desc = this.getStackDescription(sa); - final SpellAbility revertSA = new AbilityStatic(c, cost) { - @Override - public void resolve() { - unanimate.run(); - c.removeSpellAbility(this); - } - @Override - public String getDescription() { - return cost + ": End Effect: " + desc; - } - }; - c.addSpellAbility(revertSA); - } game.fireEvent(new GameEventCardStatsChanged(c)); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java index 41399ba8a1f..7e3311e1f40 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java @@ -20,10 +20,8 @@ package forge.game.ability.effects; import forge.card.CardType; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; -import forge.game.replacement.ReplacementEffect; + import forge.game.spellability.SpellAbility; -import forge.game.staticability.StaticAbility; -import forge.game.trigger.Trigger; import java.util.List; public abstract class AnimateEffectBase extends SpellAbilityEffect { @@ -128,14 +126,8 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect { * @param timestamp * a long. */ - static void doUnanimate(final Card c, SpellAbility sa, final String colorDesc, - final List hiddenKeywords, final List addedAbilities, - final List addedTriggers, final List addedReplacements, - final List addedStaticAbilities, final long timestamp) { - - if (sa.hasParam("LastsIndefinitely")) { - return; - } + static void doUnanimate(final Card c, SpellAbility sa, + final List hiddenKeywords, final long timestamp) { c.removeNewPT(timestamp); @@ -144,26 +136,12 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect { c.removeChangedCardTypes(timestamp); c.removeColor(timestamp); + c.removeChangedCardTraits(timestamp); + for (final String k : hiddenKeywords) { c.removeHiddenExtrinsicKeyword(k); } - for (final SpellAbility saAdd : addedAbilities) { - c.removeSpellAbility(saAdd); - } - - for (final Trigger t : addedTriggers) { - c.removeTrigger(t); - } - - for (final ReplacementEffect rep : addedReplacements) { - c.removeReplacementEffect(rep); - } - - for (final StaticAbility stAb : addedStaticAbilities) { - c.removeStaticAbility(stAb); - } - // any other unanimate cleanup if (!c.isCreature()) { c.unEquipAllCards(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/RegenerateBaseEffect.java b/forge-game/src/main/java/forge/game/ability/effects/RegenerateBaseEffect.java index d4ff911c8ef..2429a660154 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/RegenerateBaseEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/RegenerateBaseEffect.java @@ -58,7 +58,7 @@ public abstract class RegenerateBaseEffect extends SpellAbilityEffect { + " | TriggerDescription$ " + trigSA.getDescription(); final Trigger trigger = TriggerHandler.parseTrigger(trigStr, eff, true); trigger.setOverridingAbility(trigSA); - eff.moveTrigger(trigger); + eff.addTrigger(trigger); } // Copy text changes diff --git a/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java b/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java index 61848eba1f3..38275f3f961 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java @@ -55,7 +55,6 @@ public class RestartGameEffect extends SpellAbilityEffect { forge.game.trigger.Trigger.resetIDs(); TriggerHandler trigHandler = game.getTriggerHandler(); trigHandler.clearDelayedTrigger(); - trigHandler.cleanUpTemporaryTriggers(); trigHandler.suppressMode(TriggerType.ChangesZone); game.getStack().reset(); diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index a24259b01bc..c580357e6c8 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -18,6 +18,7 @@ package forge.game.card; import com.esotericsoftware.minlog.Log; +import com.google.common.base.Predicates; import com.google.common.base.Strings; import com.google.common.collect.*; import forge.GameCommand; @@ -121,6 +122,7 @@ public class Card extends GameEntity implements Comparable { private final Map changedCardTypes = Maps.newTreeMap(); private final NavigableMap changedCardNames = Maps.newTreeMap(); private final Map changedCardKeywords = Maps.newTreeMap(); + private final Map changedCardTraits = Maps.newTreeMap(); private final Map changedCardColors = Maps.newTreeMap(); private final NavigableMap clonedStates = Maps.newTreeMap(); private final NavigableMap textChangeStates = Maps.newTreeMap(); @@ -1012,28 +1014,15 @@ public class Card extends GameEntity implements Comparable { public final FCollectionView getTriggers() { return currentState.getTriggers(); } - // only used for LKI - public final void setTriggers(final Iterable trigs, boolean intrinsicOnly) { - final FCollection copyList = new FCollection<>(); - for (final Trigger t : trigs) { - if (!intrinsicOnly || t.isIntrinsic()) { - copyList.add(t.copy(this, true)); - } - } - currentState.setTriggers(copyList); - } public final Trigger addTrigger(final Trigger t) { - final Trigger newtrig = t.copy(this, false); - currentState.addTrigger(newtrig); - return newtrig; - } - public final void moveTrigger(final Trigger t) { - t.setHostCard(this); currentState.addTrigger(t); + return t; } + @Deprecated public final void removeTrigger(final Trigger t) { currentState.removeTrigger(t); } + @Deprecated public final void removeTrigger(final Trigger t, final CardStateName state) { getState(state).removeTrigger(t); } @@ -1050,6 +1039,25 @@ public class Card extends GameEntity implements Comparable { } public void updateTriggers(List list, CardState state) { + + boolean removeIntrinsic = false; + for (final CardTraitChanges ck : changedCardTraits.values()) { + if (ck.isRemoveIntrinsic()) { + removeIntrinsic = true; + break; + } + } + if (removeIntrinsic) { + list.clear(); + } + + for (final CardTraitChanges ck : changedCardTraits.values()) { + if (ck.isRemoveAll()) { + list.clear(); + } + list.addAll(ck.getTriggers()); + } + for (KeywordInterface kw : getUnhiddenKeywords(state)) { list.addAll(kw.getTriggers()); } @@ -2379,10 +2387,12 @@ public class Card extends GameEntity implements Comparable { } } + @Deprecated public final void removeSpellAbility(final SpellAbility a) { removeSpellAbility(a, true); } + @Deprecated public final void removeSpellAbility(final SpellAbility a, final boolean updateView) { if (currentState.removeSpellAbility(a) && updateView) { currentState.getView().updateAbilityText(this, currentState); @@ -2408,15 +2418,44 @@ public class Card extends GameEntity implements Comparable { } public void updateSpellAbilities(List list, CardState state, Boolean mana) { + + boolean removeIntrinsic = false; + for (final CardTraitChanges ck : changedCardTraits.values()) { + if (ck.isRemoveIntrinsic()) { + removeIntrinsic = true; + break; + } + } + if (removeIntrinsic) { + list.clear(); + } + // do Basic Land Abilities there - if (mana == null || mana == true) { + if (null == mana || true == mana) { updateBasicLandAbilities(list, state); } + for (final CardTraitChanges ck : changedCardTraits.values()) { + if (ck.isRemoveNonMana()) { + // List only has nonMana + if (null == mana) { + List toRemove = Lists.newArrayList( + Iterables.filter(list, Predicates.not(SpellAbilityPredicates.isManaAbility()))); + list.removeAll(toRemove); + } else if (false == mana) { + list.clear(); + } + } else if (ck.isRemoveAll()) { + list.clear(); + } + list.removeAll(ck.getRemovedAbilities()); + list.addAll(ck.getAbilities()); + } + // add Facedown abilities from Original state but only if this state is face down // need CardStateView#getState or might crash in StackOverflow if (isInZone(ZoneType.Battlefield)) { - if ((mana == null || mana == false) && isFaceDown() && state.getView().getState() == CardStateName.FaceDown) { + if ((null == mana || false == mana) && isFaceDown() && state.getView().getState() == CardStateName.FaceDown) { for (SpellAbility sa : getState(CardStateName.Original).getNonManaAbilities()) { if (sa.isManifestUp() || sa.isMorphUp()) { list.add(sa); @@ -2729,14 +2768,14 @@ public class Card extends GameEntity implements Comparable { * * Control, Controller: "Control" is the system that determines who gets to use an object in the game. * An object's "controller" is the player who currently controls it. See rule 108.4. - * - * 400.6. If an object would move from one zone to another, determine what event is moving the object. - * If the object is moving to a public zone and its owner will be able to look at it in that zone, - * its owner looks at it to see if it has any abilities that would affect the move. - * If the object is moving to the battlefield, each other player who will be able to look at it in that - * zone does so. Then any appropriate replacement effects, whether they come from that object or from - * elsewhere, are applied to that event. If any effects or rules try to do two or more contradictory or - * mutually exclusive things to a particular object, that object’s CONTROLLER—or its OWNER + * + * 400.6. If an object would move from one zone to another, determine what event is moving the object. + * If the object is moving to a public zone and its owner will be able to look at it in that zone, + * its owner looks at it to see if it has any abilities that would affect the move. + * If the object is moving to the battlefield, each other player who will be able to look at it in that + * zone does so. Then any appropriate replacement effects, whether they come from that object or from + * elsewhere, are applied to that event. If any effects or rules try to do two or more contradictory or + * mutually exclusive things to a particular object, that object’s CONTROLLER—or its OWNER * IF IT HAS NO CONTROLLER—chooses which effect to apply, and what that effect does. */ if (controller != null) { @@ -3589,6 +3628,31 @@ public class Card extends GameEntity implements Comparable { getGame().fireEvent(new GameEventCardTapped(this, false)); } + public final void addChangedCardTraits(Collection spells, Collection removedAbilities, + Collection trigger, Collection replacements, Collection statics, + boolean removeAll, boolean removeNonMana, boolean removeIntrinsic, long timestamp) { + changedCardTraits.put(timestamp, new CardTraitChanges( + spells, removedAbilities, trigger, replacements, statics, removeAll, removeNonMana, removeIntrinsic + )); + // update view + updateAbilityTextForView(); + } + + public final boolean removeChangedCardTraits(long timestamp) { + return changedCardTraits.remove(timestamp) != null; + } + + public final Map getChangedCardTraits() { + return changedCardTraits; + } + + public final void setChangedCardTraits(Map changes) { + changedCardTraits.clear(); + for (Entry e : changes.entrySet()) { + changedCardTraits.put(e.getKey(), e.getValue().copy(this, true)); + } + } + // keywords are like flying, fear, first strike, etc... public final List getKeywords() { return getKeywords(currentState); @@ -4018,11 +4082,31 @@ public class Card extends GameEntity implements Comparable { currentState.addStaticAbility(stAb); return stAb; } + + @Deprecated public final void removeStaticAbility(StaticAbility stAb) { currentState.removeStaticAbility(stAb); } public void updateStaticAbilities(List list, CardState state) { + boolean removeIntrinsic = false; + for (final CardTraitChanges ck : changedCardTraits.values()) { + if (ck.isRemoveIntrinsic()) { + removeIntrinsic = true; + break; + } + } + if (removeIntrinsic) { + list.clear(); + } + + for (final CardTraitChanges ck : changedCardTraits.values()) { + if (ck.isRemoveAll()) { + list.clear(); + } + list.addAll(ck.getStaticAbilities()); + } + for (KeywordInterface kw : getUnhiddenKeywords(state)) { list.addAll(kw.getStaticAbilities()); } @@ -5641,24 +5725,35 @@ public class Card extends GameEntity implements Comparable { return currentState.getReplacementEffects(); } - public void setReplacementEffects(final Iterable res) { - currentState.clearReplacementEffects(); - for (final ReplacementEffect replacementEffect : res) { - if (replacementEffect.isIntrinsic()) { - addReplacementEffect(replacementEffect.copy(this, false)); - } - } - } - public ReplacementEffect addReplacementEffect(final ReplacementEffect replacementEffect) { currentState.addReplacementEffect(replacementEffect); return replacementEffect; } + + @Deprecated public void removeReplacementEffect(ReplacementEffect replacementEffect) { currentState.removeReplacementEffect(replacementEffect); } public void updateReplacementEffects(List list, CardState state) { + + boolean removeIntrinsic = false; + for (final CardTraitChanges ck : changedCardTraits.values()) { + if (ck.isRemoveIntrinsic()) { + removeIntrinsic = true; + break; + } + } + if (removeIntrinsic) { + list.clear(); + } + + for (final CardTraitChanges ck : changedCardTraits.values()) { + if (ck.isRemoveAll()) { + list.clear(); + } + list.addAll(ck.getReplacements()); + } for (KeywordInterface kw : getUnhiddenKeywords(state)) { list.addAll(kw.getReplacements()); } @@ -6296,27 +6391,6 @@ public class Card extends GameEntity implements Comparable { withFlash.removeAll(timestamp); } - public void unSuppressCardTraits() { - // specially reset basic land abilities - for (final SpellAbility ab : basicLandAbilities) { - if (ab != null) { - ab.setTemporarilySuppressed(false); - } - } - for (final SpellAbility ab : getSpellAbilities()) { - ab.setTemporarilySuppressed(false); - } - for (final Trigger t : getTriggers()) { - t.setTemporarilySuppressed(false); - } - for (final StaticAbility stA : getStaticAbilities()) { - stA.setTemporarilySuppressed(false); - } - for (final ReplacementEffect rE : getReplacementEffects()) { - rE.setTemporarilySuppressed(false); - } - } - public boolean canBeDiscardedBy(SpellAbility sa) { if (!isInZone(ZoneType.Hand)) { return false; diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 8fc4114e6bf..f0317647e70 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3758,7 +3758,6 @@ public class CardFactoryUtil { newSA.setDescription(sa.getDescription() + " (by paying " + cost.toSimpleString() + " instead of its mana cost)"); newSA.setIntrinsic(intrinsic); - newSA.setTemporary(intrinsic); inst.addSpellAbility(newSA); } @@ -3788,8 +3787,6 @@ public class CardFactoryUtil { final SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.equals("Aftermath") && card.getCurrentStateName().equals(CardStateName.RightSplit)) { // Aftermath does modify existing SA, and does not add new one @@ -3809,8 +3806,6 @@ public class CardFactoryUtil { final SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Awaken")) { final String[] k = keyword.split(":"); @@ -3835,8 +3830,6 @@ public class CardFactoryUtil { awakenSpell.setBasicSpell(false); awakenSpell.setPayCosts(awakenCost); awakenSpell.setIntrinsic(intrinsic); - - awakenSpell.setTemporary(!intrinsic); inst.addSpellAbility(awakenSpell); } else if (keyword.startsWith("Bestow")) { final String[] params = keyword.split(":"); @@ -3854,8 +3847,6 @@ public class CardFactoryUtil { sa.setStackDescription("Bestow - " + card.getName()); sa.setBasicSpell(false); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Dash")) { final String[] k = keyword.split(":"); @@ -3865,8 +3856,6 @@ public class CardFactoryUtil { final SpellAbility newSA = AbilityFactory.getAbility(dashString, card); newSA.setIntrinsic(intrinsic); - - newSA.setTemporary(!intrinsic); inst.addSpellAbility(newSA); } else if (keyword.startsWith("Emerge")) { final String[] kw = keyword.split(":"); @@ -3882,8 +3871,6 @@ public class CardFactoryUtil { newSA.setPayCosts(new Cost(costStr, false)); newSA.setDescription(sa.getDescription() + " (Emerge)"); newSA.setIntrinsic(intrinsic); - - newSA.setTemporary(!intrinsic); inst.addSpellAbility(newSA); } else if (keyword.startsWith("Embalm")) { final String[] kw = keyword.split(":"); @@ -3896,8 +3883,6 @@ public class CardFactoryUtil { "| SpellDescription$ (" + inst.getReminderText() + ")" ; final SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.equals("Epic")) { // Epic does modify existing SA, and does not add new one @@ -3952,7 +3937,6 @@ public class CardFactoryUtil { // instantiate attach ability final SpellAbility newSA = AbilityFactory.getAbility(abilityStr.toString(), card); newSA.setIntrinsic(intrinsic); - newSA.setTemporary(!intrinsic); inst.addSpellAbility(newSA); } else if (keyword.startsWith("Eternalize")) { final String[] kw = keyword.split(":"); @@ -3982,8 +3966,6 @@ public class CardFactoryUtil { .append("| SpellDescription$ (").append(inst.getReminderText()).append(")"); final SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Evoke")) { final String[] k = keyword.split(":"); @@ -4005,8 +3987,6 @@ public class CardFactoryUtil { newSA.setBasicSpell(false); newSA.setEvoke(true); newSA.setIntrinsic(intrinsic); - - newSA.setTemporary(!intrinsic); inst.addSpellAbility(newSA); } else if (keyword.startsWith("Fortify")) { String[] k = keyword.split(":"); @@ -4027,14 +4007,10 @@ public class CardFactoryUtil { // instantiate attach ability final SpellAbility sa = AbilityFactory.getAbility(abilityStr.toString(), card); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Fuse") && card.getCurrentStateName().equals(CardStateName.Original)) { final SpellAbility sa = AbilityFactory.buildFusedAbility(card); card.addSpellAbility(sa); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Haunt")) { if (!card.isCreature() && intrinsic) { @@ -4067,8 +4043,6 @@ public class CardFactoryUtil { final SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Monstrosity")) { final String[] k = keyword.split(":"); @@ -4103,8 +4077,6 @@ public class CardFactoryUtil { final SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Morph")) { @@ -4146,8 +4118,6 @@ public class CardFactoryUtil { SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); // extra secondary effect for Commander Ninjutsu @@ -4161,8 +4131,6 @@ public class CardFactoryUtil { sa = AbilityFactory.getAbility(effect, card); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } } else if (keyword.startsWith("Outlast")) { @@ -4187,8 +4155,6 @@ public class CardFactoryUtil { final SpellAbility sa = AbilityFactory.getAbility(abilityStr.toString(), card); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Prowl")) { @@ -4212,7 +4178,6 @@ public class CardFactoryUtil { newSA.setProwl(true); newSA.setIntrinsic(intrinsic); - newSA.setTemporary(!intrinsic); inst.addSpellAbility(newSA); } else if (keyword.startsWith("Reinforce")) { final String[] k = keyword.split(":"); @@ -4234,8 +4199,6 @@ public class CardFactoryUtil { if (n.equals("X")) { sa.setSVar("X", "Count$xPaid"); } - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Scavenge")) { final String[] k = keyword.split(":"); @@ -4250,8 +4213,6 @@ public class CardFactoryUtil { final SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setSVar("ScavengeX", "Count$CardPower"); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Spectacle")) { @@ -4267,8 +4228,6 @@ public class CardFactoryUtil { newSA.setDescription(desc); newSA.setIntrinsic(intrinsic); - - newSA.setTemporary(!intrinsic); inst.addSpellAbility(newSA); } else if (keyword.startsWith("Surge")) { @@ -4284,8 +4243,6 @@ public class CardFactoryUtil { newSA.setDescription(desc); newSA.setIntrinsic(intrinsic); - - newSA.setTemporary(!intrinsic); inst.addSpellAbility(newSA); } else if (keyword.startsWith("Suspend") && !keyword.equals("Suspend")) { @@ -4336,8 +4293,6 @@ public class CardFactoryUtil { suspend.setStackDescription(sbStack.toString()); suspend.getRestrictions().setZone(ZoneType.Hand); - - suspend.setTemporary(!intrinsic); inst.addSpellAbility(suspend); } else if (keyword.startsWith("Transfigure")) { final String[] k = keyword.split(":"); @@ -4351,8 +4306,6 @@ public class CardFactoryUtil { final SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setSVar("TransfigureX", "Count$CardManaCost"); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Transmute")) { final String[] k = keyword.split(":"); @@ -4367,8 +4320,6 @@ public class CardFactoryUtil { final SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setSVar("TransmuteX", "Count$CardManaCost"); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Unearth")) { final String[] k = keyword.split(":"); @@ -4383,8 +4334,6 @@ public class CardFactoryUtil { final SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.endsWith(" offering")) { @@ -4403,8 +4352,6 @@ public class CardFactoryUtil { newSA.setPayCosts(sa.getPayCosts()); newSA.setDescription(sa.getDescription() + " (" + offeringType + " offering)"); newSA.setIntrinsic(intrinsic); - - newSA.setTemporary(!intrinsic); inst.addSpellAbility(newSA); } else if (keyword.startsWith("Crew")) { @@ -4420,8 +4367,6 @@ public class CardFactoryUtil { final SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Cycling")) { @@ -4440,8 +4385,6 @@ public class CardFactoryUtil { SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card); sa.setIsCycling(true); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("TypeCycling")) { @@ -4466,8 +4409,6 @@ public class CardFactoryUtil { SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card); sa.setIsCycling(true); sa.setIntrinsic(intrinsic); - - sa.setTemporary(!intrinsic); inst.addSpellAbility(sa); } diff --git a/forge-game/src/main/java/forge/game/card/CardTraitChanges.java b/forge-game/src/main/java/forge/game/card/CardTraitChanges.java new file mode 100644 index 00000000000..cb656beaaff --- /dev/null +++ b/forge-game/src/main/java/forge/game/card/CardTraitChanges.java @@ -0,0 +1,129 @@ +package forge.game.card; + +import java.util.Collection; +import java.util.List; + +import com.google.common.collect.Lists; + +import forge.game.replacement.ReplacementEffect; +import forge.game.spellability.SpellAbility; +import forge.game.staticability.StaticAbility; +import forge.game.trigger.Trigger; + +public class CardTraitChanges implements Cloneable { + + private List triggers = Lists.newArrayList(); + private List replacements = Lists.newArrayList(); + private List abilities = Lists.newArrayList(); + private List staticAbilities = Lists.newArrayList(); + + private List removedAbilities = Lists.newArrayList(); + + private boolean removeAll; + private boolean removeNonMana; + private boolean removeIntrinsic; + + public CardTraitChanges(Collection spells, Collection removedAbilities, + Collection trigger, Collection res, Collection st, + boolean removeAll, boolean removeNonMana, boolean removeIntrinsic) { + if (spells != null) { + this.abilities.addAll(spells); + } + if (removedAbilities != null) { + this.removedAbilities.addAll(removedAbilities); + } + if (trigger != null) { + this.triggers.addAll(trigger); + } + if (res != null) { + this.replacements.addAll(res); + } + if (st != null) { + this.staticAbilities.addAll(st); + } + + this.removeAll = removeAll; + this.removeNonMana = removeNonMana; + this.removeIntrinsic = removeIntrinsic; + } + + /** + * @return the triggers + */ + public Collection getTriggers() { + return triggers; + } + /** + * @return the replacements + */ + public Collection getReplacements() { + return replacements; + } + + /** + * @return the abilities + */ + public Collection getAbilities() { + return abilities; + } + + /** + * @return the abilities + */ + public Collection getRemovedAbilities() { + return removedAbilities; + } + + /** + * @return the staticAbilities + */ + public Collection getStaticAbilities() { + return staticAbilities; + } + + public boolean isRemoveAll() { + return removeAll; + } + + public boolean isRemoveNonMana() { + return removeNonMana; + } + + public boolean isRemoveIntrinsic() { + return removeIntrinsic; + } + + public CardTraitChanges copy(Card host, boolean lki) { + try { + CardTraitChanges result = (CardTraitChanges) super.clone(); + + result.abilities = Lists.newArrayList(); + for (SpellAbility sa : this.abilities) { + result.abilities.add(sa.copy(host, lki)); + } + result.removedAbilities = Lists.newArrayList(); + for (SpellAbility sa : this.removedAbilities) { + result.removedAbilities.add(sa.copy(host, lki)); + } + + result.triggers = Lists.newArrayList(); + for (Trigger tr : this.triggers) { + result.triggers.add(tr.copy(host, lki)); + } + + result.replacements = Lists.newArrayList(); + for (ReplacementEffect re : this.replacements) { + result.replacements.add(re.copy(host, lki)); + } + + result.staticAbilities = Lists.newArrayList(); + for (StaticAbility sa : this.staticAbilities) { + result.staticAbilities.add(sa.copy(host, lki)); + } + + return result; + } catch (final Exception ex) { + throw new RuntimeException("CardTraitChanges : clone() error", ex); + } + } +} diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java index 7d1a508062d..48849e677d2 100644 --- a/forge-game/src/main/java/forge/game/card/CardUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardUtil.java @@ -29,9 +29,7 @@ import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.player.Player; -import forge.game.replacement.ReplacementEffect; import forge.game.spellability.*; -import forge.game.trigger.Trigger; import forge.game.zone.ZoneType; import forge.util.TextUtil; import forge.util.collect.FCollection; @@ -240,23 +238,6 @@ public final class CardUtil { newCopy.setType(new CardType(in.getType())); newCopy.setToken(in.isToken()); - // extra copy non Intrinsic traits - for (SpellAbility sa : in.getSpellAbilities()) { - if (!sa.isIntrinsic()) { - newCopy.addSpellAbility(sa.copy(newCopy, true)); - } - } - for (Trigger tr : in.getTriggers()) { - if (!tr.isIntrinsic()) { - newCopy.moveTrigger(tr.copy(newCopy, true)); - } - } - for (ReplacementEffect re : in.getReplacementEffects()) { - if (!re.isIntrinsic()) { - newCopy.addReplacementEffect(re.copy(newCopy, true)); - } - } - // lock in the current P/T without bonus from counters newCopy.setBasePower(in.getCurrentPower() + in.getTempPowerBoost()); newCopy.setBaseToughness(in.getCurrentToughness() + in.getTempToughnessBoost()); @@ -293,6 +274,7 @@ public final class CardUtil { newCopy.setChangedCardKeywords(in.getChangedCardKeywords()); newCopy.setChangedCardTypes(in.getChangedCardTypesMap()); newCopy.setChangedCardNames(in.getChangedCardNames()); + newCopy.setChangedCardTraits(in.getChangedCardTraits()); newCopy.copyChangedTextFrom(in); 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 14ff90e380f..a187d2a101e 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -1178,7 +1178,7 @@ public class Player extends GameEntity implements Comparable { com.remove(eff); eff.setStaticAbilities(Lists.newArrayList()); } - this.updateZoneForView(com); + this.updateZoneForView(com); } @Override diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java b/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java index 1007b1fc727..0c23c297da5 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java @@ -193,7 +193,6 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { res.setActiveZone(validHostZones); res.setLayer(getLayer()); - res.setTemporary(isTemporary()); return res; } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java index 272388ef303..04f1e61cbda 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -356,31 +356,4 @@ public class ReplacementHandler { return ret; } - - public void cleanUpTemporaryReplacements() { - game.forEachCardInGame(new Visitor() { - @Override - public boolean visit(Card c) { - List toRemove = Lists.newArrayList(); - for (ReplacementEffect rep : c.getReplacementEffects()) { - if (rep.isTemporary()) { - toRemove.add(rep); - } - } - for (ReplacementEffect rep : toRemove) { - c.removeReplacementEffect(rep); - } - return true; - } - }); - game.forEachCardInGame(new Visitor() { - @Override - public boolean visit(Card c) { - for (int i = 0; i < c.getReplacementEffects().size(); i++) { - c.getReplacementEffects().get(i).setTemporarilySuppressed(false); - } - return true; - } - }); - } } diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityPredicates.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityPredicates.java index 57e6b9ee717..4f575371492 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityPredicates.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityPredicates.java @@ -32,6 +32,15 @@ public final class SpellAbilityPredicates extends CardTraitPredicates { } }; } + + public static final Predicate isManaAbility() { + return new Predicate() { + @Override + public boolean apply(final SpellAbility sa) { + return sa.isManaAbility(); + } + }; + } public static final Predicate isIntrinsic() { return new Predicate() { diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java index 45eebde5916..bad27de11c1 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java @@ -159,14 +159,14 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone } if (hasParam("RemoveAllAbilities") || hasParam("GainsAbilitiesOf")) { - layers.add(StaticAbilityLayer.ABILITIES1); + layers.add(StaticAbilityLayer.ABILITIES); } if (hasParam("AddKeyword") || hasParam("AddAbility") || hasParam("AddTrigger") || hasParam("RemoveTriggers") || hasParam("RemoveKeyword") || hasParam("AddReplacementEffects") || hasParam("AddStaticAbility") || hasParam("AddSVar")) { - layers.add(StaticAbilityLayer.ABILITIES2); + layers.add(StaticAbilityLayer.ABILITIES); } if (hasParam("CharacteristicDefining")) { @@ -183,7 +183,7 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone if (hasParam("AddHiddenKeyword")) { // special rule for can't have or gain if (getParam("AddHiddenKeyword").contains("can't have or gain")) { - layers.add(StaticAbilityLayer.ABILITIES1); + layers.add(StaticAbilityLayer.ABILITIES); } layers.add(StaticAbilityLayer.RULES); } @@ -259,14 +259,14 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone } public final CardCollectionView applyContinuousAbilityBefore(final StaticAbilityLayer layer, final CardCollectionView preList) { - if (!shouldApplyContinuousAbility(layer, false)) { + if (!shouldApplyContinuousAbility(layer)) { return null; } return StaticAbilityContinuous.applyContinuousAbility(this, layer, preList); } public final CardCollectionView applyContinuousAbility(final StaticAbilityLayer layer, final CardCollectionView affected) { - if (!shouldApplyContinuousAbility(layer, true)) { + if (!shouldApplyContinuousAbility(layer)) { return null; } return StaticAbilityContinuous.applyContinuousAbility(this, affected, layer); @@ -286,14 +286,8 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone * affects the specified layer, it's not suppressed, and its * conditions are fulfilled. */ - private boolean shouldApplyContinuousAbility(final StaticAbilityLayer layer, final boolean ignoreTempSuppression) { - final boolean isSuppressed; - if (ignoreTempSuppression) { - isSuppressed = this.isNonTempSuppressed(); - } else { - isSuppressed = this.isSuppressed(); - } - return getParam("Mode").equals("Continuous") && layers.contains(layer) && !isSuppressed && this.checkConditions(); + private boolean shouldApplyContinuousAbility(final StaticAbilityLayer layer) { + return getParam("Mode").equals("Continuous") && layers.contains(layer) && !isSuppressed() && this.checkConditions(); } // apply the ability if it has the right mode diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java index 5e584a7e324..87058d00c38 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java @@ -122,7 +122,6 @@ public final class StaticAbilityContinuous { String addColors = null; String[] addTriggers = null; String[] addStatics = null; - List addFullAbs = null; boolean removeAllAbilities = false; boolean removeIntrinsicAbilities = false; boolean removeNonMana = false; @@ -187,7 +186,7 @@ public final class StaticAbilityContinuous { toughnessBonus = AbilityUtils.calculateAmount(hostCard, addT, stAb, true); } - if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddKeyword")) { + if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("AddKeyword")) { addKeywords = params.get("AddKeyword").split(" & "); final Iterable chosencolors = hostCard.getChosenColors(); for (final String color : chosencolors) { @@ -222,31 +221,31 @@ public final class StaticAbilityContinuous { } } - if ((layer == StaticAbilityLayer.RULES || layer == StaticAbilityLayer.ABILITIES1) && params.containsKey("AddHiddenKeyword")) { + if ((layer == StaticAbilityLayer.RULES || layer == StaticAbilityLayer.ABILITIES) && params.containsKey("AddHiddenKeyword")) { // can't have or gain, need to be applyed in ABILITIES1 for (String k : params.get("AddHiddenKeyword").split(" & ")) { - if ( (k.contains("can't have or gain")) == (layer == StaticAbilityLayer.ABILITIES1)) + if ( (k.contains("can't have or gain")) == (layer == StaticAbilityLayer.ABILITIES)) addHiddenKeywords.add(k); } } - if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("RemoveKeyword")) { + if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("RemoveKeyword")) { removeKeywords = params.get("RemoveKeyword").split(" & "); } - if (layer == StaticAbilityLayer.ABILITIES1 && params.containsKey("RemoveAllAbilities")) { + if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("RemoveAllAbilities")) { removeAllAbilities = true; if (params.containsKey("ExceptManaAbilities")) { removeNonMana = true; } } // do this in type layer too in case of blood moon - if ((layer == StaticAbilityLayer.ABILITIES1 || layer == StaticAbilityLayer.TYPE) + if ((layer == StaticAbilityLayer.TYPE) && params.containsKey("RemoveIntrinsicAbilities")) { removeIntrinsicAbilities = true; } - if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddAbility")) { + if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("AddAbility")) { final String[] sVars = params.get("AddAbility").split(" & "); for (int i = 0; i < sVars.length; i++) { sVars[i] = hostCard.getSVar(sVars[i]); @@ -254,7 +253,7 @@ public final class StaticAbilityContinuous { addAbilities = sVars; } - if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddReplacementEffects")) { + if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("AddReplacementEffects")) { final String[] sVars = params.get("AddReplacementEffects").split(" & "); for (int i = 0; i < sVars.length; i++) { sVars[i] = hostCard.getSVar(sVars[i]); @@ -262,7 +261,7 @@ public final class StaticAbilityContinuous { addReplacements = sVars; } - if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddSVar")) { + if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("AddSVar")) { addSVars = params.get("AddSVar").split(" & "); } @@ -339,7 +338,7 @@ public final class StaticAbilityContinuous { } } - if (layer == StaticAbilityLayer.ABILITIES2) { + if (layer == StaticAbilityLayer.ABILITIES) { if (params.containsKey("AddTrigger")) { final String[] sVars = params.get("AddTrigger").split(" & "); for (int i = 0; i < sVars.length; i++) { @@ -357,45 +356,6 @@ public final class StaticAbilityContinuous { } } - if (layer == StaticAbilityLayer.ABILITIES1 && params.containsKey("GainsAbilitiesOf")) { - final String[] valids = params.get("GainsAbilitiesOf").split(","); - List validZones; - final boolean loyaltyAB = params.containsKey("GainsLoyaltyAbilities"); - if (params.containsKey("GainsAbilitiesOfZones")) { - validZones = ZoneType.listValueOf(params.get("GainsAbilitiesOfZones")); - } else { - validZones = ImmutableList.of(ZoneType.Battlefield); - } - - CardCollectionView cardsIGainedAbilitiesFrom = game.getCardsIn(validZones); - cardsIGainedAbilitiesFrom = CardLists.getValidCards(cardsIGainedAbilitiesFrom, valids, hostCard.getController(), hostCard, null); - - if (cardsIGainedAbilitiesFrom.size() > 0) { - addFullAbs = Lists.newArrayList(); - - for (Card c : cardsIGainedAbilitiesFrom) { - for (SpellAbility sa : c.getSpellAbilities()) { - if (sa instanceof AbilityActivated) { - if (loyaltyAB && !sa.isPwAbility()) { - continue; - } - SpellAbility newSA = sa.copy(hostCard, false); - if (params.containsKey("GainsAbilitiesLimitPerTurn")) { - newSA.setRestrictions(sa.getRestrictions()); - newSA.getRestrictions().setLimitToCheck(params.get("GainsAbilitiesLimitPerTurn")); - } - newSA.setOriginalHost(c); - newSA.setOriginalAbility(sa); // need to be set to get the Once Per turn Clause correct - newSA.setGrantorStatic(stAb); - newSA.setIntrinsic(false); - newSA.setTemporary(true); - addFullAbs.add(newSA); - } - } - } - } - } - if (layer == StaticAbilityLayer.RULES) { // These fall under Rule changes, as they don't fit any other category if (params.containsKey("MayLookAt")) { @@ -444,7 +404,6 @@ public final class StaticAbilityContinuous { if (addStatics != null) { for (String s : addStatics) { StaticAbility stat = p.addStaticAbility(hostCard, s); - stat.setTemporary(true); stat.setIntrinsic(false); } } @@ -582,38 +541,117 @@ public final class StaticAbilityContinuous { } } - if (addFullAbs != null) { - for (final SpellAbility ab : addFullAbs) { - affectedCard.addSpellAbility(ab, false); + if (layer == StaticAbilityLayer.ABILITIES) { + + List addedAbilities = Lists.newArrayList(); + List addedReplacementEffects = Lists.newArrayList(); + List addedTrigger = Lists.newArrayList(); + List addedStaticAbility = Lists.newArrayList(); + // add abilities + if (addAbilities != null) { + for (String abilty : addAbilities) { + if (abilty.contains("CardManaCost")) { + abilty = TextUtil.fastReplace(abilty, "CardManaCost", affectedCard.getManaCost().getShortString()); + } else if (abilty.contains("ConvertedManaCost")) { + final String costcmc = Integer.toString(affectedCard.getCMC()); + abilty = TextUtil.fastReplace(abilty, "ConvertedManaCost", costcmc); + } + if (abilty.startsWith("AB") || abilty.startsWith("ST")) { // grant the ability + final SpellAbility sa = AbilityFactory.getAbility(abilty, affectedCard); + sa.setIntrinsic(false); + sa.setOriginalHost(hostCard); + addedAbilities.add(sa); + } + } + } + + if (params.containsKey("GainsAbilitiesOf")) { + final String[] valids = params.get("GainsAbilitiesOf").split(","); + List validZones; + final boolean loyaltyAB = params.containsKey("GainsLoyaltyAbilities"); + if (params.containsKey("GainsAbilitiesOfZones")) { + validZones = ZoneType.listValueOf(params.get("GainsAbilitiesOfZones")); + } else { + validZones = ImmutableList.of(ZoneType.Battlefield); + } + + CardCollectionView cardsIGainedAbilitiesFrom = game.getCardsIn(validZones); + cardsIGainedAbilitiesFrom = CardLists.getValidCards(cardsIGainedAbilitiesFrom, valids, hostCard.getController(), hostCard, null); + + for (Card c : cardsIGainedAbilitiesFrom) { + for (SpellAbility sa : c.getSpellAbilities()) { + if (sa instanceof AbilityActivated) { + if (loyaltyAB && !sa.isPwAbility()) { + continue; + } + SpellAbility newSA = sa.copy(affectedCard, false); + if (params.containsKey("GainsAbilitiesLimitPerTurn")) { + newSA.setRestrictions(sa.getRestrictions()); + newSA.getRestrictions().setLimitToCheck(params.get("GainsAbilitiesLimitPerTurn")); + } + newSA.setOriginalHost(c); + newSA.setOriginalAbility(sa); // need to be set to get the Once Per turn Clause correct + newSA.setGrantorStatic(stAb); + newSA.setIntrinsic(false); + addedAbilities.add(newSA); + } + } + } + } + + // add Replacement effects + if (addReplacements != null) { + for (String rep : addReplacements) { + final ReplacementEffect actualRep = ReplacementHandler.parseReplacement(rep, affectedCard, false); + actualRep.setIntrinsic(false); + addedReplacementEffects.add(actualRep); + } + } + + // add triggers + if (addTriggers != null) { + for (final String trigger : addTriggers) { + final Trigger actualTrigger = TriggerHandler.parseTrigger(trigger, affectedCard, false); + // if the trigger has Execute param, which most trigger gained by Static Abilties should have + // turn them into SpellAbility object before adding to card + // with that the TargetedCard does not need the Svars added to them anymore + // but only do it if the trigger doesn't already have a overriding ability + if (actualTrigger.hasParam("Execute") && actualTrigger.getOverridingAbility() == null) { + SpellAbility sa = AbilityFactory.getAbility(hostCard, actualTrigger.getParam("Execute")); + // set hostcard there so when the card is added to trigger, it doesn't make a copy of it + sa.setHostCard(affectedCard); + // set OriginalHost to get the owner of this static ability + sa.setOriginalHost(hostCard); + // set overriding ability to the trigger + actualTrigger.setOverridingAbility(sa); + } + actualTrigger.setIntrinsic(false); + addedTrigger.add(actualTrigger); + } + } + + // add static abilities + if (addStatics != null) { + for (String s : addStatics) { + if (s.contains("ConvertedManaCost")) { + final String costcmc = Integer.toString(affectedCard.getCMC()); + s = TextUtil.fastReplace(s, "ConvertedManaCost", costcmc); + } + + StaticAbility stat = new StaticAbility(s, affectedCard); + stat.setIntrinsic(false); + addedStaticAbility.add(stat); + } + } + + if (!addedAbilities.isEmpty() || addReplacements != null || addTriggers != null || addStatics != null + || removeAllAbilities) { + affectedCard.addChangedCardTraits(addedAbilities, null, addedTrigger, addedReplacementEffects, addedStaticAbility, removeAllAbilities, removeNonMana, false, hostCard.getTimestamp()); } } - // add abilities - if (addAbilities != null) { - for (String abilty : addAbilities) { - if (abilty.contains("CardManaCost")) { - abilty = TextUtil.fastReplace(abilty, "CardManaCost", affectedCard.getManaCost().getShortString()); - } else if (abilty.contains("ConvertedManaCost")) { - final String costcmc = Integer.toString(affectedCard.getCMC()); - abilty = TextUtil.fastReplace(abilty, "ConvertedManaCost", costcmc); - } - if (abilty.startsWith("AB") || abilty.startsWith("ST")) { // grant the ability - final SpellAbility sa = AbilityFactory.getAbility(abilty, affectedCard); - sa.setTemporary(true); - sa.setIntrinsic(false); - sa.setOriginalHost(hostCard); - affectedCard.addSpellAbility(sa, false); - } - } - } - - // add Replacement effects - if (addReplacements != null) { - for (String rep : addReplacements) { - final ReplacementEffect actualRep = ReplacementHandler.parseReplacement(rep, affectedCard, false); - actualRep.setIntrinsic(false); - affectedCard.addReplacementEffect(actualRep).setTemporary(true); - } + if (layer == StaticAbilityLayer.TYPE && removeIntrinsicAbilities) { + affectedCard.addChangedCardTraits(null, null, null, null, null, false, false, removeIntrinsicAbilities, hostCard.getTimestamp()); } // add Types @@ -628,81 +666,6 @@ public final class StaticAbilityContinuous { affectedCard.addColor(addColors, !overwriteColors, hostCard.getTimestamp()); } - // add triggers - if (addTriggers != null) { - for (final String trigger : addTriggers) { - final Trigger actualTrigger = TriggerHandler.parseTrigger(trigger, affectedCard, false); - // if the trigger has Execute param, which most trigger gained by Static Abilties should have - // turn them into SpellAbility object before adding to card - // with that the TargetedCard does not need the Svars added to them anymore - // but only do it if the trigger doesn't already have a overriding ability - if (actualTrigger.hasParam("Execute") && actualTrigger.getOverridingAbility() == null) { - SpellAbility sa = AbilityFactory.getAbility(hostCard, actualTrigger.getParam("Execute")); - // set hostcard there so when the card is added to trigger, it doesn't make a copy of it - sa.setHostCard(affectedCard); - // set OriginalHost to get the owner of this static ability - sa.setOriginalHost(hostCard); - // set overriding ability to the trigger - actualTrigger.setOverridingAbility(sa); - } - actualTrigger.setIntrinsic(false); - affectedCard.addTrigger(actualTrigger).setTemporary(true); - } - } - - // add static abilities - if (addStatics != null) { - for (String s : addStatics) { - if (s.contains("ConvertedManaCost")) { - final String costcmc = Integer.toString(affectedCard.getCMC()); - s = TextUtil.fastReplace(s, "ConvertedManaCost", costcmc); - } - - StaticAbility stat = affectedCard.addStaticAbility(s); - stat.setTemporary(true); - stat.setIntrinsic(false); - } - } - - // remove triggers - if ((layer == StaticAbilityLayer.ABILITIES2 && (params.containsKey("RemoveTriggers")) - || removeAllAbilities || removeIntrinsicAbilities)) { - for (final Trigger trigger : affectedCard.getTriggers()) { - if (removeAllAbilities || (removeIntrinsicAbilities && trigger.isIntrinsic())) { - trigger.setTemporarilySuppressed(true); - } - } - } - - // remove activated and static abilities - if (removeAllAbilities || removeIntrinsicAbilities) { - if (removeNonMana) { // Blood Sun - for (final SpellAbility mana : affectedCard.getNonManaAbilities()) { - if (removeAllAbilities - || (removeIntrinsicAbilities && mana.isIntrinsic() && !mana.isBasicLandAbility())) { - mana.setTemporarilySuppressed(true); - } - } - } else { - for (final SpellAbility ab : affectedCard.getSpellAbilities()) { - if (removeAllAbilities - || (removeIntrinsicAbilities && ab.isIntrinsic() && !ab.isBasicLandAbility())) { - ab.setTemporarilySuppressed(true); - } - } - } - for (final StaticAbility stA : affectedCard.getStaticAbilities()) { - if (removeAllAbilities || (removeIntrinsicAbilities && stA.isIntrinsic())) { - stA.setTemporarilySuppressed(true); - } - } - for (final ReplacementEffect rE : affectedCard.getReplacementEffects()) { - if (removeAllAbilities || (removeIntrinsicAbilities && rE.isIntrinsic())) { - rE.setTemporarilySuppressed(true); - } - } - } - if (layer == StaticAbilityLayer.RULES) { if (params.containsKey("Goad")) { affectedCard.addGoad(se.getTimestamp(), hostCard.getController()); @@ -765,11 +728,11 @@ public final class StaticAbilityContinuous { } }; - addIgnore.setTemporary(true); + addIgnore.setIntrinsic(false); addIgnore.setApi(ApiType.InternalIgnoreEffect); addIgnore.setDescription(cost + " Ignore the effect until end of turn."); - sourceCard.addSpellAbility(addIgnore); + sourceCard.addChangedCardTraits(ImmutableList.of(addIgnore), null, null, null, null, false, false, false, sourceCard.getTimestamp()); final GameCommand removeIgnore = new GameCommand() { private static final long serialVersionUID = -5415775215053216360L; diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityLayer.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityLayer.java index 290b220c2b8..48e9a75e05e 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityLayer.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityLayer.java @@ -18,11 +18,8 @@ public enum StaticAbilityLayer { /** Layer 5 for color-changing effects. */ COLOR, - /** Layer 6 for ability-removing and -copying effects. */ - ABILITIES1, - - /** Layer 6 for ability-granting effects. */ - ABILITIES2, + /** Layer 6 for ability effects. */ + ABILITIES, /** Layer 7a for characteristic-defining power/toughness effects. */ CHARACTERISTIC, @@ -37,5 +34,5 @@ public enum StaticAbilityLayer { RULES; public final static ImmutableList CONTINUOUS_LAYERS = - ImmutableList.of(COPY, CONTROL, TEXT, TYPE, COLOR, ABILITIES1, ABILITIES2, CHARACTERISTIC, SETPT, MODIFYPT, RULES); + ImmutableList.of(COPY, CONTROL, TEXT, TYPE, COLOR, ABILITIES, CHARACTERISTIC, SETPT, MODIFYPT, RULES); } diff --git a/forge-game/src/main/java/forge/game/trigger/Trigger.java b/forge-game/src/main/java/forge/game/trigger/Trigger.java index 2aa850822d4..c655f6ae904 100644 --- a/forge-game/src/main/java/forge/game/trigger/Trigger.java +++ b/forge-game/src/main/java/forge/game/trigger/Trigger.java @@ -561,7 +561,6 @@ public abstract class Trigger extends TriggerReplacementBase { copy.setTriggerPhases(Lists.newArrayList(validPhases)); } copy.setActiveZone(validHostZones); - copy.setTemporary(isTemporary()); return copy; } diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java index bd971ea8aa1..720e7301910 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java @@ -67,42 +67,6 @@ public class TriggerHandler { } public final void cleanUpTemporaryTriggers() { - game.forEachCardInGame(new Visitor() { - @Override - public boolean visit(Card c) { - boolean changed = false; - List toRemove = Lists.newArrayList(); - for (Trigger t : c.getTriggers()) { - if (t.isTemporary()) { - toRemove.add(t); - } - } - for (Trigger t : toRemove) { - changed = true; - c.removeTrigger(t); - } - if (changed) { - c.updateStateForView(); - } - return true; - } - }); - game.forEachCardInGame(new Visitor() { - @Override - public boolean visit(Card c) { - boolean changed = false; - for (int i = 0; i < c.getTriggers().size(); i++) { - if (c.getTriggers().get(i).isSuppressed()) { - c.getTriggers().get(i).setTemporarilySuppressed(false); - changed = true; - } - } - if (changed) { - c.updateStateForView(); - } - return true; - } - }); } public final boolean hasDelayedTriggers() { @@ -699,9 +663,6 @@ public class TriggerHandler { Player p = regtrig.getHostCard().getController(); p.getZone(ZoneType.Command).remove(regtrig.getHostCard()); } - else { - regtrig.getHostCard().removeTrigger(regtrig); - } } } From f6134e3ccf39e20da245d003f32f2b572965d8d5 Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Sat, 5 Oct 2019 22:24:05 -0600 Subject: [PATCH 15/17] update `canReplace` method --- .../main/java/forge/ai/ComputerUtilMana.java | 11 +++---- .../game/replacement/ReplaceAddCounter.java | 13 +++++---- .../game/replacement/ReplaceCounter.java | 9 +++--- .../forge/game/replacement/ReplaceDamage.java | 27 ++++++++--------- .../game/replacement/ReplaceDestroy.java | 13 +++++---- .../game/replacement/ReplaceDiscard.java | 11 +++---- .../forge/game/replacement/ReplaceDraw.java | 7 +++-- .../game/replacement/ReplaceDrawCards.java | 7 +++-- .../game/replacement/ReplaceGainLife.java | 11 +++---- .../game/replacement/ReplaceGameLoss.java | 5 ++-- .../forge/game/replacement/ReplaceMoved.java | 29 ++++++++++--------- .../game/replacement/ReplaceProduceMana.java | 9 +++--- .../game/replacement/ReplaceSetInMotion.java | 5 ++-- .../game/replacement/ReplaceSurveil.java | 7 +++-- .../forge/game/replacement/ReplaceToken.java | 13 +++++---- .../game/replacement/ReplaceTurnFaceUp.java | 5 ++-- .../forge/game/replacement/ReplaceUntap.java | 7 +++-- .../game/replacement/ReplacementEffect.java | 3 +- .../game/replacement/ReplacementHandler.java | 2 +- .../java/forge/match/input/InputPayMana.java | 17 +++++------ 20 files changed, 113 insertions(+), 98 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java index 9c724737a83..4102df2fefb 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java @@ -13,6 +13,7 @@ import forge.card.mana.ManaCostParser; import forge.card.mana.ManaCostShard; import forge.game.Game; import forge.game.GameActionUtil; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.card.*; @@ -1408,11 +1409,11 @@ public class ComputerUtilMana { AbilityManaPart mp = m.getManaPart(); // setup produce mana replacement effects - final Map repParams = new HashMap<>(); - repParams.put("Mana", mp.getOrigProduced()); - repParams.put("Affected", sourceCard); - repParams.put("Player", ai); - repParams.put("AbilityMana", m); + final Map repParams = AbilityKey.newMap(); + repParams.put(AbilityKey.Mana, mp.getOrigProduced()); + repParams.put(AbilityKey.Affected, sourceCard); + repParams.put(AbilityKey.Player, ai); + repParams.put(AbilityKey.AbilityMana, m); for (final ReplacementEffect replacementEffect : replacementEffects) { if (replacementEffect.canReplace(repParams)) { diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java b/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java index 882daefed56..bc19054dc6f 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java @@ -1,5 +1,6 @@ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.card.CounterType; import forge.game.player.Player; @@ -27,20 +28,20 @@ public class ReplaceAddCounter extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { - if (((int) runParams.get("CounterNum")) <= 0) { + public boolean canReplace(Map runParams) { + if (((int) runParams.get(AbilityKey.CounterNum)) <= 0) { return false; } if (hasParam("EffectOnly")) { - final Boolean effectOnly = (Boolean) runParams.get("EffectOnly"); + final Boolean effectOnly = (Boolean) runParams.get(AbilityKey.EffectOnly); if (!effectOnly) { return false; } } if (hasParam("ValidCard")) { - Object o = runParams.get("Affected"); + Object o = runParams.get(AbilityKey.Affected); if (!(o instanceof Card)) { return false; } @@ -48,7 +49,7 @@ public class ReplaceAddCounter extends ReplacementEffect { return false; } } else if (hasParam("ValidPlayer")) { - Object o = runParams.get("Affected"); + Object o = runParams.get(AbilityKey.Affected); if (!(o instanceof Player)) { return false; } @@ -59,7 +60,7 @@ public class ReplaceAddCounter extends ReplacementEffect { if (hasParam("ValidCounterType")) { String type = getParam("ValidCounterType"); - if (CounterType.getType(type) != runParams.get("CounterType")) { + if (CounterType.getType(type) != runParams.get(AbilityKey.CounterType)) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceCounter.java b/forge-game/src/main/java/forge/game/replacement/ReplaceCounter.java index b3d27814b95..56644cfb3cf 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceCounter.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceCounter.java @@ -17,6 +17,7 @@ */ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.spellability.SpellAbility; @@ -42,15 +43,15 @@ public class ReplaceCounter extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { - final SpellAbility spellAbility = (SpellAbility) runParams.get("TgtSA"); + public boolean canReplace(Map runParams) { + final SpellAbility spellAbility = (SpellAbility) runParams.get(AbilityKey.TgtSA); if (hasParam("ValidCard")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidCard").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) { return false; } } if (hasParam("ValidCause")) { - if (!matchesValid(runParams.get("Cause"), getParam("ValidCause").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Cause), getParam("ValidCause").split(","), this.getHostCard())) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java b/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java index 4063ec610bb..aae8f952b89 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java @@ -17,6 +17,7 @@ */ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.card.CardFactoryUtil; @@ -46,49 +47,49 @@ public class ReplaceDamage extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { - if (!(runParams.containsKey("Prevention") == (hasParam("PreventionEffect") || hasParam("Prevent")))) { + public boolean canReplace(Map runParams) { + if (!(runParams.containsKey(AbilityKey.Prevention) == (hasParam("PreventionEffect") || hasParam("Prevent")))) { return false; } - if (((Integer) runParams.get("DamageAmount")) == 0) { + if (((Integer) runParams.get(AbilityKey.DamageAmount)) == 0) { // If no actual damage is dealt, there is nothing to replace return false; } if (hasParam("ValidSource")) { String validSource = getParam("ValidSource"); validSource = AbilityUtils.applyAbilityTextChangeEffects(validSource, this); - if (!matchesValid(runParams.get("DamageSource"), validSource.split(","), getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.DamageSource), validSource.split(","), getHostCard())) { return false; } } if (hasParam("ValidTarget")) { String validTarget = getParam("ValidTarget"); validTarget = AbilityUtils.applyAbilityTextChangeEffects(validTarget, this); - if (!matchesValid(runParams.get("Affected"), validTarget.split(","), getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), validTarget.split(","), getHostCard())) { return false; } } if (hasParam("ValidCause")) { - if (!runParams.containsKey("Cause")) { + if (!runParams.containsKey(AbilityKey.Cause)) { return false; } - SpellAbility cause = (SpellAbility) runParams.get("Cause"); + SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause); String validCause = getParam("ValidCause"); validCause = AbilityUtils.applyAbilityTextChangeEffects(validCause, this); if (!matchesValid(cause, validCause.split(","), getHostCard())) { return false; } if (hasParam("CauseIsSource")) { - if (!cause.getHostCard().equals(runParams.get("DamageSource"))) { + if (!cause.getHostCard().equals(runParams.get(AbilityKey.DamageSource))) { return false; } } } if (hasParam("RelativeToSource")) { - Card source = (Card) runParams.get("DamageSource"); + Card source = (Card) runParams.get(AbilityKey.DamageSource); String validRelative = getParam("RelativeToSource"); validRelative = AbilityUtils.applyAbilityTextChangeEffects(validRelative, this); - if (!matchesValid(runParams.get("DamageTarget"), validRelative.split(","), source)) { + if (!matchesValid(runParams.get(AbilityKey.DamageTarget), validRelative.split(","), source)) { return false; } } @@ -103,17 +104,17 @@ public class ReplaceDamage extends ReplacementEffect { intoperand = CardFactoryUtil.xCount(getHostCard(), getHostCard().getSVar(operand)); } - if (!Expressions.compare((Integer) runParams.get("DamageAmount"), operator, intoperand)) { + if (!Expressions.compare((Integer) runParams.get(AbilityKey.DamageAmount), operator, intoperand)) { return false; } } if (hasParam("IsCombat")) { if (getParam("IsCombat").equals("True")) { - if (!((Boolean) runParams.get("IsCombat"))) { + if (!((Boolean) runParams.get(AbilityKey.IsCombat))) { return false; } } else { - if ((Boolean) runParams.get("IsCombat")) { + if ((Boolean) runParams.get(AbilityKey.IsCombat)) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceDestroy.java b/forge-game/src/main/java/forge/game/replacement/ReplaceDestroy.java index d5fe606ab2b..08420e3817d 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDestroy.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDestroy.java @@ -17,6 +17,7 @@ */ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.spellability.SpellAbility; @@ -42,23 +43,23 @@ public class ReplaceDestroy extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { + public boolean canReplace(Map runParams) { if (hasParam("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) { return false; } } if (hasParam("ValidCard")) { - Card card = (Card)runParams.get("Card"); + Card card = (Card)runParams.get(AbilityKey.Card); if (!matchesValid(card, getParam("ValidCard").split(","), getHostCard())) { return false; } // extra check for Regeneration if (hasParam("Regeneration")) { - if (!runParams.containsKey("Regeneration")) { + if (!runParams.containsKey(AbilityKey.Regeneration)) { return false; } - if (!(Boolean)runParams.get("Regeneration")) { + if (!(Boolean)runParams.get(AbilityKey.Regeneration)) { return false; } if (!card.canBeShielded()) { @@ -71,7 +72,7 @@ public class ReplaceDestroy extends ReplacementEffect { } } if (hasParam("ValidSource")) { - if (!matchesValid(runParams.get("Source"), getParam("ValidSource").split(","), getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Source), getParam("ValidSource").split(","), getHostCard())) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceDiscard.java b/forge-game/src/main/java/forge/game/replacement/ReplaceDiscard.java index e761d06540e..9d69bd7c31b 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDiscard.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDiscard.java @@ -17,6 +17,7 @@ */ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.spellability.SpellAbility; @@ -42,24 +43,24 @@ public class ReplaceDiscard extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { + public boolean canReplace(Map runParams) { if (hasParam("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) { return false; } } if (hasParam("ValidCard")) { - if (!matchesValid(runParams.get("Card"), getParam("ValidCard").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Card), getParam("ValidCard").split(","), this.getHostCard())) { return false; } } if (hasParam("ValidSource")) { - if (!matchesValid(runParams.get("Source"), getParam("ValidSource").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Source), getParam("ValidSource").split(","), this.getHostCard())) { return false; } } if (hasParam("DiscardFromEffect")) { - if (null == runParams.get("Source")) { + if (null == runParams.get(AbilityKey.Source)) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceDraw.java b/forge-game/src/main/java/forge/game/replacement/ReplaceDraw.java index 7a32b0b30d0..de69e9bda57 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDraw.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDraw.java @@ -17,6 +17,7 @@ */ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.phase.PhaseType; import forge.game.player.Player; @@ -44,14 +45,14 @@ public class ReplaceDraw extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { + public boolean canReplace(Map runParams) { if (hasParam("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) { return false; } } if (hasParam("NotFirstCardInDrawStep")) { - final Player p = (Player)runParams.get("Affected"); + final Player p = (Player)runParams.get(AbilityKey.Affected); if (p.numDrawnThisDrawStep() == 0 && this.getHostCard().getGame().getPhaseHandler().is(PhaseType.DRAW) && this.getHostCard().getGame().getPhaseHandler().isPlayerTurn(p)) { diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceDrawCards.java b/forge-game/src/main/java/forge/game/replacement/ReplaceDrawCards.java index ca486aa3e64..f2310586db2 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDrawCards.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDrawCards.java @@ -17,6 +17,7 @@ */ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.spellability.SpellAbility; import forge.util.Expressions; @@ -43,14 +44,14 @@ public class ReplaceDrawCards extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { + public boolean canReplace(Map runParams) { if (hasParam("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) { return false; } } if (hasParam("Number")) { - final int n = (Integer)runParams.get("Number"); + final int n = (Integer)runParams.get(AbilityKey.Number); String comparator = getParam("Number"); final String operator = comparator.substring(0, 2); final int operandValue = Integer.parseInt(comparator.substring(2)); diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceGainLife.java b/forge-game/src/main/java/forge/game/replacement/ReplaceGainLife.java index c026bd4ff38..a432be40f6e 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceGainLife.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceGainLife.java @@ -17,6 +17,7 @@ */ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.spellability.SpellAbility; @@ -42,22 +43,22 @@ public class ReplaceGainLife extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { - if (((int)runParams.get("LifeGained")) <= 0) { + public boolean canReplace(Map runParams) { + if (((int)runParams.get(AbilityKey.LifeGained)) <= 0) { return false; } if (hasParam("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) { return false; } } if (hasParam("ValidSource")) { - if (!matchesValid(runParams.get("Source"), getParam("ValidSource").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Source), getParam("ValidSource").split(","), this.getHostCard())) { return false; } } if ("True".equals(getParam("SourceController"))) { - if (runParams.get("Source") == null || !runParams.get("Affected").equals(((Card)runParams.get("Source")).getController())) { + if (runParams.get(AbilityKey.Source) == null || !runParams.get(AbilityKey.Affected).equals(((Card)runParams.get(AbilityKey.Source)).getController())) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceGameLoss.java b/forge-game/src/main/java/forge/game/replacement/ReplaceGameLoss.java index 0cb784588e5..3860af6c119 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceGameLoss.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceGameLoss.java @@ -1,5 +1,6 @@ package forge.game.replacement; + import forge.game.ability.AbilityKey; import forge.game.card.Card; import java.util.Map; @@ -24,9 +25,9 @@ public class ReplaceGameLoss extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { + public boolean canReplace(Map runParams) { if (hasParam("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceMoved.java b/forge-game/src/main/java/forge/game/replacement/ReplaceMoved.java index 650b0e82085..5da9b24a876 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceMoved.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceMoved.java @@ -1,5 +1,6 @@ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.player.Player; @@ -28,9 +29,9 @@ public class ReplaceMoved extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { + public boolean canReplace(Map runParams) { final Player controller = getHostCard().getController(); - final Card affected = (Card) runParams.get("Affected"); + final Card affected = (Card) runParams.get(AbilityKey.Affected); if (hasParam("ValidCard")) { if (!matchesValid(affected, getParam("ValidCard").split(","), getHostCard())) { @@ -39,27 +40,27 @@ public class ReplaceMoved extends ReplacementEffect { } if (hasParam("ValidLKI")) { - if (!matchesValid(runParams.get("CardLKI"), getParam("ValidLKI").split(","), getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.CardLKI), getParam("ValidLKI").split(","), getHostCard())) { return false; } } if (hasParam("Origin")) { - ZoneType zt = (ZoneType) runParams.get("Origin"); + ZoneType zt = (ZoneType) runParams.get(AbilityKey.Origin); if (!ZoneType.listValueOf(getParam("Origin")).contains(zt)) { return false; } } if (hasParam("Destination")) { - ZoneType zt = (ZoneType) runParams.get("Destination"); + ZoneType zt = (ZoneType) runParams.get(AbilityKey.Destination); if (!ZoneType.listValueOf(getParam("Destination")).contains(zt)) { return false; } } if (hasParam("ExcludeDestination")) { - ZoneType zt = (ZoneType) runParams.get("Destination"); + ZoneType zt = (ZoneType) runParams.get(AbilityKey.Destination); if (ZoneType.listValueOf(getParam("ExcludeDestination")).contains(zt)) { return false; } @@ -67,29 +68,29 @@ public class ReplaceMoved extends ReplacementEffect { if (hasParam("Fizzle")) { // if Replacement look for Fizzle - if (!runParams.containsKey("Fizzle")) { + if (!runParams.containsKey(AbilityKey.Fizzle)) { return false; } - Boolean val = (Boolean) runParams.get("Fizzle"); + Boolean val = (Boolean) runParams.get(AbilityKey.Fizzle); if ("True".equals(getParam("Fizzle")) != val) { return false; } } if (hasParam("ValidStackSa")) { - if (!runParams.containsKey("StackSa")) { + if (!runParams.containsKey(AbilityKey.StackSa)) { return false; } - if (!((SpellAbility)runParams.get("StackSa")).isValid(getParam("ValidStackSa").split(","), getHostCard().getController(), getHostCard(), null)) { + if (!((SpellAbility)runParams.get(AbilityKey.StackSa)).isValid(getParam("ValidStackSa").split(","), getHostCard().getController(), getHostCard(), null)) { return false; } } if (hasParam("Cause")) { - if (!runParams.containsKey("Cause")) { + if (!runParams.containsKey(AbilityKey.Cause)) { return false; } - SpellAbility cause = (SpellAbility) runParams.get("Cause"); + SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause); if (cause == null) { return false; } @@ -99,8 +100,8 @@ public class ReplaceMoved extends ReplacementEffect { } if (hasParam("NotCause")) { - if (runParams.containsKey("Cause")) { - SpellAbility cause = (SpellAbility) runParams.get("Cause"); + if (runParams.containsKey(AbilityKey.Cause)) { + SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause); if (cause != null) { if (cause.isValid(getParam("NotCause").split(","), controller, getHostCard(), null)) { return false; diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceProduceMana.java b/forge-game/src/main/java/forge/game/replacement/ReplaceProduceMana.java index 3cfc1f92d81..13e8b68f782 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceProduceMana.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceProduceMana.java @@ -1,5 +1,6 @@ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.card.CardFactoryUtil; import forge.game.spellability.SpellAbility; @@ -29,10 +30,10 @@ public class ReplaceProduceMana extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { + public boolean canReplace(Map runParams) { //Check for tapping if (!hasParam("NoTapCheck")) { - final SpellAbility manaAbility = (SpellAbility) runParams.get("AbilityMana"); + final SpellAbility manaAbility = (SpellAbility) runParams.get(AbilityKey.AbilityMana); if (manaAbility == null || manaAbility.getRootAbility().getPayCosts() == null || !manaAbility.getRootAbility().getPayCosts().hasTapCost()) { return false; } @@ -48,14 +49,14 @@ public class ReplaceProduceMana extends ReplacementEffect { } catch (NumberFormatException e) { intoperand = CardFactoryUtil.xCount(getHostCard(), getHostCard().getSVar(operand)); } - int manaAmount = StringUtils.countMatches((String) runParams.get("Mana"), " ") + 1; + int manaAmount = StringUtils.countMatches((String) runParams.get(AbilityKey.Mana), " ") + 1; if (!Expressions.compare(manaAmount, operator, intoperand)) { return false; } } if (hasParam("ValidCard")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidCard").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceSetInMotion.java b/forge-game/src/main/java/forge/game/replacement/ReplaceSetInMotion.java index d74b1171dad..1b2b39f382b 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceSetInMotion.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceSetInMotion.java @@ -17,6 +17,7 @@ */ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import java.util.Map; @@ -41,9 +42,9 @@ public class ReplaceSetInMotion extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { + public boolean canReplace(Map runParams) { if (hasParam("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java b/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java index 3ee74291981..507cf5e941b 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java @@ -1,5 +1,6 @@ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.spellability.SpellAbility; @@ -25,13 +26,13 @@ public class ReplaceSurveil extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.Map) */ @Override - public boolean canReplace(Map runParams) { - if (((int) runParams.get("SurveilNum")) <= 0) { + public boolean canReplace(Map runParams) { + if (((int) runParams.get(AbilityKey.SurveilNum)) <= 0) { return false; } if (hasParam("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java b/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java index fc6bb5ef15c..80d41010819 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java @@ -1,5 +1,6 @@ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.spellability.SpellAbility; @@ -25,27 +26,27 @@ public class ReplaceToken extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.Map) */ @Override - public boolean canReplace(Map runParams) { - if (((int) runParams.get("TokenNum")) <= 0) { + public boolean canReplace(Map runParams) { + if (((int) runParams.get(AbilityKey.TokenNum)) <= 0) { return false; } if (hasParam("EffectOnly")) { - final Boolean effectOnly = (Boolean) runParams.get("EffectOnly"); + final Boolean effectOnly = (Boolean) runParams.get(AbilityKey.EffectOnly); if (!effectOnly) { return false; } } if (hasParam("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) { return false; } } if (hasParam("ValidToken")) { - if (runParams.containsKey("Token")) { - if (!matchesValid(runParams.get("Token"), getParam("ValidToken").split(","), getHostCard())) { + if (runParams.containsKey(AbilityKey.Token)) { + if (!matchesValid(runParams.get(AbilityKey.Token), getParam("ValidToken").split(","), getHostCard())) { return false; } } else { diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceTurnFaceUp.java b/forge-game/src/main/java/forge/game/replacement/ReplaceTurnFaceUp.java index a2c78959de3..37feb4fba4e 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceTurnFaceUp.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceTurnFaceUp.java @@ -1,5 +1,6 @@ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.spellability.SpellAbility; @@ -25,9 +26,9 @@ public class ReplaceTurnFaceUp extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { + public boolean canReplace(Map runParams) { if (hasParam("ValidCard")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidCard").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) { return false; } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceUntap.java b/forge-game/src/main/java/forge/game/replacement/ReplaceUntap.java index 7e4168f1281..d6307edb38b 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceUntap.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceUntap.java @@ -17,6 +17,7 @@ */ package forge.game.replacement; +import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.player.Player; import forge.game.phase.PhaseType; @@ -44,14 +45,14 @@ public class ReplaceUntap extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) */ @Override - public boolean canReplace(Map runParams) { + public boolean canReplace(Map runParams) { if (hasParam("ValidCard")) { - if (!matchesValid(runParams.get("Affected"), getParam("ValidCard").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) { return false; } } if (hasParam("UntapStep")) { - final Object o = runParams.get("Affected"); + final Object o = runParams.get(AbilityKey.Affected); //normally should not happen, but protect from possible crash. if (!(o instanceof Card)) { return false; diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java b/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java index 1007b1fc727..87a81af46fb 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java @@ -19,6 +19,7 @@ package forge.game.replacement; import forge.game.Game; import forge.game.TriggerReplacementBase; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.phase.PhaseType; @@ -121,7 +122,7 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { * the run params * @return true, if successful */ - public abstract boolean canReplace(final Map runParams); + public abstract boolean canReplace (final Map runParams); /** *

diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java index d2273e35e2a..97b049b770f 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -118,7 +118,7 @@ public class ReplacementHandler { && (layer == null || replacementEffect.getLayer() == layer) && event.equals(replacementEffect.getMode()) && replacementEffect.requirementsCheck(game) - && replacementEffect.canReplace(toStringMap(runParams)) + && replacementEffect.canReplace(runParams) && !possibleReplacers.contains(replacementEffect) && replacementEffect.zonesCheck(cardZone)) { possibleReplacers.add(replacementEffect); diff --git a/forge-gui/src/main/java/forge/match/input/InputPayMana.java b/forge-gui/src/main/java/forge/match/input/InputPayMana.java index 21dfe05227d..de1da8bf5b6 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPayMana.java +++ b/forge-gui/src/main/java/forge/match/input/InputPayMana.java @@ -1,13 +1,10 @@ package forge.match.input; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; +import java.util.*; import forge.GuiBase; import forge.game.GameActionUtil; +import forge.game.ability.AbilityKey; import forge.game.spellability.SpellAbilityView; import forge.util.TextUtil; import org.apache.commons.lang3.StringUtils; @@ -363,11 +360,11 @@ public abstract class InputPayMana extends InputSyncronizedBase { final Card source = am.getHostCard(); final Player activator = am.getActivatingPlayer(); final Game g = source.getGame(); - final HashMap repParams = new HashMap<>(); - repParams.put("Mana", m.getOrigProduced()); - repParams.put("Affected", source); - repParams.put("Player", activator); - repParams.put("AbilityMana", am); + final Map repParams = AbilityKey.newMap(); + repParams.put(AbilityKey.Mana, m.getOrigProduced()); + repParams.put(AbilityKey.Affected, source); + repParams.put(AbilityKey.Player, activator); + repParams.put(AbilityKey.AbilityMana, am); for (final Player p : g.getPlayers()) { for (final Card crd : p.getAllCards()) { From 5f3a0b3f0b5dd5057fadae05af27b30cde09edee Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Sat, 5 Oct 2019 23:44:22 -0600 Subject: [PATCH 16/17] change `replacingObjects` type --- .../java/forge/ai/ability/ChangeZoneAi.java | 2 +- .../java/forge/game/ability/AbilityUtils.java | 16 ++++++++------- .../ability/effects/ETBReplacementEffect.java | 3 ++- .../game/ability/effects/TokenEffect.java | 8 ++++++-- .../game/replacement/ReplaceAddCounter.java | 12 +++++------ .../game/replacement/ReplaceCounter.java | 4 ++-- .../forge/game/replacement/ReplaceDamage.java | 8 ++++---- .../game/replacement/ReplaceDestroy.java | 4 ++-- .../game/replacement/ReplaceDiscard.java | 8 ++++---- .../forge/game/replacement/ReplaceDraw.java | 4 ++-- .../game/replacement/ReplaceDrawCards.java | 4 ++-- .../game/replacement/ReplaceGainLife.java | 6 +++--- .../forge/game/replacement/ReplaceMoved.java | 8 ++++---- .../game/replacement/ReplaceSurveil.java | 6 +++--- .../forge/game/replacement/ReplaceToken.java | 6 +++--- .../game/replacement/ReplaceTurnFaceUp.java | 4 ++-- .../forge/game/replacement/ReplaceUntap.java | 4 ++-- .../game/replacement/ReplacementEffect.java | 6 ++---- .../game/replacement/ReplacementHandler.java | 4 ++-- .../forge/game/spellability/SpellAbility.java | 20 +++---------------- 20 files changed, 64 insertions(+), 73 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java index ecaa91b27d0..40c59393086 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java @@ -1814,7 +1814,7 @@ public class ChangeZoneAi extends SpellAbilityAi { // A blink effect implemented using a delayed trigger return !"Exile".equals(exec.getParam("Origin")) || !"Battlefield".equals(exec.getParam("Destination")); } - } else return causeSa.getHostCard() == null || !causeSa.getHostCard().equals(sa.getReplacingObject("Card")) + } else return causeSa.getHostCard() == null || !causeSa.getHostCard().equals(sa.getReplacingObject(AbilityKey.Card)) || !causeSa.getActivatingPlayer().equals(aiPlayer); } diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index f17336ca80a..97877f115ad 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -48,7 +48,7 @@ public class AbilityUtils { public static CounterType getCounterType(String name, SpellAbility sa) throws Exception { CounterType counterType; if ("ReplacedCounterType".equals(name)) { - name = (String) sa.getReplacingObject("CounterType"); + name = (String) sa.getReplacingObject(AbilityKey.CounterType); } try { counterType = CounterType.getType(name); @@ -157,7 +157,9 @@ public class AbilityUtils { } else if (defined.startsWith("Replaced") && (sa != null)) { final SpellAbility root = sa.getRootAbility(); - final Object crd = root.getReplacingObject(defined.substring(8)); + AbilityKey type = AbilityKey.fromString(defined.substring(8)); + final Object crd = root.getReplacingObject(type); + if (crd instanceof Card) { c = game.getCardState((Card) crd); } else if (crd instanceof List) { @@ -712,7 +714,7 @@ public class AbilityUtils { } else if (calcX[0].startsWith("Replaced")) { final SpellAbility root = sa.getRootAbility(); - list = new CardCollection((Card) root.getReplacingObject(calcX[0].substring(8))); + list = new CardCollection((Card) root.getReplacingObject(AbilityKey.fromString(calcX[0].substring(8)))); } else if (calcX[0].startsWith("ReplaceCount")) { // ReplaceCount is similar to a regular Count, but just @@ -720,7 +722,7 @@ public class AbilityUtils { final SpellAbility root = sa.getRootAbility(); final String[] l = calcX[1].split("/"); final String m = CardFactoryUtil.extractOperators(calcX[1]); - final int count = (Integer) root.getReplacingObject(l[0]); + final int count = (Integer) root.getReplacingObject(AbilityKey.fromString(l[0])); return CardFactoryUtil.doXMath(count, m, card) * multiplier; } @@ -1063,7 +1065,7 @@ public class AbilityUtils { if (defined.endsWith("Controller")) { String replacingType = defined.substring(8); replacingType = replacingType.substring(0, replacingType.length() - 10); - final Object c = root.getReplacingObject(replacingType); + final Object c = root.getReplacingObject(AbilityKey.fromString(replacingType)); if (c instanceof Card) { o = ((Card) c).getController(); } @@ -1074,14 +1076,14 @@ public class AbilityUtils { else if (defined.endsWith("Owner")) { String replacingType = defined.substring(8); replacingType = replacingType.substring(0, replacingType.length() - 5); - final Object c = root.getReplacingObject(replacingType); + final Object c = root.getReplacingObject(AbilityKey.fromString(replacingType)); if (c instanceof Card) { o = ((Card) c).getOwner(); } } else { final String replacingType = defined.substring(8); - o = root.getReplacingObject(replacingType); + o = root.getReplacingObject(AbilityKey.fromString(replacingType)); } if (o != null) { if (o instanceof Player) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ETBReplacementEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ETBReplacementEffect.java index 4241b8280d1..b524281dbe7 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ETBReplacementEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ETBReplacementEffect.java @@ -1,5 +1,6 @@ package forge.game.ability.effects; +import forge.game.ability.AbilityKey; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.spellability.SpellAbility; @@ -11,6 +12,6 @@ import forge.game.spellability.SpellAbility; public class ETBReplacementEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { - sa.getActivatingPlayer().getGame().getAction().moveToPlay(((Card) sa.getReplacingObject("Card")), sa); + sa.getActivatingPlayer().getGame().getAction().moveToPlay(((Card) sa.getReplacingObject(AbilityKey.Card)), sa); } } \ No newline at end of file diff --git a/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java b/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java index 0d76b269cdc..2d142123536 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.List; import forge.card.MagicColor; +import forge.game.ability.AbilityKey; import forge.game.card.token.TokenInfo; import org.apache.commons.lang3.StringUtils; @@ -224,8 +225,11 @@ public class TokenEffect extends SpellAbilityEffect { // Cause of the Token Effect, in general it should be this // but if its a Replacement Effect, it might be something else or null SpellAbility cause = sa; - if (root.isReplacementAbility() && root.hasReplacingObject("Cause")) { - cause = (SpellAbility)root.getReplacingObject("Cause"); + if (root.isReplacementAbility()) { + Object replacingObject = root.getReplacingObject(AbilityKey.Cause); + if (replacingObject != null) { + cause = (SpellAbility) replacingObject; + } } final boolean remember = sa.hasParam("RememberTokens"); diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java b/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java index bc19054dc6f..27a388c2160 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java @@ -72,14 +72,14 @@ public class ReplaceAddCounter extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("CounterNum", runParams.get("CounterNum")); - sa.setReplacingObject("CounterType", ((CounterType) runParams.get("CounterType")).getName()); - Object o = runParams.get("Affected"); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.CounterNum, runParams.get(AbilityKey.CounterNum)); + sa.setReplacingObject(AbilityKey.CounterType, ((CounterType) runParams.get(AbilityKey.CounterType)).getName()); + Object o = runParams.get(AbilityKey.Affected); if (o instanceof Card) { - sa.setReplacingObject("Card", o); + sa.setReplacingObject(AbilityKey.Card, o); } else if (o instanceof Player) { - sa.setReplacingObject("Player", o); + sa.setReplacingObject(AbilityKey.Player, o); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceCounter.java b/forge-game/src/main/java/forge/game/replacement/ReplaceCounter.java index 56644cfb3cf..c5968fd1d16 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceCounter.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceCounter.java @@ -68,8 +68,8 @@ public class ReplaceCounter extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("Card", runParams.get("Affected")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Affected)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java b/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java index aae8f952b89..2d8681ef508 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java @@ -150,10 +150,10 @@ public class ReplaceDamage extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("DamageAmount", runParams.get("DamageAmount")); - sa.setReplacingObject("Target", runParams.get("Affected")); - sa.setReplacingObject("Source", runParams.get("DamageSource")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.DamageAmount, runParams.get(AbilityKey.DamageAmount)); + sa.setReplacingObject(AbilityKey.Target, runParams.get(AbilityKey.Affected)); + sa.setReplacingObject(AbilityKey.Source, runParams.get(AbilityKey.DamageSource)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceDestroy.java b/forge-game/src/main/java/forge/game/replacement/ReplaceDestroy.java index 08420e3817d..e9c22681fb7 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDestroy.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDestroy.java @@ -84,8 +84,8 @@ public class ReplaceDestroy extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("Card", runParams.get("Card")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Card)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceDiscard.java b/forge-game/src/main/java/forge/game/replacement/ReplaceDiscard.java index 9d69bd7c31b..25bde9c0c6e 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDiscard.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDiscard.java @@ -72,10 +72,10 @@ public class ReplaceDiscard extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("Card", runParams.get("Card")); - sa.setReplacingObject("Player", runParams.get("Affected")); - sa.setReplacingObject("Source", runParams.get("Source")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Card)); + sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected)); + sa.setReplacingObject(AbilityKey.Source, runParams.get(AbilityKey.Source)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceDraw.java b/forge-game/src/main/java/forge/game/replacement/ReplaceDraw.java index de69e9bda57..9dbaf529cad 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDraw.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDraw.java @@ -69,7 +69,7 @@ public class ReplaceDraw extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("Player", runParams.get("Affected")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceDrawCards.java b/forge-game/src/main/java/forge/game/replacement/ReplaceDrawCards.java index f2310586db2..fecf53a8bf2 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDrawCards.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDrawCards.java @@ -69,7 +69,7 @@ public class ReplaceDrawCards extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("Player", runParams.get("Affected")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceGainLife.java b/forge-game/src/main/java/forge/game/replacement/ReplaceGainLife.java index a432be40f6e..083ad7b23d2 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceGainLife.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceGainLife.java @@ -70,9 +70,9 @@ public class ReplaceGainLife extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("LifeGained", runParams.get("LifeGained")); - sa.setReplacingObject("Player", runParams.get("Affected")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.LifeGained, runParams.get(AbilityKey.LifeGained)); + sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceMoved.java b/forge-game/src/main/java/forge/game/replacement/ReplaceMoved.java index 5da9b24a876..ee295efe59d 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceMoved.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceMoved.java @@ -117,10 +117,10 @@ public class ReplaceMoved extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("Card", runParams.get("Affected")); - sa.setReplacingObject("CardLKI", runParams.get("CardLKI")); - sa.setReplacingObject("Cause", runParams.get("Cause")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Affected)); + sa.setReplacingObject(AbilityKey.CardLKI, runParams.get(AbilityKey.CardLKI)); + sa.setReplacingObject(AbilityKey.Cause, runParams.get(AbilityKey.Cause)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java b/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java index 507cf5e941b..e7b8440e0b5 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java @@ -44,9 +44,9 @@ public class ReplaceSurveil extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.Map, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("Player", runParams.get("Affected")); - sa.setReplacingObject("SurveilNum", runParams.get("SurveilNum")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected)); + sa.setReplacingObject(AbilityKey.SurveilNum, runParams.get(AbilityKey.SurveilNum)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java b/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java index 80d41010819..7204edfdcbe 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java @@ -62,9 +62,9 @@ public class ReplaceToken extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.Map, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("TokenNum", runParams.get("TokenNum")); - sa.setReplacingObject("Player", runParams.get("Affected")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.TokenNum, runParams.get(AbilityKey.TokenNum)); + sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceTurnFaceUp.java b/forge-game/src/main/java/forge/game/replacement/ReplaceTurnFaceUp.java index 37feb4fba4e..3f433f38916 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceTurnFaceUp.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceTurnFaceUp.java @@ -39,8 +39,8 @@ public class ReplaceTurnFaceUp extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("Card", runParams.get("Affected")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Affected)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceUntap.java b/forge-game/src/main/java/forge/game/replacement/ReplaceUntap.java index d6307edb38b..d52c65e75b8 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceUntap.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceUntap.java @@ -73,8 +73,8 @@ public class ReplaceUntap extends ReplacementEffect { * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) */ @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject("Card", runParams.get("Affected")); + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Affected)); } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java b/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java index 87a81af46fb..c4e0296f419 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java @@ -200,13 +200,11 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { /** * Sets the replacing objects. - * - * @param runParams + * @param runParams * the run params * @param spellAbility - * the SpellAbility */ - public void setReplacingObjects(final Map runParams, final SpellAbility spellAbility) { + public void setReplacingObjects(final Map runParams, final SpellAbility spellAbility) { // Should be overridden by replacers that need it. } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java index 97b049b770f..815ba915123 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -238,7 +238,7 @@ public class ReplacementHandler { SpellAbility tailend = effectSA; do { - replacementEffect.setReplacingObjects(toStringMap(runParams), tailend); + replacementEffect.setReplacingObjects(runParams, tailend); //set original Params to update them later tailend.setReplacingObject(AbilityKey.OriginalParams, runParams); tailend = tailend.getSubAbility(); @@ -249,7 +249,7 @@ public class ReplacementHandler { effectSA = replacementEffect.getOverridingAbility(); SpellAbility tailend = effectSA; do { - replacementEffect.setReplacingObjects(toStringMap(runParams), tailend); + replacementEffect.setReplacingObjects(runParams, tailend); //set original Params to update them later tailend.setReplacingObject(AbilityKey.OriginalParams, runParams); tailend = tailend.getSubAbility(); 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 ea335a7df7d..55760357af4 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -143,7 +143,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit private EnumMap triggeringObjects = AbilityKey.newMap(); - private HashMap replacingObjects = Maps.newHashMap(); + private EnumMap replacingObjects = AbilityKey.newMap(); private List chosenList = null; private CardCollection tappedForConvoke = new CardCollection(); @@ -593,29 +593,15 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit triggerRemembered = Lists.newArrayList(); } - public HashMap getReplacingObjects() { + public Map getReplacingObjects() { return replacingObjects; } - public boolean hasReplacingObject(final String type) { - return replacingObjects.containsKey(type); - } public Object getReplacingObject(final AbilityKey type) { - return getReplacingObject(type.toString()); - } - // Eventually we want to switch the internal map to be a `Map` instead of a - // `Map`. - @Deprecated - public Object getReplacingObject(final String type) { final Object res = replacingObjects.get(type); return res; } + public void setReplacingObject(final AbilityKey type, final Object o) { - setReplacingObject(type.toString(), o); - } - // Eventually we want to switch the internal map to be a `Map` instead of a - // `Map`. - @Deprecated - public void setReplacingObject(final String type, final Object o) { replacingObjects.put(type, o); } From 33ccc5c21f6dc3ca0b7576c62936748482a4ab5e Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Sat, 5 Oct 2019 23:52:14 -0600 Subject: [PATCH 17/17] remove import ... --- .../main/java/forge/game/replacement/ReplacementHandler.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java index 815ba915123..07625c7e86e 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -41,8 +41,6 @@ import com.google.common.collect.Sets; import java.util.*; -import static forge.util.EnumMapUtil.toStringMap; - public class ReplacementHandler { private final Game game; /**