diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index f5a7ff663af..b8d7cc6e80c 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -791,7 +791,7 @@ public class AiController { } int oldCMC = -1; - boolean xCost = sa.costHasX() || host.hasKeyword(Keyword.STRIVE); + boolean xCost = sa.costHasX() || host.hasKeyword(Keyword.STRIVE) || sa.getApi() == ApiType.Charm; if (!xCost) { if (!ComputerUtilCost.canPayCost(sa, player, sa.isTrigger())) { // for most costs, it's OK to check if they can be paid early in order to avoid running a heavy API check @@ -820,7 +820,7 @@ public class AiController { if (tgt.hasKeyword(Keyword.WARD) && tgt.isInPlay() && tgt.getController().isOpponentOf(host.getController())) { Cost wardCost = ComputerUtilCard.getTotalWardCost(tgt); if (wardCost.hasManaCost()) { - xCost = wardCost.getTotalMana().getCMC() > 0; + xCost |= wardCost.getTotalMana().getCMC() > 0; } SpellAbilityAi topAI = new SpellAbilityAi() {}; if (!topAI.willPayCosts(player, sa, wardCost, host)) { diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index 723669d51de..5eeefb0243b 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -966,8 +966,7 @@ public class PlayerControllerAi extends PlayerController { * forge.game.player.PlayerController.BinaryChoiceType, java.util.Map) */ @Override - public boolean chooseBinary(SpellAbility sa, String question, BinaryChoiceType kindOfChoice, - Map params) { + public boolean chooseBinary(SpellAbility sa, String question, BinaryChoiceType kindOfChoice, Map params) { ApiType api = sa.getApi(); if (null == api) { throw new InvalidParameterException("SA is not api-based, this is not supported yet"); diff --git a/forge-ai/src/main/java/forge/ai/ability/CharmAi.java b/forge-ai/src/main/java/forge/ai/ability/CharmAi.java index 7a642b7a831..90057c6b3be 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CharmAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CharmAi.java @@ -14,7 +14,6 @@ import forge.ai.SpellAbilityAi; import forge.game.ability.AbilityUtils; import forge.game.ability.effects.CharmEffect; import forge.game.card.Card; -import forge.game.keyword.Keyword; import forge.game.player.Player; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; @@ -41,6 +40,7 @@ public class CharmAi extends SpellAbilityAi { // Reset the chosen list otherwise it will be locked in forever by earlier calls sa.setChosenList(null); + sa.setSubAbility(null); List chosenList; if (!ai.equals(sa.getActivatingPlayer())) { @@ -51,7 +51,7 @@ public class CharmAi extends SpellAbilityAi { chosenList = chooseTriskaidekaphobia(choices, ai); } else { // only randomize if not all possible together - if (num < choices.size() || source.hasKeyword(Keyword.ESCALATE)) { + if (num < choices.size()) { Collections.shuffle(choices); } @@ -80,7 +80,13 @@ public class CharmAi extends SpellAbilityAi { return false; } } + + // store the choices so they'll get reused sa.setChosenList(chosenList); + if (sa.isSpell()) { + // prebuild chain to improve cost calculation accuracy + CharmEffect.chainAbilities(sa, chosenList); + } // prevent run-away activations - first time will always return true return MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); diff --git a/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java index 6a9798bbee3..2ec60ba0491 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java @@ -249,7 +249,7 @@ public class CharmEffect extends SpellAbilityEffect { return true; } - private static void chainAbilities(SpellAbility sa, List chosen) { + public static void chainAbilities(SpellAbility sa, List chosen) { if (chosen == null) { return; }