From c74b0a017b2bbdfa0c8c328e81ecce56b51db9c1 Mon Sep 17 00:00:00 2001 From: Hanmac Date: Sun, 4 Mar 2018 20:22:45 +0100 Subject: [PATCH] Damage: add Cause Param for damage deal, needed for Silhouette or Bronze Horse --- .../src/main/java/forge/game/GameEntity.java | 35 ++++++++++++------- .../game/ability/effects/DamageAllEffect.java | 4 +-- .../ability/effects/DamageDealEffect.java | 6 ++-- .../ability/effects/DamageEachEffect.java | 8 ++--- .../game/ability/effects/FightEffect.java | 8 ++--- .../effects/ReplaceSplitDamageEffect.java | 3 +- .../main/java/forge/game/cost/CostDamage.java | 2 +- .../forge/game/replacement/ReplaceDamage.java | 24 ++++++++++--- .../src/main/java/forge/player/HumanPlay.java | 2 +- 9 files changed, 59 insertions(+), 33 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameEntity.java b/forge-game/src/main/java/forge/game/GameEntity.java index 1e2529c616c..1cdfd7997ef 100644 --- a/forge-game/src/main/java/forge/game/GameEntity.java +++ b/forge-game/src/main/java/forge/game/GameEntity.java @@ -24,6 +24,7 @@ import forge.game.card.CardDamageMap; import forge.game.card.CounterType; import forge.game.event.GameEventCardAttachment; import forge.game.event.GameEventCardAttachment.AttachMethod; +import forge.game.spellability.SpellAbility; import forge.game.trigger.TriggerType; import forge.util.collect.FCollection; @@ -58,22 +59,22 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { } public final int addDamage(final int damage, final Card source, boolean isCombat, boolean noPrevention, - final CardDamageMap damageMap, final CardDamageMap preventMap) { + final CardDamageMap damageMap, final CardDamageMap preventMap, final SpellAbility cause) { if (noPrevention) { - return addDamageWithoutPrevention(damage, source, damageMap, preventMap); + return addDamageWithoutPrevention(damage, source, damageMap, preventMap, cause); } else if (isCombat) { return addCombatDamage(damage, source, damageMap, preventMap); } else { - return addDamage(damage, source, damageMap, preventMap); + return addDamage(damage, source, damageMap, preventMap, cause); } } public int addDamage(final int damage, final Card source, final CardDamageMap damageMap, - final CardDamageMap preventMap) { + final CardDamageMap preventMap, final SpellAbility cause) { int damageToDo = damage; - damageToDo = replaceDamage(damageToDo, source, false, true, damageMap, preventMap); - damageToDo = preventDamage(damageToDo, source, false, preventMap); + damageToDo = replaceDamage(damageToDo, source, false, true, damageMap, preventMap, cause); + damageToDo = preventDamage(damageToDo, source, false, preventMap, cause); return addDamageAfterPrevention(damageToDo, source, false, damageMap); } @@ -82,8 +83,8 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { final CardDamageMap preventMap) { int damageToDo = damage; - damageToDo = replaceDamage(damageToDo, source, true, true, damageMap, preventMap); - damageToDo = preventDamage(damageToDo, source, true, preventMap); + damageToDo = replaceDamage(damageToDo, source, true, true, damageMap, preventMap, null); + damageToDo = preventDamage(damageToDo, source, true, preventMap, null); if (damageToDo > 0) { source.getDamageHistory().registerCombatDamage(this); @@ -97,13 +98,13 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { } public int addDamageWithoutPrevention(final int damage, final Card source, final CardDamageMap damageMap, - final CardDamageMap preventMap) { - int damageToDo = replaceDamage(damage, source, false, false, damageMap, preventMap); + final CardDamageMap preventMap, final SpellAbility cause) { + int damageToDo = replaceDamage(damage, source, false, false, damageMap, preventMap, cause); return addDamageAfterPrevention(damageToDo, source, false, damageMap); } public int replaceDamage(final int damage, final Card source, final boolean isCombat, final boolean prevention, - final CardDamageMap damageMap, final CardDamageMap preventMap) { + final CardDamageMap damageMap, final CardDamageMap preventMap, final SpellAbility cause) { // Replacement effects final Map repParams = Maps.newHashMap(); repParams.put("Event", "DamageDone"); @@ -114,6 +115,9 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { repParams.put("NoPreventDamage", !prevention); repParams.put("DamageMap", damageMap); repParams.put("PreventMap", preventMap); + if (cause != null) { + repParams.put("Cause", cause); + } switch (getGame().getReplacementHandler().run(repParams)) { case NotReplaced: @@ -126,7 +130,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { return newDamage; } else { if (prevention) { - newDamage = newTarget.preventDamage(newDamage, source, isCombat, preventMap); + newDamage = newTarget.preventDamage(newDamage, source, isCombat, preventMap, cause); } newTarget.addDamageAfterPrevention(newDamage, source, isCombat, damageMap); } @@ -146,7 +150,9 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { // not change the game state) public abstract int staticReplaceDamage(final int damage, final Card source, final boolean isCombat); - public final int preventDamage(final int damage, final Card source, final boolean isCombat, CardDamageMap preventMap) { + public final int preventDamage( + final int damage, final Card source, final boolean isCombat, CardDamageMap preventMap, + final SpellAbility cause) { if (getGame().getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noPrevention) || source.hasKeyword("Damage that would be dealt by CARDNAME can't be prevented.")) { return damage; @@ -163,6 +169,9 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { repParams.put("IsCombat", isCombat); repParams.put("Prevention", true); repParams.put("PreventMap", preventMap); + if (cause != null) { + repParams.put("Cause", cause); + } switch (getGame().getReplacementHandler().run(repParams)) { case NotReplaced: diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java index f22f79c9cdb..d7ef3c3e07f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java @@ -97,13 +97,13 @@ public class DamageAllEffect extends DamageBaseEffect { } for (final Card c : list) { - c.addDamage(dmg, sourceLKI, damageMap, preventMap); + c.addDamage(dmg, sourceLKI, damageMap, preventMap, sa); } if (!players.equals("")) { final List playerList = AbilityUtils.getDefinedPlayers(card, players, sa); for (final Player p : playerList) { - p.addDamage(dmg, sourceLKI, damageMap, preventMap); + p.addDamage(dmg, sourceLKI, damageMap, preventMap, sa); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java index 73115f2a938..9c7dc421749 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java @@ -156,7 +156,7 @@ public class DamageDealEffect extends DamageBaseEffect { Player assigningPlayer = players.get(0); Map map = assigningPlayer.getController().assignCombatDamage(sourceLKI, assigneeCards, dmg, null, true); for (Entry dt : map.entrySet()) { - dt.getKey().addDamage(dt.getValue(), sourceLKI, damageMap, preventMap); + dt.getKey().addDamage(dt.getValue(), sourceLKI, damageMap, preventMap, sa); } if (!usedDamageMap) { @@ -183,13 +183,13 @@ public class DamageDealEffect extends DamageBaseEffect { c.clearAssignedDamage(); } else { - c.addDamage(dmg, sourceLKI, false, noPrevention, damageMap, preventMap); + c.addDamage(dmg, sourceLKI, false, noPrevention, damageMap, preventMap, sa); } } } else if (o instanceof Player) { final Player p = (Player) o; if (!targeted || p.canBeTargetedBy(sa)) { - p.addDamage(dmg, sourceLKI, false, noPrevention, damageMap, preventMap); + p.addDamage(dmg, sourceLKI, false, noPrevention, damageMap, preventMap, sa); } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java index 1ccd9ecae9d..22a9fb9643b 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java @@ -91,13 +91,13 @@ public class DamageEachEffect extends DamageBaseEffect { if (o instanceof Card) { final Card c = (Card) o; if (c.isInPlay() && (!targeted || c.canBeTargetedBy(sa))) { - c.addDamage(dmg, sourceLKI, damageMap, preventMap); + c.addDamage(dmg, sourceLKI, damageMap, preventMap, sa); } } else if (o instanceof Player) { final Player p = (Player) o; if (!targeted || p.canBeTargetedBy(sa)) { - p.addDamage(dmg, sourceLKI, damageMap, preventMap); + p.addDamage(dmg, sourceLKI, damageMap, preventMap, sa); } } } @@ -110,7 +110,7 @@ public class DamageEachEffect extends DamageBaseEffect { final int dmg = CardFactoryUtil.xCount(source, card.getSVar("X")); // System.out.println(source+" deals "+dmg+" damage to "+source); - source.addDamage(dmg, sourceLKI, damageMap, preventMap); + source.addDamage(dmg, sourceLKI, damageMap, preventMap, sa); } } if (sa.getParam("DefinedCards").equals("Remembered")) { @@ -122,7 +122,7 @@ public class DamageEachEffect extends DamageBaseEffect { if (o instanceof Card) { Card rememberedcard = (Card) o; // System.out.println(source + " deals " + dmg + " damage to " + rememberedcard); - rememberedcard.addDamage(dmg, sourceLKI, damageMap, preventMap); + rememberedcard.addDamage(dmg, sourceLKI, damageMap, preventMap, sa); } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/FightEffect.java b/forge-game/src/main/java/forge/game/ability/effects/FightEffect.java index ef2d2e7babb..a2ab96ac797 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/FightEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/FightEffect.java @@ -63,8 +63,8 @@ public class FightEffect extends DamageBaseEffect { final int dmg1 = fightToughness ? fighters.get(0).getNetToughness() : fighters.get(0).getNetPower(); final int dmg2 = fightToughness ? fighters.get(1).getNetToughness() : fighters.get(1).getNetPower(); - dealDamage(fighters.get(0), fighters.get(1), dmg1, damageMap, preventMap); - dealDamage(fighters.get(1), fighters.get(0), dmg2, damageMap, preventMap); + dealDamage(fighters.get(0), fighters.get(1), dmg1, damageMap, preventMap, sa); + dealDamage(fighters.get(1), fighters.get(0), dmg2, damageMap, preventMap, sa); preventMap.triggerPreventDamage(false); damageMap.triggerDamageDoneOnce(false); @@ -121,8 +121,8 @@ public class FightEffect extends DamageBaseEffect { return fighterList; } - private void dealDamage(Card source, Card target, int damage, CardDamageMap damageMap, CardDamageMap preventMap) { - target.addDamage(damage, source, damageMap, preventMap); + private void dealDamage(Card source, Card target, int damage, CardDamageMap damageMap, CardDamageMap preventMap, final SpellAbility sa) { + target.addDamage(damage, source, damageMap, preventMap, sa); } } 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 a6e9bb7ad20..c7f0201c785 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 @@ -57,13 +57,14 @@ public class ReplaceSplitDamageEffect extends SpellAbilityEffect { CardDamageMap damageMap = (CardDamageMap) originalParams.get("DamageMap"); CardDamageMap preventMap = (CardDamageMap) originalParams.get("PreventMap"); + SpellAbility cause = (SpellAbility) originalParams.get("Cause"); boolean isCombat = (Boolean) originalParams.get("IsCombat"); boolean noPrevention = (Boolean) originalParams.get("NoPreventDamage"); GameEntity obj = (GameEntity) list.get(0); - obj.addDamage(n, sourceLKI, isCombat, noPrevention, damageMap, preventMap); + obj.addDamage(n, sourceLKI, isCombat, noPrevention, damageMap, preventMap, cause); } // no damage for original target anymore diff --git a/forge-game/src/main/java/forge/game/cost/CostDamage.java b/forge-game/src/main/java/forge/game/cost/CostDamage.java index e90f14b5d04..9e19d698a4d 100644 --- a/forge-game/src/main/java/forge/game/cost/CostDamage.java +++ b/forge-game/src/main/java/forge/game/cost/CostDamage.java @@ -64,7 +64,7 @@ public class CostDamage extends CostPart { CardDamageMap damageMap = new CardDamageMap(); CardDamageMap preventMap = new CardDamageMap(); - payer.addDamage(decision.c, source, damageMap, preventMap); + payer.addDamage(decision.c, source, damageMap, preventMap, null); preventMap.triggerPreventDamage(false); damageMap.triggerDamageDoneOnce(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 d3e8995658d..05cf878c177 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceDamage.java @@ -54,19 +54,35 @@ public class ReplaceDamage extends ReplacementEffect { return false; } if (hasParam("ValidSource")) { - String validSource = getParam("ValidSource"); - validSource = AbilityUtils.applyAbilityTextChangeEffects(validSource, this); + String validSource = getParam("ValidSource"); + validSource = AbilityUtils.applyAbilityTextChangeEffects(validSource, this); if (!matchesValid(runParams.get("DamageSource"), validSource.split(","), getHostCard())) { return false; } } if (hasParam("ValidTarget")) { - String validTarget = getParam("ValidTarget"); - validTarget = AbilityUtils.applyAbilityTextChangeEffects(validTarget, this); + String validTarget = getParam("ValidTarget"); + validTarget = AbilityUtils.applyAbilityTextChangeEffects(validTarget, this); if (!matchesValid(runParams.get("Affected"), validTarget.split(","), getHostCard())) { return false; } } + if (hasParam("ValidCause")) { + if (!runParams.containsKey("Cause")) { + return false; + } + SpellAbility cause = (SpellAbility) runParams.get("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"))) { + return false; + } + } + } if (((Integer) runParams.get("DamageAmount")) == 0) { // If no actual damage is dealt, there is nothing to replace return false; diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index 27063b28406..67d9522cb9a 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -424,7 +424,7 @@ public class HumanPlay { CardDamageMap damageMap = new CardDamageMap(); CardDamageMap preventMap = new CardDamageMap(); - p.addDamage(amount, source, damageMap, preventMap); + p.addDamage(amount, source, damageMap, preventMap, null); preventMap.triggerPreventDamage(false); damageMap.triggerDamageDoneOnce(false);