From fed033d4301e177b819fd676e7c96202afc41f99 Mon Sep 17 00:00:00 2001 From: excessum Date: Sun, 1 Mar 2015 11:08:46 +0000 Subject: [PATCH] - Basic implementation of canPumpAgainstRemoval for CountersPutAi (eg. Abzan Charm, High Sentinels of Arashin) - Restricted use of non-sorcery speed CountersPut abilities to opponent's EOT --- .../src/main/java/forge/ai/ComputerUtil.java | 34 ++++++++++++++++--- .../java/forge/ai/ability/CountersPutAi.java | 22 ++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index 519a82d8738..c7e44958b28 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -1083,7 +1083,7 @@ public class ComputerUtil { Iterable objects = new ArrayList(); final List threatened = new ArrayList(); ApiType saviourApi = saviour == null ? null : saviour.getApi(); - int defense = 0; + int toughness = 0; boolean grantIndestructible = false; boolean grantShroud = false; @@ -1127,7 +1127,7 @@ public class ComputerUtil { } if (saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll) { - defense = saviour.hasParam("NumDef") ? + toughness = saviour.hasParam("NumDef") ? AbilityUtils.calculateAmount(saviour.getHostCard(), saviour.getParam("NumDef"), saviour) : 0; final List keywords = saviour.hasParam("KW") ? Arrays.asList(saviour.getParam("KW").split(" & ")) : new ArrayList(); @@ -1138,6 +1138,14 @@ public class ComputerUtil { grantShroud = true; } } + + if (saviourApi == ApiType.PutCounter || saviourApi == ApiType.PutCounterAll) { + if (saviour.getParam("CounterType").equals("P1P1")) { + toughness = AbilityUtils.calculateAmount(saviour.getHostCard(), saviour.getParam("CounterNum"), saviour); + } else { + return threatened; + } + } // Determine if Defined Objects are "threatened" will be destroyed // due to this SA @@ -1179,13 +1187,20 @@ public class ComputerUtil { } if (saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll) { - boolean canSave = ComputerUtilCombat.predictDamageTo(c, dmg - defense, source, false) < ComputerUtilCombat.getDamageToKill(c); + boolean canSave = ComputerUtilCombat.predictDamageTo(c, dmg - toughness, source, false) < ComputerUtilCombat.getDamageToKill(c); if ((tgt == null && !grantIndestructible && !canSave) || (!grantIndestructible && !grantShroud && !canSave)) { continue; } } + if (saviourApi == ApiType.PutCounter || saviourApi == ApiType.PutCounterAll) { + boolean canSave = ComputerUtilCombat.predictDamageTo(c, dmg - toughness, source, false) < ComputerUtilCombat.getDamageToKill(c); + if (!canSave) { + continue; + } + } + // cannot protect against source if (saviourApi == ApiType.Protection && (ProtectAi.toProtectFrom(source, saviour) == null)) { continue; @@ -1227,14 +1242,23 @@ public class ComputerUtil { if (!canRemove) { continue; } + if (saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll) { - final boolean cantSave = c.getNetToughness() + defense <= dmg + final boolean cantSave = c.getNetToughness() + toughness <= dmg || (!c.hasKeyword("Indestructible") && c.getShieldCount() == 0 && !grantIndestructible - && (dmg >= defense + ComputerUtilCombat.getDamageToKill(c))); + && (dmg >= toughness + ComputerUtilCombat.getDamageToKill(c))); if (cantSave && (tgt == null || !grantShroud)) { continue; } } + + if (saviourApi == ApiType.PutCounter || saviourApi == ApiType.PutCounterAll) { + boolean canSave = c.getNetToughness() + toughness > dmg; + if (!canSave) { + continue; + } + } + if (saviourApi == ApiType.Protection) { if (tgt == null || (ProtectAi.toProtectFrom(source, saviour) == null)) { continue; diff --git a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java index 36fd2b32d48..305669ca896 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java @@ -204,6 +204,23 @@ public class CountersPutAi extends SpellAbilityAi { return false; } } + + if (!ai.getGame().getStack().isEmpty() && !SpellAbilityAi.isSorcerySpeed(sa)) { + // only evaluates case where all tokens are placed on a single target + if (abTgt.getMinTargets(sa.getHostCard(), sa) < 2) { + if (ComputerUtilCard.canPumpAgainstRemoval(ai, sa)) { + Card c = sa.getTargets().getFirstTargetedCard(); + if (sa.getTargets().getNumTargeted() > 1) { + sa.resetTargets(); + sa.getTargets().add(c); + } + abTgt.addDividedAllocation(sa.getTargetCard(), amount); + return true; + } else { + return false; + } + } + } // Targeting if (abTgt != null) { @@ -339,6 +356,11 @@ public class CountersPutAi extends SpellAbilityAi { return false; } + if (type.equals("P1P1") && !SpellAbilityAi.isSorcerySpeed(sa) && !ph.is(PhaseType.END_OF_TURN, ai.getOpponent()) && abCost != null) { + sa.resetTargets(); + return false; + } + return true; }