- More thorough check for X in SA cost parts.

This commit is contained in:
Agetian
2018-12-04 08:12:06 +03:00
parent f0f9e26ed1
commit 02d1b28124
2 changed files with 22 additions and 9 deletions

View File

@@ -670,10 +670,9 @@ public class AiController {
// This is for playing spells regularly (no Cascade/Ripple etc.) // This is for playing spells regularly (no Cascade/Ripple etc.)
private AiPlayDecision canPlayAndPayFor(final SpellAbility sa) { private AiPlayDecision canPlayAndPayFor(final SpellAbility sa) {
boolean XCost = sa.getPayCosts() != null && sa.getPayCosts().getCostMana() != null boolean xCost = ComputerUtilMana.hasXInAnyCostPart(sa);
&& sa.getPayCosts().getCostMana().getAmountOfX() > 0;
if (!XCost && !ComputerUtilCost.canPayCost(sa, player)) { if (!xCost && !ComputerUtilCost.canPayCost(sa, player)) {
// for most costs, it's OK to check if they can be paid early in order to avoid running a heavy API check // for most costs, it's OK to check if they can be paid early in order to avoid running a heavy API check
// when the AI won't even be able to play the spell in the first place (even if it could afford it) // when the AI won't even be able to play the spell in the first place (even if it could afford it)
return AiPlayDecision.CantAfford; return AiPlayDecision.CantAfford;
@@ -688,7 +687,7 @@ public class AiController {
return canPlay; return canPlay;
} }
if (XCost && !ComputerUtilCost.canPayCost(sa, player)) { if (xCost && !ComputerUtilCost.canPayCost(sa, player)) {
// for dependent costs with X, e.g. Repeal, which require a valid target to be specified before a decision can be made // for dependent costs with X, e.g. Repeal, which require a valid target to be specified before a decision can be made
// on whether the cost can be paid, this can only be checked late after canPlaySa has been run (or the AI will misplay) // on whether the cost can be paid, this can only be checked late after canPlaySa has been run (or the AI will misplay)
return AiPlayDecision.CantAfford; return AiPlayDecision.CantAfford;

View File

@@ -16,11 +16,7 @@ import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType; import forge.game.ability.ApiType;
import forge.game.card.*; import forge.game.card.*;
import forge.game.combat.CombatUtil; import forge.game.combat.CombatUtil;
import forge.game.cost.Cost; import forge.game.cost.*;
import forge.game.cost.CostAdjustment;
import forge.game.cost.CostPartMana;
import forge.game.cost.CostPayEnergy;
import forge.game.cost.CostPayment;
import forge.game.mana.Mana; import forge.game.mana.Mana;
import forge.game.mana.ManaCostBeingPaid; import forge.game.mana.ManaCostBeingPaid;
import forge.game.mana.ManaPool; import forge.game.mana.ManaPool;
@@ -1560,6 +1556,24 @@ public class ComputerUtilMana {
return convoke; return convoke;
} }
public static boolean hasXInAnyCostPart(SpellAbility sa) {
boolean xCost = false;
if (sa.getPayCosts() != null) {
for (CostPart p : sa.getPayCosts().getCostParts()) {
if (p instanceof CostPartMana) {
if (((CostPartMana) p).getAmountOfX() > 0) {
xCost = true;
break;
}
} else if (p.getAmount().equals("X")) {
xCost = true;
break;
}
}
}
return xCost;
}
public static int determineMaxAffordableX(Player ai, SpellAbility sa) { public static int determineMaxAffordableX(Player ai, SpellAbility sa) {
if (sa.getPayCosts() == null || sa.getPayCosts().getCostMana() == null) { if (sa.getPayCosts() == null || sa.getPayCosts().getCostMana() == null) {
return -1; return -1;