- 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
This commit is contained in:
excessum
2015-03-01 11:08:46 +00:00
parent 74548eca35
commit fed033d430
2 changed files with 51 additions and 5 deletions

View File

@@ -1083,7 +1083,7 @@ public class ComputerUtil {
Iterable<? extends GameObject> objects = new ArrayList<GameObject>();
final List<GameObject> threatened = new ArrayList<GameObject>();
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<String> keywords = saviour.hasParam("KW") ?
Arrays.asList(saviour.getParam("KW").split(" & ")) : new ArrayList<String>();
@@ -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;

View File

@@ -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;
}