From b5b41186cebf5a94f88614b1f3fe6aff8b35255b Mon Sep 17 00:00:00 2001 From: rikimbo Date: Tue, 11 Oct 2022 03:01:36 -0500 Subject: [PATCH] Add additional AI logic for playing blink effects (try to get own stuff back or trigger ETB effects). (#1664) --- .../java/forge/ai/ability/ChangeZoneAi.java | 49 +++++++++++-------- .../res/cardsfolder/e/eerie_interlude.txt | 1 - 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java index 7870795e185..07102b4afed 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java @@ -1000,6 +1000,35 @@ public class ChangeZoneAi extends SpellAbilityAi { return true; } + // blink logic: get my own permanents back or blink permanents with ETB effects + if (blink) { + CardCollection blinkTargets = CardLists.filter(list, new Predicate() { + @Override + public boolean apply(final Card c) { + return !c.isToken() && c.getOwner().equals(ai) && (c.getController().isOpponentOf(ai) || c.hasETBTrigger(false)); + } + }); + if (!blinkTargets.isEmpty()) { + CardCollection opponentBlinkTargets = CardLists.filterControlledBy(blinkTargets, ai.getOpponents()); + // prefer post-combat unless targeting opponent's stuff or part of another ability + if (immediately || sa.getParent() != null || sa.isTrigger() || !opponentBlinkTargets.isEmpty() || !game.getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)) { + while (!blinkTargets.isEmpty() && sa.canAddMoreTarget()) { + Card choice = null; + // first prefer targeting opponents stuff + if (!opponentBlinkTargets.isEmpty()) { + choice = ComputerUtilCard.getBestAI(opponentBlinkTargets); + opponentBlinkTargets.remove(choice); + } + else { + choice = ComputerUtilCard.getBestAI(blinkTargets); + } + sa.getTargets().add(choice); + blinkTargets.remove(choice); + } + return true; + } + } + } // bounce opponent's stuff list = CardLists.filterControlledBy(list, ai.getOpponents()); if (!CardLists.getNotType(list, "Land").isEmpty()) { @@ -1017,26 +1046,6 @@ public class ChangeZoneAi extends SpellAbilityAi { } }); } - // TODO: Blink permanents with ETB triggers - /*else if (!sa.isTrigger() && SpellAbilityAi.playReusable(ai, sa)) { - aiPermanents = CardLists.filter(aiPermanents, new Predicate() { - @Override - public boolean apply(final Card c) { - if (c.hasCounters()) { - return false; // don't blink something with - } - // counters TODO check good and - // bad counters - // checks only if there is a dangerous ETB effect - return !c.equals(sa.getHostCard()) && SpellPermanent.checkETBEffects(c, ai); - } - }); - if (!aiPermanents.isEmpty()) { - // Choose "best" of the remaining to save - sa.getTargets().add(ComputerUtilCard.getBestAI(aiPermanents)); - return true; - } - }*/ } } else if (origin.contains(ZoneType.Graveyard)) { diff --git a/forge-gui/res/cardsfolder/e/eerie_interlude.txt b/forge-gui/res/cardsfolder/e/eerie_interlude.txt index 0f1b5068441..ba6360cd1bb 100644 --- a/forge-gui/res/cardsfolder/e/eerie_interlude.txt +++ b/forge-gui/res/cardsfolder/e/eerie_interlude.txt @@ -6,5 +6,4 @@ SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ Tr SVar:TrigReturn:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Defined$ DelayTriggerRememberedLKI SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Count$Valid Creature.YouCtrl -AI:RemoveDeck:All Oracle:Exile any number of target creatures you control. Return those cards to the battlefield under their owner's control at the beginning of the next end step.