Merge branch 'master' into 'ward'

# Conflicts:
#   forge-ai/src/main/java/forge/ai/AiController.java
#   forge-ai/src/main/java/forge/ai/ComputerUtilCost.java
This commit is contained in:
Michael Kamensky
2021-10-31 10:25:32 +00:00
3 changed files with 34 additions and 3 deletions

View File

@@ -747,8 +747,22 @@ public class AiController {
if (sa.usesTargeting()) {
for (Card tgt : sa.getTargets().getTargetCards()) {
if (tgt.hasKeyword(Keyword.WARD) && tgt.getController().isOpponentOf(sa.getHostCard().getController())) {
int amount = tgt.getKeywordMagnitude(Keyword.WARD);
if (amount > 0 && !ComputerUtilCost.canPayCost(sa, player)) {
int amount = 0;
Cost wardCost = ComputerUtilCard.getTotalWardCost(tgt);
if (wardCost.hasManaCost()) {
amount = wardCost.getTotalMana().getCMC();
if (amount > 0 && !ComputerUtilCost.canPayCost(sa, player)) {
return AiPlayDecision.CantAfford;
}
}
if (wardCost.hasSpecificCostType(CostPayLife.class)) {
int lifeToPay = wardCost.getCostPartByType(CostPayLife.class).convertAmount();
if (lifeToPay > player.getLife() || (lifeToPay == player.getLife() && !player.cantLoseForZeroOrLessLife())) {
return AiPlayDecision.CantAfford;
}
}
if (wardCost.hasSpecificCostType(CostDiscard.class)
&& wardCost.getCostPartByType(CostDiscard.class).convertAmount() > player.getCardsIn(ZoneType.Hand).size()) {
return AiPlayDecision.CantAfford;
}
}

View File

@@ -11,6 +11,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import forge.card.mana.ManaCost;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.apache.commons.lang3.tuple.Pair;
@@ -1971,6 +1972,19 @@ public class ComputerUtilCard {
return AiPlayDecision.WillPlay;
}
public static Cost getTotalWardCost(Card c) {
Cost totalCost = new Cost(ManaCost.NO_COST, false);
for (final KeywordInterface inst : c.getKeywords()) {
if (inst.getKeyword() == Keyword.WARD) {
final String keyword = inst.getOriginal();
final String[] k = keyword.split(":");
final Cost wardCost = new Cost(k[1], false);
totalCost = totalCost.add(wardCost);
}
}
return totalCost;
}
// Determine if the AI has an AI:RemoveDeck:All or an AI:RemoveDeck:Random hint specified.
// Includes a NPE guard on getRules() which might otherwise be tripped on some cards (e.g. tokens).
public static boolean isCardRemAIDeck(final Card card) {

View File

@@ -593,7 +593,10 @@ public class ComputerUtilCost {
if (sa.usesTargeting()) {
for (Card tgt : sa.getTargets().getTargetCards()) {
if (tgt.hasKeyword(Keyword.WARD) && tgt.getController().isOpponentOf(sa.getHostCard().getController())) {
extraManaNeeded += tgt.getKeywordMagnitude(Keyword.WARD);
Cost wardCost = ComputerUtilCard.getTotalWardCost(tgt);
if (wardCost.hasManaCost()) {
extraManaNeeded += wardCost.getTotalMana().getCMC();
}
}
}
}