diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index ebfd378dfce..96ec1f25169 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -20,6 +20,7 @@ package forge.ai; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.*; +import forge.ai.ability.ChooseGenericEffectAi; import forge.ai.ability.ProtectAi; import forge.ai.ability.TokenAi; import forge.card.CardType; @@ -986,6 +987,11 @@ public class ComputerUtil { return true; } + if (card.hasKeyword(Keyword.RIOT) && ChooseGenericEffectAi.preferHasteForRiot(sa, ai)) { + // Planning to choose Haste for Riot, so do this in Main 1 + return true; + } + // if we have non-persistent mana in our pool, would be good to try to use it and not waste it if (ai.getManaPool().willManaBeLostAtEndOfPhase()) { boolean canUseToPayCost = false; diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index 481cab38688..e2393972f59 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -1455,7 +1455,7 @@ public class ComputerUtilCombat { continue; } - if (ability.hasParam("Adapt") && blocker.getCounters(CounterType.P1P1) > 0) { + if (ability.hasParam("Adapt") && blocker != null && blocker.getCounters(CounterType.P1P1) > 0) { continue; } diff --git a/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java b/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java index da6ea137f92..39541df0f28 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java @@ -350,48 +350,54 @@ public class ChooseGenericEffectAi extends SpellAbilityAi { } } else if ("Riot".equals(logic)) { SpellAbility counterSA = spells.get(0), hasteSA = spells.get(1); - - final Card copy = CardUtil.getLKICopy(host); - copy.setLastKnownZone(player.getZone(ZoneType.Battlefield)); - - // check state it would have on the battlefield - CardCollection preList = new CardCollection(copy); - game.getAction().checkStaticAbilities(false, Sets.newHashSet(copy), preList); - // reset again? - game.getAction().checkStaticAbilities(false); - - // can't gain counters, use Haste - if (!copy.canReceiveCounters(CounterType.P1P1)) { - return hasteSA; - } - - // already has Haste, use counter - if (copy.hasKeyword(Keyword.HASTE)) { - return counterSA; - } - - // not AI turn - if (!game.getPhaseHandler().isPlayerTurn(player)) { - return counterSA; - } - - // not before Combat - if (!game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) { - return counterSA; - } - - // TODO check other opponents too if able - final Player opp = player.getWeakestOpponent(); - if (opp != null) { - // TODO add predict Combat Damage? - if (opp.getLife() < copy.getNetPower()) { - return hasteSA; - } - } - - // haste might not be good enough? - return counterSA; + return preferHasteForRiot(sa, player) ? hasteSA : counterSA; } return spells.get(0); // return first choice if no logic found } -} \ No newline at end of file + + public static boolean preferHasteForRiot(SpellAbility sa, Player player) { + // returning true means preferring Haste, returning false means preferring a +1/+1 counter + final Card host = sa.getHostCard(); + final Game game = host.getGame(); + final Card copy = CardUtil.getLKICopy(host); + copy.setLastKnownZone(player.getZone(ZoneType.Battlefield)); + + // check state it would have on the battlefield + CardCollection preList = new CardCollection(copy); + game.getAction().checkStaticAbilities(false, Sets.newHashSet(copy), preList); + // reset again? + game.getAction().checkStaticAbilities(false); + + // can't gain counters, use Haste + if (!copy.canReceiveCounters(CounterType.P1P1)) { + return true; + } + + // already has Haste, use counter + if (copy.hasKeyword(Keyword.HASTE)) { + return false; + } + + // not AI turn + if (!game.getPhaseHandler().isPlayerTurn(player)) { + return false; + } + + // not before Combat + if (!game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) { + return false; + } + + // TODO check other opponents too if able + final Player opp = player.getWeakestOpponent(); + if (opp != null) { + // TODO add predict Combat Damage? + if (opp.getLife() < copy.getNetPower()) { + return true; + } + } + + // haste might not be good enough? + return false; + } +}