Add additional AI logic for playing blink effects (try to get own stuff back or trigger ETB effects). (#1664)

This commit is contained in:
rikimbo
2022-10-11 03:01:36 -05:00
committed by GitHub
parent bd72614c0e
commit b5b41186ce
2 changed files with 29 additions and 21 deletions

View File

@@ -1000,6 +1000,35 @@ public class ChangeZoneAi extends SpellAbilityAi {
return true; return true;
} }
// blink logic: get my own permanents back or blink permanents with ETB effects
if (blink) {
CardCollection blinkTargets = CardLists.filter(list, new Predicate<Card>() {
@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 // bounce opponent's stuff
list = CardLists.filterControlledBy(list, ai.getOpponents()); list = CardLists.filterControlledBy(list, ai.getOpponents());
if (!CardLists.getNotType(list, "Land").isEmpty()) { 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<Card>() {
@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)) { } else if (origin.contains(ZoneType.Graveyard)) {

View File

@@ -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:TrigReturn:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Defined$ DelayTriggerRememberedLKI
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Count$Valid Creature.YouCtrl 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. 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.