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 f69de11875e..48948a0b672 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java @@ -1035,6 +1035,21 @@ public class ChangeZoneAi extends SpellAbilityAi { sa.getTargets().add(choice); } + // Honor the Single Zone restriction. For now, simply remove targets that do not belong to the same zone as the first targeted card. + // TODO: ideally the AI should consider at this point which targets exactly to pick (e.g. one card in the first player's graveyard + // vs. two cards in the second player's graveyard, which cards are more relevant to be targeted, etc.). Consider improving. + if (sa.getTargetRestrictions().isSingleZone()) { + List removalCandidates = new ArrayList<>(); + Card firstTgt = sa.getTargets().getFirstTargetedCard(); + if (firstTgt != null) { + for (Card t : sa.getTargets().getTargetCards()) { + if (!t.getController().equals(firstTgt.getController())) { + sa.getTargets().remove(t); + } + } + } + } + return true; } diff --git a/forge-gui/src/main/java/forge/player/TargetSelection.java b/forge-gui/src/main/java/forge/player/TargetSelection.java index f62a3c7926f..e978fd1cfda 100644 --- a/forge-gui/src/main/java/forge/player/TargetSelection.java +++ b/forge-gui/src/main/java/forge/player/TargetSelection.java @@ -73,6 +73,7 @@ public class TargetSelection { final int maxTargets = numTargets != null ? numTargets.intValue() : tgt.getMaxTargets(ability.getHostCard(), ability); //final int maxTotalCMC = tgt.getMaxTotalCMC(ability.getHostCard(), ability); final int numTargeted = ability.getTargets().getNumTargeted(); + final boolean isSingleZone = ability.getTargetRestrictions().isSingleZone(); final boolean hasEnoughTargets = minTargets == 0 || numTargeted >= minTargets; final boolean hasAllTargets = numTargeted == maxTargets && maxTargets > 0; @@ -114,6 +115,19 @@ public class TargetSelection { } else { final List validTargets = CardUtil.getValidCardsToTarget(tgt, ability); + // single zone + if (isSingleZone) { + final List removeCandidates = new ArrayList<>(); + final Card firstTgt = ability.getTargets().getFirstTargetedCard(); + if (firstTgt != null) { + for (Card t : validTargets) { + if (!t.getController().equals(firstTgt.getController())) { + removeCandidates.add(t); + } + } + validTargets.removeAll(removeCandidates); + } + } if (validTargets.isEmpty()) { //if no valid cards to target and only one valid non-card, auto-target the non-card //this handles "target opponent" cards, along with any other cards that can only target a single non-card game entity