From dbd02a1db5198ea51a3391d44cdf910c8be912ad Mon Sep 17 00:00:00 2001 From: theelk801 Date: Wed, 30 Apr 2025 16:25:16 -0400 Subject: [PATCH] [PIP] Implement Vault 13: Dweller's Journey --- .../mage/cards/v/Vault13DwellersJourney.java | 132 ++++++++++++++++++ Mage.Sets/src/mage/sets/Fallout.java | 4 +- 2 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/v/Vault13DwellersJourney.java diff --git a/Mage.Sets/src/mage/cards/v/Vault13DwellersJourney.java b/Mage.Sets/src/mage/cards/v/Vault13DwellersJourney.java new file mode 100644 index 00000000000..84ccfe61af4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/Vault13DwellersJourney.java @@ -0,0 +1,132 @@ +package mage.cards.v; + +import mage.abilities.Ability; +import mage.abilities.common.SagaAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.TargetPermanent; +import mage.target.common.TargetCardInExile; +import mage.target.targetadjustment.ForEachOpponentTargetsAdjuster; +import mage.util.CardUtil; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Vault13DwellersJourney extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("enchantment or creature"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(Predicates.or( + CardType.ENCHANTMENT.getPredicate(), + CardType.CREATURE.getPredicate() + )); + } + + public Vault13DwellersJourney(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + this.subtype.add(SubType.SAGA); + + // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.) + SagaAbility sagaAbility = new SagaAbility(this); + + // I -- For each player, exile up to one other target enchantment or creature that player controls until Vault 13 leaves the battlefield. + sagaAbility.addChapterEffect( + this, SagaChapter.CHAPTER_I, + triggeredAbility -> { + triggeredAbility.addEffect(new ExileUntilSourceLeavesEffect() + .setText("for each player, exile up to one other target enchantment or " + + "creature that player controls until {this} leaves the battlefield")); + triggeredAbility.addTarget(new TargetPermanent(filter)); + triggeredAbility.setTargetAdjuster(new ForEachOpponentTargetsAdjuster()); + } + ); + + // II -- You gain 2 life and scry 2. + sagaAbility.addChapterEffect( + this, SagaChapter.CHAPTER_II, new GainLifeEffect(2), + new ScryEffect(2, false).concatBy("and") + ); + + // III -- Return two cards exiled with Vault 13 to the battlefield under their owners' control and put the rest on the bottom of their owners' libraries. + sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new Vault13DwellersJourneyEffect()); + this.addAbility(sagaAbility); + } + + private Vault13DwellersJourney(final Vault13DwellersJourney card) { + super(card); + } + + @Override + public Vault13DwellersJourney copy() { + return new Vault13DwellersJourney(this); + } +} + +class Vault13DwellersJourneyEffect extends OneShotEffect { + + Vault13DwellersJourneyEffect() { + super(Outcome.Benefit); + staticText = "return two cards exiled with {this} to the battlefield " + + "under their owners' control and put the rest on the bottom of their owners' libraries"; + } + + private Vault13DwellersJourneyEffect(final Vault13DwellersJourneyEffect effect) { + super(effect); + } + + @Override + public Vault13DwellersJourneyEffect copy() { + return new Vault13DwellersJourneyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Cards cards = new CardsImpl(); + Optional.ofNullable(game.getExile().getExileZone(CardUtil.getExileZoneId(game, source))) + .ifPresent(cards::addAll); + if (player == null || cards.isEmpty()) { + return false; + } + Cards toPlay = new CardsImpl(); + if (cards.size() > 2) { + TargetCard target = new TargetCardInExile(2, 2, StaticFilters.FILTER_CARD_CARDS); + target.withNotTarget(true); + target.withChooseHint("to return to the battlefield"); + player.choose(outcome, cards, target, source, game); + toPlay.addAll(target.getTargets()); + } else { + toPlay.addAll(cards); + } + toPlay.retainZone(Zone.EXILED, game); + if (!toPlay.isEmpty()) { + player.moveCards( + toPlay.getCards(game), Zone.BATTLEFIELD, source, game, + false, false, true, null + ); + cards.retainZone(Zone.EXILED, game); + } + player.putCardsOnBottomOfLibrary(cards, game, source, true); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Fallout.java b/Mage.Sets/src/mage/sets/Fallout.java index 05f0598b516..0cf9a4160b3 100644 --- a/Mage.Sets/src/mage/sets/Fallout.java +++ b/Mage.Sets/src/mage/sets/Fallout.java @@ -1020,8 +1020,8 @@ public final class Fallout extends ExpansionSet { cards.add(new SetCardInfo("Vault 11: Voter's Dilemma", 649, Rarity.RARE, mage.cards.v.Vault11VotersDilemma.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vault 12: The Necropolis", 51, Rarity.RARE, mage.cards.v.Vault12TheNecropolis.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vault 12: The Necropolis", 579, Rarity.RARE, mage.cards.v.Vault12TheNecropolis.class, NON_FULL_USE_VARIOUS)); - //cards.add(new SetCardInfo("Vault 13: Dweller's Journey", 26, Rarity.RARE, mage.cards.v.Vault13DwellersJourney.class, NON_FULL_USE_VARIOUS)); - //cards.add(new SetCardInfo("Vault 13: Dweller's Journey", 554, Rarity.RARE, mage.cards.v.Vault13DwellersJourney.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vault 13: Dweller's Journey", 26, Rarity.RARE, mage.cards.v.Vault13DwellersJourney.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vault 13: Dweller's Journey", 554, Rarity.RARE, mage.cards.v.Vault13DwellersJourney.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vault 21: House Gambit", 597, Rarity.RARE, mage.cards.v.Vault21HouseGambit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vault 21: House Gambit", 69, Rarity.RARE, mage.cards.v.Vault21HouseGambit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vault 75: Middle School", 27, Rarity.RARE, mage.cards.v.Vault75MiddleSchool.class, NON_FULL_USE_VARIOUS));