From 211157c0d0bdc6c6e3efa7927dc7443c304d29db Mon Sep 17 00:00:00 2001 From: Hanmac Date: Wed, 18 Apr 2018 17:24:59 +0200 Subject: [PATCH] ReplaceDamage: new Effect for reducing Damage inside ReplacementEffect --- .../src/main/java/forge/ai/SpellApiToAi.java | 1 + .../main/java/forge/game/ability/ApiType.java | 1 + .../ability/effects/ReplaceDamageEffect.java | 79 +++++++++++++++++++ forge-gui/res/cardsfolder/h/healing_grace.txt | 12 +++ 4 files changed, 93 insertions(+) create mode 100644 forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java create mode 100644 forge-gui/res/cardsfolder/h/healing_grace.txt diff --git a/forge-ai/src/main/java/forge/ai/SpellApiToAi.java b/forge-ai/src/main/java/forge/ai/SpellApiToAi.java index df9a2a35993..c11bd25aad6 100644 --- a/forge-ai/src/main/java/forge/ai/SpellApiToAi.java +++ b/forge-ai/src/main/java/forge/ai/SpellApiToAi.java @@ -126,6 +126,7 @@ public enum SpellApiToAi { .put(ApiType.Repeat, RepeatAi.class) .put(ApiType.RepeatEach, RepeatEachAi.class) .put(ApiType.ReplaceEffect, AlwaysPlayAi.class) + .put(ApiType.ReplaceDamage, AlwaysPlayAi.class) .put(ApiType.ReplaceSplitDamage, AlwaysPlayAi.class) .put(ApiType.RestartGame, RestartGameAi.class) .put(ApiType.Reveal, RevealAi.class) diff --git a/forge-game/src/main/java/forge/game/ability/ApiType.java b/forge-game/src/main/java/forge/game/ability/ApiType.java index f3d9407a46e..ad4f48c739c 100644 --- a/forge-game/src/main/java/forge/game/ability/ApiType.java +++ b/forge-game/src/main/java/forge/game/ability/ApiType.java @@ -124,6 +124,7 @@ public enum ApiType { Repeat (RepeatEffect.class), RepeatEach (RepeatEachEffect.class), ReplaceEffect (ReplaceEffect.class), + ReplaceDamage (ReplaceDamageEffect.class), ReplaceSplitDamage (ReplaceSplitDamageEffect.class), RestartGame (RestartGameEffect.class), Reveal (RevealEffect.class), 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 new file mode 100644 index 00000000000..4a48ba83f09 --- /dev/null +++ b/forge-game/src/main/java/forge/game/ability/effects/ReplaceDamageEffect.java @@ -0,0 +1,79 @@ +package forge.game.ability.effects; + +import java.util.Map; + +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; +import forge.game.card.Card; +import forge.game.replacement.ReplacementResult; +import forge.game.spellability.SpellAbility; + +public class ReplaceDamageEffect extends SpellAbilityEffect { + + @Override + public void resolve(SpellAbility sa) { + final Card card = sa.getHostCard(); + final Game game = card.getGame(); + + // outside of Replacement Effect, unwanted result + if (!sa.getRootAbility().isReplacementAbility()) { + return; + } + + String varValue = sa.getParamOrDefault("VarName", "1"); + + @SuppressWarnings("unchecked") + Map originalParams = (Map) sa.getReplacingObject("OriginalParams"); + Map params = Maps.newHashMap(originalParams); + + Integer dmg = (Integer) sa.getReplacingObject("DamageAmount"); + + int prevent = AbilityUtils.calculateAmount(card, varValue, sa); + + // Currently it does reduce damage by amount, need second mode for Setting Damage + + if (prevent > 0) { + int n = Math.min(dmg, prevent); + dmg -= n; + prevent -= n; + + if (card.getType().hasStringType("Effect") && prevent <= 0) { + game.getAction().exile(card, null); + } else if (!StringUtils.isNumeric(varValue)) { + card.setSVar(varValue, "Number$" + prevent); + } + } + + // no damage for original target anymore + if (dmg <= 0) { + originalParams.put("ReplacementResult", ReplacementResult.Replaced); + return; + } + params.put("DamageAmount", dmg); + + + //try to call replacementHandler with new Params + ReplacementResult result = game.getReplacementHandler().run(params); + switch (result) { + case NotReplaced: + case Updated: { + for (Map.Entry e : params.entrySet()) { + originalParams.put(e.getKey(), e.getValue()); + } + // effect was updated + originalParams.put("ReplacementResult", ReplacementResult.Updated); + break; + } + default: + // effect was replaced with something else + originalParams.put("ReplacementResult", result); + break; + } + } + +} diff --git a/forge-gui/res/cardsfolder/h/healing_grace.txt b/forge-gui/res/cardsfolder/h/healing_grace.txt new file mode 100644 index 00000000000..f9512f27292 --- /dev/null +++ b/forge-gui/res/cardsfolder/h/healing_grace.txt @@ -0,0 +1,12 @@ +Name:Healing Grace +ManaCost:W +Types:Instant +A:SP$ ChooseSource | Cost$ W | Choices$ Card,Emblem | SubAbility$ DBEffect | StackDescription$ SpellDescription | SpellDescription$ Prevent the next 3 damage that would be dealt to any target this turn by a source of your choice. You gain 3 life. +SVar:DBEffect:DB$ Effect | ValidTgts$ Creature,Player | TgtPrompt$ Select target to prevent damage to | ReplacementEffects$ GraceDamage | SVars$ GraceDmg,X | References$ GraceDamage,GraceDmg,X | ForgetOnMoved$ Battlefield | RememberObjects$ Targeted | SubAbility$ DBGainLife +SVar:GraceDamage:Event$ DamageDone | ValidTarget$ Creature.IsRemembered,Player.IsRemembered | ValidSource$ Card.ChosenCard,Emblem.ChosenCard | ReplaceWith$ GraceDmg | PreventionEffect$ True | Description$ Prevent the next 3 damage that would be dealt to any target this turn by a source of your choice. +SVar:GraceDmg:DB$ ReplaceDamage | VarName$ X | References$ X +SVar:DBGainLife:DB$ GainLife | LifeAmount$ 3 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +SVar:X:Number$3 +SVar:RemAIDeck:True +Oracle:Prevent the next 3 damage that would be dealt to any target this turn by a source of your choice. You gain 3 life.