diff --git a/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java b/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java index 50216fc3f4c..a49de701014 100644 --- a/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java +++ b/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java @@ -182,13 +182,12 @@ public abstract class SpellAbilityAi { return doTriggerNoCostWithSubs(aiPlayer, sa, mandatory); } - public final boolean doTriggerNoCostWithSubs(final Player aiPlayer, final SpellAbility sa, final boolean mandatory) - { + public final boolean doTriggerNoCostWithSubs(final Player aiPlayer, final SpellAbility sa, final boolean mandatory) { if (!doTriggerAINoCost(aiPlayer, sa, mandatory) && !"Always".equals(sa.getParam("AILogic"))) { return false; } final AbilitySub subAb = sa.getSubAbility(); - return subAb == null || chkDrawbackWithSubs(aiPlayer, subAb) || mandatory; + return subAb == null || chkDrawbackWithSubs(aiPlayer, subAb) || mandatory; } /** diff --git a/forge-ai/src/main/java/forge/ai/ability/AttachAi.java b/forge-ai/src/main/java/forge/ai/ability/AttachAi.java index de8ec15c3f3..bb444e4fd66 100644 --- a/forge-ai/src/main/java/forge/ai/ability/AttachAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/AttachAi.java @@ -979,7 +979,7 @@ public class AttachAi extends SpellAbilityAi { if (tgt == null) { targets = AbilityUtils.getDefinedObjects(card, sa.getParam("Defined"), sa); } else { - AttachAi.attachPreference(sa, tgt, mandatory); + attachPreference(sa, tgt, mandatory); targets = sa.getTargets(); } @@ -1362,7 +1362,6 @@ public class AttachAi extends SpellAbilityAi { list = AbilityUtils.getDefinedCards(attachSource, sa.getParam("Defined"), sa); } else { list = CardLists.getValidCards(aiPlayer.getGame().getCardsIn(tgt.getZone()), tgt.getValidTgts(), sa.getActivatingPlayer(), attachSource, sa); - list = CardLists.filter(list, CardPredicates.canBeAttached(attachSource)); // TODO If Attaching without casting, don't need to actually target. @@ -1734,6 +1733,22 @@ public class AttachAi extends SpellAbilityAi { return chosen; } + @Override + public boolean chkAIDrawback(final SpellAbility sa, final Player ai) { + // TODO for targeting optional Halvar trigger, needs to be coordinated with PumpAi to make it playable + if (sa.isTrigger() && sa.usesTargeting()) { + CardCollection targetables = CardLists.getTargetableCards(ai.getCardsIn(ZoneType.Battlefield), sa); + CardCollection source = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Object"), sa); + Card tgt = attachGeneralAI(ai, sa, targetables, true, source.getFirst(), null); + if (tgt != null) { + sa.resetTargets(); + sa.getTargets().add(tgt); + } + return sa.isTargetNumberValid(); + } + return false; + } + @Override public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) { return true; diff --git a/forge-ai/src/main/java/forge/ai/ability/TokenAi.java b/forge-ai/src/main/java/forge/ai/ability/TokenAi.java index afabd4aa4ba..35398c0bf32 100644 --- a/forge-ai/src/main/java/forge/ai/ability/TokenAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/TokenAi.java @@ -222,11 +222,11 @@ public class TokenAi extends SpellAbilityAi { private boolean canInterruptSacrifice(final Player ai, final SpellAbility sa, final Card token, final String tokenAmount) { final Game game = ai.getGame(); if (game.getStack().isEmpty()) { - return false; // nothing to interrupt + return false; // nothing to interrupt } final SpellAbility topStack = game.getStack().peekAbility(); if (topStack.getApi() != ApiType.Sacrifice) { - return false; // not sacrifice effect + return false; // not sacrifice effect } final int nTokens = AbilityUtils.calculateAmount(sa.getHostCard(), tokenAmount, sa); final String valid = topStack.getParamOrDefault("SacValid", "Card.Self");