From f1467d5a3ecee73020593413e5e9783125e03b6b Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Thu, 21 Oct 2021 22:50:11 +0200 Subject: [PATCH] Fix miscalculation of damage shields --- .../java/forge/ai/AiAttackController.java | 4 +-- .../main/java/forge/ai/AiBlockController.java | 10 +++--- .../src/main/java/forge/ai/ComputerUtil.java | 12 +++---- .../main/java/forge/ai/ComputerUtilCard.java | 4 +-- .../java/forge/ai/ComputerUtilCombat.java | 35 +++++++++---------- .../java/forge/ai/ability/DamageAllAi.java | 2 +- .../java/forge/ai/ability/DamageDealAi.java | 2 +- .../main/java/forge/ai/ability/FightAi.java | 25 +++++-------- .../main/java/forge/ai/ability/LifeSetAi.java | 2 +- .../java/forge/ai/ability/PumpAiBase.java | 2 +- .../main/java/forge/ai/ability/PumpAllAi.java | 4 +-- .../game/ability/effects/LifeSetEffect.java | 4 +-- .../res/cardsfolder/r/revival_revenge.txt | 2 +- 13 files changed, 49 insertions(+), 59 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index bba7e2def1f..23f5b9e7b31 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -1063,7 +1063,7 @@ public class AiAttackController { final Card attacker = attackersLeft.get(i); if (this.aiAggression < 5 && !attacker.hasFirstStrike() && !attacker.hasDoubleStrike() && ComputerUtilCombat.getTotalFirstStrikeBlockPower(attacker, this.defendingOpponent) - >= ComputerUtilCombat.getDamageToKill(attacker)) { + >= ComputerUtilCombat.getDamageToKill(attacker, false)) { continue; } @@ -1086,7 +1086,7 @@ public class AiAttackController { } } // if enough damage: switch to next planeswalker - if (damage >= ComputerUtilCombat.getDamageToKill((Card) defender)) { + if (damage >= ComputerUtilCombat.getDamageToKill((Card) defender, true)) { break; } } diff --git a/forge-ai/src/main/java/forge/ai/AiBlockController.java b/forge-ai/src/main/java/forge/ai/AiBlockController.java index d8750635803..5ffd4d94d9c 100644 --- a/forge-ai/src/main/java/forge/ai/AiBlockController.java +++ b/forge-ai/src/main/java/forge/ai/AiBlockController.java @@ -368,7 +368,7 @@ public class AiBlockController { if (firstStrikeBlockers.size() > 1) { CardLists.sortByPowerDesc(firstStrikeBlockers); for (final Card blocker : firstStrikeBlockers) { - final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker) + final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker, false) + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false); // if the total damage of the blockgang was not enough // without but is enough with this blocker finish the blockgang @@ -446,7 +446,7 @@ public class AiBlockController { final int additionalDamage = ComputerUtilCombat.dealsDamageAsBlocker(attacker, blocker); final int absorbedDamage2 = ComputerUtilCombat.getEnoughDamageToKill(blocker, attacker.getNetCombatDamage(), attacker, true); final int addedValue = ComputerUtilCard.evaluateCreature(blocker); - final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker) + final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker, false) + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false); if ((damageNeeded > currentDamage || CombatUtil.getMinNumBlockersForAttacker(attacker, ai) > blockGang.size()) && !(damageNeeded > currentDamage + additionalDamage) @@ -486,7 +486,7 @@ public class AiBlockController { final int additionalDamage2 = ComputerUtilCombat.dealsDamageAsBlocker(attacker, secondBlocker); final int absorbedDamage2 = ComputerUtilCombat.getEnoughDamageToKill(secondBlocker, attacker.getNetCombatDamage(), attacker, true); final int addedValue2 = ComputerUtilCard.evaluateCreature(secondBlocker); - final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker) + final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker, false) + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, secondBlocker, combat, false); List usableBlockersAsThird = new ArrayList<>(usableBlockers); @@ -774,7 +774,7 @@ public class AiBlockController { if (blockers.size() > 0) { safeBlockers = getSafeBlockers(combat, attacker, blockers); for (final Card blocker : safeBlockers) { - final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker) + final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker, false) + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false); // Add an additional blocker if the current blockers are not // enough and the new one would deal additional damage @@ -801,7 +801,7 @@ public class AiBlockController { } for (final Card blocker : safeBlockers) { - final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker) + final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker, false) + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false); // Add an additional blocker if the current blockers are not // enough and the new one would deal the remaining damage diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index 7976398a194..3b07e537b07 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -1687,7 +1687,7 @@ public class ComputerUtil { } if (saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll) { - boolean canSave = ComputerUtilCombat.predictDamageTo(c, dmg - toughness, source, false) < ComputerUtilCombat.getDamageToKill(c); + boolean canSave = ComputerUtilCombat.predictDamageTo(c, dmg - toughness, source, false) < ComputerUtilCombat.getDamageToKill(c, false); if ((!topStack.usesTargeting() && !grantIndestructible && !canSave) || (!grantIndestructible && !grantShroud && !canSave)) { continue; @@ -1695,14 +1695,14 @@ public class ComputerUtil { } if (saviourApi == ApiType.PutCounter || saviourApi == ApiType.PutCounterAll) { - boolean canSave = ComputerUtilCombat.predictDamageTo(c, dmg - toughness, source, false) < ComputerUtilCombat.getDamageToKill(c); + boolean canSave = ComputerUtilCombat.predictDamageTo(c, dmg - toughness, source, false) < ComputerUtilCombat.getDamageToKill(c, false); if (!canSave) { continue; } } // cannot protect against source - if (saviourApi == ApiType.Protection && (ProtectAi.toProtectFrom(source, saviour) == null)) { + if (saviourApi == ApiType.Protection && ProtectAi.toProtectFrom(source, saviour) == null) { continue; } @@ -1712,7 +1712,7 @@ public class ComputerUtil { continue; } - if (ComputerUtilCombat.predictDamageTo(c, dmg, source, false) >= ComputerUtilCombat.getDamageToKill(c)) { + if (ComputerUtilCombat.predictDamageTo(c, dmg, source, false) >= ComputerUtilCombat.getDamageToKill(c, false)) { threatened.add(c); } } else if (o instanceof Player) { @@ -1739,7 +1739,7 @@ public class ComputerUtil { if (o instanceof Card) { final Card c = (Card) o; final boolean canRemove = (c.getNetToughness() <= dmg) - || (!c.hasKeyword(Keyword.INDESTRUCTIBLE) && c.getShieldCount() == 0 && (dmg >= ComputerUtilCombat.getDamageToKill(c))); + || (!c.hasKeyword(Keyword.INDESTRUCTIBLE) && c.getShieldCount() == 0 && (dmg >= ComputerUtilCombat.getDamageToKill(c, false))); if (!canRemove) { continue; } @@ -1747,7 +1747,7 @@ public class ComputerUtil { if (saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll) { final boolean cantSave = c.getNetToughness() + toughness <= dmg || (!c.hasKeyword(Keyword.INDESTRUCTIBLE) && c.getShieldCount() == 0 && !grantIndestructible - && (dmg >= toughness + ComputerUtilCombat.getDamageToKill(c))); + && (dmg >= toughness + ComputerUtilCombat.getDamageToKill(c, false))); if (cantSave && (!topStack.usesTargeting() || !grantShroud)) { continue; } diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java index 5604582d97e..af792a1b66b 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java @@ -1498,7 +1498,7 @@ public class ComputerUtilCard { } if (c.hasKeyword(Keyword.TRAMPLE) || keywords.contains("Trample")) { for (Card b : combat.getBlockers(c)) { - pumpedDmg -= ComputerUtilCombat.getDamageToKill(b); + pumpedDmg -= ComputerUtilCombat.getDamageToKill(b, false); } } else { pumpedDmg = 0; @@ -1526,7 +1526,7 @@ public class ComputerUtilCard { if (combat.isBlocked(atk)) { // consider Trample damage properly for a blocked creature for (Card blk : combat.getBlockers(atk)) { - totalPowerUnblocked -= ComputerUtilCombat.getDamageToKill(blk); + totalPowerUnblocked -= ComputerUtilCombat.getDamageToKill(blk, false); } } } diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index 24628dd7044..a841b338cd3 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -164,7 +164,7 @@ public class ComputerUtilCombat { } }); - return totalDamageOfBlockers(attacker, list); + return totalFirstStrikeDamageOfBlockers(attacker, list); } // This function takes Doran and Double Strike into account @@ -619,7 +619,7 @@ public class ComputerUtilCombat { if (flankingMagnitude >= defender.getNetToughness()) { return 0; } - if ((flankingMagnitude >= (defender.getNetToughness() - defender.getDamage())) + if (flankingMagnitude >= (defender.getNetToughness() - defender.getDamage()) && !defender.hasKeyword(Keyword.INDESTRUCTIBLE)) { return 0; } @@ -698,7 +698,7 @@ public class ComputerUtilCombat { final int defBushidoMagnitude = blocker.getKeywordMagnitude(Keyword.BUSHIDO); - final int defenderDefense = (blocker.getLethalDamage() - flankingMagnitude) + defBushidoMagnitude; + final int defenderDefense = blocker.getLethalDamage() - flankingMagnitude + defBushidoMagnitude; return defenderDefense; } // shieldDamage @@ -751,10 +751,10 @@ public class ComputerUtilCombat { // Consider first strike and double strike if (attacker.hasKeyword(Keyword.FIRST_STRIKE) || attacker.hasKeyword(Keyword.DOUBLE_STRIKE)) { - return firstStrikeBlockerDmg >= getDamageToKill(attacker); + return firstStrikeBlockerDmg >= getDamageToKill(attacker, true); } - return totalDamageOfBlockers(attacker, blockers) >= getDamageToKill(attacker); + return totalDamageOfBlockers(attacker, blockers) >= getDamageToKill(attacker, false); } // Will this trigger trigger? @@ -1611,7 +1611,7 @@ public class ComputerUtilCombat { } //Check triggers that deal damage or shrink the attacker - if (getDamageToKill(attacker) + if (getDamageToKill(attacker, false) + predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities) <= 0) { return true; } @@ -1763,9 +1763,9 @@ public class ComputerUtilCombat { return false; } - final int defenderLife = getDamageToKill(blocker) + final int defenderLife = getDamageToKill(blocker, false) + predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities); - final int attackerLife = getDamageToKill(attacker) + final int attackerLife = getDamageToKill(attacker, false) + predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities); if (blocker.hasKeyword(Keyword.DOUBLE_STRIKE)) { @@ -1790,13 +1790,11 @@ public class ComputerUtilCombat { return true; } } // defender double strike - else { // no double strike for defender // Attacker may kill the blocker before he can deal any damage if (dealsFirstStrikeDamage(attacker, withoutAbilities, combat) && !blocker.hasKeyword(Keyword.INDESTRUCTIBLE) && !dealsFirstStrikeDamage(blocker, withoutAbilities, combat)) { - if (attackerDamage >= defenderLife) { return false; } @@ -1810,7 +1808,6 @@ public class ComputerUtilCombat { } return defenderDamage >= attackerLife; - } // defender no double strike return false;// should never arrive here } // canDestroyAttacker @@ -1856,7 +1853,7 @@ public class ComputerUtilCombat { if (flankingMagnitude >= blocker.getNetToughness()) { return true; } - if ((flankingMagnitude >= getDamageToKill(blocker)) + if (flankingMagnitude >= getDamageToKill(blocker, false) && !blocker.hasKeyword(Keyword.INDESTRUCTIBLE)) { return true; } @@ -1867,7 +1864,7 @@ public class ComputerUtilCombat { return false; } - if (getDamageToKill(blocker) + if (getDamageToKill(blocker, false) + predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities) <= 0) { return true; } @@ -1996,9 +1993,9 @@ public class ComputerUtilCombat { } } - final int defenderLife = getDamageToKill(blocker) + final int defenderLife = getDamageToKill(blocker, false) + predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities); - final int attackerLife = getDamageToKill(attacker) + final int attackerLife = getDamageToKill(attacker, false) + predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities); if (attacker.hasKeyword(Keyword.DOUBLE_STRIKE)) { @@ -2128,7 +2125,7 @@ public class ComputerUtilCombat { if (dmgCanDeal > 0 ) { // if any damage left undistributed, if (hasTrample && isAttacking) // if you have trample, deal damage to defending entity damageMap.put(null, dmgCanDeal); - else if ( lastBlocker != null ) { // otherwise flush it into last blocker + else if (lastBlocker != null) { // otherwise flush it into last blocker damageMap.put(lastBlocker, dmgCanDeal + damageMap.get(lastBlocker)); } } @@ -2171,7 +2168,7 @@ public class ComputerUtilCombat { */ public static final int getEnoughDamageToKill(final Card c, final int maxDamage, final Card source, final boolean isCombat, final boolean noPrevention) { - final int killDamage = getDamageToKill(c); + final int killDamage = getDamageToKill(c, false); if (c.hasKeyword(Keyword.INDESTRUCTIBLE) || c.getShieldCount() > 0) { if (!(source.hasKeyword(Keyword.WITHER) || source.hasKeyword(Keyword.INFECT))) { @@ -2212,8 +2209,8 @@ public class ComputerUtilCombat { * * @return a int. */ - public final static int getDamageToKill(final Card c) { - int damageShield = c.getPreventNextDamageTotalShields(); + public final static int getDamageToKill(final Card c, boolean withShields) { + int damageShield = withShields ? c.getPreventNextDamageTotalShields() : 0; int killDamage = (c.isPlaneswalker() ? c.getCurrentLoyalty() : c.getLethalDamage()) + damageShield; if (killDamage > damageShield diff --git a/forge-ai/src/main/java/forge/ai/ability/DamageAllAi.java b/forge-ai/src/main/java/forge/ai/ability/DamageAllAi.java index d21327c08c6..016c5a4878b 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DamageAllAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DamageAllAi.java @@ -256,7 +256,7 @@ public class DamageAllAi extends SpellAbilityAi { final Predicate filterKillable = new Predicate() { @Override public boolean apply(final Card c) { - return (ComputerUtilCombat.predictDamageTo(c, dmg, source, false) >= ComputerUtilCombat.getDamageToKill(c)); + return (ComputerUtilCombat.predictDamageTo(c, dmg, source, false) >= ComputerUtilCombat.getDamageToKill(c, false)); } }; diff --git a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java index 210330df3b2..580509510e0 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java @@ -807,7 +807,7 @@ public class DamageDealAi extends DamageAiBase { if (o instanceof Card) { Card c = (Card) o; final int restDamage = ComputerUtilCombat.predictDamageTo(c, dmg, saMe.getHostCard(), false); - if (!c.hasKeyword(Keyword.INDESTRUCTIBLE) && ComputerUtilCombat.getDamageToKill(c) <= restDamage) { + if (!c.hasKeyword(Keyword.INDESTRUCTIBLE) && ComputerUtilCombat.getDamageToKill(c, false) <= restDamage) { if (c.getController().equals(ai)) { return false; } else { diff --git a/forge-ai/src/main/java/forge/ai/ability/FightAi.java b/forge-ai/src/main/java/forge/ai/ability/FightAi.java index e065c168cf6..4b8771b2d2c 100644 --- a/forge-ai/src/main/java/forge/ai/ability/FightAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/FightAi.java @@ -70,14 +70,11 @@ public class FightAi extends SpellAbilityAi { } Card fighter1 = fighter1List.get(0); for (Card humanCreature : humCreatures) { - if (ComputerUtilCombat.getDamageToKill(humanCreature) <= fighter1.getNetPower() - && humanCreature.getNetPower() < ComputerUtilCombat.getDamageToKill(fighter1)) { + if (canKill(fighter1, humanCreature, 0) + && !canKill(humanCreature, fighter1, 0)) { // todo: check min/max targets; see if we picked the best matchup sa.getTargets().add(humanCreature); return true; - } else if (humanCreature.getSVar("Targeting").equals("Dies")) { - sa.getTargets().add(humanCreature); - return true; } } return false; // bail at this point, otherwise the AI will overtarget and waste the activation @@ -87,16 +84,12 @@ public class FightAi extends SpellAbilityAi { if (!(humCreatures.isEmpty() && aiCreatures.isEmpty())) { for (Card humanCreature : humCreatures) { for (Card aiCreature : aiCreatures) { - if (ComputerUtilCombat.getDamageToKill(humanCreature) <= aiCreature.getNetPower() - && humanCreature.getNetPower() < ComputerUtilCombat.getDamageToKill(aiCreature)) { + if (canKill(aiCreature, humanCreature, 0) + && !canKill(humanCreature, aiCreature, 0)) { // todo: check min/max targets; see if we picked the best matchup sa.getTargets().add(humanCreature); sa.getTargets().add(aiCreature); return true; - } else if (humanCreature.getSVar("Targeting").equals("Dies")) { - sa.getTargets().add(humanCreature); - sa.getTargets().add(aiCreature); - return true; } } } @@ -111,8 +104,8 @@ public class FightAi extends SpellAbilityAi { if (sa.hasParam("TargetsWithoutSameCreatureType") && creature1.sharesCreatureTypeWith(creature2)) { continue; } - if (ComputerUtilCombat.getDamageToKill(creature1) <= creature2.getNetPower() - && creature1.getNetPower() >= ComputerUtilCombat.getDamageToKill(creature2)) { + if (canKill(creature1, creature2, 0) + && canKill(creature2, creature1, 0)) { // todo: check min/max targets; see if we picked the best matchup sa.getTargets().add(creature1); sa.getTargets().add(creature2); @@ -152,14 +145,14 @@ public class FightAi extends SpellAbilityAi { if (sa.hasParam("Defined")) { Card aiCreature = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa).get(0); for (Card humanCreature : humCreatures) { - if (ComputerUtilCombat.getDamageToKill(humanCreature) <= aiCreature.getNetPower() + if (canKill(aiCreature, humanCreature, 0) && ComputerUtilCard.evaluateCreature(humanCreature) > ComputerUtilCard.evaluateCreature(aiCreature)) { sa.getTargets().add(humanCreature); return true; } } for (Card humanCreature : humCreatures) { - if (ComputerUtilCombat.getDamageToKill(aiCreature) > humanCreature.getNetPower()) { + if (!canKill(humanCreature, aiCreature, 0)) { sa.getTargets().add(humanCreature); return true; } @@ -312,7 +305,7 @@ public class FightAi extends SpellAbilityAi { return false; } if (fighter.hasKeyword(Keyword.DEATHTOUCH) - || ComputerUtilCombat.getDamageToKill(opponent) <= fighter.getNetPower() + pumpAttack) { + || ComputerUtilCombat.getDamageToKill(opponent, true) <= fighter.getNetPower() + pumpAttack) { return true; } return false; diff --git a/forge-ai/src/main/java/forge/ai/ability/LifeSetAi.java b/forge-ai/src/main/java/forge/ai/ability/LifeSetAi.java index b8f9b8cab61..ef07915ded9 100644 --- a/forge-ai/src/main/java/forge/ai/ability/LifeSetAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/LifeSetAi.java @@ -136,7 +136,7 @@ public class LifeSetAi extends SpellAbilityAi { if (tgt.canOnlyTgtOpponent()) { sa.getTargets().add(opponent); } else { - if ((amount > myLife) && (myLife <= 10)) { + if (amount > myLife && myLife <= 10) { sa.getTargets().add(ai); } else if (hlife > amount) { sa.getTargets().add(opponent); diff --git a/forge-ai/src/main/java/forge/ai/ability/PumpAiBase.java b/forge-ai/src/main/java/forge/ai/ability/PumpAiBase.java index da20573236d..459ea2aa6e2 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PumpAiBase.java +++ b/forge-ai/src/main/java/forge/ai/ability/PumpAiBase.java @@ -467,7 +467,7 @@ public abstract class PumpAiBase extends SpellAbilityAi { if (c.getSVar("Targeting").equals("Dies") || c.getNetToughness() <= -defense) { return true; // can kill indestructible creatures } - return (ComputerUtilCombat.getDamageToKill(c) <= -defense && !c.hasKeyword(Keyword.INDESTRUCTIBLE)); + return ComputerUtilCombat.getDamageToKill(c, false) <= -defense && !c.hasKeyword(Keyword.INDESTRUCTIBLE); } }); // leaves all creatures that will be destroyed } // -X/-X end diff --git a/forge-ai/src/main/java/forge/ai/ability/PumpAllAi.java b/forge-ai/src/main/java/forge/ai/ability/PumpAllAi.java index e882a63bbe3..e240f51cd27 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PumpAllAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PumpAllAi.java @@ -90,7 +90,7 @@ public class PumpAllAi extends PumpAiBase { if (c.getNetToughness() <= -defense) { return true; // can kill indestructible creatures } - return ((ComputerUtilCombat.getDamageToKill(c) <= -defense) && !c.hasKeyword(Keyword.INDESTRUCTIBLE)); + return ComputerUtilCombat.getDamageToKill(c, false) <= -defense && !c.hasKeyword(Keyword.INDESTRUCTIBLE); } }); // leaves all creatures that will be destroyed human = CardLists.filter(human, new Predicate() { @@ -99,7 +99,7 @@ public class PumpAllAi extends PumpAiBase { if (c.getNetToughness() <= -defense) { return true; // can kill indestructible creatures } - return ((ComputerUtilCombat.getDamageToKill(c) <= -defense) && !c.hasKeyword(Keyword.INDESTRUCTIBLE)); + return ComputerUtilCombat.getDamageToKill(c, false) <= -defense && !c.hasKeyword(Keyword.INDESTRUCTIBLE); } }); // leaves all creatures that will be destroyed } // -X/-X end diff --git a/forge-game/src/main/java/forge/game/ability/effects/LifeSetEffect.java b/forge-game/src/main/java/forge/game/ability/effects/LifeSetEffect.java index 3c44569919e..c92d6cd6134 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/LifeSetEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/LifeSetEffect.java @@ -24,14 +24,14 @@ public class LifeSetEffect extends SpellAbilityEffect { if (redistribute) { for (final Player p : getTargetPlayers(sa)) { - if ((tgt == null) || p.canBeTargetedBy(sa)) { + if (tgt == null || p.canBeTargetedBy(sa)) { lifetotals.add(p.getLife()); } } } for (final Player p : getTargetPlayers(sa)) { - if ((tgt == null) || p.canBeTargetedBy(sa)) { + if (tgt == null || p.canBeTargetedBy(sa)) { if (!redistribute) { p.setLife(lifeAmount, sa.getHostCard()); } else { diff --git a/forge-gui/res/cardsfolder/r/revival_revenge.txt b/forge-gui/res/cardsfolder/r/revival_revenge.txt index 00c1c485b06..4758b0c118f 100644 --- a/forge-gui/res/cardsfolder/r/revival_revenge.txt +++ b/forge-gui/res/cardsfolder/r/revival_revenge.txt @@ -11,7 +11,7 @@ ALTERNATE Name:Revenge ManaCost:4 W B Types:Sorcery -A:SP$ SetLife | LifeAmount$ X | SubAbility$ DBLoseHalf | SpellDescription$ Double your life total. Target opponent loses half their life, rounded up. +A:SP$ SetLife | LifeAmount$ X | Defined$ You | SubAbility$ DBLoseHalf | SpellDescription$ Double your life total. Target opponent loses half their life, rounded up. SVar:DBLoseHalf:DB$ LoseLife | ValidTgts$ Opponent | LifeAmount$ Y SVar:X:Count$YourLifeTotal/Twice SVar:Y:Count$TargetedLifeTotal/HalfUp