From 1fece8781918543bf987aad2e4d64d74a52f8972 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 28 Oct 2022 09:59:32 -0400 Subject: [PATCH] [BRO] Implemented Titania, Voice of Gaea / Argoth, Sanctum of Nature / Titania, Gaea Incarnate --- .../mage/cards/a/ArgothSanctumOfNature.java | 82 +++++++++++++ .../mage/cards/t/TitaniaGaeaIncarnate.java | 112 ++++++++++++++++++ .../src/mage/cards/t/TitaniaVoiceOfGaea.java | 107 +++++++++++++++++ Mage.Sets/src/mage/sets/TheBrothersWar.java | 3 + 4 files changed, 304 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/ArgothSanctumOfNature.java create mode 100644 Mage.Sets/src/mage/cards/t/TitaniaGaeaIncarnate.java create mode 100644 Mage.Sets/src/mage/cards/t/TitaniaVoiceOfGaea.java diff --git a/Mage.Sets/src/mage/cards/a/ArgothSanctumOfNature.java b/Mage.Sets/src/mage/cards/a/ArgothSanctumOfNature.java new file mode 100644 index 00000000000..f4321fb91f3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArgothSanctumOfNature.java @@ -0,0 +1,82 @@ +package mage.cards.a; + +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.MillCardsControllerEffect; +import mage.abilities.effects.common.TapSourceEffect; +import mage.abilities.mana.GreenManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.permanent.token.BearToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ArgothSanctumOfNature extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent(); + + static { + filter.add(SuperType.LEGENDARY.getPredicate()); + filter.add(new ColorPredicate(ObjectColor.GREEN)); + } + + private static final Condition condition + = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0); + + public ArgothSanctumOfNature(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.meldsWithClazz = mage.cards.t.TitaniaVoiceOfGaea.class; + + // Argoth, Sanctum of Nature enters the battlefield tapped unless you control a legendary green creature. + this.addAbility(new EntersBattlefieldAbility( + new ConditionalOneShotEffect(new TapSourceEffect(), condition, ""), + "tapped unless you control a legendary green creature" + )); + + // {T}: Add {G}. + this.addAbility(new GreenManaAbility()); + + // {2}{G}{G}, {T}: Create a 2/2 green Bear creature token, then mill three cards. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + new CreateTokenEffect(new BearToken()), new ManaCostsImpl<>("{2}{G}{G}") + ); + ability.addCost(new TapSourceCost()); + ability.addEffect(new MillCardsControllerEffect(3).concatBy(", then")); + this.addAbility(ability); + + // (Melds with Titania, Voice of Gaea.) + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new InfoEffect("(Melds with Titania, Voice of Gaea.)") + )); + } + + private ArgothSanctumOfNature(final ArgothSanctumOfNature card) { + super(card); + } + + @Override + public ArgothSanctumOfNature copy() { + return new ArgothSanctumOfNature(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TitaniaGaeaIncarnate.java b/Mage.Sets/src/mage/cards/t/TitaniaGaeaIncarnate.java new file mode 100644 index 00000000000..deb1c6ce09a --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TitaniaGaeaIncarnate.java @@ -0,0 +1,112 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.LandsYouControlCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.ReachAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardSetInfo; +import mage.cards.MeldCard; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.token.custom.CreatureToken; +import mage.players.Player; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TitaniaGaeaIncarnate extends MeldCard { + + public TitaniaGaeaIncarnate(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.AVATAR); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + this.color.setGreen(true); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // Titania, Gaea Incarnate's power and toughness are each equal to the number of lands you control. + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new SetBasePowerToughnessSourceEffect(LandsYouControlCount.instance, Duration.EndOfGame) + )); + + // When Titania, Gaea Incarnate enters the battlefield, return all land cards from your graveyard to the battlefield tapped. + this.addAbility(new EntersBattlefieldTriggeredAbility(new TitaniaGaeaIncarnateEffect())); + + // {3}{G}: Put four +1/+1 counters on target land you control. It becomes a 0/0 Elemental creature with haste. It's still a land. + Ability ability = new SimpleActivatedAbility( + new AddCountersTargetEffect(CounterType.P1P1.createInstance(4)), new ManaCostsImpl<>("{3}{G}") + ); + ability.addEffect(new BecomesCreatureTargetEffect( + new CreatureToken(0, 0, "", SubType.ELEMENTAL) + .withAbility(HasteAbility.getInstance()), + false, true, Duration.Custom + ).setText("It becomes a 0/0 Elemental creature with haste. It's still a land.")); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + this.addAbility(ability); + } + + private TitaniaGaeaIncarnate(final TitaniaGaeaIncarnate card) { + super(card); + } + + @Override + public TitaniaGaeaIncarnate copy() { + return new TitaniaGaeaIncarnate(this); + } +} + +class TitaniaGaeaIncarnateEffect extends OneShotEffect { + + TitaniaGaeaIncarnateEffect() { + super(Outcome.Benefit); + staticText = "return all land cards from your graveyard to the battlefield tapped"; + } + + private TitaniaGaeaIncarnateEffect(final TitaniaGaeaIncarnateEffect effect) { + super(effect); + } + + @Override + public TitaniaGaeaIncarnateEffect copy() { + return new TitaniaGaeaIncarnateEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + return player != null && player.moveCards( + player.getGraveyard().getCards(StaticFilters.FILTER_CARD_LAND, game), + Zone.BATTLEFIELD, source, game, true, false, false, null + ); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TitaniaVoiceOfGaea.java b/Mage.Sets/src/mage/cards/t/TitaniaVoiceOfGaea.java new file mode 100644 index 00000000000..0a4c96edad0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TitaniaVoiceOfGaea.java @@ -0,0 +1,107 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.condition.CompoundCondition; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.CardsInControllerGraveyardCondition; +import mage.abilities.condition.common.MeldCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.MeldEffect; +import mage.abilities.keyword.ReachAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeGroupEvent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TitaniaVoiceOfGaea extends CardImpl { + + private static final Condition condition = new CompoundCondition( + new CardsInControllerGraveyardCondition(4, StaticFilters.FILTER_CARD_LAND), + new MeldCondition("Argoth, Sanctum of Nature", CardType.LAND) + ); + + public TitaniaVoiceOfGaea(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + this.meldsWithClazz = mage.cards.a.ArgothSanctumOfNature.class; + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // Whenever one or more land cards are put into your graveyard from anywhere, you gain 2 life. + this.addAbility(new TitaniaVoiceOfGaeaTriggeredAbility()); + + // At the beginning of your upkeep, if there are four or more land cards in your graveyard and you both own and control Titania, Voice of Gaea and a land named Argoth, Sanctum of Nature, exile them, then meld them into Titania, Gaea Incarnate. + this.addAbility(new ConditionalInterveningIfTriggeredAbility( + new BeginningOfUpkeepTriggeredAbility(new MeldEffect( + "Argoth, Sanctum of Nature", "Titania, Gaea Incarnate" + ), TargetController.YOU, false), condition, "At the beginning of your upkeep, " + + "if there are four or more land cards in your graveyard and you both own and control {this} " + + "and a land named Argoth, Sanctum of Nature, exile them, then meld them into Titania, Gaea Incarnate." + )); + } + + private TitaniaVoiceOfGaea(final TitaniaVoiceOfGaea card) { + super(card); + } + + @Override + public TitaniaVoiceOfGaea copy() { + return new TitaniaVoiceOfGaea(this); + } +} + +class TitaniaVoiceOfGaeaTriggeredAbility extends TriggeredAbilityImpl { + + public TitaniaVoiceOfGaeaTriggeredAbility() { + super(Zone.BATTLEFIELD, new GainLifeEffect(2)); + } + + private TitaniaVoiceOfGaeaTriggeredAbility(final TitaniaVoiceOfGaeaTriggeredAbility ability) { + super(ability); + } + + @Override + public TitaniaVoiceOfGaeaTriggeredAbility copy() { + return new TitaniaVoiceOfGaeaTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE_GROUP; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + ZoneChangeGroupEvent zEvent = (ZoneChangeGroupEvent) event; + return zEvent != null + && zEvent.getToZone() == Zone.GRAVEYARD + && zEvent.getCards() != null + && zEvent.getCards() + .stream() + .filter(card -> card.isLand(game)) + .map(Card::getOwnerId) + .anyMatch(this::isControlledBy); + } + + @Override + public String getRule() { + return "Whenever one or more land cards are put into your graveyard from anywhere, you gain 2 life."; + } +} diff --git a/Mage.Sets/src/mage/sets/TheBrothersWar.java b/Mage.Sets/src/mage/sets/TheBrothersWar.java index c52482b96b7..60842699c8e 100644 --- a/Mage.Sets/src/mage/sets/TheBrothersWar.java +++ b/Mage.Sets/src/mage/sets/TheBrothersWar.java @@ -20,6 +20,7 @@ public final class TheBrothersWar extends ExpansionSet { this.blockName = "The Brothers' War"; this.hasBoosters = false; // temporary + cards.add(new SetCardInfo("Argoth, Sanctum of Nature", "256a", Rarity.RARE, mage.cards.a.ArgothSanctumOfNature.class)); cards.add(new SetCardInfo("Ashnod's Harvester", 117, Rarity.UNCOMMON, mage.cards.a.AshnodsHarvester.class)); cards.add(new SetCardInfo("Battlefield Forge", 257, Rarity.RARE, mage.cards.b.BattlefieldForge.class)); cards.add(new SetCardInfo("Brushland", 259, Rarity.RARE, mage.cards.b.Brushland.class)); @@ -41,6 +42,8 @@ public final class TheBrothersWar extends ExpansionSet { cards.add(new SetCardInfo("Surge Engine", 81, Rarity.MYTHIC, mage.cards.s.SurgeEngine.class)); cards.add(new SetCardInfo("Swamp", 282, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("The Mightstone and Weakstone", "238a", Rarity.RARE, mage.cards.t.TheMightstoneAndWeakstone.class)); + cards.add(new SetCardInfo("Titania, Gaea Incarnate", "256b", Rarity.MYTHIC, mage.cards.t.TitaniaGaeaIncarnate.class)); + cards.add(new SetCardInfo("Titania, Voice of Gaea", 193, Rarity.MYTHIC, mage.cards.t.TitaniaVoiceOfGaea.class)); cards.add(new SetCardInfo("Underground River", 267, Rarity.RARE, mage.cards.u.UndergroundRiver.class)); cards.add(new SetCardInfo("Urza, Lord Protector", 225, Rarity.MYTHIC, mage.cards.u.UrzaLordProtector.class)); cards.add(new SetCardInfo("Urza, Planeswalker", "238b", Rarity.MYTHIC, mage.cards.u.UrzaPlaneswalker.class));