From 9485d61c5cc055e99fc0da86f4f7f0cb2c2732ba Mon Sep 17 00:00:00 2001 From: theelk801 Date: Wed, 19 Mar 2025 10:18:20 -0400 Subject: [PATCH] [TDM] Implement Qarsi Revenant --- Mage.Sets/src/mage/cards/a/AgentOfKotis.java | 18 +--- Mage.Sets/src/mage/cards/q/QarsiRevenant.java | 54 ++++++++++++ .../src/mage/sets/TarkirDragonstorm.java | 1 + .../mage/abilities/common/RenewAbility.java | 83 +++++++++++++++++++ 4 files changed, 140 insertions(+), 16 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/q/QarsiRevenant.java create mode 100644 Mage/src/main/java/mage/abilities/common/RenewAbility.java diff --git a/Mage.Sets/src/mage/cards/a/AgentOfKotis.java b/Mage.Sets/src/mage/cards/a/AgentOfKotis.java index 4ec05f88a3d..185970c3989 100644 --- a/Mage.Sets/src/mage/cards/a/AgentOfKotis.java +++ b/Mage.Sets/src/mage/cards/a/AgentOfKotis.java @@ -1,19 +1,12 @@ package mage.cards.a; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.ActivateAsSorceryActivatedAbility; -import mage.abilities.costs.common.ExileSourceFromGraveCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.common.RenewAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.counters.CounterType; -import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -31,14 +24,7 @@ public final class AgentOfKotis extends CardImpl { this.toughness = new MageInt(1); // Renew -- {3}{U}, Exile this card from your graveyard: Put two +1/+1 counters on target creature. Activate only as a sorcery. - Ability ability = new ActivateAsSorceryActivatedAbility( - Zone.GRAVEYARD, - new AddCountersTargetEffect(CounterType.P1P1.createInstance()), - new ManaCostsImpl<>("{3}{U}") - ); - ability.addCost(new ExileSourceFromGraveCost()); - ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability.setAbilityWord(AbilityWord.RENEW)); + this.addAbility(new RenewAbility("{3}{U}", CounterType.P1P1.createInstance(2))); } private AgentOfKotis(final AgentOfKotis card) { diff --git a/Mage.Sets/src/mage/cards/q/QarsiRevenant.java b/Mage.Sets/src/mage/cards/q/QarsiRevenant.java new file mode 100644 index 00000000000..0386db198e8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/q/QarsiRevenant.java @@ -0,0 +1,54 @@ +package mage.cards.q; + +import mage.MageInt; +import mage.abilities.common.RenewAbility; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class QarsiRevenant extends CardImpl { + + public QarsiRevenant(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); + + this.subtype.add(SubType.VAMPIRE); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // Renew -- {2}{B}, Exile this card from your graveyard: Put a flying counter, a deathtouch counter, and a lifelink counter on target creature. Activate only as a sorcery. + this.addAbility(new RenewAbility( + "{2}{B}", + CounterType.FLYING.createInstance(), + CounterType.DEATHTOUCH.createInstance(), + CounterType.LIFELINK.createInstance() + )); + } + + private QarsiRevenant(final QarsiRevenant card) { + super(card); + } + + @Override + public QarsiRevenant copy() { + return new QarsiRevenant(this); + } +} diff --git a/Mage.Sets/src/mage/sets/TarkirDragonstorm.java b/Mage.Sets/src/mage/sets/TarkirDragonstorm.java index 3915d32884b..3a33c8b1789 100644 --- a/Mage.Sets/src/mage/sets/TarkirDragonstorm.java +++ b/Mage.Sets/src/mage/sets/TarkirDragonstorm.java @@ -42,6 +42,7 @@ public final class TarkirDragonstorm extends ExpansionSet { cards.add(new SetCardInfo("Mox Jasper", 246, Rarity.MYTHIC, mage.cards.m.MoxJasper.class)); cards.add(new SetCardInfo("Narset, Jeskai Waymaster", 209, Rarity.RARE, mage.cards.n.NarsetJeskaiWaymaster.class)); cards.add(new SetCardInfo("Plains", 277, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Qarsi Revenant", 86, Rarity.RARE, mage.cards.q.QarsiRevenant.class)); cards.add(new SetCardInfo("Rally the Monastery", 19, Rarity.UNCOMMON, mage.cards.r.RallyTheMonastery.class)); cards.add(new SetCardInfo("Reigning Victor", 216, Rarity.COMMON, mage.cards.r.ReigningVictor.class)); cards.add(new SetCardInfo("Ringing Strike Mastery", 53, Rarity.COMMON, mage.cards.r.RingingStrikeMastery.class)); diff --git a/Mage/src/main/java/mage/abilities/common/RenewAbility.java b/Mage/src/main/java/mage/abilities/common/RenewAbility.java new file mode 100644 index 00000000000..7a533e1b204 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/RenewAbility.java @@ -0,0 +1,83 @@ +package mage.abilities.common; + +import mage.abilities.Ability; +import mage.abilities.costs.common.ExileSourceFromGraveCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.constants.AbilityWord; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.Counter; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; +import mage.util.CardUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public class RenewAbility extends ActivateAsSorceryActivatedAbility { + + public RenewAbility(String manaString, Counter... counters) { + super(Zone.GRAVEYARD, new RenewEffect(counters), new ManaCostsImpl<>(manaString)); + this.addCost(new ExileSourceFromGraveCost()); + this.addTarget(new TargetCreaturePermanent()); + this.setAbilityWord(AbilityWord.RENEW); + } + + private RenewAbility(final RenewAbility ability) { + super(ability); + } + + @Override + public RenewAbility copy() { + return new RenewAbility(this); + } +} + +class RenewEffect extends OneShotEffect { + + private final List counters = new ArrayList<>(); + + RenewEffect(Counter... counters) { + super(Outcome.Benefit); + for (Counter counter : counters) { + this.counters.add(counter); + } + staticText = makeText(this.counters); + } + + private RenewEffect(final RenewEffect effect) { + super(effect); + for (Counter counter : effect.counters) { + this.counters.add(counter.copy()); + } + } + + @Override + public RenewEffect copy() { + return new RenewEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent == null) { + return false; + } + for (Counter counter : counters) { + permanent.addCounters(counter, source, game); + } + return true; + } + + private static String makeText(List counters) { + return "put " + CardUtil.concatWithAnd( + counters.stream().map(Counter::getDescription).collect(Collectors.toList()) + ) + " on target creature"; + } +}