From 04811da9ccdef187ed7876a3ade7f06e19d5fcf8 Mon Sep 17 00:00:00 2001 From: Lyu Zong-Hong Date: Mon, 10 May 2021 08:09:27 +0900 Subject: [PATCH] Update AI damage prevention prediction code --- .../java/forge/ai/ComputerUtilCombat.java | 20 +++++++++++++++++-- .../src/main/java/forge/game/card/Card.java | 13 ++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index d40ce7cf5df..c0c45b7afad 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -2293,7 +2293,8 @@ public class ComputerUtilCombat { for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) { for (final ReplacementEffect re : ca.getReplacementEffects()) { Map params = re.getMapParams(); - if (!re.getMode().equals(ReplacementType.DamageDone) || !params.containsKey("PreventionEffect")) { + if (!re.getMode().equals(ReplacementType.DamageDone) || + (!params.containsKey("PreventionEffect") && !params.containsKey("Prevent"))) { continue; } // Immortal Coil prevents the damage but has a similar negative effect @@ -2320,6 +2321,14 @@ public class ComputerUtilCombat { } } + if (params.containsKey("Prevent")) { + return 0; + } else if (re.getOverridingAbility() != null) { + SpellAbility repSA = re.getOverridingAbility(); + if (repSA.getApi() == ApiType.ReplaceDamage) { + return Math.max(0, restDamage - AbilityUtils.calculateAmount(ca, repSA.getParam("Amount"), repSA)); + } + } return 0; } } @@ -2491,7 +2500,14 @@ public class ComputerUtilCombat { List list = game.getReplacementHandler().getReplacementList( ReplacementType.DamageDone, repParams, ReplacementLayer.Other); - return !list.isEmpty(); + for (final ReplacementEffect re : list) { + Map params = re.getMapParams(); + if (params.containsKey("Prevent") || + (re.getOverridingAbility() != null && re.getOverridingAbility().getApi() != ApiType.ReplaceDamage)) { + return true; + } + } + return false; } public static boolean attackerHasThreateningAfflict(Card attacker, Player aiDefender) { 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 a61eb9a6e90..0ea766d0c02 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -5170,10 +5170,11 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return damage; } - for (final Card ca : getGame().getCardsIn(ZoneType.Battlefield)) { + for (final Card ca : getGame().getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) { for (final ReplacementEffect re : ca.getReplacementEffects()) { Map params = re.getMapParams(); - if (!re.getMode().equals(ReplacementType.DamageDone) || !params.containsKey("PreventionEffect")) { + if (!re.getMode().equals(ReplacementType.DamageDone) || + (!params.containsKey("PreventionEffect") && !params.containsKey("Prevent"))) { continue; } if (params.containsKey("ValidSource") @@ -5195,6 +5196,14 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } } } + if (params.containsKey("Prevent")) { + return 0; + } else if (re.getOverridingAbility() != null) { + SpellAbility repSA = re.getOverridingAbility(); + if (repSA.getApi() == ApiType.ReplaceDamage) { + return Math.max(0, damage - AbilityUtils.calculateAmount(ca, repSA.getParam("Amount"), repSA)); + } + } return 0; } }