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 07102b4afed..c02636e2df3 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java @@ -1275,17 +1275,15 @@ public class ChangeZoneAi extends SpellAbilityAi { // 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()) { - Card firstTgt = sa.getTargets().getFirstTargetedCard(); + Card firstTgt = sa.getTargetCard(); CardCollection toRemove = new CardCollection(); if (firstTgt != null) { for (Card t : sa.getTargets().getTargetCards()) { - if (!t.getController().equals(firstTgt.getController())) { - toRemove.add(t); - } - } - for (Card dontTarget : toRemove) { - sa.getTargets().remove(dontTarget); + if (!t.getController().equals(firstTgt.getController())) { + toRemove.add(t); + } } + sa.getTargets().removeAll(toRemove); } } diff --git a/forge-ai/src/main/java/forge/ai/ability/CloneAi.java b/forge-ai/src/main/java/forge/ai/ability/CloneAi.java index 9928a485383..e181d18a202 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CloneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CloneAi.java @@ -158,7 +158,7 @@ public class CloneAi extends SpellAbilityAi { if (sa.hasParam("AILogic") && (!sa.usesTargeting() || sa.isTargetNumberValid())) { // Had a special logic for it and managed to target, so confirm if viable if ("CloneBestCreature".equals(sa.getParam("AILogic"))) { - return ComputerUtilCard.evaluateCreature(sa.getTargets().getFirstTargetedCard()) > ComputerUtilCard.evaluateCreature(sa.getHostCard()); + return ComputerUtilCard.evaluateCreature(sa.getTargetCard()) > ComputerUtilCard.evaluateCreature(sa.getHostCard()); } else if ("IfDefinedCreatureIsBetter".equals(sa.getParam("AILogic"))) { List defined = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa); Card bestDefined = ComputerUtilCard.getBestCreatureAI(defined); @@ -229,7 +229,7 @@ public class CloneAi extends SpellAbilityAi { tgtCard = cloneTargets.get(0); } } else if (sa.hasParam("Choices") && sa.usesTargeting()) { - tgtCard = sa.getTargets().getFirstTargetedCard(); + tgtCard = sa.getTargetCard(); } return tgtCard; 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 5e68ec6c13b..c30cba8b3eb 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java @@ -460,12 +460,12 @@ public class CountersPutAi extends CountersAi { // only evaluates case where all tokens are placed on a single target if (sa.usesTargeting() && sa.getMinTargets() < 2) { if (ComputerUtilCard.canPumpAgainstRemoval(ai, sa)) { - Card c = sa.getTargets().getFirstTargetedCard(); + Card c = sa.getTargetCard(); if (sa.getTargets().size() > 1) { sa.resetTargets(); sa.getTargets().add(c); } - sa.addDividedAllocation(sa.getTargetCard(), amount); + sa.addDividedAllocation(c, amount); return true; } else { return false; diff --git a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java index cdeeeda85cf..9d53f7713d9 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java @@ -210,7 +210,7 @@ public class DamageDealAi extends DamageAiBase { if (ai.getGame().getPhaseHandler().is(PhaseType.END_OF_TURN)) { boolean doTarget = damageTargetAI(ai, sa, dmg, true); if (doTarget) { - Card tgt = sa.getTargets().getFirstTargetedCard(); + Card tgt = sa.getTargetCard(); if (tgt != null) { return ai.getGame().getPhaseHandler().getPlayerTurn() == tgt.getController(); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java index fffc8ca0680..4312f9c15f7 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java @@ -40,7 +40,7 @@ public class CloneEffect extends SpellAbilityEffect { cardToCopy = cloneSources.get(0); } } else if (sa.usesTargeting()) { - cardToCopy = sa.getTargets().getFirstTargetedCard(); + cardToCopy = sa.getTargetCard(); } List cloneTargets = AbilityUtils.getDefinedCards(host, sa.getParam("CloneTarget"), sa); @@ -98,7 +98,7 @@ public class CloneEffect extends SpellAbilityEffect { cardToCopy = cloneSources.get(0); } } else if (sa.usesTargeting()) { - cardToCopy = sa.getTargets().getFirstTargetedCard(); + cardToCopy = sa.getTargetCard(); } else if (sa.hasParam("CopyFromChosenName")) { String name = host.getChosenName(); cardToCopy = Card.fromPaperCard(StaticData.instance().getCommonCards().getUniqueByName(name), activator); @@ -122,7 +122,7 @@ public class CloneEffect extends SpellAbilityEffect { return; } } else if (sa.hasParam("Choices") && sa.usesTargeting()) { - tgtCard = sa.getTargets().getFirstTargetedCard(); + tgtCard = sa.getTargetCard(); game.getTriggerHandler().clearActiveTriggers(tgtCard, null); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java b/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java index c912877686c..b7c006fd560 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java @@ -17,7 +17,7 @@ public class HauntEffect extends SpellAbilityEffect { } else if (sa.usesTargeting() && !card.isToken() && host.equalsWithTimestamp(card)) { // haunt target but only if card is no token and still in grave final Card copy = game.getAction().exile(card, sa); - sa.getTargets().getFirstTargetedCard().addHauntedBy(copy); + sa.getTargetCard().addHauntedBy(copy); } else if (!sa.usesTargeting() && card.getHaunting() != null) { // unhaunt card.getHaunting().removeHauntedBy(card); diff --git a/forge-gui/src/main/java/forge/player/TargetSelection.java b/forge-gui/src/main/java/forge/player/TargetSelection.java index 80d4891b15c..9ef8a768aa8 100644 --- a/forge-gui/src/main/java/forge/player/TargetSelection.java +++ b/forge-gui/src/main/java/forge/player/TargetSelection.java @@ -104,7 +104,7 @@ public class TargetSelection { } List candidates = tgt.getAllCandidates(this.ability, true); - final boolean hasEnoughCandidates = candidates.size() >= minTargets; + final boolean hasEnoughCandidates = candidates.size() >= minTargets || tgt.getZone().contains(ZoneType.Stack); if (!hasEnoughCandidates && !hasEnoughTargets) { // Cancel ability if there aren't any valid Candidates return false; @@ -151,7 +151,7 @@ public class TargetSelection { // single zone if (isSingleZone) { final List removeCandidates = new ArrayList<>(); - final Card firstTgt = ability.getTargets().getFirstTargetedCard(); + final Card firstTgt = ability.getTargetCard(); if (firstTgt != null) { for (Card t : validTargets) { if (!t.getController().equals(firstTgt.getController())) {