From 0b6db8cf1839102db7a72b1bb4c2db7cfd894bc9 Mon Sep 17 00:00:00 2001 From: Grath <1895280+Grath@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:33:46 -0500 Subject: [PATCH] [DSC] Implement Disorienting Choice. Also having noticed it, change Decoy Gambit to use log names for increased clarity. --- Mage.Sets/src/mage/cards/d/DecoyGambit.java | 5 +- .../src/mage/cards/d/DisorientingChoice.java | 119 ++++++++++++++++++ .../sets/DuskmournHouseOfHorrorCommander.java | 1 + 3 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/d/DisorientingChoice.java diff --git a/Mage.Sets/src/mage/cards/d/DecoyGambit.java b/Mage.Sets/src/mage/cards/d/DecoyGambit.java index 84caf26ba54..ed151069b49 100644 --- a/Mage.Sets/src/mage/cards/d/DecoyGambit.java +++ b/Mage.Sets/src/mage/cards/d/DecoyGambit.java @@ -86,11 +86,12 @@ class DecoyGambitEffect extends OneShotEffect { continue; } if (player.chooseUse(outcome, "Have " + controller.getName() + " draw a card? If you don't, " - + permanent.getName() + " will be returned to its owner's hand.", source, game)) { + + permanent.getLogName() + " will be returned to its owner's hand.", source, game)) { game.informPlayers(player.getLogName() + " chose to have " + controller.getName() + " draw a card."); numberOfCardsToDraw += 1; } else { - game.informPlayers(player.getLogName() + " chose to have their creature returned to their hand."); + game.informPlayers(player.getLogName() + " chose to have their creature " + permanent.getLogName() + + " returned to their hand."); permanentToHand.add(permanent); } } diff --git a/Mage.Sets/src/mage/cards/d/DisorientingChoice.java b/Mage.Sets/src/mage/cards/d/DisorientingChoice.java new file mode 100644 index 00000000000..29b98c0c493 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DisorientingChoice.java @@ -0,0 +1,119 @@ +package mage.cards.d; + +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.filter.common.FilterLandCard; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.common.TargetCardInLibrary; +import mage.target.targetadjustment.ForEachOpponentTargetsAdjuster; + +/** + * + * @author Grath + */ +public final class DisorientingChoice extends CardImpl { + + public DisorientingChoice(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}"); + + // For each opponent, choose up to one target artifact or enchantment that player controls. For each permanent chosen this way, its controller may exile it. Then if one or more of the chosen permanents are still on the battlefield, you search your library for up to that many land cards, put them onto the battlefield tapped, then shuffle. + this.getSpellAbility().addEffect(new DisorientingChoiceEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(0,1, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); + this.getSpellAbility().setTargetAdjuster(new ForEachOpponentTargetsAdjuster()); + } + + private DisorientingChoice(final DisorientingChoice card) { + super(card); + } + + @Override + public DisorientingChoice copy() { + return new DisorientingChoice(this); + } +} + +class DisorientingChoiceEffect extends OneShotEffect { + + DisorientingChoiceEffect() { + super(Outcome.Benefit); + staticText = "For each opponent, choose up to one target artifact or enchantment that player controls. " + + "For each permanent chosen this way, its controller may exile it. Then if one or more of the " + + "chosen permanents are still on the battlefield, you search your library for up to that many " + + "land cards, put them onto the battlefield tapped, then shuffle."; + } + + private DisorientingChoiceEffect(final DisorientingChoiceEffect effect) { + super(effect); + } + + @Override + public DisorientingChoiceEffect copy() { + return new DisorientingChoiceEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Cards permanentsToExile = new CardsImpl(); + int numberOfLandsToFetch = 0; + if (controller == null) { + return false; + } + List permanents = source + .getTargets() + .stream() + .map(Target::getTargets) + .flatMap(Collection::stream) + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + for (Permanent permanent : permanents) { + Player player = game.getPlayer(permanent.getControllerId()); + if (player == null) { + continue; + } + if (player.chooseUse(outcome, "Exile " + permanent.getLogName() + "? If you don't, " + + controller.getName() + " will get a land from their library.", source, game)) { + game.informPlayers(player.getLogName() + " chose to have their " + permanent.getLogName() + " exiled."); + permanentsToExile.add(permanent); + } else { + game.informPlayers(player.getLogName() + " chose to have " + controller.getName() + " get a land."); + numberOfLandsToFetch += 1; + } + } + /* + When Disorienting Choice resolves, the next opponent in turn order that controls a permanent chosen with + Disorienting Choice decides whether or not to exile that permanent. Then each other opponent in turn order + does the same. Then all appropriate permanents are exiled simultaneously. Opponents will know what choices + opponents earlier in the turn order made. + */ + controller.moveCards(permanentsToExile, Zone.EXILED, source, game); + if (numberOfLandsToFetch > 0) { + TargetCardInLibrary target = new TargetCardInLibrary(0, numberOfLandsToFetch, new FilterLandCard()); + if (controller.searchLibrary(target, source, game)) { + for (UUID cardId : target.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + } + } + } + } + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java index f179c592766..4b74280d21f 100644 --- a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java +++ b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java @@ -91,6 +91,7 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("Diabolic Vision", 87, Rarity.UNCOMMON, mage.cards.d.DiabolicVision.class)); cards.add(new SetCardInfo("Dig Through Time", 115, Rarity.RARE, mage.cards.d.DigThroughTime.class)); cards.add(new SetCardInfo("Dimir Aqueduct", 270, Rarity.UNCOMMON, mage.cards.d.DimirAqueduct.class)); + cards.add(new SetCardInfo("Disorienting Choice", 32, Rarity.RARE, mage.cards.d.DisorientingChoice.class)); cards.add(new SetCardInfo("Doomwake Giant", 138, Rarity.RARE, mage.cards.d.DoomwakeGiant.class)); cards.add(new SetCardInfo("Dragonskull Summit", 271, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); cards.add(new SetCardInfo("Dream Eater", 116, Rarity.MYTHIC, mage.cards.d.DreamEater.class));