From 905bb8c2e498bbfefdbe3374acc722949aca5d2c Mon Sep 17 00:00:00 2001 From: theelk801 Date: Tue, 8 Jul 2025 08:17:38 -0400 Subject: [PATCH] [EOE] implement Anticausal Vestige --- .../src/mage/cards/a/AnticausalVestige.java | 71 +++++++++++++++++++ Mage.Sets/src/mage/sets/EdgeOfEternities.java | 7 ++ .../mage/abilities/keyword/WarpAbility.java | 51 +++++++++++++ Utils/keywords.txt | 1 + Utils/mtg-cards-data.txt | 1 + 5 files changed, 131 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AnticausalVestige.java create mode 100644 Mage/src/main/java/mage/abilities/keyword/WarpAbility.java diff --git a/Mage.Sets/src/mage/cards/a/AnticausalVestige.java b/Mage.Sets/src/mage/cards/a/AnticausalVestige.java new file mode 100644 index 00000000000..f2a1d07588e --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AnticausalVestige.java @@ -0,0 +1,71 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.LandsYouControlCount; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; +import mage.abilities.hint.common.LandsYouControlHint; +import mage.abilities.keyword.WarpAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.common.FilterPermanentCard; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AnticausalVestige extends CardImpl { + + private static final FilterCard filter = new FilterPermanentCard( + "a permanent card with mana value less than or equal to the number of lands you control" + ); + + static { + filter.add(AnticausalVestigePredicate.instance); + } + + public AnticausalVestige(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}"); + + this.subtype.add(SubType.ELDRAZI); + this.power = new MageInt(7); + this.toughness = new MageInt(5); + + // When this creature leaves the battlefield, draw a card, then you may put a permanent card with mana value less than or equal to the number of lands you control from your hand onto the battlefield tapped. + Ability ability = new LeavesBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)); + ability.addEffect(new PutCardFromHandOntoBattlefieldEffect(filter, false, true).concatBy(", then")); + this.addAbility(ability.addHint(LandsYouControlHint.instance)); + + // Warp {4} + this.addAbility(new WarpAbility(this, "{4}")); + } + + private AnticausalVestige(final AnticausalVestige card) { + super(card); + } + + @Override + public AnticausalVestige copy() { + return new AnticausalVestige(this); + } +} + +enum AnticausalVestigePredicate implements ObjectSourcePlayerPredicate { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + return input.getObject().getManaValue() + <= LandsYouControlCount.instance.calculate(game, input.getSource(), null); + } +} diff --git a/Mage.Sets/src/mage/sets/EdgeOfEternities.java b/Mage.Sets/src/mage/sets/EdgeOfEternities.java index c8da13a1e5b..11cffac7709 100644 --- a/Mage.Sets/src/mage/sets/EdgeOfEternities.java +++ b/Mage.Sets/src/mage/sets/EdgeOfEternities.java @@ -4,11 +4,15 @@ import mage.cards.ExpansionSet; import mage.constants.Rarity; import mage.constants.SetType; +import java.util.Arrays; +import java.util.List; + /** * @author TheElk801 */ public final class EdgeOfEternities extends ExpansionSet { + private static final List unfinished = Arrays.asList("Anticausal Vestige"); private static final EdgeOfEternities instance = new EdgeOfEternities(); public static EdgeOfEternities getInstance() { @@ -21,6 +25,7 @@ public final class EdgeOfEternities extends ExpansionSet { this.rotationSet = true; cards.add(new SetCardInfo("Alpharael, Dreaming Acolyte", 212, Rarity.UNCOMMON, mage.cards.a.AlpharaelDreamingAcolyte.class)); + cards.add(new SetCardInfo("Anticausal Vestige", 1, Rarity.RARE, mage.cards.a.AnticausalVestige.class)); cards.add(new SetCardInfo("Breeding Pool", 251, Rarity.RARE, mage.cards.b.BreedingPool.class)); cards.add(new SetCardInfo("Command Bridge", 252, Rarity.COMMON, mage.cards.c.CommandBridge.class)); cards.add(new SetCardInfo("Embrace Oblivion", 98, Rarity.COMMON, mage.cards.e.EmbraceOblivion.class)); @@ -49,5 +54,7 @@ public final class EdgeOfEternities extends ExpansionSet { cards.add(new SetCardInfo("Tezzeret, Cruel Captain", 2, Rarity.MYTHIC, mage.cards.t.TezzeretCruelCaptain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tezzeret, Cruel Captain", 287, Rarity.MYTHIC, mage.cards.t.TezzeretCruelCaptain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Watery Grave", 261, Rarity.RARE, mage.cards.w.WateryGrave.class)); + + cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/WarpAbility.java b/Mage/src/main/java/mage/abilities/keyword/WarpAbility.java new file mode 100644 index 00000000000..3e4cc681e0c --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/WarpAbility.java @@ -0,0 +1,51 @@ +package mage.abilities.keyword; + +import mage.abilities.SpellAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.cards.Card; +import mage.constants.SpellAbilityType; +import mage.constants.TimingRule; + +/** + * @author TheElk801 + */ +public class WarpAbility extends SpellAbility { + + public static final String WARP_ACTIVATION_VALUE_KEY = "warpActivation"; + + public WarpAbility(Card card, String manaString) { + super(new ManaCostsImpl<>(manaString), card.getName() + " with Warp"); + this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE; + this.setAdditionalCostsRuleVisible(false); + this.timing = TimingRule.SORCERY; + } + + private WarpAbility(final WarpAbility ability) { + super(ability); + } + + @Override + public WarpAbility copy() { + return new WarpAbility(this); + } + + @Override + public String getRule() { + StringBuilder sb = new StringBuilder("Warp"); + if (getCosts().isEmpty()) { + sb.append(' '); + } else { + sb.append("—"); + } + sb.append(getManaCosts().getText()); + if (!getCosts().isEmpty()) { + sb.append(", "); + sb.append(getCosts().getText()); + sb.append('.'); + } + sb.append(" (You may cast this card from your hand for its warp cost. "); + sb.append("Exile this creature at the beginning of the next end step, "); + sb.append("then you may cast it from exile on a later turn.)"); + return sb.toString(); + } +} diff --git a/Utils/keywords.txt b/Utils/keywords.txt index ea6b857b8ce..724bdd48e22 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -147,4 +147,5 @@ Unleash|new| Vanishing|number| Vigilance|instance| Ward|cost| +Warp|card, manaString| Wither|instance| diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index ae9ddb98b4a..208a3c66755 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -59108,6 +59108,7 @@ Green Goblin, Nemesis|Marvel's Spider-Man Eternal|23|R|{2}{B}{R}|Legendary Creat Doc Ock, Evil Inventor|Marvel's Spider-Man Eternal|24|R|{5}{U}{B}|Legendary Creature - Human Scientist Villain|8|8|At the beginning of combat on your turn, target noncreature artifact you control becomes an 8/8 Robot Villain artifact creature in addition to its other types.| Sensational Spider-Man|Marvel's Spider-Man Eternal|25|R|{1}{W}{U}|Legendary Creature - Spider Human Hero|3|3|Whenever Sensational Spider-Man attacks, tap target creature defending player controls and put a stun counter on it. Then you may remove up to three stun counters from among all permanents. Draw cards equal to the number of stun counters removed this way.| Pumpkin Bombs|Marvel's Spider-Man Eternal|26|R|{1}{R}|Artifact|||{T}, Discard two cards: Draw three cards, then put a fuse counter on this artifact. It deals damage equal to the number of fuse counters on it to target opponent. They gain control of this artifact.| +Anticausal Vestige|Edge of Eternities|1|R|{6}|Creature - Eldrazi|7|5|Whenever an artifact you control enters, put a loyalty counter on Tezzeret.$0: Untap target artifact or creature. If it's an artifact creature, put a +1/+1 counter on it.$-3: Search your library for an artifact card with mana value 1 or less, reveal it, put it in your hand, then shuffle.$-7: You get an emblem with "At the beginning of combat on your turn, put three +1/+1 counters on target artifact you control. If it's not a creature, it becomes a 0/0 Robot artifact creature."| Tezzeret, Cruel Captain|Edge of Eternities|2|M|{3}|Legendary Planeswalker - Tezzeret|4|Whenever an artifact you control enters, put a loyalty counter on Tezzeret.$0: Untap target artifact or creature. If it's an artifact creature, put a +1/+1 counter on it.$-3: Search your library for an artifact card with mana value 1 or less, reveal it, put it in your hand, then shuffle.$-7: You get an emblem with "At the beginning of combat on your turn, put three +1/+1 counters on target artifact you control. If it's not a creature, it becomes a 0/0 Robot artifact creature."| The Seriema|Edge of Eternities|35|R|{1}{W}{W}|Legendary Artifact - Spacecraft|||When The Seriema enters, search your library for a legendary creature card, reveal it, put it into your hand, then shuffle.$Station$STATION 7+$Flying$Other tapped legendary creatures you control have indestructible.$5/5| Embrace Oblivion|Edge of Eternities|98|C|{B}|Sorcery|||As an additional cost to cast this spell, sacrifice an artifact or creature.$Destroy target creature or Spacecraft.|