mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-12 00:38:44 +00:00
Fix AI failing to pay Spree-like charm because it didn't see final cost (#5208)
Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.60>
This commit is contained in:
@@ -791,7 +791,7 @@ public class AiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int oldCMC = -1;
|
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 (!xCost) {
|
||||||
if (!ComputerUtilCost.canPayCost(sa, player, sa.isTrigger())) {
|
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
|
// 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())) {
|
if (tgt.hasKeyword(Keyword.WARD) && tgt.isInPlay() && tgt.getController().isOpponentOf(host.getController())) {
|
||||||
Cost wardCost = ComputerUtilCard.getTotalWardCost(tgt);
|
Cost wardCost = ComputerUtilCard.getTotalWardCost(tgt);
|
||||||
if (wardCost.hasManaCost()) {
|
if (wardCost.hasManaCost()) {
|
||||||
xCost = wardCost.getTotalMana().getCMC() > 0;
|
xCost |= wardCost.getTotalMana().getCMC() > 0;
|
||||||
}
|
}
|
||||||
SpellAbilityAi topAI = new SpellAbilityAi() {};
|
SpellAbilityAi topAI = new SpellAbilityAi() {};
|
||||||
if (!topAI.willPayCosts(player, sa, wardCost, host)) {
|
if (!topAI.willPayCosts(player, sa, wardCost, host)) {
|
||||||
|
|||||||
@@ -966,8 +966,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
* forge.game.player.PlayerController.BinaryChoiceType, java.util.Map)
|
* forge.game.player.PlayerController.BinaryChoiceType, java.util.Map)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseBinary(SpellAbility sa, String question, BinaryChoiceType kindOfChoice,
|
public boolean chooseBinary(SpellAbility sa, String question, BinaryChoiceType kindOfChoice, Map<String, Object> params) {
|
||||||
Map<String, Object> params) {
|
|
||||||
ApiType api = sa.getApi();
|
ApiType api = sa.getApi();
|
||||||
if (null == api) {
|
if (null == api) {
|
||||||
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import forge.ai.SpellAbilityAi;
|
|||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.effects.CharmEffect;
|
import forge.game.ability.effects.CharmEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.keyword.Keyword;
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.AbilitySub;
|
import forge.game.spellability.AbilitySub;
|
||||||
import forge.game.spellability.SpellAbility;
|
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
|
// Reset the chosen list otherwise it will be locked in forever by earlier calls
|
||||||
sa.setChosenList(null);
|
sa.setChosenList(null);
|
||||||
|
sa.setSubAbility(null);
|
||||||
List<AbilitySub> chosenList;
|
List<AbilitySub> chosenList;
|
||||||
|
|
||||||
if (!ai.equals(sa.getActivatingPlayer())) {
|
if (!ai.equals(sa.getActivatingPlayer())) {
|
||||||
@@ -51,7 +51,7 @@ public class CharmAi extends SpellAbilityAi {
|
|||||||
chosenList = chooseTriskaidekaphobia(choices, ai);
|
chosenList = chooseTriskaidekaphobia(choices, ai);
|
||||||
} else {
|
} else {
|
||||||
// only randomize if not all possible together
|
// only randomize if not all possible together
|
||||||
if (num < choices.size() || source.hasKeyword(Keyword.ESCALATE)) {
|
if (num < choices.size()) {
|
||||||
Collections.shuffle(choices);
|
Collections.shuffle(choices);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +80,13 @@ public class CharmAi extends SpellAbilityAi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store the choices so they'll get reused
|
||||||
sa.setChosenList(chosenList);
|
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
|
// prevent run-away activations - first time will always return true
|
||||||
return MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
|
return MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ public class CharmEffect extends SpellAbilityEffect {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void chainAbilities(SpellAbility sa, List<AbilitySub> chosen) {
|
public static void chainAbilities(SpellAbility sa, List<AbilitySub> chosen) {
|
||||||
if (chosen == null) {
|
if (chosen == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user