From 6bf4c4ad66f805b85724d5124ea7d42ad69de1a1 Mon Sep 17 00:00:00 2001 From: Agetian Date: Thu, 14 Jul 2016 06:09:33 +0000 Subject: [PATCH] - Attempted to fix the "single zone" targeting restriction for cards that require choosing multiple cards via a list input. - For the human player, once the first target is chosen, the other targets are only listed from the same zone (e.g. from the same graveyard), other targets are not listed. - For the AI player, the illegally chosen targets are removed post-selection from the targeting list. This is suboptimal and is only done this way so the AI at least does not cheat. We need an AI expert to expand on this to make the AI choose targets sanely in the first place. --- .../main/java/forge/ai/ability/ChangeZoneAi.java | 15 +++++++++++++++ .../main/java/forge/player/TargetSelection.java | 14 ++++++++++++++ 2 files changed, 29 insertions(+) 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