From 5070f8bef72864e93dc9429615235eebfd229a48 Mon Sep 17 00:00:00 2001 From: xenohedron Date: Sat, 26 Oct 2024 20:23:50 -0400 Subject: [PATCH] Fix auto-choose targets for activated abilities and spells (#13036) * rework Armory Automaton * remove redundant "setRequired(false)" from effects that separate into piles * replace setRequired(false) with minTargets 0 * remove setRequired(false) where minTargets already 0 * remove setRequired(false) where preceded by chooseUse * Revert "Player auto-choose respects required targets (#10557)" This reverts commit fb8424556e63754a6b7a46da1a26a186c0c9be8c. --- .../src/mage/player/human/HumanPlayer.java | 12 ++-- .../src/mage/cards/a/ArmoryAutomaton.java | 70 ++++++------------- .../src/mage/cards/b/BrilliantUltimatum.java | 1 - Mage.Sets/src/mage/cards/c/CreditVoucher.java | 1 - Mage.Sets/src/mage/cards/d/DoOrDie.java | 1 - Mage.Sets/src/mage/cards/f/FightOrFlight.java | 1 - Mage.Sets/src/mage/cards/g/GenesisHydra.java | 4 +- .../src/mage/cards/k/KnickknackOuphe.java | 1 - .../src/mage/cards/l/LilianaOfTheVeil.java | 1 - Mage.Sets/src/mage/cards/m/MercadianLift.java | 1 - .../src/mage/cards/r/RepelIntruders.java | 6 +- .../src/mage/cards/r/ReversalOfFortune.java | 3 +- Mage.Sets/src/mage/cards/s/ScrollRack.java | 1 - .../src/mage/cards/s/SpectersShriek.java | 3 +- Mage.Sets/src/mage/cards/s/StandOrFall.java | 1 - Mage.Sets/src/mage/cards/t/TruthOrTale.java | 1 - .../src/mage/cards/v/VendilionClique.java | 4 +- .../src/mage/cards/w/WhimsOfTheFates.java | 1 - .../src/main/java/mage/target/TargetImpl.java | 2 +- 19 files changed, 32 insertions(+), 83 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index e63b3f1dee2..de9f95c640b 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -681,7 +681,7 @@ public class HumanPlayer extends PlayerImpl { required = false; } - UUID responseId = required ? target.tryToAutoChoose(abilityControllerId, source, game) : null; + UUID responseId = target.tryToAutoChoose(abilityControllerId, source, game); // responseId is null if a choice couldn't be automatically made if (responseId == null) { @@ -780,7 +780,7 @@ public class HumanPlayer extends PlayerImpl { required = false; } - UUID responseId = required ? target.tryToAutoChoose(abilityControllerId, source, game) : null; + UUID responseId = target.tryToAutoChoose(abilityControllerId, source, game); // responseId is null if a choice couldn't be automatically made if (responseId == null) { @@ -877,8 +877,7 @@ public class HumanPlayer extends PlayerImpl { required = false; } - UUID responseId = required ? target.tryToAutoChoose(abilityControllerId, source, game, possibleTargets) - : null; + UUID responseId = target.tryToAutoChoose(abilityControllerId, source, game, possibleTargets); if (responseId == null) { Map options = getOptions(target, null); @@ -958,8 +957,7 @@ public class HumanPlayer extends PlayerImpl { required = false; } - UUID responseId = required ? target.tryToAutoChoose(abilityControllerId, source, game, possibleTargets) - : null; + UUID responseId = target.tryToAutoChoose(abilityControllerId, source, game, possibleTargets); if (responseId == null) { List chosenTargets = target.getTargets(); @@ -1041,7 +1039,7 @@ public class HumanPlayer extends PlayerImpl { required = false; } - UUID responseId = required ? target.tryToAutoChoose(abilityControllerId, source, game) : null; + UUID responseId = target.tryToAutoChoose(abilityControllerId, source, game); // responseId is null if a choice couldn't be automatically made if (responseId == null) { diff --git a/Mage.Sets/src/mage/cards/a/ArmoryAutomaton.java b/Mage.Sets/src/mage/cards/a/ArmoryAutomaton.java index c7487805f22..a56ef46f944 100644 --- a/Mage.Sets/src/mage/cards/a/ArmoryAutomaton.java +++ b/Mage.Sets/src/mage/cards/a/ArmoryAutomaton.java @@ -10,25 +10,23 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.filter.FilterPermanent; -import mage.filter.common.FilterArtifactPermanent; -import mage.filter.common.FilterEquipmentPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.CardIdPredicate; -import mage.filter.predicate.permanent.AttachedToPredicate; -import mage.filter.predicate.permanent.PermanentIdPredicate; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; import mage.target.TargetPermanent; import java.util.UUID; /** - * @author spjspj + * @author xenohedron */ public final class ArmoryAutomaton extends CardImpl { + private static final FilterPermanent filter = new FilterPermanent("Equipment"); + + static { + filter.add(SubType.EQUIPMENT.getPredicate()); + } + public ArmoryAutomaton(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); @@ -36,8 +34,10 @@ public final class ArmoryAutomaton extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); - // Whenever Armory Automaton enters the battlefield or attacks, attach any number of target Equipment to it. - this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new ArmoryAutomatonEffect())); + // Whenever Armory Automaton enters or attacks, you may attach any number of target Equipment to it. + Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new ArmoryAutomatonEffect(), true); + ability.addTarget(new TargetPermanent(0, Integer.MAX_VALUE, filter)); + this.addAbility(ability); } private ArmoryAutomaton(final ArmoryAutomaton card) { @@ -52,12 +52,6 @@ public final class ArmoryAutomaton extends CardImpl { class ArmoryAutomatonEffect extends OneShotEffect { - private static final FilterArtifactPermanent filter = new FilterArtifactPermanent("Equipment"); - - static { - filter.add(SubType.EQUIPMENT.getPredicate()); - } - ArmoryAutomatonEffect() { super(Outcome.Benefit); this.staticText = "attach any number of target Equipment to it"; @@ -74,38 +68,16 @@ class ArmoryAutomatonEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (player != null && sourcePermanent != null) { - - // dynamic filter (can't selects own attaches and can't selects twice) - FilterPermanent currentFilter = new FilterEquipmentPermanent(); - FilterPermanent filterSourceId = new FilterPermanent(); - filterSourceId.add(new CardIdPredicate(source.getSourceId())); - currentFilter.add(Predicates.not(new AttachedToPredicate(filterSourceId))); - - int countBattlefield = game.getBattlefield().getActivePermanents(currentFilter, source.getControllerId(), source, game).size(); - while (player.canRespond() && countBattlefield > 0 && player.chooseUse(Outcome.Benefit, "Select and attach a target Equipment?", source, game)) { - Target targetEquipment = new TargetPermanent(currentFilter); - targetEquipment.setRequired(false); - if (player.choose(Outcome.Benefit, targetEquipment, source, game) && targetEquipment.getFirstTarget() != null) { - currentFilter.add(Predicates.not(new PermanentIdPredicate(targetEquipment.getFirstTarget()))); // exclude selected for next time - - Permanent aura = game.getPermanent(targetEquipment.getFirstTarget()); - if (aura != null) { - Permanent attachedTo = game.getPermanent(aura.getAttachedTo()); - if (attachedTo != null) { - attachedTo.removeAttachment(aura.getId(), source, game); - } - sourcePermanent.addAttachment(aura.getId(), source, game); - } - } else { - break; - } - countBattlefield = game.getBattlefield().getActivePermanents(currentFilter, source.getControllerId(), source, game).size(); - } - return true; + Permanent creature = source.getSourcePermanentIfItStillExists(game); + if (creature == null) { + return false; } - return false; + for (UUID targetId : getTargetPointer().getTargets(game, source)) { + Permanent equipment = game.getPermanent(targetId); + if (equipment != null) { + creature.addAttachment(equipment.getId(), source, game); + } + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java b/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java index ab395fc95b7..a9aad7466b5 100644 --- a/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java +++ b/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java @@ -77,7 +77,6 @@ class BrilliantUltimatumEffect extends OneShotEffect { Player opponent = game.getPlayer(targetOpponent.getFirstTarget()); if (opponent != null) { TargetCard target = new TargetCard(0, pile2.size(), Zone.EXILED, new FilterCard("cards to put in the first pile")); - target.setRequired(false); Cards pile1 = new CardsImpl(); List pileOne = new ArrayList<>(); List pileTwo = new ArrayList<>(); diff --git a/Mage.Sets/src/mage/cards/c/CreditVoucher.java b/Mage.Sets/src/mage/cards/c/CreditVoucher.java index 7a0486dad0a..1f03f0c96ab 100644 --- a/Mage.Sets/src/mage/cards/c/CreditVoucher.java +++ b/Mage.Sets/src/mage/cards/c/CreditVoucher.java @@ -69,7 +69,6 @@ class CreditVoucherEffect extends OneShotEffect { if (controller != null && sourceObject != null) { FilterCard filter = new FilterCard("card in your hand to shuffle away"); TargetCardInHand target = new TargetCardInHand(0, controller.getHand().size(), filter); - target.setRequired(false); int amountShuffled = 0; if (target.canChoose(source.getControllerId(), source, game) && target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), source, game)) { if (!target.getTargets().isEmpty()) { diff --git a/Mage.Sets/src/mage/cards/d/DoOrDie.java b/Mage.Sets/src/mage/cards/d/DoOrDie.java index 30457517ff1..0b95336936b 100644 --- a/Mage.Sets/src/mage/cards/d/DoOrDie.java +++ b/Mage.Sets/src/mage/cards/d/DoOrDie.java @@ -70,7 +70,6 @@ class DoOrDieEffect extends OneShotEffect { filter.add(new ControllerIdPredicate(targetPlayer.getId())); TargetCreaturePermanent creatures = new TargetCreaturePermanent(0, Integer.MAX_VALUE, filter, true); List pile1 = new ArrayList<>(); - creatures.setRequired(false); if (player.choose(Outcome.Neutral, creatures, source, game)) { List targets = creatures.getTargets(); for (UUID targetId : targets) { diff --git a/Mage.Sets/src/mage/cards/f/FightOrFlight.java b/Mage.Sets/src/mage/cards/f/FightOrFlight.java index ea78fca2827..ff01aa3b5b3 100644 --- a/Mage.Sets/src/mage/cards/f/FightOrFlight.java +++ b/Mage.Sets/src/mage/cards/f/FightOrFlight.java @@ -75,7 +75,6 @@ class FightOrFlightEffect extends OneShotEffect { filter.add(new ControllerIdPredicate(targetPlayer.getId())); TargetCreaturePermanent creatures = new TargetCreaturePermanent(0, Integer.MAX_VALUE, filter, true); List pile1 = new ArrayList<>(); - creatures.setRequired(false); if (player.choose(Outcome.Neutral, creatures, source, game)) { List targets = creatures.getTargets(); for (UUID targetId : targets) { diff --git a/Mage.Sets/src/mage/cards/g/GenesisHydra.java b/Mage.Sets/src/mage/cards/g/GenesisHydra.java index 0a5112802cf..6ebbb69e954 100644 --- a/Mage.Sets/src/mage/cards/g/GenesisHydra.java +++ b/Mage.Sets/src/mage/cards/g/GenesisHydra.java @@ -1,4 +1,3 @@ - package mage.cards.g; import mage.MageInt; @@ -76,8 +75,7 @@ class GenesisHydraPutOntoBattlefieldEffect extends OneShotEffect { FilterCard filter = new FilterPermanentCard("a nonland permanent card with mana value " + count + " or less to put onto the battlefield"); filter.add(Predicates.not(CardType.LAND.getPredicate())); filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, count + 1)); - TargetCard target1 = new TargetCard(Zone.LIBRARY, filter); - target1.setRequired(false); + TargetCard target1 = new TargetCard(0, 1, Zone.LIBRARY, filter); if (cards.count(filter, source.getSourceId(), source, game) > 0) { if (controller.choose(Outcome.PutCardInPlay, cards, target1, source, game)) { Card card = cards.get(target1.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/cards/k/KnickknackOuphe.java b/Mage.Sets/src/mage/cards/k/KnickknackOuphe.java index 369aeb81c02..b17a707cbfc 100644 --- a/Mage.Sets/src/mage/cards/k/KnickknackOuphe.java +++ b/Mage.Sets/src/mage/cards/k/KnickknackOuphe.java @@ -87,7 +87,6 @@ class KnickknackOuphePutOntoBattlefieldEffect extends OneShotEffect { if (cards.count(filter, controller.getId(), source, game) > 0) { TargetCard targetAuras = new TargetCard(0, count, Zone.LIBRARY, filter); - targetAuras.setRequired(false); if (controller.choose(Outcome.PutCardInPlay, cards, targetAuras, source, game)) { targetAuras.getTargets().stream().forEach(t -> { diff --git a/Mage.Sets/src/mage/cards/l/LilianaOfTheVeil.java b/Mage.Sets/src/mage/cards/l/LilianaOfTheVeil.java index 0f8e77efaa8..ee9ca9135cf 100644 --- a/Mage.Sets/src/mage/cards/l/LilianaOfTheVeil.java +++ b/Mage.Sets/src/mage/cards/l/LilianaOfTheVeil.java @@ -86,7 +86,6 @@ class LilianaOfTheVeilEffect extends OneShotEffect { filter.add(new ControllerIdPredicate(targetPlayer.getId())); TargetPermanent target = new TargetPermanent(0, count, filter, true); List pile1 = new ArrayList<>(); - target.setRequired(false); if (player.choose(Outcome.Neutral, target, source, game)) { List targets = target.getTargets(); for (UUID targetId : targets) { diff --git a/Mage.Sets/src/mage/cards/m/MercadianLift.java b/Mage.Sets/src/mage/cards/m/MercadianLift.java index c05150145ed..ef20be53885 100644 --- a/Mage.Sets/src/mage/cards/m/MercadianLift.java +++ b/Mage.Sets/src/mage/cards/m/MercadianLift.java @@ -83,7 +83,6 @@ class MercadianLiftEffect extends OneShotEffect { if (target.canChoose(controller.getId(), source, game) && controller.chooseUse(Outcome.PutCardInPlay, "Put " + filter.getMessage() + " from your hand onto the battlefield?", source, game) && controller.choose(Outcome.PutCardInPlay, target, source, game)) { - target.setRequired(false); Card card = game.getCard(target.getFirstTarget()); if (card != null) { return controller.moveCards(card, Zone.BATTLEFIELD, source, game); diff --git a/Mage.Sets/src/mage/cards/r/RepelIntruders.java b/Mage.Sets/src/mage/cards/r/RepelIntruders.java index cd20d75b7bf..d3dea29aad2 100644 --- a/Mage.Sets/src/mage/cards/r/RepelIntruders.java +++ b/Mage.Sets/src/mage/cards/r/RepelIntruders.java @@ -8,7 +8,6 @@ import mage.abilities.effects.common.InfoEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.ColoredManaSymbol; import mage.filter.common.FilterCreatureSpell; import mage.game.permanent.token.KithkinSoldierToken; import mage.target.TargetSpell; @@ -24,15 +23,13 @@ public final class RepelIntruders extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W/U}"); // Create two 1/1 white Kithkin Soldier creature tokens if {W} was spent to cast Repel Intruders. Counter up to one target creature spell if {U} was spent to cast Repel Intruders. - TargetSpell target = new TargetSpell(0, 1, new FilterCreatureSpell()); - target.setRequired(false); this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new CreateTokenEffect(new KithkinSoldierToken(), 2), ManaWasSpentCondition.WHITE, "Create two 1/1 white Kithkin Soldier creature tokens if {W} was spent to cast this spell")); this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new CounterTargetEffect(), ManaWasSpentCondition.BLUE, "Counter up to one target creature spell if {U} was spent to cast this spell")); - this.getSpellAbility().addTarget(target); + this.getSpellAbility().addTarget(new TargetSpell(0, 1, new FilterCreatureSpell())); this.getSpellAbility().addEffect(new InfoEffect("(Do both if {W}{U} was spent.)")); } @@ -46,4 +43,3 @@ public final class RepelIntruders extends CardImpl { return new RepelIntruders(this); } } - diff --git a/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java b/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java index fe4cc5918f4..7c6771dae54 100644 --- a/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java +++ b/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java @@ -74,8 +74,7 @@ class ReversalOfFortuneEffect extends OneShotEffect { opponent.revealCards("Reveal", revealedCards, game); //You may copy an instant or sorcery card in it - TargetCard target = new TargetCard(1, Zone.HAND, new FilterInstantOrSorceryCard()); - target.setRequired(false); + TargetCard target = new TargetCard(0, 1, Zone.HAND, new FilterInstantOrSorceryCard()); if (controller.choose(Outcome.PlayForFree, revealedCards, target, source, game)) { Card card = revealedCards.get(target.getFirstTarget(), game); //If you do, you may cast the copy without paying its mana cost diff --git a/Mage.Sets/src/mage/cards/s/ScrollRack.java b/Mage.Sets/src/mage/cards/s/ScrollRack.java index f37cf63108c..560ab770d14 100644 --- a/Mage.Sets/src/mage/cards/s/ScrollRack.java +++ b/Mage.Sets/src/mage/cards/s/ScrollRack.java @@ -63,7 +63,6 @@ class ScrollRackEffect extends OneShotEffect { if (controller != null && sourceObject != null) { FilterCard filter = new FilterCard("card in your hand to exile"); TargetCardInHand target = new TargetCardInHand(0, controller.getHand().size(), filter); - target.setRequired(false); int amountExiled = 0; if (target.canChoose(source.getControllerId(), source, game) && target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), source, game)) { if (!target.getTargets().isEmpty()) { diff --git a/Mage.Sets/src/mage/cards/s/SpectersShriek.java b/Mage.Sets/src/mage/cards/s/SpectersShriek.java index 2f38e613c3e..0374dacc8f7 100644 --- a/Mage.Sets/src/mage/cards/s/SpectersShriek.java +++ b/Mage.Sets/src/mage/cards/s/SpectersShriek.java @@ -76,9 +76,8 @@ class SpectersShriekEffect extends OneShotEffect { + player.getName() + "'s hand?", source, game)) { return false; } - TargetCard target = new TargetCard(Zone.HAND, new FilterNonlandCard()); + TargetCard target = new TargetCard(0, 1, Zone.HAND, new FilterNonlandCard()); target.withNotTarget(true); - target.setRequired(false); if (!controller.chooseTarget(Outcome.Benefit, player.getHand(), target, source, game)) { return false; } diff --git a/Mage.Sets/src/mage/cards/s/StandOrFall.java b/Mage.Sets/src/mage/cards/s/StandOrFall.java index 8fb67bd5f92..35c0f7ae56b 100644 --- a/Mage.Sets/src/mage/cards/s/StandOrFall.java +++ b/Mage.Sets/src/mage/cards/s/StandOrFall.java @@ -79,7 +79,6 @@ class StandOrFallEffect extends OneShotEffect { FilterCreaturePermanent opponentFilter = new FilterCreaturePermanent(); opponentFilter.add(new ControllerIdPredicate(oppId)); TargetCreaturePermanent creatures = new TargetCreaturePermanent(0, Integer.MAX_VALUE, opponentFilter, true); - creatures.setRequired(false); List pile1 = new ArrayList<>(); if (player.choose(Outcome.Neutral, creatures, source, game)) { List targets = creatures.getTargets(); diff --git a/Mage.Sets/src/mage/cards/t/TruthOrTale.java b/Mage.Sets/src/mage/cards/t/TruthOrTale.java index db894f4f618..7f8e8c5d655 100644 --- a/Mage.Sets/src/mage/cards/t/TruthOrTale.java +++ b/Mage.Sets/src/mage/cards/t/TruthOrTale.java @@ -80,7 +80,6 @@ class TruthOrTaleEffect extends OneShotEffect { if (opponent != null) { TargetCard target = new TargetCard(0, cards.size(), Zone.LIBRARY, new FilterCard("cards to put in the first pile")); List pile1 = new ArrayList<>(); - target.setRequired(false); if (controller.choose(Outcome.Neutral, cards, target, source, game)) { List targets = target.getTargets(); for (UUID targetId : targets) { diff --git a/Mage.Sets/src/mage/cards/v/VendilionClique.java b/Mage.Sets/src/mage/cards/v/VendilionClique.java index 1ff9aa4e669..2f0ab5a0640 100644 --- a/Mage.Sets/src/mage/cards/v/VendilionClique.java +++ b/Mage.Sets/src/mage/cards/v/VendilionClique.java @@ -1,4 +1,3 @@ - package mage.cards.v; import java.util.UUID; @@ -76,8 +75,7 @@ class VendilionCliqueEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); if (player != null && controller != null && sourceObject != null) { - TargetCard targetCard = new TargetCard(Zone.ALL, new FilterNonlandCard()); - targetCard.setRequired(false); + TargetCard targetCard = new TargetCard(0, 1, Zone.ALL, new FilterNonlandCard()); if (controller.choose(Outcome.Discard, player.getHand(), targetCard, source, game)) { Card card = game.getCard(targetCard.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/cards/w/WhimsOfTheFates.java b/Mage.Sets/src/mage/cards/w/WhimsOfTheFates.java index 0cf0c74c72e..e246f1e5933 100644 --- a/Mage.Sets/src/mage/cards/w/WhimsOfTheFates.java +++ b/Mage.Sets/src/mage/cards/w/WhimsOfTheFates.java @@ -103,7 +103,6 @@ class WhimsOfTheFateEffect extends OneShotEffect { } else { target = new TargetSecondPilePermanent(playerPiles.get(1), filter); } - target.setRequired(false); currentPlayer.chooseTarget(outcome, target, source, game); StringBuilder message = new StringBuilder(currentPlayer.getLogName()).append(" pile ").append(i).append(": "); if (target.getTargets().isEmpty()) { diff --git a/Mage/src/main/java/mage/target/TargetImpl.java b/Mage/src/main/java/mage/target/TargetImpl.java index 3fde07ecd1e..12386ee5180 100644 --- a/Mage/src/main/java/mage/target/TargetImpl.java +++ b/Mage/src/main/java/mage/target/TargetImpl.java @@ -370,7 +370,7 @@ public abstract class TargetImpl implements Target { } } else { // Try to autochoosen - UUID autoChosenId = required ? tryToAutoChoose(playerId, source, game) : null; + UUID autoChosenId = tryToAutoChoose(playerId, source, game); if (autoChosenId != null) { addTarget(autoChosenId, source, game); } else if (!targetController.chooseTarget(outcome, this, source, game)) { // If couldn't autochoose ask player