From b3857dfcfd3f432f0006c6f2bb01cd0efeddfff4 Mon Sep 17 00:00:00 2001 From: Agetian Date: Fri, 10 Jul 2020 12:18:09 +0300 Subject: [PATCH 1/2] - Allow the AI to trample over defenders it can't kill (e.g. Orgg vs. a regenerating blocker). --- forge-ai/src/main/java/forge/ai/AiAttackController.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index b3dc45e4999..5527d9f4d62 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -38,6 +38,7 @@ import forge.game.spellability.SpellAbility; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; +import forge.util.Aggregates; import forge.util.Expressions; import forge.util.MyRandom; import forge.util.TextUtil; @@ -1164,6 +1165,9 @@ public class AiAttackController { return CombatUtil.canBlock(attacker, defender); } }); + + boolean canTrampleOverDefenders = attacker.hasKeyword(Keyword.TRAMPLE) && attacker.getNetPower() > Aggregates.sum(validBlockers, CardPredicates.Accessors.fnGetNetToughness); + // used to check that CanKillAllDangerous check makes sense in context where creatures with dangerous abilities are present boolean dangerousBlockersPresent = !CardLists.filter(validBlockers, Predicates.or( CardPredicates.hasKeyword(Keyword.WITHER), CardPredicates.hasKeyword(Keyword.INFECT), @@ -1294,7 +1298,9 @@ public class AiAttackController { } break; case 2: // attack expecting to attract a group block or destroying a single blocker and surviving - if (!canBeBlocked || ((canKillAll || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne && + if (!canBeBlocked + || (!canBeKilled && !dangerousBlockersPresent && canTrampleOverDefenders) + || ((canKillAll || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne && ((dangerousBlockersPresent && canKillAllDangerous) || !canBeKilled))) { if (LOG_AI_ATTACKS) System.out.println(attacker.getName() + " = attacking expecting to survive or attract group block"); From 082fd8cf5f0ef3f3c4372c17315daf3da001bde4 Mon Sep 17 00:00:00 2001 From: Agetian Date: Fri, 10 Jul 2020 12:34:42 +0300 Subject: [PATCH 2/2] - Somewhat more appropriate location for the updated trample AI code. --- forge-ai/src/main/java/forge/ai/AiAttackController.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index 5527d9f4d62..f8472d1ed22 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -1257,6 +1257,10 @@ public class AiAttackController { if (LOG_AI_ATTACKS) System.out.println(attacker.getName() + " = attacking because they can't block, expecting to kill or damage player"); return true; + } else if (!canBeKilled && !dangerousBlockersPresent && canTrampleOverDefenders) { + if (LOG_AI_ATTACKS) + System.out.println(attacker.getName() + " = expecting to survive and get some Trample damage through"); + return true; } if (numberOfPossibleBlockers > 2 @@ -1298,9 +1302,7 @@ public class AiAttackController { } break; case 2: // attack expecting to attract a group block or destroying a single blocker and surviving - if (!canBeBlocked - || (!canBeKilled && !dangerousBlockersPresent && canTrampleOverDefenders) - || ((canKillAll || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne && + if (!canBeBlocked || ((canKillAll || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne && ((dangerousBlockersPresent && canKillAllDangerous) || !canBeKilled))) { if (LOG_AI_ATTACKS) System.out.println(attacker.getName() + " = attacking expecting to survive or attract group block");