diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index 658c66fd8ee..f86ed4b3ac7 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -737,6 +737,13 @@ public class AiController { int a1 = a.getPayCosts() == null ? 0 : a.getPayCosts().getTotalMana().getCMC(); int b1 = b.getPayCosts() == null ? 0 : b.getPayCosts().getTotalMana().getCMC(); + // deprioritize SAs explicitly marked as preferred to be activated last compared to all other SAs + if (a.hasParam("AIActivateLast") && !b.hasParam("AIActivateLast")) { + return 1; + } else if (b.hasParam("AIActivateLast") && !a.hasParam("AIActivateLast")) { + return -1; + } + // deprioritize planar die roll marked with AIRollPlanarDieParams:LowPriority$ True if (ApiType.RollPlanarDice == a.getApi() && a.getHostCard() != null && a.getHostCard().hasSVar("AIRollPlanarDieParams") && a.getHostCard().getSVar("AIRollPlanarDieParams").toLowerCase().matches(".*lowpriority\\$\\s*true.*")) { return 1; diff --git a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java index 171d3431506..97eefea9ad8 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java @@ -12,10 +12,7 @@ import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.card.*; import forge.game.combat.CombatUtil; -import forge.game.cost.Cost; -import forge.game.cost.CostPart; -import forge.game.cost.CostRemoveCounter; -import forge.game.cost.CostSacrifice; +import forge.game.cost.*; import forge.game.keyword.Keyword; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; @@ -433,6 +430,18 @@ public class CountersPutAi extends SpellAbilityAi { return false; } + // Activate +Loyalty planeswalker abilities even if they have no target (e.g. Vivien of the Arkbow), + // but try to do it in Main 2 then so that the AI has a chance to play creatures first. + if (list.isEmpty() + && sa.hasParam("Planeswalker") + && sa.getPayCosts() != null + && sa.getPayCosts().hasOnlySpecificCostType(CostPutCounter.class) + && sa.isTargetNumberValid() + && sa.getTargets().getNumTargeted() == 0 + && ai.getGame().getPhaseHandler().is(PhaseType.MAIN2, ai)) { + return true; + } + if (sourceName.equals("Abzan Charm")) { final TargetRestrictions abTgt = sa.getTargetRestrictions(); // specific AI for instant with distribute two +1/+1 counters diff --git a/forge-gui/res/cardsfolder/v/vivien_of_the_arkbow.txt b/forge-gui/res/cardsfolder/v/vivien_of_the_arkbow.txt index 3fb233b6d82..f570d8b3fb8 100644 --- a/forge-gui/res/cardsfolder/v/vivien_of_the_arkbow.txt +++ b/forge-gui/res/cardsfolder/v/vivien_of_the_arkbow.txt @@ -1,7 +1,7 @@ Name:Vivien of the Arkbow ManaCost:4 G G Types:Legendary Planeswalker Vivien -A:AB$ PutCounter | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | CounterNum$ 2 | CounterType$ P1P1 | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature | TgtPrompt$ Select target creature | Planeswalker$ True | SpellDescription$ Put two +1/+1 counters on up to one target creature. +A:AB$ PutCounter | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | CounterNum$ 2 | CounterType$ P1P1 | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature | TgtPrompt$ Select target creature | AIActivateLast$ True | SpellDescription$ Put two +1/+1 counters on up to one target creature. A:AB$ Pump | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | | ValidTgts$ Creature.YouCtrl | AILogic$ PowerDmg | TgtPrompt$ Select target creature you control | SubAbility$ TailDamage | StackDescription$ None | SpellDescription$ Target creature you control deals damage equal to its power to target creature you don't control. SVar:TailDamage:DB$ DealDamage | ValidTgts$ Creature.YouDontCtrl | AILogic$ PowerDmg | TgtPrompt$ Select target creature you don't control | NumDmg$ X | References$ X | ConditionDefined$ Targeted | ConditionPresent$ Creature | ConditionCompare$ EQ1 | DamageSource$ ParentTarget SVar:X:ParentTargeted$CardPower