diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index a027cc9ea1c..343b67e6970 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -48,6 +48,7 @@ import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; import forge.game.replacement.ReplaceMoved; import forge.game.replacement.ReplacementEffect; +import forge.game.replacement.ReplacementType; import forge.game.spellability.*; import forge.game.staticability.StaticAbility; import forge.game.trigger.Trigger; @@ -1660,13 +1661,13 @@ public class AiController { hostCard = game.getCardState(hostCard); } - if (effect.getMapParams().containsKey("AICheckSVar")) { + if (effect.hasParam("AICheckSVar")) { System.out.println("aiShouldRun?" + sa); final String svarToCheck = effect.getMapParams().get("AICheckSVar"); String comparator = "GE"; int compareTo = 1; - if (effect.getMapParams().containsKey("AISVarCompare")) { + if (effect.hasParam("AISVarCompare")) { final String fullCmp = effect.getMapParams().get("AISVarCompare"); comparator = fullCmp.substring(0, 2); final String strCmpTo = fullCmp.substring(2); @@ -1690,7 +1691,7 @@ public class AiController { } System.out.println("aiShouldRun?" + left + comparator + compareTo); return Expressions.compare(left, comparator, compareTo); - } else if (effect.getMapParams().containsKey("AICheckDredge")) { + } else if (effect.hasParam("AICheckDredge")) { return player.getCardsIn(ZoneType.Library).size() > 8 || player.isCardInPlay("Laboratory Maniac"); } else return sa != null && doTrigger(sa, false); @@ -2085,35 +2086,35 @@ public class AiController { return Iterables.getFirst(list, null); } - if (runParams.containsKey("Event")) { - // replace lifegain effects - if ("GainLife".equals(runParams.get("Event"))) { - List noGain = filterListByAiLogic(list, "NoLife"); - List loseLife = filterListByAiLogic(list, "LoseLife"); - List doubleLife = filterListByAiLogic(list, "DoubleLife"); - List lichDraw = filterListByAiLogic(list, "LichDraw"); + ReplacementType mode = Iterables.getFirst(list, null).getMode(); - if (!noGain.isEmpty()) { - // no lifegain is better than lose life - return Iterables.getFirst(noGain, null); - } else if (!loseLife.isEmpty()) { - // lose life before double life to prevent lose double - return Iterables.getFirst(loseLife, null); - } else if (!lichDraw.isEmpty()) { - // lich draw before double life to prevent to draw to much - return Iterables.getFirst(lichDraw, null); - } else if (!doubleLife.isEmpty()) { - // other than that, do double life - return Iterables.getFirst(doubleLife, null); - } - } else if ("DamageDone".equals(runParams.get("Event"))) { - List prevention = filterList(list, CardTraitPredicates.hasParam("Prevention")); + // replace lifegain effects + if (mode.equals(ReplacementType.GainLife)) { + List noGain = filterListByAiLogic(list, "NoLife"); + List loseLife = filterListByAiLogic(list, "LoseLife"); + List doubleLife = filterListByAiLogic(list, "DoubleLife"); + List lichDraw = filterListByAiLogic(list, "LichDraw"); - // TODO when Protection is done as ReplacementEffect do them - // before normal prevention - if (!prevention.isEmpty()) { - return Iterables.getFirst(prevention, null); - } + if (!noGain.isEmpty()) { + // no lifegain is better than lose life + return Iterables.getFirst(noGain, null); + } else if (!loseLife.isEmpty()) { + // lose life before double life to prevent lose double + return Iterables.getFirst(loseLife, null); + } else if (!lichDraw.isEmpty()) { + // lich draw before double life to prevent to draw to much + return Iterables.getFirst(lichDraw, null); + } else if (!doubleLife.isEmpty()) { + // other than that, do double life + return Iterables.getFirst(doubleLife, null); + } + } else if (mode.equals(ReplacementType.DamageDone)) { + List prevention = filterList(list, CardTraitPredicates.hasParam("Prevention")); + + // TODO when Protection is done as ReplacementEffect do them + // before normal prevention + if (!prevention.isEmpty()) { + return Iterables.getFirst(prevention, null); } } diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index a5de6d50c5f..790e9a20be9 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -43,6 +43,7 @@ import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementLayer; +import forge.game.replacement.ReplacementType; import forge.game.spellability.*; import forge.game.staticability.StaticAbility; import forge.game.trigger.Trigger; @@ -2849,12 +2850,13 @@ public class ComputerUtil { // Run any applicable replacement effects. final Map repParams = Maps.newHashMap(); - repParams.put("Event", "GainLife"); repParams.put("Affected", player); repParams.put("LifeGained", 1); repParams.put("Source", source); - List list = player.getGame().getReplacementHandler().getReplacementList(repParams, + List list = player.getGame().getReplacementHandler().getReplacementList( + ReplacementType.GainLife, + repParams, ReplacementLayer.Other); if (Iterables.any(list, CardTraitPredicates.hasParam("AiLogic", "NoLife"))) { @@ -2879,12 +2881,13 @@ public class ComputerUtil { // Run any applicable replacement effects. final Map repParams = Maps.newHashMap(); - repParams.put("Event", "GainLife"); repParams.put("Affected", player); repParams.put("LifeGained", n); repParams.put("Source", source); - List list = player.getGame().getReplacementHandler().getReplacementList(repParams, + List list = player.getGame().getReplacementHandler().getReplacementList( + ReplacementType.GainLife, + repParams, ReplacementLayer.Other); if (Iterables.any(list, CardTraitPredicates.hasParam("AiLogic", "NoLife"))) { diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index 262d63705e9..d1616e3ab7f 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -42,6 +42,7 @@ import forge.game.phase.Untap; import forge.game.player.Player; import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementLayer; +import forge.game.replacement.ReplacementType; import forge.game.spellability.AbilityActivated; import forge.game.spellability.SpellAbility; import forge.game.staticability.StaticAbility; @@ -2397,7 +2398,7 @@ public class ComputerUtilCombat { for (final Card ca : game.getCardsIn(ZoneType.listValueOf("Battlefield,Command"))) { for (final ReplacementEffect re : ca.getReplacementEffects()) { Map params = re.getMapParams(); - if (!"DamageDone".equals(params.get("Event")) || !params.containsKey("PreventionEffect")) { + if (!re.getMode().equals(ReplacementType.DamageDone) || !params.containsKey("PreventionEffect")) { continue; } // Immortal Coil prevents the damage but has a similar negative effect @@ -2583,7 +2584,6 @@ public class ComputerUtilCombat { // first try to replace the damage final Map repParams = Maps.newHashMap(); - repParams.put("Event", "DamageDone"); repParams.put("Affected", target); repParams.put("DamageSource", attacker); repParams.put("DamageAmount", damage); @@ -2591,8 +2591,8 @@ public class ComputerUtilCombat { repParams.put("Prevention", true); // repParams.put("PreventMap", preventMap); - List list = game.getReplacementHandler().getReplacementList(repParams, - ReplacementLayer.Other); + List list = game.getReplacementHandler().getReplacementList( + ReplacementType.DamageDone, repParams, ReplacementLayer.Other); return !list.isEmpty(); } diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java index 1a1b9fc6df5..426de3f7c8a 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java @@ -25,6 +25,7 @@ import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.player.PlayerPredicates; import forge.game.replacement.ReplacementEffect; +import forge.game.replacement.ReplacementType; import forge.game.spellability.AbilityManaPart; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; @@ -1364,7 +1365,8 @@ public class ComputerUtilMana { for (final Card crd : p.getAllCards()) { for (final ReplacementEffect replacementEffect : crd.getReplacementEffects()) { if (replacementEffect.requirementsCheck(game) - && replacementEffect.getMapParams().containsKey("ManaReplacement") + && replacementEffect.getMode() == ReplacementType.ProduceMana + && replacementEffect.hasParam("ManaReplacement") && replacementEffect.zonesCheck(game.getZoneOf(crd))) { replacementEffects.add(replacementEffect); } @@ -1405,7 +1407,6 @@ public class ComputerUtilMana { // setup produce mana replacement effects final Map repParams = new HashMap<>(); - repParams.put("Event", "ProduceMana"); repParams.put("Mana", mp.getOrigProduced()); repParams.put("Affected", sourceCard); repParams.put("Player", ai); 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 57e70f7fe58..f98cd0bd02e 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ManifestAi.java @@ -19,6 +19,7 @@ import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementLayer; +import forge.game.replacement.ReplacementType; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; import forge.util.MyRandom; @@ -97,12 +98,11 @@ public class ManifestAi extends SpellAbilityAi { topCopy.setManifested(true); final Map repParams = Maps.newHashMap(); - repParams.put("Event", "Moved"); repParams.put("Affected", topCopy); repParams.put("Origin", card.getZone().getZoneType()); repParams.put("Destination", ZoneType.Battlefield); repParams.put("Source", sa.getHostCard()); - List list = game.getReplacementHandler().getReplacementList(repParams, ReplacementLayer.Other); + 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/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index d45c5794e99..f4bb52e9114 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -35,6 +35,7 @@ import forge.game.player.GameLossReason; import forge.game.player.Player; import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementResult; +import forge.game.replacement.ReplacementType; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityPredicates; @@ -292,7 +293,6 @@ public class GameAction { } Map repParams = AbilityKey.newMap(); - repParams.put(AbilityKey.Event, "Moved"); repParams.put(AbilityKey.Affected, copied); repParams.put(AbilityKey.CardLKI, lastKnownInfo); repParams.put(AbilityKey.Cause, cause); @@ -303,7 +303,7 @@ public class GameAction { repParams.putAll(params); } - ReplacementResult repres = game.getReplacementHandler().run(toStringMap(repParams)); + ReplacementResult repres = game.getReplacementHandler().run(ReplacementType.Moved, toStringMap(repParams)); if (repres != ReplacementResult.NotReplaced) { // reset failed manifested Cards back to original if (c.isManifested()) { @@ -1399,13 +1399,12 @@ public class GameAction { // Replacement effects final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Event", "Destroy"); repRunParams.put("Source", sa); repRunParams.put("Card", c); repRunParams.put("Affected", c); repRunParams.put("Regeneration", regenerate); - if (game.getReplacementHandler().run(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 9549c75dea7..c8a82cbf8d2 100644 --- a/forge-game/src/main/java/forge/game/GameEntity.java +++ b/forge-game/src/main/java/forge/game/GameEntity.java @@ -28,6 +28,7 @@ import forge.game.card.CounterType; import forge.game.event.GameEventCardAttachment; import forge.game.keyword.Keyword; import forge.game.player.Player; +import forge.game.replacement.ReplacementType; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; import forge.game.staticability.StaticAbility; @@ -115,7 +116,6 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { final CardDamageMap damageMap, final CardDamageMap preventMap, GameEntityCounterTable counterTable, final SpellAbility cause) { // Replacement effects final Map repParams = Maps.newHashMap(); - repParams.put("Event", "DamageDone"); repParams.put("Affected", this); repParams.put("DamageSource", source); repParams.put("DamageAmount", damage); @@ -128,7 +128,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { repParams.put("Cause", cause); } - switch (getGame().getReplacementHandler().run(repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.DamageDone, repParams)) { case NotReplaced: return damage; case Updated: @@ -171,7 +171,6 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { // first try to replace the damage final Map repParams = Maps.newHashMap(); - repParams.put("Event", "DamageDone"); repParams.put("Affected", this); repParams.put("DamageSource", source); repParams.put("DamageAmount", damage); @@ -182,7 +181,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { repParams.put("Cause", cause); } - switch (getGame().getReplacementHandler().run(repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.DamageDone, repParams)) { case NotReplaced: restDamage = damage; break; 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 fe5b8bb1162..a33cd8e8f3e 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,8 @@ package forge.game.ability; import java.util.EnumMap; import java.util.Map; +import forge.game.card.Card; + /** * Keys for Ability parameter maps. */ @@ -112,184 +114,12 @@ public enum AbilityKey { * @return the corresponding key if there is one or null otherwise */ public static AbilityKey fromString(String s) { - switch (s) { - case "AbilityMana": - return AbilityMana; - case "Activator": - return Activator; - case "Affected": - return Affected; - case "AllVotes": - return AllVotes; - case "Amount": - return Amount; - case "Attach": - return Attach; - case "AttachSource": - return AttachSource; - case "AttachTarget": - return AttachTarget; - case "Attacked": - return Attacked; - case "Attacker": - return Attacker; - case "Attackers": - return Attackers; - case "AttackingPlayer": - return AttackingPlayer; - case "AttackedTarget": - return AttackedTarget; - case "Blocker": - return Blocker; - case "Blockers": - return Blockers; - case "CastSA": - return CastSA; - case "CastSACMC": - return CastSACMC; - case "Card": - return Card; - case "Cards": - return Cards; - case "CardLKI": - return CardLKI; - case "Cause": - return Cause; - case "Causer": - return Causer; - case "Championed": - return Championed; - case "CopySA": - return CopySA; - case "Cost": - return Cost; - case "CostStack": - return CostStack; - case "CounterAmount": - return CounterAmount; - case "CounteredSA": - return CounteredSA; - case "CounterType": - return CounterType; - case "Crew": - return Crew; - case "CumulativeUpkeepPaid": - return CumulativeUpkeepPaid; - case "CurrentCastSpells": - return CurrentCastSpells; - case "CurrentStormCount": - return CurrentStormCount; - case "DamageAmount": - return DamageAmount; - case "DamageSource": - return DamageSource; - case "DamageSources": - return DamageSources; - case "DamageTarget": - return DamageTarget; - case "DamageTargets": - return DamageTargets; - case "Defender": - return Defender; - case "Defenders": - return Defenders; - case "DefendingPlayer": - return DefendingPlayer; - case "Destination": - return Destination; - case "Devoured": - return Devoured; - case "EchoPaid": - return EchoPaid; - case "Exploited": - return Exploited; - case "Explorer": - return Explorer; - case "Event": - return Event; - case "Fighter": - return Fighter; - case "FirstTime": - return FirstTime; - case "Fizzle": - return Fizzle; - case "IsCombatDamage": - return IsCombatDamage; - case "IndividualCostPaymentInstance": - return IndividualCostPaymentInstance; - case "IsMadness": - return IsMadness; - case "LifeAmount": - return LifeAmount; - case "MonstrosityAmount": - return MonstrosityAmount; - case "NewCounterAmount": - return NewCounterAmount; - case "Num": - return Num; - case "NumBlockers": - return NumBlockers; - case "NumThisTurn": - return NumThisTurn; - case "Number": - return Number; - case "Object": - return Object; - case "Objects": - return Objects; - case "OtherAttackers": - return OtherAttackers; - case "OtherVoters": - return OtherVoters; - case "Origin": - return Origin; - case "OriginalController": - return OriginalController; - case "OriginalDefender": - return OriginalDefender; - case "PayingMana": - return PayingMana; - case "Phase": - return Phase; - case "Player": - return Player; - case "Produced": - return Produced; - case "Result": - return Result; - case "Scheme": - return Scheme; - case "Source": - return Source; - case "Sources": - return Sources; - case "SourceSA": - return SourceSA; - case "SpellAbility": - return SpellAbility; - case "SpellAbilityStackInstance": - return SpellAbilityStackInstance; - case "SpellAbilityTargetingCards": - return SpellAbilityTargetingCards; - case "StackInstance": - return StackInstance; - case "StackSa": - return StackSa; - case "StackSi": - return StackSi; - case "Target": - return Target; - case "Targets": - return Targets; - case "Transformer": - return Transformer; - case "Vehicle": - return Vehicle; - case "Won": - return Won; - default: - return null; + for (AbilityKey k : values()) { + if (k.toString().equalsIgnoreCase(s)) { + return k; + } } + return null; } @@ -305,7 +135,7 @@ public enum AbilityKey { return new EnumMap<>(map); } - public static Map mapFromCard(forge.game.card.Card card) { + public static Map mapFromCard(Card card) { final Map runParams = newMap(); runParams.put(Card, card); 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 25728de2544..f17336ca80a 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -1714,7 +1714,7 @@ public class AbilityUtils { } public static final String applyAbilityTextChangeEffects(final String def, final CardTraitBase ability) { - if (ability == null || !ability.isIntrinsic() || ability.getMapParams().containsKey("LockInText")) { + if (ability == null || !ability.isIntrinsic() || ability.hasParam("LockInText")) { return def; } return applyTextChangeEffects(def, ability.getHostCard(), false); @@ -1728,7 +1728,7 @@ public class AbilityUtils { } public static final String applyDescriptionTextChangeEffects(final String def, final CardTraitBase ability) { - if (ability == null || !ability.isIntrinsic() || ability.getMapParams().containsKey("LockInText")) { + if (ability == null || !ability.isIntrinsic() || ability.hasParam("LockInText")) { return def; } return applyTextChangeEffects(def, ability.getHostCard(), true); 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 54b961f0954..1c072cf3dba 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 @@ -7,6 +7,7 @@ import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.card.CardFactoryUtil; import forge.game.replacement.ReplacementResult; +import forge.game.replacement.ReplacementType; import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityStackInstance; import forge.game.spellability.SpellPermanent; @@ -155,11 +156,10 @@ public class CounterEffect extends SpellAbilityEffect { final Game game = tgtSA.getActivatingPlayer().getGame(); // Run any applicable replacement effects. final Map repParams = Maps.newHashMap(); - repParams.put("Event", "Counter"); repParams.put("TgtSA", tgtSA); repParams.put("Affected", tgtSA.getHostCard()); repParams.put("Cause", srcSA.getHostCard()); - if (game.getReplacementHandler().run(repParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(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 4a48ba83f09..6620b89c346 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 @@ -11,6 +11,7 @@ import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.replacement.ReplacementResult; +import forge.game.replacement.ReplacementType; import forge.game.spellability.SpellAbility; public class ReplaceDamageEffect extends SpellAbilityEffect { @@ -21,9 +22,11 @@ public class ReplaceDamageEffect extends SpellAbilityEffect { final Game game = card.getGame(); // outside of Replacement Effect, unwanted result - if (!sa.getRootAbility().isReplacementAbility()) { + if (!sa.isReplacementAbility()) { return; } + + final ReplacementType event = sa.getReplacementEffect().getMode(); String varValue = sa.getParamOrDefault("VarName", "1"); @@ -58,7 +61,7 @@ public class ReplaceDamageEffect extends SpellAbilityEffect { //try to call replacementHandler with new Params - ReplacementResult result = game.getReplacementHandler().run(params); + ReplacementResult result = game.getReplacementHandler().run(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 a81bdeeed66..260eb307491 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 @@ -13,6 +13,7 @@ import forge.game.card.Card; import forge.game.card.token.TokenInfo; import forge.game.player.Player; import forge.game.replacement.ReplacementResult; +import forge.game.replacement.ReplacementType; import forge.game.spellability.SpellAbility; public class ReplaceEffect extends SpellAbilityEffect { @@ -25,6 +26,7 @@ public class ReplaceEffect extends SpellAbilityEffect { final String varName = 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"); @@ -59,7 +61,7 @@ public class ReplaceEffect extends SpellAbilityEffect { } //try to call replacementHandler with new Params - ReplacementResult result = game.getReplacementHandler().run(params); + ReplacementResult result = game.getReplacementHandler().run(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 45c31fb3749..4d504b97c28 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 @@ -16,6 +16,7 @@ import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.card.CardDamageMap; import forge.game.replacement.ReplacementResult; +import forge.game.replacement.ReplacementType; import forge.game.spellability.SpellAbility; public class ReplaceSplitDamageEffect extends SpellAbilityEffect { @@ -26,9 +27,11 @@ public class ReplaceSplitDamageEffect extends SpellAbilityEffect { final Game game = card.getGame(); // outside of Replacement Effect, unwanted result - if (!sa.getRootAbility().isReplacementAbility()) { + if (!sa.isReplacementAbility()) { return; } + + final ReplacementType event = sa.getReplacementEffect().getMode(); String varValue = sa.getParamOrDefault("VarName", "1"); @@ -77,7 +80,7 @@ public class ReplaceSplitDamageEffect extends SpellAbilityEffect { params.put("DamageAmount", dmg); //try to call replacementHandler with new Params - ReplacementResult result = game.getReplacementHandler().run(params); + ReplacementResult result = game.getReplacementHandler().run(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 cf42e514f99..03476d73b88 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -48,6 +48,7 @@ import forge.game.player.PlayerCollection; import forge.game.replacement.ReplaceMoved; import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementResult; +import forge.game.replacement.ReplacementType; import forge.game.spellability.*; import forge.game.staticability.StaticAbility; import forge.game.trigger.Trigger; @@ -687,9 +688,8 @@ public class Card extends GameEntity implements Comparable { if (result && runTriggers) { // Run replacement effects Map repParams = Maps.newHashMap(); - repParams.put("Event", "TurnFaceUp"); repParams.put("Affected", this); - getGame().getReplacementHandler().run(repParams); + getGame().getReplacementHandler().run(ReplacementType.TurnFaceUp, repParams); // Run triggers getGame().getTriggerHandler().registerActiveTrigger(this, false); @@ -1234,14 +1234,13 @@ public class Card extends GameEntity implements Comparable { return 0; } final Map repParams = Maps.newHashMap(); - repParams.put("Event", "AddCounter"); repParams.put("Affected", this); repParams.put("Source", source); repParams.put("CounterType", counterType); repParams.put("CounterNum", addAmount); repParams.put("EffectOnly", applyMultiplier); - switch (getGame().getReplacementHandler().run(repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.AddCounter, repParams)) { case NotReplaced: break; case Updated: { @@ -3574,10 +3573,9 @@ public class Card extends GameEntity implements Comparable { // Run Replacement effects final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Event", "Untap"); repRunParams.put("Affected", this); - if (getGame().getReplacementHandler().run(repRunParams) != ReplacementResult.NotReplaced) { + if (getGame().getReplacementHandler().run(ReplacementType.Untap, repRunParams) != ReplacementResult.NotReplaced) { return; } @@ -4702,7 +4700,7 @@ public class Card extends GameEntity implements Comparable { for (final Card ca : getGame().getCardsIn(ZoneType.Battlefield)) { for (final ReplacementEffect re : ca.getReplacementEffects()) { Map params = re.getMapParams(); - if (!"DamageDone".equals(params.get("Event")) || !params.containsKey("PreventionEffect")) { + if (!re.getMode().equals(ReplacementType.DamageDone) || !params.containsKey("PreventionEffect")) { continue; } if (params.containsKey("ValidSource") diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index ecbfaeae056..d98e48cb803 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -671,12 +671,12 @@ public class CardFactory { } trig.setActivatingPlayer(sa.getActivatingPlayer()); - if (t.getMapParams().containsKey("TriggerController")) { + if (t.hasParam("TriggerController")) { Player p = AbilityUtils.getDefinedPlayers(t.getHostCard(), t.getMapParams().get("TriggerController"), trig).get(0); trig.setActivatingPlayer(p); } - if (t.getMapParams().containsKey("RememberController")) { + if (t.hasParam("RememberController")) { sa.getHostCard().addRemembered(sa.getActivatingPlayer()); } 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 4abd4a7447e..59000cb3b8f 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 @@ -16,6 +16,7 @@ import forge.game.card.CardFactoryUtil; import forge.game.card.CardUtil; import forge.game.keyword.KeywordInterface; import forge.game.player.Player; +import forge.game.replacement.ReplacementType; import forge.game.spellability.SpellAbility; import forge.item.PaperToken; @@ -166,13 +167,12 @@ public class TokenInfo { Card proto = prototype; final Map repParams = Maps.newHashMap(); - repParams.put("Event", "CreateToken"); repParams.put("Affected", player); repParams.put("Token", prototype); repParams.put("TokenNum", multiplier); repParams.put("EffectOnly", applyMultiplier); - switch (game.getReplacementHandler().run(repParams)) { + switch (game.getReplacementHandler().run(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 94ecc6ed017..02b148414e7 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -40,6 +40,7 @@ import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.game.replacement.ReplacementHandler; import forge.game.replacement.ReplacementResult; +import forge.game.replacement.ReplacementType; import forge.game.spellability.AbilityActivated; import forge.game.spellability.SpellAbility; import forge.game.staticability.StaticAbility; @@ -235,10 +236,9 @@ public class Player extends GameEntity implements Comparable { // Replacement effects final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Event", "SetInMotion"); repRunParams.put("Affected", this); - if (game.getReplacementHandler().run(repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(ReplacementType.SetInMotion, repRunParams) != ReplacementResult.NotReplaced) { return; } @@ -404,7 +404,6 @@ public class Player extends GameEntity implements Comparable { // Run any applicable replacement effects. final Map repParams = Maps.newHashMap(); - repParams.put("Event", "GainLife"); repParams.put("Affected", this); repParams.put("LifeGained", lifeGain); repParams.put("Source", source); @@ -413,7 +412,7 @@ public class Player extends GameEntity implements Comparable { return false; } - switch (getGame().getReplacementHandler().run(repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.GainLife, repParams)) { case NotReplaced: break; case Updated: @@ -916,14 +915,13 @@ public class Player extends GameEntity implements Comparable { } final Map repParams = Maps.newHashMap(); - repParams.put("Event", "AddCounter"); repParams.put("Affected", this); repParams.put("Source", source); repParams.put("CounterType", counterType); repParams.put("CounterNum", addAmount); repParams.put("EffectOnly", applyMultiplier); - switch (getGame().getReplacementHandler().run(repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.AddCounter, repParams)) { case NotReplaced: break; case Updated: { @@ -1279,12 +1277,11 @@ public class Player extends GameEntity implements Comparable { public void surveil(int num, SpellAbility cause) { final Map repParams = Maps.newHashMap(); - repParams.put("Event", "Surveil"); repParams.put("Affected", this); repParams.put("Source", cause); repParams.put("SurveilNum", num); - switch (getGame().getReplacementHandler().run(repParams)) { + switch (getGame().getReplacementHandler().run(ReplacementType.Surveil, repParams)) { case NotReplaced: break; case Updated: { @@ -1350,11 +1347,10 @@ public class Player extends GameEntity implements Comparable { // Replacement effects final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Event", "DrawCards"); repRunParams.put("Affected", this); repRunParams.put("Number", n); - if (game.getReplacementHandler().run(repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(ReplacementType.DrawCards, repRunParams) != ReplacementResult.NotReplaced) { return drawn; } @@ -1383,10 +1379,9 @@ public class Player extends GameEntity implements Comparable { // Replacement effects final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Event", "Draw"); repRunParams.put("Affected", this); - if (game.getReplacementHandler().run(repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(ReplacementType.Draw, repRunParams) != ReplacementResult.NotReplaced) { return drawn; } @@ -1562,12 +1557,11 @@ public class Player extends GameEntity implements Comparable { if (!discardToTopOfLibrary && !discardMadness) { // Replacement effects final Map repRunParams = Maps.newHashMap(); - repRunParams.put("Event", "Discard"); repRunParams.put("Card", c); repRunParams.put("Source", source); repRunParams.put("Affected", this); - if (game.getReplacementHandler().run(repRunParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(ReplacementType.Discard, repRunParams) != ReplacementResult.NotReplaced) { return null; } } @@ -1869,9 +1863,8 @@ public class Player extends GameEntity implements Comparable { // Replacement effects final Map runParams = Maps.newHashMap(); runParams.put("Affected", this); - runParams.put("Event", "GameLoss"); - if (game.getReplacementHandler().run(runParams) != ReplacementResult.NotReplaced) { + if (game.getReplacementHandler().run(ReplacementType.GameLoss, runParams) != ReplacementResult.NotReplaced) { return false; } } 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 05bf6c1627d..1a12a4186b6 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java @@ -28,7 +28,7 @@ public class ReplaceAddCounter extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("AddCounter") || ((int) runParams.get("CounterNum")) <= 0) { + if (((int) runParams.get("CounterNum")) <= 0) { return false; } @@ -44,7 +44,7 @@ public class ReplaceAddCounter extends ReplacementEffect { if (!(o instanceof Card)) { return false; } - if (!matchesValid(o, this.getMapParams().get("ValidCard").split(","), this.getHostCard())) { + if (!matchesValid(o, getParam("ValidCard").split(","), this.getHostCard())) { return false; } } else if (mapParams.containsKey("ValidPlayer")) { @@ -52,13 +52,13 @@ public class ReplaceAddCounter extends ReplacementEffect { if (!(o instanceof Player)) { return false; } - if (!matchesValid(o, this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) { + if (!matchesValid(o, getParam("ValidPlayer").split(","), this.getHostCard())) { return false; } } if (mapParams.containsKey("ValidCounterType")) { - String type = this.getMapParams().get("ValidCounterType"); + String type = getParam("ValidCounterType"); if (CounterType.getType(type) != runParams.get("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 6708d29b7ed..b3d27814b95 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceCounter.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceCounter.java @@ -44,21 +44,18 @@ public class ReplaceCounter extends ReplacementEffect { @Override public boolean canReplace(Map runParams) { final SpellAbility spellAbility = (SpellAbility) runParams.get("TgtSA"); - if (!runParams.get("Event").equals("Counter")) { - return false; - } - if (this.getMapParams().containsKey("ValidCard")) { - if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidCard").split(","), this.getHostCard())) { + if (hasParam("ValidCard")) { + if (!matchesValid(runParams.get("Affected"), getParam("ValidCard").split(","), this.getHostCard())) { return false; } } - if (this.getMapParams().containsKey("ValidCause")) { - if (!matchesValid(runParams.get("Cause"), this.getMapParams().get("ValidCause").split(","), this.getHostCard())) { + if (hasParam("ValidCause")) { + if (!matchesValid(runParams.get("Cause"), getParam("ValidCause").split(","), this.getHostCard())) { return false; } } - if (this.getMapParams().containsKey("ValidType")) { - String type = this.getMapParams().get("ValidType"); + if (hasParam("ValidType")) { + String type = getParam("ValidType"); if (type.equals("Spell") && !spellAbility.isSpell()) { 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 9893d28bf63..4063ec610bb 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java @@ -47,9 +47,6 @@ public class ReplaceDamage extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("DamageDone")) { - return false; - } if (!(runParams.containsKey("Prevention") == (hasParam("PreventionEffect") || hasParam("Prevent")))) { 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 fa61c0e1123..d5fe606ab2b 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDestroy.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDestroy.java @@ -43,9 +43,6 @@ public class ReplaceDestroy extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("Destroy")) { - return false; - } if (hasParam("ValidPlayer")) { if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").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 20499fc1de2..e761d06540e 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDiscard.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDiscard.java @@ -43,25 +43,22 @@ public class ReplaceDiscard extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("Discard")) { - return false; - } - if (this.getMapParams().containsKey("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) { + if (hasParam("ValidPlayer")) { + if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) { return false; } } - if (this.getMapParams().containsKey("ValidCard")) { - if (!matchesValid(runParams.get("Card"), this.getMapParams().get("ValidCard").split(","), this.getHostCard())) { + if (hasParam("ValidCard")) { + if (!matchesValid(runParams.get("Card"), getParam("ValidCard").split(","), this.getHostCard())) { return false; } } - if (this.getMapParams().containsKey("ValidSource")) { - if (!matchesValid(runParams.get("Source"), this.getMapParams().get("ValidSource").split(","), this.getHostCard())) { + if (hasParam("ValidSource")) { + if (!matchesValid(runParams.get("Source"), getParam("ValidSource").split(","), this.getHostCard())) { return false; } } - if (this.getMapParams().containsKey("DiscardFromEffect")) { + if (hasParam("DiscardFromEffect")) { if (null == runParams.get("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 4b7b2d80f38..7a32b0b30d0 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDraw.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDraw.java @@ -45,15 +45,12 @@ public class ReplaceDraw extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("Draw")) { - return false; - } - if (this.getMapParams().containsKey("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) { + if (hasParam("ValidPlayer")) { + if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) { return false; } } - if (this.getMapParams().containsKey("NotFirstCardInDrawStep")) { + if (hasParam("NotFirstCardInDrawStep")) { final Player p = (Player)runParams.get("Affected"); if (p.numDrawnThisDrawStep() == 0 && this.getHostCard().getGame().getPhaseHandler().is(PhaseType.DRAW) 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 30f56eceb9d..ca486aa3e64 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDrawCards.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDrawCards.java @@ -44,17 +44,14 @@ public class ReplaceDrawCards extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("DrawCards")) { - return false; - } - if (this.getMapParams().containsKey("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) { + if (hasParam("ValidPlayer")) { + if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) { return false; } } - if (this.getMapParams().containsKey("Number")) { + if (hasParam("Number")) { final int n = (Integer)runParams.get("Number"); - String comparator = this.getMapParams().get("Number"); + String comparator = getParam("Number"); final String operator = comparator.substring(0, 2); final int operandValue = Integer.parseInt(comparator.substring(2)); if (!Expressions.compare(n, operator, operandValue)) { 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 d269f9c044f..c026bd4ff38 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceGainLife.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceGainLife.java @@ -43,20 +43,20 @@ public class ReplaceGainLife extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("GainLife") || ((int)runParams.get("LifeGained")) <= 0) { + if (((int)runParams.get("LifeGained")) <= 0) { return false; } - if (this.getMapParams().containsKey("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) { + if (hasParam("ValidPlayer")) { + if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) { return false; } } - if (this.getMapParams().containsKey("ValidSource")) { - if (!matchesValid(runParams.get("Source"), this.getMapParams().get("ValidSource").split(","), this.getHostCard())) { + if (hasParam("ValidSource")) { + if (!matchesValid(runParams.get("Source"), getParam("ValidSource").split(","), this.getHostCard())) { return false; } } - if ("True".equals(this.getMapParams().get("SourceController"))) { + if ("True".equals(getParam("SourceController"))) { if (runParams.get("Source") == null || !runParams.get("Affected").equals(((Card)runParams.get("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 298f6cf470b..0cb784588e5 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceGameLoss.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceGameLoss.java @@ -25,11 +25,8 @@ public class ReplaceGameLoss extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("GameLoss")) { - return false; - } - if (this.getMapParams().containsKey("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) { + if (hasParam("ValidPlayer")) { + if (!matchesValid(runParams.get("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 162d87bca99..650b0e82085 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceMoved.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceMoved.java @@ -29,9 +29,6 @@ public class ReplaceMoved extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("Moved")) { - return false; - } final Player controller = getHostCard().getController(); final Card affected = (Card) runParams.get("Affected"); 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 90abfa87fd6..cfbba6dd10d 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceProduceMana.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceProduceMana.java @@ -30,9 +30,6 @@ public class ReplaceProduceMana extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("ProduceMana")) { - return false; - } //Check for tapping if (!mapParams.containsKey("NoTapCheck")) { final SpellAbility manaAbility = (SpellAbility) runParams.get("AbilityMana"); @@ -57,8 +54,8 @@ public class ReplaceProduceMana extends ReplacementEffect { } } - if (this.getMapParams().containsKey("ValidCard")) { - if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidCard").split(","), this.getHostCard())) { + if (hasParam("ValidCard")) { + if (!matchesValid(runParams.get("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 d4c2c7a2c1f..d74b1171dad 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceSetInMotion.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceSetInMotion.java @@ -42,11 +42,8 @@ public class ReplaceSetInMotion extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("SetInMotion")) { - return false; - } - if (this.getMapParams().containsKey("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) { + if (hasParam("ValidPlayer")) { + if (!matchesValid(runParams.get("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 ad6a9478245..3ee74291981 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java @@ -26,12 +26,12 @@ public class ReplaceSurveil extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("Surveil") || ((int) runParams.get("SurveilNum")) <= 0) { + if (((int) runParams.get("SurveilNum")) <= 0) { return false; } if (hasParam("ValidPlayer")) { - if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) { + if (!matchesValid(runParams.get("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 d58cd697b4a..fc6bb5ef15c 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java @@ -26,7 +26,7 @@ public class ReplaceToken extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("CreateToken") || ((int) runParams.get("TokenNum")) <= 0) { + if (((int) runParams.get("TokenNum")) <= 0) { return false; } 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 d1d4bbe2845..a2c78959de3 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceTurnFaceUp.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceTurnFaceUp.java @@ -26,11 +26,8 @@ public class ReplaceTurnFaceUp extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("TurnFaceUp")) { - return false; - } - if (this.getMapParams().containsKey("ValidCard")) { - if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidCard").split(","), this.getHostCard())) { + if (hasParam("ValidCard")) { + if (!matchesValid(runParams.get("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 d336af27279..7e4168f1281 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceUntap.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceUntap.java @@ -45,15 +45,12 @@ public class ReplaceUntap extends ReplacementEffect { */ @Override public boolean canReplace(Map runParams) { - if (!runParams.get("Event").equals("Untap")) { - return false; - } - if (this.getMapParams().containsKey("ValidCard")) { - if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidCard").split(","), this.getHostCard())) { + if (hasParam("ValidCard")) { + if (!matchesValid(runParams.get("Affected"), getParam("ValidCard").split(","), this.getHostCard())) { return false; } } - if (this.getMapParams().containsKey("UntapStep")) { + if (hasParam("UntapStep")) { final Object o = runParams.get("Affected"); //normally should not happen, but protect from possible crash. if (!(o instanceof Card)) { 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 fd7796a1bf3..1007b1fc727 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java @@ -40,6 +40,8 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { /** The ID. */ private int id; + private ReplacementType mode; + private ReplacementLayer layer = ReplacementLayer.Other; /** The has run. */ @@ -264,4 +266,12 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { public int hashCode() { return Objects.hash(ReplacementEffect.class, getId()); } + + public ReplacementType getMode() { + return mode; + } + + void setMode(ReplacementType mode) { + this.mode = mode; + } } 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 b624d9c979e..272388ef303 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -52,7 +52,7 @@ public class ReplacementHandler { //private final List tmpEffects = new ArrayList(); - public ReplacementResult run(final Map runParams) { + public ReplacementResult run(ReplacementType event, final Map runParams) { final Object affected = runParams.get("Affected"); Player decider = null; @@ -66,7 +66,7 @@ public class ReplacementHandler { // try out all layer for (ReplacementLayer layer : ReplacementLayer.values()) { - ReplacementResult res = run(runParams, layer, decider); + ReplacementResult res = run(event, runParams, layer, decider); if (res != ReplacementResult.NotReplaced) { return res; } @@ -76,21 +76,21 @@ public class ReplacementHandler { } - public List getReplacementList(final Map runParams, final ReplacementLayer layer) { + public List getReplacementList(final ReplacementType event, final Map runParams, final ReplacementLayer layer) { final CardCollection preList = new CardCollection(); boolean checkAgain = false; Card affectedLKI = null; Card affectedCard = null; - if ("Moved".equals(runParams.get("Event")) && ZoneType.Battlefield.equals(runParams.get("Destination"))) { + if (ReplacementType.Moved.equals(event) && ZoneType.Battlefield.equals(runParams.get("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"); if (cause != null && cause.isReplacementAbility()) { final ReplacementEffect re = cause.getReplacementEffect(); // only return for same layer - if ("Moved".equals(re.getParam("Event")) && layer.equals(re.getLayer())) { + if (ReplacementType.Moved.equals(re.getMode()) && layer.equals(re.getLayer())) { return re.getOtherChoices(); } } @@ -137,6 +137,7 @@ public class ReplacementHandler { if (!replacementEffect.hasRun() && (layer == null || replacementEffect.getLayer() == layer) + && event.equals(replacementEffect.getMode()) && replacementEffect.requirementsCheck(game) && replacementEffect.canReplace(runParams) && !possibleReplacers.contains(replacementEffect) @@ -172,8 +173,8 @@ public class ReplacementHandler { * the run params,same as for triggers. * @return true if the event was replaced. */ - public ReplacementResult run(final Map runParams, final ReplacementLayer layer, final Player decider) { - final List possibleReplacers = getReplacementList(runParams, layer); + public 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; @@ -188,7 +189,7 @@ public class ReplacementHandler { ReplacementResult res = executeReplacement(runParams, chosenRE, decider, game); if (res == ReplacementResult.NotReplaced) { if (!possibleReplacers.isEmpty()) { - res = run(runParams); + res = run(event, runParams); } chosenRE.setHasRun(false); chosenRE.setOtherChoices(null); @@ -263,7 +264,7 @@ public class ReplacementHandler { } // Decider gets to choose whether or not to apply the replacement. - if (replacementEffect.getMapParams().containsKey("Optional")) { + if (replacementEffect.hasParam("Optional")) { Player optDecider = decider; if (mapParams.containsKey("OptionalDecider") && (effectSA != null)) { effectSA.setActivatingPlayer(host.getController()); diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementType.java b/forge-game/src/main/java/forge/game/replacement/ReplacementType.java index 0f10844b665..9ddaa8dd6d7 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementType.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementType.java @@ -58,6 +58,7 @@ public enum ReplacementType { if (pp[0].isAssignableFrom(Map.class)) { try { ReplacementEffect res = c.newInstance(mapParams, host, intrinsic); + res.setMode(this); return res; } catch (IllegalArgumentException e) { // TODO Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. 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 031843a49a0..8d1cd6db131 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java @@ -45,6 +45,7 @@ import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementHandler; import forge.game.replacement.ReplacementLayer; import forge.game.replacement.ReplacementResult; +import forge.game.replacement.ReplacementType; import forge.game.trigger.TriggerType; /** @@ -128,12 +129,11 @@ public class AbilityManaPart implements java.io.Serializable { final ManaPool manaPool = player.getManaPool(); String afterReplace = applyManaReplacement(sa, produced); final Map repParams = Maps.newHashMap(); - repParams.put("Event", "ProduceMana"); repParams.put("Mana", afterReplace); repParams.put("Affected", source); repParams.put("Player", player); repParams.put("AbilityMana", sa); - if (player.getGame().getReplacementHandler().run(repParams) != ReplacementResult.NotReplaced) { + if (player.getGame().getReplacementHandler().run(ReplacementType.ProduceMana, repParams) != ReplacementResult.NotReplaced) { return; } //clear lastProduced 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 b399b2b4f66..8d9b3bebae9 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java @@ -438,7 +438,7 @@ public class TriggerHandler { } } - if (t.getMapParams().containsKey("OncePerEffect")) { + if (t.hasParam("OncePerEffect")) { SpellAbilityStackInstance si = (SpellAbilityStackInstance) runParams.get(AbilityKey.SpellAbilityStackInstance); if (si != null) { 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 76573d288b3..21dfe05227d 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPayMana.java +++ b/forge-gui/src/main/java/forge/match/input/InputPayMana.java @@ -26,6 +26,7 @@ import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; import forge.game.player.PlayerView; import forge.game.replacement.ReplacementEffect; +import forge.game.replacement.ReplacementType; import forge.game.spellability.AbilityManaPart; import forge.game.spellability.SpellAbility; import forge.player.HumanPlay; @@ -363,7 +364,6 @@ public abstract class InputPayMana extends InputSyncronizedBase { final Player activator = am.getActivatingPlayer(); final Game g = source.getGame(); final HashMap repParams = new HashMap<>(); - repParams.put("Event", "ProduceMana"); repParams.put("Mana", m.getOrigProduced()); repParams.put("Affected", source); repParams.put("Player", activator); @@ -373,8 +373,9 @@ public abstract class InputPayMana extends InputSyncronizedBase { for (final Card crd : p.getAllCards()) { for (final ReplacementEffect replacementEffect : crd.getReplacementEffects()) { if (replacementEffect.requirementsCheck(g) + && replacementEffect.getMode() == ReplacementType.ProduceMana && replacementEffect.canReplace(repParams) - && replacementEffect.getMapParams().containsKey("ManaReplacement") + && replacementEffect.hasParam("ManaReplacement") && replacementEffect.zonesCheck(g.getZoneOf(crd))) { return true; }