diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index 4b573cfe5c6..3d81de32e70 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -226,7 +226,7 @@ public class AiController { } // if trigger is not mandatory - no problem - if (params.get("OptionalDecider") != null) { + if (params.get("OptionalDecider") != null && api == null) { continue; } @@ -243,6 +243,11 @@ public class AiController { } else { rightapi = true; } + if (!(exSA instanceof AbilitySub)) { + if (!ComputerUtilCost.canPayCost(exSA, player)) { + return false; + } + } } if (sa != null) { @@ -255,7 +260,7 @@ public class AiController { // Run non-mandatory trigger. // These checks only work if the Executing SpellAbility is an Ability_Sub. - if ((exSA instanceof AbilitySub) && !doTrigger(exSA, false)) { + if (exSA instanceof AbilitySub && !doTrigger(exSA, false)) { // AI would not run this trigger if given the chance return false; } @@ -691,6 +696,7 @@ public class AiController { && (game.getPhaseHandler().isPlayerTurn(player) || game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) && (!card.hasETBTrigger(true) || card.hasSVar("AmbushAI")) + && game.getStack().isEmpty() && !ComputerUtil.castPermanentInMain1(player, sa)) { return AiPlayDecision.AnotherTime; } diff --git a/forge-ai/src/main/java/forge/ai/ability/CounterAi.java b/forge-ai/src/main/java/forge/ai/ability/CounterAi.java index bde063c0dd9..bba32fbc87c 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CounterAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CounterAi.java @@ -1,5 +1,7 @@ package forge.ai.ability; +import java.util.Iterator; + import forge.ai.ComputerUtilCost; import forge.ai.ComputerUtilMana; import forge.ai.SpellAbilityAi; @@ -10,6 +12,7 @@ import forge.game.card.CardFactoryUtil; import forge.game.cost.Cost; import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.spellability.SpellAbilityStackInstance; import forge.game.spellability.TargetRestrictions; import forge.util.MyRandom; @@ -119,7 +122,24 @@ public class CounterAi extends SpellAbilityAi { if (game.getStack().isEmpty()) { return false; } - final SpellAbility topSA = game.getStack().peekAbility(); + + SpellAbility topSA = game.getStack().peekAbility(); + + // triggered abilities see themselves on the stack, so find another spell on the stack + if (sa.isTrigger() && topSA.isTrigger() && game.getStack().size() > 1) { + Iterator it = game.getStack().iterator(); + SpellAbilityStackInstance si = game.getStack().peek(); + while (it.hasNext()) { + si = it.next(); + if (si.isTrigger()) { + it.remove(); + } else { + break; + } + } + topSA = si.getSpellAbility(true); + } + if (!CardFactoryUtil.isCounterableBy(topSA.getHostCard(), sa) || topSA.getActivatingPlayer() == ai) { return false; } @@ -170,7 +190,6 @@ public class CounterAi extends SpellAbilityAi { // force the Human into making decisions) // But really it should be more picky about how it counters things - return true; } diff --git a/forge-ai/src/main/java/forge/ai/ability/PermanentCreatureAi.java b/forge-ai/src/main/java/forge/ai/ability/PermanentCreatureAi.java index 0ac5e6a890d..2268b6e102f 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PermanentCreatureAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PermanentCreatureAi.java @@ -79,7 +79,7 @@ public class PermanentCreatureAi extends SpellAbilityAi { } // Wait for Main2 if possible - if (ph.is(PhaseType.MAIN1) + if (ph.is(PhaseType.MAIN1) && ph.isPlayerTurn(aiPlayer) && !ComputerUtil.castPermanentInMain1(aiPlayer, sa)) { return false; } diff --git a/forge-ai/src/main/java/forge/ai/ability/PermanentNoncreatureAi.java b/forge-ai/src/main/java/forge/ai/ability/PermanentNoncreatureAi.java index 6c8534e8ce8..1fb9ed76ac9 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PermanentNoncreatureAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PermanentNoncreatureAi.java @@ -2,6 +2,8 @@ package forge.ai.ability; import forge.ai.ComputerUtil; import forge.ai.SpellAbilityAi; +import forge.game.Game; +import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.spellability.SpellAbility; @@ -18,13 +20,15 @@ public class PermanentNoncreatureAi extends SpellAbilityAi { @Override protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { String logic = sa.getParam("AILogic"); + Game game = aiPlayer.getGame(); + final PhaseHandler ph = game.getPhaseHandler(); if ("DontCast".equals(logic)) { return false; } // Wait for Main2 if possible - if (aiPlayer.getGame().getPhaseHandler().is(PhaseType.MAIN1) + if (ph.is(PhaseType.MAIN1) && ph.isPlayerTurn(aiPlayer) && !ComputerUtil.castPermanentInMain1(aiPlayer, sa)) { return false; }