From fc8922e271672fcf9305f88d3bb09bd1e195be7e Mon Sep 17 00:00:00 2001 From: Agetian Date: Sun, 5 Jul 2020 13:47:16 +0300 Subject: [PATCH] - Improve logic for grantsUsefulExtraBlockOpts, fix an issue where the AI would start spam-activating pump abilities randomly when about to lose. --- .../main/java/forge/ai/ability/PumpAi.java | 2 +- .../java/forge/ai/ability/PumpAiBase.java | 31 +++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java index ced79a57318..75ecdc36a27 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java @@ -388,7 +388,7 @@ public class PumpAi extends PumpAiBase { } return true; - } else if (grantsUsefulExtraBlockOpts(ai, card)) { + } else if (grantsUsefulExtraBlockOpts(ai, sa, card, keywords)) { return true; } } 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 aba764dbe89..d5d675de9f1 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PumpAiBase.java +++ b/forge-ai/src/main/java/forge/ai/ability/PumpAiBase.java @@ -9,6 +9,7 @@ import forge.ai.ComputerUtilCombat; import forge.ai.SpellAbilityAi; import forge.card.MagicColor; import forge.game.Game; +import forge.game.ability.AbilityUtils; import forge.game.card.*; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; @@ -37,22 +38,48 @@ public abstract class PumpAiBase extends SpellAbilityAi { } - public boolean grantsUsefulExtraBlockOpts(final Player ai, final Card card) { + public boolean grantsUsefulExtraBlockOpts(final Player ai, final SpellAbility sa, final Card card, List keywords) { PhaseHandler ph = ai.getGame().getPhaseHandler(); + + Card pumped = ComputerUtilCard.getPumpedCreature(ai, sa, card, 0, 0, keywords); + ai.getGame().getAction().checkStaticAbilities(false); + if (ph.isPlayerTurn(ai) || !ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS)) { return false; } + int canBlockNum = 1 + card.canBlockAdditional(); + int canBlockNumPumped = canBlockNum; // PumpedCreature doesn't return a meaningful value of canBlockAdditional, so we'll use sa params below + + if (sa.hasParam("CanBlockAny")) { + canBlockNumPumped = Integer.MAX_VALUE; + } else if (sa.hasParam("CanBlockAmount")) { + canBlockNumPumped += AbilityUtils.calculateAmount(pumped, sa.getParam("CanBlockAmount"), sa); + } + int possibleBlockNum = 0; + int possibleBlockNumPumped = 0; + for (Card attacker : ai.getGame().getCombat().getAttackers()) { if (CombatUtil.canBlock(attacker, card)) { possibleBlockNum++; if (possibleBlockNum > canBlockNum) { + possibleBlockNum = canBlockNum; break; } } } - return possibleBlockNum > canBlockNum; + for (Card attacker : ai.getGame().getCombat().getAttackers()) { + if (CombatUtil.canBlock(attacker, pumped)) { + possibleBlockNumPumped++; + if (possibleBlockNumPumped > canBlockNumPumped) { + possibleBlockNumPumped = canBlockNumPumped; + break; + } + } + } + + return possibleBlockNumPumped > possibleBlockNum; } /**