From 9285b7e78a0e2c9a86898cb69b454c746eafb98c Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 10 Apr 2025 18:26:13 -0400 Subject: [PATCH] [TDM] Implement Perennation --- .../src/mage/cards/g/GracefulRestoration.java | 2 +- Mage.Sets/src/mage/cards/p/Perennation.java | 36 +++++++++++++++ Mage.Sets/src/mage/cards/r/RakdosJoinsUp.java | 2 +- .../mage/cards/t/TheRevelationsOfEzio.java | 4 +- .../src/mage/sets/TarkirDragonstorm.java | 1 + ...dToBattlefieldWithCounterTargetEffect.java | 44 +++++++++++-------- 6 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/p/Perennation.java diff --git a/Mage.Sets/src/mage/cards/g/GracefulRestoration.java b/Mage.Sets/src/mage/cards/g/GracefulRestoration.java index fed8e25db2f..3421be44ed7 100644 --- a/Mage.Sets/src/mage/cards/g/GracefulRestoration.java +++ b/Mage.Sets/src/mage/cards/g/GracefulRestoration.java @@ -32,7 +32,7 @@ public final class GracefulRestoration extends CardImpl { // Choose one — // • Return target creature card from your graveyard to the battlefield with an additional +1/+1 counter on it. - this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(CounterType.P1P1.createInstance(), true)); + this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(true, CounterType.P1P1.createInstance())); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); // • Return up to two target creature cards with power 2 or less from your graveyard to the battlefield. diff --git a/Mage.Sets/src/mage/cards/p/Perennation.java b/Mage.Sets/src/mage/cards/p/Perennation.java new file mode 100644 index 00000000000..ad266c96dce --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/Perennation.java @@ -0,0 +1,36 @@ +package mage.cards.p; + +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldWithCounterTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Perennation extends CardImpl { + + public Perennation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{W}{B}{G}"); + + // Return target permanent card from your graveyard to the battlefield with a hexproof counter and an indestructible counter on it. + this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect( + CounterType.HEXPROOF.createInstance(), CounterType.INDESTRUCTIBLE.createInstance() + )); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_PERMANENT)); + } + + private Perennation(final Perennation card) { + super(card); + } + + @Override + public Perennation copy() { + return new Perennation(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RakdosJoinsUp.java b/Mage.Sets/src/mage/cards/r/RakdosJoinsUp.java index 6750ef7d2c9..493077261e8 100644 --- a/Mage.Sets/src/mage/cards/r/RakdosJoinsUp.java +++ b/Mage.Sets/src/mage/cards/r/RakdosJoinsUp.java @@ -43,7 +43,7 @@ public final class RakdosJoinsUp extends CardImpl { // When Rakdos Joins Up enters the battlefield, return target creature card from your graveyard to the battlefield with two additional +1/+1 counters on it. Ability ability = new EntersBattlefieldTriggeredAbility( - new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(CounterType.P1P1.createInstance(2), true) + new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(true, CounterType.P1P1.createInstance(2)) ); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/t/TheRevelationsOfEzio.java b/Mage.Sets/src/mage/cards/t/TheRevelationsOfEzio.java index 28664c0c876..cc52367e98d 100644 --- a/Mage.Sets/src/mage/cards/t/TheRevelationsOfEzio.java +++ b/Mage.Sets/src/mage/cards/t/TheRevelationsOfEzio.java @@ -61,7 +61,7 @@ public final class TheRevelationsOfEzio extends CardImpl { sagaAbility.addChapterEffect( this, SagaChapter.CHAPTER_III, SagaChapter.CHAPTER_III, ability -> { - ability.addEffect(new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(CounterType.P1P1.createInstance(), true)); + ability.addEffect(new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(true, CounterType.P1P1.createInstance())); ability.addTarget(new TargetCardInYourGraveyard(assassinFilter)); } ); @@ -116,4 +116,4 @@ class TheRevelationsOfEzioTriggeredAbility extends DelayedTriggeredAbility { public String getRule() { return "Whenever an Assassin you control attacks this turn, put a +1/+1 counter on it."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/TarkirDragonstorm.java b/Mage.Sets/src/mage/sets/TarkirDragonstorm.java index e1984864701..f797ae0ada3 100644 --- a/Mage.Sets/src/mage/sets/TarkirDragonstorm.java +++ b/Mage.Sets/src/mage/sets/TarkirDragonstorm.java @@ -181,6 +181,7 @@ public final class TarkirDragonstorm extends ExpansionSet { cards.add(new SetCardInfo("Opulent Palace", 264, Rarity.UNCOMMON, mage.cards.o.OpulentPalace.class)); cards.add(new SetCardInfo("Osseous Exhale", 17, Rarity.COMMON, mage.cards.o.OsseousExhale.class)); cards.add(new SetCardInfo("Overwhelming Surge", 115, Rarity.UNCOMMON, mage.cards.o.OverwhelmingSurge.class)); + cards.add(new SetCardInfo("Perennation", 212, Rarity.MYTHIC, mage.cards.p.Perennation.class)); cards.add(new SetCardInfo("Piercing Exhale", 151, Rarity.COMMON, mage.cards.p.PiercingExhale.class)); cards.add(new SetCardInfo("Plains", 277, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Poised Practitioner", 18, Rarity.COMMON, mage.cards.p.PoisedPractitioner.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardToBattlefieldWithCounterTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardToBattlefieldWithCounterTargetEffect.java index 2bf4ce8bc1f..7d85a7a1a30 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardToBattlefieldWithCounterTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardToBattlefieldWithCounterTargetEffect.java @@ -7,6 +7,8 @@ import mage.counters.Counters; import mage.game.Game; import mage.util.CardUtil; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; /** @@ -17,15 +19,17 @@ public class ReturnFromGraveyardToBattlefieldWithCounterTargetEffect extends Ret private final Counters counters; private final String counterText; - public ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(Counter counter) { - this(counter, false); + public ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(Counter... counters) { + this(false, counters); } - public ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(Counter counter, boolean additional) { + public ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(boolean additional, Counter... counters) { super(false); this.counters = new Counters(); - this.counters.addCounter(counter); - this.counterText = makeText(counter, additional); + for (Counter counter : counters) { + this.counters.addCounter(counter); + } + this.counterText = makeText(additional, counters); } protected ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(final ReturnFromGraveyardToBattlefieldWithCounterTargetEffect effect) { @@ -47,22 +51,26 @@ public class ReturnFromGraveyardToBattlefieldWithCounterTargetEffect extends Ret return super.apply(game, source); } - private String makeText(Counter counter, boolean additional) { - StringBuilder sb = new StringBuilder(" with "); - if (counter.getCount() == 1) { - if (additional) { - sb.append("an additional ").append(counter.getName()); + private static String makeText(boolean additional, Counter... counters) { + List strings = new ArrayList<>(); + for (Counter counter : counters) { + StringBuilder sb = new StringBuilder(); + if (counter.getCount() == 1) { + if (additional) { + sb.append("an additional ").append(counter.getName()); + } else { + sb.append(CardUtil.addArticle(counter.getName())); + } + sb.append(" counter"); } else { - sb.append(CardUtil.addArticle(counter.getName())); + sb.append(CardUtil.numberToText(counter.getCount())); + sb.append(additional ? " additional " : " "); + sb.append(counter.getName()); + sb.append(" counters"); } - sb.append(" counter"); - } else { - sb.append(CardUtil.numberToText(counter.getCount())); - sb.append(additional ? " additional " : " "); - sb.append(counter.getName()); - sb.append(" counters"); + strings.add(sb.toString()); } - return sb.toString(); + return " with " + CardUtil.concatWithAnd(strings); } @Override