From 1a62ea36bbafa5e4cfa737585ab248dedda4aac3 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Sun, 11 May 2025 11:45:42 -0400 Subject: [PATCH] [FIN] Implement Zanarkand, Ancient Metropolis --- .../cards/z/ZanarkandAncientMetropolis.java | 87 +++++++++++++++++++ Mage.Sets/src/mage/sets/FinalFantasy.java | 2 + .../cost/adventure/AdventureCardsTest.java | 53 +++++++++++ .../common/ExileAdventureSpellEffect.java | 2 +- 4 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/z/ZanarkandAncientMetropolis.java diff --git a/Mage.Sets/src/mage/cards/z/ZanarkandAncientMetropolis.java b/Mage.Sets/src/mage/cards/z/ZanarkandAncientMetropolis.java new file mode 100644 index 00000000000..e4c0c1623d2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZanarkandAncientMetropolis.java @@ -0,0 +1,87 @@ +package mage.cards.z; + +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.dynamicvalue.common.LandsYouControlCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.hint.common.LandsYouControlHint; +import mage.abilities.mana.GreenManaAbility; +import mage.cards.AdventureCard; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.HeroToken; +import mage.game.permanent.token.Token; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ZanarkandAncientMetropolis extends AdventureCard { + + public ZanarkandAncientMetropolis(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, new CardType[]{CardType.SORCERY}, "", "Lasting Fayth", "{4}{G}{G}"); + + this.subtype.add(SubType.TOWN); + + // This land enters tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // {T}: Add {G}. + this.addAbility(new GreenManaAbility()); + + // Lasting Fayth + // Create a 1/1 colorless Hero creature token. Put a +1/+1 counter on it for each land you control. + this.getSpellCard().getSpellAbility().addEffect(new ZanarkandAncientMetropolisEffect()); + this.getSpellCard().getSpellAbility().addHint(LandsYouControlHint.instance); + this.getSpellCard().finalizeSpell(); + } + + private ZanarkandAncientMetropolis(final ZanarkandAncientMetropolis card) { + super(card); + } + + @Override + public ZanarkandAncientMetropolis copy() { + return new ZanarkandAncientMetropolis(this); + } +} + +class ZanarkandAncientMetropolisEffect extends OneShotEffect { + + ZanarkandAncientMetropolisEffect() { + super(Outcome.Benefit); + staticText = "create a 1/1 colorless Hero creature token. Put a +1/+1 counter on it for each land you control"; + } + + private ZanarkandAncientMetropolisEffect(final ZanarkandAncientMetropolisEffect effect) { + super(effect); + } + + @Override + public ZanarkandAncientMetropolisEffect copy() { + return new ZanarkandAncientMetropolisEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Token token = new HeroToken(); + token.putOntoBattlefield(1, game, source); + int amount = LandsYouControlCount.instance.calculate(game, source, this); + if (amount < 1) { + return true; + } + for (UUID tokenId : token.getLastAddedTokenIds()) { + Permanent permanent = game.getPermanent(tokenId); + if (permanent != null) { + permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/FinalFantasy.java b/Mage.Sets/src/mage/sets/FinalFantasy.java index d815074093f..295ea7b9d9d 100644 --- a/Mage.Sets/src/mage/sets/FinalFantasy.java +++ b/Mage.Sets/src/mage/sets/FinalFantasy.java @@ -124,6 +124,8 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Ultimecia, Time Sorceress", 513, Rarity.UNCOMMON, mage.cards.u.UltimeciaTimeSorceress.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Wastes", 309, Rarity.COMMON, mage.cards.w.Wastes.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("White Mage's Staff", 42, Rarity.COMMON, mage.cards.w.WhiteMagesStaff.class)); + cards.add(new SetCardInfo("Zanarkand, Ancient Metropolis", 293, Rarity.RARE, mage.cards.z.ZanarkandAncientMetropolis.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Zanarkand, Ancient Metropolis", 314, Rarity.RARE, mage.cards.z.ZanarkandAncientMetropolis.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Zell Dincht", 170, Rarity.RARE, mage.cards.z.ZellDincht.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Zell Dincht", 468, Rarity.RARE, mage.cards.z.ZellDincht.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Zenos yae Galvus", 127, Rarity.RARE, mage.cards.z.ZenosYaeGalvus.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java index 473f80354d8..2197d57296d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java @@ -855,4 +855,57 @@ public class AdventureCardsTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Servo Token", 3); assertExileCount(playerA, "Lonesome Unicorn", 1); } + + private static final String zanarkand = "Zanarkand, Ancient Metropolis"; + + @Test + public void test_ZanarkandRegularPlay() { + addCard(Zone.HAND, playerA, zanarkand); + + playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, zanarkand); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertTapped(zanarkand, true); + } + + private static final String fayth = "Lasting Fayth"; + private static final String heroToken = "Hero Token"; + + @Test + public void test_ZanarkandAdventure() { + addCard(Zone.HAND, playerA, zanarkand); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 6); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fayth); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, heroToken, 1); + assertPowerToughness(playerA, heroToken, 1 + 6, 1 + 6); + assertExileCount(playerA, zanarkand, 1); + } + + @Test + public void test_ZanarkandAdventurePlusPlay() { + addCard(Zone.HAND, playerA, zanarkand); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 6); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fayth); + + playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, zanarkand); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, heroToken, 1); + assertPowerToughness(playerA, heroToken, 1 + 6, 1 + 6); + assertTapped(zanarkand, true); + assertExileCount(playerA, zanarkand, 0); + } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java index 706af3cd62a..fa639b927f0 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java @@ -72,7 +72,7 @@ public class ExileAdventureSpellEffect extends OneShotEffect implements MageSing class AdventureCastFromExileEffect extends AsThoughEffectImpl { public AdventureCastFromExileEffect() { - super(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit); + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit); staticText = "Then exile this card. You may cast the creature later from exile."; }