From 5dee4904f1433b16b29b82f9410736b24b58257c Mon Sep 17 00:00:00 2001 From: jimga150 Date: Sat, 13 Jan 2024 15:43:22 -0500 Subject: [PATCH] [REX] Implement Welcome To... // Jurassic Park (#11642) --- Mage.Sets/src/mage/cards/j/JurassicPark.java | 107 +++++++++++++ Mage.Sets/src/mage/cards/w/WelcomeTo.java | 147 ++++++++++++++++++ .../mage/sets/JurassicWorldCollection.java | 2 + 3 files changed, 256 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/j/JurassicPark.java create mode 100644 Mage.Sets/src/mage/cards/w/WelcomeTo.java diff --git a/Mage.Sets/src/mage/cards/j/JurassicPark.java b/Mage.Sets/src/mage/cards/j/JurassicPark.java new file mode 100644 index 00000000000..32b4c2146b3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JurassicPark.java @@ -0,0 +1,107 @@ +package mage.cards.j; + +import java.util.Objects; +import java.util.UUID; + +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.EscapeAbility; +import mage.abilities.mana.DynamicManaAbility; +import mage.constants.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author jimga150 + */ +public final class JurassicPark extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent("Dinosaurs you control"); + + static { + filter.add(SubType.DINOSAUR.getPredicate()); + } + + private static final Hint hint = new ValueHint( + "Number of Dinosaurs you control", new PermanentsOnBattlefieldCount(filter) + ); + + public JurassicPark(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.supertype.add(SuperType.LEGENDARY); + this.nightCard = true; + + // (Transforms from Welcome to ....) + // Each Dinosaur card in your graveyard has escape. The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard. + // Based on Underworld Breach + this.addAbility(new SimpleStaticAbility(new JurassicParkEffect())); + + // {T}: Add {G} for each Dinosaur you control. + // Based on Gaea's Cradle + DynamicManaAbility ability = new DynamicManaAbility( + Mana.GreenMana(1), + new PermanentsOnBattlefieldCount(filter) + ); + this.addAbility(ability.addHint(hint)); + } + + private JurassicPark(final JurassicPark card) { + super(card); + } + + @Override + public JurassicPark copy() { + return new JurassicPark(this); + } +} + +class JurassicParkEffect extends ContinuousEffectImpl { + + JurassicParkEffect() { + super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); + staticText = "Each Dinosaur card in your graveyard has escape. " + + "The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard."; + } + + private JurassicParkEffect(final JurassicParkEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + controller + .getGraveyard() + .getCards(game) + .stream() + .filter(Objects::nonNull) + .filter(card -> !card.getManaCost().getText().isEmpty()) // card must have a mana cost + .filter(card -> card.getSubtype().contains(SubType.DINOSAUR)) + .forEach(card -> { + Ability ability = new EscapeAbility(card, card.getManaCost().getText(), 3); + ability.setSourceId(card.getId()); + ability.setControllerId(card.getOwnerId()); + game.getState().addOtherAbility(card, ability); + }); + return true; + } + + @Override + public JurassicParkEffect copy() { + return new JurassicParkEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WelcomeTo.java b/Mage.Sets/src/mage/cards/w/WelcomeTo.java new file mode 100644 index 00000000000..21acbf32ae2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WelcomeTo.java @@ -0,0 +1,147 @@ +package mage.cards.w; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.SagaAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.*; +import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.DefenderAbility; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.TransformAbility; +import mage.cards.Card; +import mage.constants.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterNoncreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.token.DinosaurToken; +import mage.game.permanent.token.custom.CreatureToken; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.TargetPermanent; +import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; +import mage.target.targetpointer.EachTargetPointer; +import mage.target.targetpointer.FixedTarget; +import mage.target.targetpointer.FixedTargets; + +/** + * + * @author jimga150 + */ +public final class WelcomeTo extends CardImpl { + + private static FilterPermanent filter = new FilterPermanent("walls"); + + static { + filter.add(SubType.WALL.getPredicate()); + } + + // Based on Azusa's Many Journeys // Likeness of the Seeker, Vronos Masked Inquisitor, In the Darkness Bind Then, + public WelcomeTo(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{G}"); + + this.subtype.add(SubType.SAGA); + this.secondSideCardClazz = mage.cards.j.JurassicPark.class; + + // (As this Saga enters and after your draw step, add a lore counter.) + SagaAbility sagaAbility = new SagaAbility(this); + + // I -- For each opponent, up to one target noncreature artifact they control becomes a 0/4 Wall artifact creature with defender for as long as you control this Saga. + sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, ability -> { + ability.addEffect( + new BecomesCreatureTargetEffect(new CreatureToken(0, 4).withSubType(SubType.WALL), + false, false, Duration.WhileControlled) + .setText("For each opponent, up to one target noncreature artifact they control becomes " + + "a 0/4 Wall artifact creature with defender for as long as you control this Saga.")); + ability.addEffect(new GainAbilityTargetEffect(DefenderAbility.getInstance(), Duration.WhileControlled, "")); + ability.getEffects().setTargetPointer(new EachTargetPointer()); + ability.setTargetAdjuster(WelcomeToAdjuster.instance); + }); + + // II -- Create a 3/3 green Dinosaur creature token with trample. It gains haste until end of turn. + // Based on Mordor on the March + sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new WelcomeToEffect()); + + // III -- Destroy all Walls. Exile this Saga, then return it to the battlefield transformed under your control. + this.addAbility(new TransformAbility()); + sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, ability -> { + ability.addEffect(new DestroyAllEffect(filter)); + ability.addEffect(new ExileSagaAndReturnTransformedEffect()); + }); + + this.addAbility(sagaAbility); + } + + private WelcomeTo(final WelcomeTo card) { + super(card); + } + + @Override + public WelcomeTo copy() { + return new WelcomeTo(this); + } +} + +// Based on Vronos, Masked Inquisitor +enum WelcomeToAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + for (UUID opponentId : game.getOpponents(ability.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent == null) { + continue; + } + FilterPermanent filter = new FilterNoncreaturePermanent( + "noncreature artifact controlled by " + opponent.getLogName()); + filter.add(Predicates.and(CardType.ARTIFACT.getPredicate(), new ControllerIdPredicate(opponentId))); + ability.addTarget(new TargetPermanent(0, 1, filter, false)); + } + } +} + +// Based on Mordor on the March +class WelcomeToEffect extends OneShotEffect { + + public WelcomeToEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "Create a 3/3 green Dinosaur creature token with trample. It gains haste until end of turn."; + } + + private WelcomeToEffect(final WelcomeToEffect effect) { + super(effect); + } + + @Override + public WelcomeToEffect copy() { + return new WelcomeToEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + CreateTokenEffect effect = new CreateTokenEffect(new DinosaurToken()); + effect.apply(game, source); + effect.getLastAddedTokenIds().forEach(permanentID -> { + ContinuousEffect continuousEffect = new GainAbilityTargetEffect( + HasteAbility.getInstance(), Duration.EndOfTurn + ); + continuousEffect.setTargetPointer(new FixedTarget(permanentID)); + game.addEffect(continuousEffect, source); + }); + return true; + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/JurassicWorldCollection.java b/Mage.Sets/src/mage/sets/JurassicWorldCollection.java index de677ae8538..54956c8de10 100644 --- a/Mage.Sets/src/mage/sets/JurassicWorldCollection.java +++ b/Mage.Sets/src/mage/sets/JurassicWorldCollection.java @@ -28,6 +28,7 @@ public final class JurassicWorldCollection extends ExpansionSet { cards.add(new SetCardInfo("Hunting Velociraptor", 4, Rarity.RARE, mage.cards.h.HuntingVelociraptor.class)); cards.add(new SetCardInfo("Island", 22, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Island", "22b", Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Jurassic Park", 7, Rarity.RARE, mage.cards.j.JurassicPark.class)); cards.add(new SetCardInfo("Mountain", 24, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Mountain", "24b", Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Permission Denied", 17, Rarity.RARE, mage.cards.p.PermissionDenied.class)); @@ -35,5 +36,6 @@ public final class JurassicWorldCollection extends ExpansionSet { cards.add(new SetCardInfo("Plains", "21b", Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Swamp", 23, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Swamp", "23b", Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Welcome to . . .", 7, Rarity.RARE, mage.cards.w.WelcomeTo.class)); } }