From 7997b4fcd9bb0f2be51f2d040ccd04ad0432a9e1 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Sun, 30 May 2021 14:18:16 -0500 Subject: [PATCH 001/188] [MH2] Implemented Endurance --- Mage.Sets/src/mage/cards/e/Endurance.java | 91 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 92 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/Endurance.java diff --git a/Mage.Sets/src/mage/cards/e/Endurance.java b/Mage.Sets/src/mage/cards/e/Endurance.java new file mode 100644 index 00000000000..146ea4a203c --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/Endurance.java @@ -0,0 +1,91 @@ +package mage.cards.e; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.ExileFromHandCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.EvokeAbility; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.abilities.keyword.FlashAbility; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInHand; + +/** + * + * @author weirddan455 + */ +public final class Endurance extends CardImpl { + + private static final FilterCard filter = new FilterCard("a green card from your hand"); + + static { + filter.add(new ColorPredicate(ObjectColor.GREEN)); + } + + public Endurance(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.INCARNATION); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // When Endurance enters the battlefield, up to one target player puts all the cards from their graveyard on the bottom of their library in a random order. + Ability ability = new EntersBattlefieldTriggeredAbility(new EnduranceEffect()); + ability.addTarget(new TargetPlayer(0, 1, false)); + this.addAbility(ability); + + // Evoke—Exile a green card from your hand. + this.addAbility(new EvokeAbility(new ExileFromHandCost(new TargetCardInHand(filter)))); + } + + private Endurance(final Endurance card) { + super(card); + } + + @Override + public Endurance copy() { + return new Endurance(this); + } +} + +class EnduranceEffect extends OneShotEffect { + + public EnduranceEffect() { + super(Outcome.Detriment); + this.staticText = "up to one target player puts all the cards from their graveyard on the bottom of their library in a random order"; + } + + private EnduranceEffect(final EnduranceEffect effect) { + super(effect); + } + + @Override + public EnduranceEffect copy() { + return new EnduranceEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); + return targetPlayer != null && targetPlayer.putCardsOnBottomOfLibrary(targetPlayer.getGraveyard(), game, source, false); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 0fe7f95727b..d3252b2a817 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -59,6 +59,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Drey Keeper", 194, Rarity.COMMON, mage.cards.d.DreyKeeper.class)); cards.add(new SetCardInfo("Drossforge Bridge", 246, Rarity.COMMON, mage.cards.d.DrossforgeBridge.class)); cards.add(new SetCardInfo("Enchantress's Presence", 283, Rarity.RARE, mage.cards.e.EnchantresssPresence.class)); + cards.add(new SetCardInfo("Endurance", 157, Rarity.MYTHIC, mage.cards.e.Endurance.class)); cards.add(new SetCardInfo("Extruder", 296, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); cards.add(new SetCardInfo("Fire // Ice", 290, Rarity.RARE, mage.cards.f.FireIce.class)); cards.add(new SetCardInfo("Flame Rift", 278, Rarity.UNCOMMON, mage.cards.f.FlameRift.class)); From 55d4c404077a44557e384000b6536bb2bd435feb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 17:19:22 -0400 Subject: [PATCH 002/188] [MH2] updated spoiler and reprints --- Mage.Sets/src/mage/sets/ModernHorizons2.java | 7 +++- Utils/mtg-cards-data.txt | 42 +++++++++++++++++--- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index d3252b2a817..7987008e564 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -46,10 +46,12 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Breya's Apprentice", 117, Rarity.RARE, mage.cards.b.BreyasApprentice.class)); cards.add(new SetCardInfo("Cabal Coffers", 301, Rarity.MYTHIC, mage.cards.c.CabalCoffers.class)); cards.add(new SetCardInfo("Calibrated Blast", 118, Rarity.RARE, mage.cards.c.CalibratedBlast.class)); + cards.add(new SetCardInfo("Chainer, Nightmare Adept", 289, Rarity.RARE, mage.cards.c.ChainerNightmareAdept.class)); cards.add(new SetCardInfo("Chance Encounter", 277, Rarity.RARE, mage.cards.c.ChanceEncounter.class)); cards.add(new SetCardInfo("Chatterstorm", 152, Rarity.COMMON, mage.cards.c.Chatterstorm.class)); cards.add(new SetCardInfo("Constable of the Realm", 10, Rarity.UNCOMMON, mage.cards.c.ConstableOfTheRealm.class)); cards.add(new SetCardInfo("Counterspell", 267, Rarity.UNCOMMON, mage.cards.c.Counterspell.class)); + cards.add(new SetCardInfo("Cursed Totem", 295, Rarity.RARE, mage.cards.c.CursedTotem.class)); cards.add(new SetCardInfo("Dakkon, Shadow Slayer", 192, Rarity.MYTHIC, mage.cards.d.DakkonShadowSlayer.class)); cards.add(new SetCardInfo("Darkmoss Bridge", 245, Rarity.COMMON, mage.cards.d.DarkmossBridge.class)); cards.add(new SetCardInfo("Diamond Lion", 225, Rarity.RARE, mage.cards.d.DiamondLion.class)); @@ -67,8 +69,8 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Flay Essence", 85, Rarity.UNCOMMON, mage.cards.f.FlayEssence.class)); cards.add(new SetCardInfo("Forest", 489, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); - cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); cards.add(new SetCardInfo("Gaea's Will", 162, Rarity.RARE, mage.cards.g.GaeasWill.class)); + cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); cards.add(new SetCardInfo("Goblin Bombardment", 279, Rarity.RARE, mage.cards.g.GoblinBombardment.class)); cards.add(new SetCardInfo("Goldmire Bridge", 247, Rarity.COMMON, mage.cards.g.GoldmireBridge.class)); cards.add(new SetCardInfo("Gorilla Shaman", 280, Rarity.UNCOMMON, mage.cards.g.GorillaShaman.class)); @@ -117,8 +119,10 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Scalding Tarn", 254, Rarity.RARE, mage.cards.s.ScaldingTarn.class)); cards.add(new SetCardInfo("Scurry Oak", 172, Rarity.UNCOMMON, mage.cards.s.ScurryOak.class)); cards.add(new SetCardInfo("Scuttletide", 61, Rarity.UNCOMMON, mage.cards.s.Scuttletide.class)); + cards.add(new SetCardInfo("Sea Drake", 268, Rarity.RARE, mage.cards.s.SeaDrake.class)); cards.add(new SetCardInfo("Seal of Cleansing", 264, Rarity.UNCOMMON, mage.cards.s.SealOfCleansing.class)); cards.add(new SetCardInfo("Seal of Removal", 269, Rarity.UNCOMMON, mage.cards.s.SealOfRemoval.class)); + cards.add(new SetCardInfo("Shardless Agent", 321, Rarity.RARE, mage.cards.s.ShardlessAgent.class)); cards.add(new SetCardInfo("Silverbluff Bridge", 255, Rarity.COMMON, mage.cards.s.SilverbluffBridge.class)); cards.add(new SetCardInfo("Skirge Familiar", 276, Rarity.UNCOMMON, mage.cards.s.SkirgeFamiliar.class)); cards.add(new SetCardInfo("Skophos Reaver", 140, Rarity.COMMON, mage.cards.s.SkophosReaver.class)); @@ -143,6 +147,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Thrasta, Tempest's Roar", 178, Rarity.MYTHIC, mage.cards.t.ThrastaTempestsRoar.class)); cards.add(new SetCardInfo("Timeless Dragon", 35, Rarity.RARE, mage.cards.t.TimelessDragon.class)); cards.add(new SetCardInfo("Timeless Witness", 179, Rarity.UNCOMMON, mage.cards.t.TimelessWitness.class)); + cards.add(new SetCardInfo("Titania, Protector of Argoth", 287, Rarity.MYTHIC, mage.cards.t.TitaniaProtectorOfArgoth.class)); cards.add(new SetCardInfo("Tormod's Cryptkeeper", 239, Rarity.COMMON, mage.cards.t.TormodsCryptkeeper.class)); cards.add(new SetCardInfo("Tourach's Canticle", 103, Rarity.COMMON, mage.cards.t.TourachsCanticle.class)); cards.add(new SetCardInfo("Underworld Hermit", 105, Rarity.UNCOMMON, mage.cards.u.UnderworldHermit.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index f32349b4444..9c35b983e38 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -41344,11 +41344,16 @@ Late to Dinner|Modern Horizons 2|19|C|{3}{W}|Sorcery|||Return target creature ca Out of Time|Modern Horizons 2|23|R|{1}{W}{W}|Enchantment|||When Out of Time enters the battlefield, untap all creatures, then phase them out until Out of Time leaves the battlefield. Put a time counter on Out of Time for each creature phased out this way.$Vanishing| Prismatic Ending|Modern Horizons 2|25|U|{X}{W}|Sorcery|||Converge — Exile target nonland permanent if its mana value is less than or equal to the number of colors of mana spent to cast this spell.| Sanctifier en-Vec|Modern Horizons 2|27|R|{W}{W}|Creature - Human Cleric|2|2|Protection from black and from red$When Sanctifier en-Vec enters the battlefield, exile all cards that are black and red from all graveyards.$If a black or red permanent, spell, or card not on the battlefield would be put into a graveyard, exile it instead.| +Serra's Emissary|Modern Horizons 2|30|M|{4}{W}{W}{W}|Creature - Angel|7|7|Flying$As Serra's Emissary enters the battlefield, choose a card type.$You and creatures you control have protection from the chosen card type.| +Skyblade's Boon|Modern Horizons 2|31|U|{1}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +1/+1 and has flying.${2}{W}: Return Skyblade's Boon to its owner's hand. Activate only if Skyblade's Boon is on the battlefield or in your graveyard.| Solitude|Modern Horizons 2|32|M|{3}{W}{W}|Creature - Elemental Incarnation|3|2|Flash$Lifelink$When Solitude enters the battlefield, exile up to one other target creature. That creature's controller gains life equal to its power.$Evoke—Exile a white card from your hand.| +Thraben Watcher|Modern Horizons 2|34|U|{2}{W}{W}|Creature - Angel|2|2|Flying, vigilance$Other nontoken creatures you control get +1/+1 and have vigilance.| Timeless Dragon|Modern Horizons 2|35|R|{3}{W}{W}|Creature - Dragon|5|5|Flying$Plainscycling {2}$Eternalize {2}{W}{W}| Aeromoeba|Modern Horizons 2|37|C|{3}{U}|Creature - Elemental Beast|2|4|Flying$Discard a card: Switch Aeromoeba's power and toughness until end of turn.| Dress Down|Modern Horizons 2|39|R|{1}{U}|Enchantment|||Flash$When Dress Down enters the battlefield, draw a card.$Creatures lose all abilities.$At the beginning of the end step, sacrifice Dress Down.| +Filigree Attendant|Modern Horizons 2|41|U|{2}{U}{U}|Artifact Creature - Homunculus|*|3|Flying$Filigree Attendant's power is equal to the number of artifacts you control.| Fractured Sanity|Modern Horizons 2|44|R|{U}{U}{U}|Sorcery|||Each opponent mills fourteen cards.$Cycling {1}{U}$When you cycle Fractured Sanity, each opponent mills four cards.| +Ghost-Lit Drifter|Modern Horizons 2|45|U|{2}{U}|Creature - Spirit|2|2|Flying${2}{U}: Another target creature gains flying until end of turn.$Channel — {X}{U}, Discard Ghost-Lit Drifter: X target creatures gain flying until end of turn.| Junk Winder|Modern Horizons 2|48|U|{5}{U}{U}|Creature - Serpent|5|6|Affinity for tokens$Whenever a token enters the battlefield under your control, tap target nonland permanent an opponent controls. It doesn't untap during its controller's next untap step.| Lose Focus|Modern Horizons 2|49|C|{1}{U}|Instant|||Replicate {U}$Counter target spell unless its controller pays {2}.| Lucid Dreams|Modern Horizons 2|50|U|{3}{U}{U}|Sorcery|||Draw X cards, where X is the number of card types among cards in your graveyard.| @@ -41363,32 +41368,38 @@ So Shiny|Modern Horizons 2|63|C|{2}{U}|Enchantment - Aura|||Enchant creature$Whe Step Through|Modern Horizons 2|66|C|{3}{U}{U}|Sorcery|||Return two target creatures to their owners' hands.$Wizardcycling {2}| Subtlety|Modern Horizons 2|67|M|{2}{U}{U}|Creature - Elemental Incarnation|3|3|Flash$Flying$When Subtlety enters the battlefield, choose up to one target creature spell or planeswalker spell. Its owner puts it on the top or bottom of their library.$Evoke—Exile a blue card from your hand.| Suspend|Modern Horizons 2|68|R|{U}|Instant|||Exile target creature and put two time counters on it. If it doesn't have suspend, it gains suspend.| +Svyelun of Sea and Sky|Modern Horizons 2|69|M|{1}{U}{U}|Legendary Creature - Merfolk God|3|4|Svyelun of Sea and Sky has indestructible as long as you control at least two other Merfolk.$Whenever Svyelun attacks, draw a card.$Other Merfolk you control have ward {1}| Sweep the Skies|Modern Horizons 2|70|U|{X}{U}{U}|Sorcery|||Converge — Create a 1/1 colorless Thopter artifact creature token with flying for each color of mana spent to cast this spell.| Vedalken Infiltrator|Modern Horizons 2|73|U|{1}{U}|Creature - Vedalken Rogue|1|3|Vedalken Infiltrator can't be blocked.$Metalcraft — Vedalken Infiltrator gets +1/+0 as long as you control three or more artifacts.| Archfiend of Sorrows|Modern Horizons 2|74|U|{5}{B}{B}|Creature - Demon|4|5|Flying$When Archfiend of Sorrows enters the battlefield, creatures your opponents control get -2/-2 until end of turn.$Unearth {3}{B}{B}| +Archon of Cruelty|Modern Horizons 2|75|M|{6}{B}{B}|Creature - Archon|6|6|Flying$Whenever Archon of Cruelty enters the battlefield or attacks, target opponent sacrifices a creature or planeswalker, discards a card, and loses 3 life. You draw a card and gain 3 life.| Bone Shards|Modern Horizons 2|76|C|{B}|Sorcery|||As an additional cost to cast this spell, sacrifice a creature or discard a card.$Destroy target creature or planeswalker.| Clattering Augur|Modern Horizons 2|79|U|{1}{B}|Creature - Skeleton Shaman|1|1|Clattering Augur can't block.$When Clattering Augur enters the battlefield, you draw a card and you lose 1 life.${2}{B}{B}: Return Clattering Augur from your graveyard to your hand.| Damn|Modern Horizons 2|80|R|{B}{B}|Sorcery|||Destroy target creature. A creature destroyed this way can't be regenerated.$Overload {2}{W}{W}| Discerning Taste|Modern Horizons 2|82|C|{2}{B}|Sorcery|||Look at the top four cards of your library. Put one of them into your hand and the rest into your graveyard. You gain life equal to the greatest power among creature cards put into your graveyard this way.| -Fast of Sanity|Modern Horizons 2|84|U|{3}{B}|Enchantment|||Whenever you discard a card, Fast of Sanity deals 1 damage to any target and you gain 1 life.| +Feast of Sanity|Modern Horizons 2|84|U|{3}{B}|Enchantment|||Whenever you discard a card, Feast of Sanity deals 1 damage to any target and you gain 1 life.| Flay Essence|Modern Horizons 2|85|U|{1}{B}{B}|Sorcery|||Exile target creature or planeswalker. You gain life equal to the number of counters on it.| Grief|Modern Horizons 2|87|M|{2}{B}{B}|Creature - Elemental Incarnation|3|2|Menace$When Grief enters the battlefield, target opponent reveals their hand. You choose a nonland card from it. That player discards that card.$Evoke—Exile a black card from your hand.| Kitchen Imp|Modern Horizons 2|89|C|{3}{B}|Creature - Imp|2|2|Flying, haste$Madness {B}| Legion Vanguard|Modern Horizons 2|90|U|{1}{B}|Creature - Vampire Soldier|2|2|{1}, Sacrifice another creature: Legion Vanguard explores.| Necromancer's Familiar|Modern Horizons 2|94|U|{3}{B}|Creature - Bird Spirit|3|1|Flying$Hellbent — Necromancer's Familiar has lifelink as long as you have no cards in hand.${B}, Discard a card: Necromancer's Familiar gains indestructible until end of turn. Tap it.| +Persist|Modern Horizons 2|96|R|{1}{B}|Sorcery|||Return target nonlegendary creature card from your graveyard to the battlefield with a -1/-1 counter on it.| Profane Tutor|Modern Horizons 2|97|R||Sorcery|||Suspend 2—{1}{B}$Search your library for a card, put that card into your hand, then shuffle.| Sudden Edict|Modern Horizons 2|100|U|{1}{B}|Instant|||Split second$Target player sacrifices a creature.| +Tourach, Dread Cantor|Modern Horizons 2|102|M|{1}{B}|Legendary Creature - Human Cleric|2|1|Kicker {B}{B}$Protection from white$Whenever an opponent discards a card, put a +1/+1 counter on Tourach, Dread Cantor.$When Tourach enters the battelfield, if it was kicked, target opponent discards two cards at random.| Tourach's Canticle|Modern Horizons 2|103|C|{3}{B}|Sorcery|||Target opponent reveals their hand. You choose a card from it. That player discards that card, then discards a card at random.| Underworld Hermit|Modern Horizons 2|105|U|{4}{B}{B}|Creature - Human Peasant|3|3|When Underworld Hermit enters the battlefield, create a number of 1/1 green Squirrel creature tokens equal to your devotion to black.| Unmarked Grave|Modern Horizons 2|106|R|{1}{B}|Sorcery|||Search your library for a nonlegendary card, put that card into your graveyard, then shuffle.| World-Weary|Modern Horizons 2|109|C|{3}{B}{B}|Enchantment - Aura|||Enchant creature$Enchanted creature gets -4/-4.$Basic landcycling {1}{B}| +Young Necromancer|Modern Horizons 2|110|U|{4}{B}|Creature - Human Warlock|2|3|When Young Necromancer enters the battlefield, you may exile two cards from your graveyard. When you do, return target creature card from your graveyard to the battlefield.| Arcbound Whelp|Modern Horizons 2|113|U|{3}{R}|Artifact Creature - Dragon|0|0|Flying${R}: Arcbound Whelp gets +1/+0 until end of turn.$Modular 2| Battle Plan|Modern Horizons 2|114|C|{3}{R}|Enchantment|||At the beginning of combat on your turn, target creature you control gets +2/+0 until end of turn.$Basic landcycling {1}{R}| -Blazing Rootwalla|Modern Horizons 2|115|U|{R}|Creature - Lizard|1|1|{R}: Gets +2/+0 until end of turn. Activate only once each turn.$Madness {0}| +Blazing Rootwalla|Modern Horizons 2|115|U|{R}|Creature - Lizard|1|1|{R}: Blazing Rootwalla gets +2/+0 until end of turn. Activate only once each turn.$Madness {0}| Breya's Apprentice|Modern Horizons 2|117|R|{2}{R}|Artifact Creature - Human Artificer|2|3|When Breya's Apprentice enters the battlefield, create a 1/1 colorless Thopter artifact creature token with flying.${T}, Sacrifice an artifact: Choose one —$• Exile the top card of your library. Until the end of your next turn, you may play that card.$• Target creature gets +2/+0 until end of turn.| Calibrated Blast|Modern Horizons 2|118|R|{2}{R}|Instant|||Reveal cards from the top of your library until you reveal a nonland card. Put the revealed cards on the bottom of your library in a random order. When you reveal a nonland card this way, Calibrated Blast deals damage equal to that card's mana value to any target.$Flashback {3}{R}{R}| Chef's Kiss|Modern Horizons 2|120|R|{1}{R}{R}|Instant|||Gain control of target spell that targets only a single permanent or player. Copy it, then reselect the targets at random for the spell and the copy. The new targets can't be you or a permanent you control.| Dragon's Rage Channeler|Modern Horizons 2|121|U|{R}|Creature - Human Shaman|1|1|Whenever you cast a noncreature spell, surveil 1.$Delirium — As long as there are four or more card types among cards in your graveyard, Dragon's Rage Channeler gets +2/+2, has flying, and attacks each combat if able.| +Fast // Furious|Modern Horizons 2|123|U|{2}{R}|Instant|||Discard a card, then draw two cards.$Furious${3}{R}{R}$Sorcery$Furious deals 3 damage to each creature without flying.| Flame Blitz|Modern Horizons 2|124|U|{R}|Enchantment|||At the beginning of your end step, Flame Blitz deals 5 damage to each planeswalker.$Cycling {2}| Flametongue Yearling|Modern Horizons 2|125|U|{R}{R}|Creature - Kavu|2|1|Multikicker {2}$Flametongue Yearling enters the battlefield with a +1/+1 counter on it for each time it was kicked.$When Flametongue Yearling enters the battlefield, it deals damage equal to its power to target creature.| Galvanic Relay|Modern Horizons 2|127|C|{2}{R}|Sorcery|||Exile the top card of your library. During your next turn, you may play that card.$Storm| @@ -41397,15 +41408,19 @@ Harmonic Prodigy|Modern Horizons 2|132|R|{1}{R}|Creature - Human Wizard|1|3|Prow Obsidian Charmaw|Modern Horizons 2|137|R|{3}{R}{R}|Creature - Dragon|4|4|This spell costs {1} less to cast for each land your opponents control that could produce {C}.$Flying$When Obsidian Charmaw enters the battlefield, destroy target nonbasic land an opponent controls.| Ragavan, Nimble Pilferer|Modern Horizons 2|138|M|{R}|Legendary Creature - Monkey Pirate|2|1|Whenever Ragavan, Nimble Pilferer deals combat damage to a player, create a Treasure token and exile the top card of that player's library. Until end of turn, you may cast that card.$Dash {1}{R}| Skophos Reaver|Modern Horizons 2|140|C|{2}{R}|Creature - Minotaur Warrior|2|3|As long as it's your turn, Skophos Reaver gets +2/+0.$Madness {1}{R}| +Strike It Rich|Modern Horizons 2|141|U|{R}|Sorcery|||Create a Treasure token.$Flashback {2}{R}| Spreading Insurrection|Modern Horizons 2|142|U|{4}{R}|Sorcery|||Gain control of target creature you don't control until end of turn. Untap that creature. It gains haste until end of turn.$Storm| Abundant Harvest|Modern Horizons 2|147|C|{G}|Sorcery|||Choose land or nonland. Reveal cards from the top of your library until you reveal a card of the chosen kind. Put that card into your hand and the rest on the bottom of your library in a random order.| Aeve, Progenitor Ooze|Modern Horizons 2|148|R|{2}{G}{G}{G}|Legendary Creature - Ooze|2|2|Storm$Aeve, Progenitor Ooze isn't legendary as long as it's a token.$Aeve enters the battlefield with a +1/+1 counter on it for each Ooze you control.| Chatterfang, Squirrel General|Modern Horizons 2|151|M|{2}{G}|Legendary Creature - Squirrel Warrior|3|3|Forestwalk$If one or more tokens would be created under your control, those tokens plus that many 1/1 green Squirrel creature tokens are created instead.${B}, Sacrifice X Squirrels: Target creature gets +X/-X until end of turn.| Chatterstorm|Modern Horizons 2|152|C|{1}{G}|Sorcery|||Create a 1/1 green Squirrel creature token.$Storm| Endurance|Modern Horizons 2|157|M|{1}{G}{G}|Creature - Elemental Incarnation|3|4|Flash$Reach$When Endurance enters the battlefield, up to one target player puts all the cards from their graveyard on the bottom of their library in a random order.$Evoke—Exile a green card from your hand.| +Fae Offering|Modern Horizons 2|158|U|{2}{G}|Enchantment|||At the beginning of each end step, if you've cast both a creature spell and a noncreature spell this turn, create a Clue token, a Food token, and a Treasure token.| Gaea's Will|Modern Horizons 2|162|R||Sorcery|||Suspend 4—{G}$Until end of turn, you may play land cards and cast spells from your graveyard.$If a card would be put into your graveyard from anywhere this turn, exile that card instead.| +Glinting Creeper|Modern Horizons 2|164|U|{4}{G}|Creature - Plant|0|0|Converge — Glinting Creeper enters the battlefield with two +1/+1 counters on it for each color of mana spent to cast it.$Glinting Creeper can't be blocked by creatures with power 2 or less.| Herd Baloth|Modern Horizons 2|165|U|{3}{G}{G}|Creature - Beast|4|4|Whenever one or more +1/+1 counters are put on Herd Baloth, you may create a 4/4 green Beast creature token.| Ignoble Hierarch|Modern Horizons 2|166|R|{G}|Creature - Goblin Shaman|0|1|Exalted${T}: Add {B}, {R}, or {G}.| +Jade Avenger|Modern Horizons 2|167|C|{1}{G}|Creature - Frog Samurai|2|2|Bushido 2| Orchard Strider|Modern Horizons 2|169|C|{4}{G}{G}|Creature - Treefolk|6|4|When Orchard Strider enters the battlefield, create two Food tokens.$Basic landcycling {1}{G}| Rift Sower|Modern Horizons 2|170|C|{2}{G}|Creature - Elf Druid|1|3|{T}: Add one mana of any color.$Suspend 2—{G}| Sanctum Weaver|Modern Horizons 2|171|R|{1}{G}|Enchantment Creature - Dryad|0|2|{T}: Add X mana of any one color, where X is the number of enchantments you control.| @@ -41413,37 +41428,47 @@ Scurry Oak|Modern Horizons 2|172|U|{2}{G}|Creature - Treefolk|1|2|Evolve$Wheneve Squirrel Sanctuary|Modern Horizons 2|174|U|{G}|Enchantment|||When Squirrel Sanctuary enters the battlefield, create a 1/1 green Squirrel creature token.$Whenever a nontoken creature you control dies, you may pay {1}. If you do, return Squirrel Sanctuary to its owner's hand.| Squirrel Sovereign|Modern Horizons 2|175|U|{1}{G}|Creature - Squirrel Noble|2|2|Other Squirrels you control get +1/+1.| Sylvan Anthem|Modern Horizons 2|176|R|{G}{G}|Enchantment|||Green creatures you control get +1/+1.$Whenever a green creature enters the battlefield under your control, scry 1.| +Terarmorph|Modern Horizons 2|177|U|{3}{G}|Sorcery|||Search your library for a basic land card, put it into the battlefield, then shuffle.$Rebound| Thrasta, Tempest's Roar|Modern Horizons 2|178|M|{10}{G}{G}|Legendary Creature - Dinosaur|7|7|This spell costs {3} less to cast for each other spell cast this turn.$Trample, haste$Trample over planeswalkers$Thrasta, Tempest's Roar has hexproof as long as it entered the battlefield this turn.| -Timeless Witness|Modern Horizons 2|179|U|{2}{G}{G}|Creature - Human Shaman|2|1|When Timeless Witness enters the battlefield, you may return target card from your graveyard to your hand.$Eternalize {5}{G}{G}| +Timeless Witness|Modern Horizons 2|179|U|{2}{G}{G}|Creature - Human Shaman|2|1|When Timeless Witness enters the battlefield, return target card from your graveyard to your hand.$Eternalize {5}{G}{G}| +Tireless Provisioner|Modern Horizons 2|180|U|{2}{G}|Creature - Elf Scout|3|2|Landfall — Whenever a land enters the battelfield under your control, create a Food token or a Treasure token.| Urban Daggertooth|Modern Horizons 2|181|C|{2}{G}{G}|Creature - Dinosaur|4|3|Vigilance$Enrage — Whenever Urban Daggertooth is dealt damage, proliferate.| Verdant Command|Modern Horizons 2|182|R|{1}{G}|Instant|||Choose two —$• Target player creates two tapped 1/1 green Squirrel creature tokens.$• Counter target loyalty ability of a planeswalker.$• Exile target card from a graveyard.$• Target player gains 3 life.| Arcbound Shikari|Modern Horizons 2|184|U|{1}{R}{W}|Artifact Creature - Cat Soldier|0|0|First Strike$When Arcbound Shikari enters the battlefield, put a +1/+1 counter on each other artifact creature you control.$Modular 2| Asmoranomardicadaistinaculdacar|Modern Horizons 2|186|R||Legendary Creature - Human Wizard|3|3|As long as you've discarded a card this turn, you may pay {B/R} to cast this spell.$When Asmoranomardicadaistinaculdacar enters the battlefield, you may search your library for a card named The Underworld Cookbook, reveal it, put it into your hand, then shuffle.$Sacrifice two Foods: Target creature deals 6 damage to itself.| Carth the Lion|Modern Horizons 2|189|R|{2}{B}{G}|Legendary Creature - Human Warrior|3|5|Whenever Carth the Lion enters the battlefield or a planeswalker you control dies, look at the top seven cards of your library. You may reveal a planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.$Planeswalkers' loyalty abilities you activate cost an additional {+1} to activate.| +Combine Chrysalis|Modern Horizons 2|191|U|{G}{U}|Artifact|||Creature tokens you control have flying.${2}{G}{U}, {T}, Sacrifice a token: Create a 4/4 green Beast creature token. Activate only as a sorcery.| Dakkon, Shadow Slayer|Modern Horizons 2|192|M|{W}{U}{B}|Legendary Planeswalker - Dakkon|0|Dakkon, Shadow Slayer enters the battlefield with a number of loyalty counters on him equal to the number of lands you control.$+1: Surveil 2.$−3: Exile target creature.$−6: You may put an artifact card from your hand or graveyard onto the battlefield.| Drey Keeper|Modern Horizons 2|194|C|{3}{B}{G}|Creature - Elf Druid|2|2|When Drey Keeper enters the battlefield, create two 1/1 green Squirrel creature tokens.${3}{B}: Squirrels you control get +1/+0 and gain menace until end of turn.| Garth One-Eye|Modern Horizons 2|197|M|{W}{U}{B}{R}{G}|Legendary Creature - Human Wizard|5|5|{T}: Choose a card name that hasn't been chosen from among Disenchant, Braingeyser, Terror, Shivan Dragon, Regrowth, or Black Lotus. Create a copy of the card with the chosen name. You may cast the copy.| -Geyadrone Dihada|Modern Horizons 2|199|M|{1}{U}{B}{R}|Legendary Planeswalker - Dihada|4|Protection from permanents with corruption counters on them.$+1: Each opponent loses 2 life and you gain 2 life. Put a corruption counter on up to one other target creature or planeswalker.$−3: Gain control of target creature or planeswalker until end of tun. Untap it and put a corruption counter on it. It gains haste until end of turn.$−7: Gain control of each permanent with a corruption counter on it.| +General Ferrous Rokiric|Modern Horizons 2|198|R|{1}{R}{W}|Legendary Creature - Human Soldier|3|1|Hexproof from monocolored$Whenever you cast a multicolored spell, create a 4/4 red and white Golem artifact creature token.| +Geyadrone Dihada|Modern Horizons 2|199|M|{1}{U}{B}{R}|Legendary Planeswalker - Dihada|4|Protection from permanents with corruption counters on them$+1: Each opponent loses 2 life and you gain 2 life. Put a corruption counter on up to one other target creature or planeswalker.$−3: Gain control of target creature or planeswalker until end of tun. Untap it and put a corruption counter on it. It gains haste until end of turn.$−7: Gain control of each permanent with a corruption counter on it.| Graceful Restoration|Modern Horizons 2|201|U|{3}{W}{B}|Sorcery|||Choose one —$• Return target creature card from your graveyard to the battlefield with an additional +1/+1 counter on it.$• Return up to two target creature cards with power 2 or less from your graveyard to the battlefield.| Grist, the Hunger Tide|Modern Horizons 2|202|M|{1}{B}{G}|Legendary Planeswalker - Grist|3|As long as Grist, the Hunger Tide isn't on the battlefield, it's a 1/1 Insect creature in addition to its other types.$+1: Create a 1/1 black and green Insect creature token, then mill a card. If an Insect card was milled this way, put a loyalty counter on Grist and repeat this process.$−2: You may sacrifice a creature. When you do, destroy target creature or planeswalker.$−5: Each opponent loses life equal to the number of creature cards in your graveyard.| Lonis, Cryptozoologist|Modern Horizons 2|204|R|{G}{U}|Legendary Creature - Snake Elf Scout|1|2|Whenever another nontoken creature enters the battlefield under your control, investigate.${T}, Sacrifice X Clues: Target opponent reveals the top X cards of their library. You may put a nonland permanent card with mana value X or less from among them onto the battlefield under your control. That player puts the rest on the bottom of their library in a random order.| Master of Death|Modern Horizons 2|205|R|{1}{U}{B}|Creature - Zombie Wizard|3|1|When Master of Death enters the battlefield, surveil 2.$At the beginning of your upkeep, if Master of Death is in your graveyard, you may pay 1 life. If you do, return it to your hand.| +Moderation|Modern Horizons 2|206|R|{1}{W}{U}|Enchantment|||You can't cast more than one spell each turn.$Whenever you cast a spell, draw a card.| Piru, the Volatile|Modern Horizons 2|207|R|{2}{R}{R}{W}{W}{B}{B}|Legendary Creature - Elder Dragon|7|7|Flying, lifelink$At the beginning of your upkeep, sacrifice Piru, the Volatile unless you pay {R}{W}{B}.$When Piru dies, it deals 7 damage to each nonlegendary creature.| Priest of Fell Rites|Modern Horizons 2|208|R|{W}{B}|Creature - Human Warlock|2|2|{T}, Pay 3 life, Sacrifice Priest of Fell Rites: Return target creature card from your graveyard to the battlefield. Activate only as a sorcery.$Unearth {3}{W}{B}| -Prophetic Titan|Modern Horizons 2|209|U|{4}{U}{R}|Creature - Giant Wizard|4|4|Delirium — When Prophetic Titan enters the battlefield, choose one. If there are four or more card types among cards in your graveyard, choose both.$• Prophetic Titan deals 4 damage to any target.$• Look at the top four cards of your library. Put one in your hand and the rest on the bottom of your library in a random order.| +Prophetic Titan|Modern Horizons 2|209|U|{4}{U}{R}|Creature - Giant Wizard|4|4|Delirium — When Prophetic Titan enters the battlefield, choose one. If there are four or more card types among cards in your graveyard, choose both.$• Prophetic Titan deals 4 damage to any target.$• Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in a random order.| Ravenous Squirrel|Modern Horizons 2|211|U|{B/G}|Creature - Squirrel|1|1|Whenever you sacrifice an artifact or creature, put a +1/+1 counter on Ravenous Squirrel.${1}{B}{G}, Sacrifice an artifact or creature: You gain 1 life and draw a card.| Road // Ruin|Modern Horizons 2|212|U|{2}{G}|Instant|||Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.$Ruin${1}{R}{R}$Sorcery$Aftermath$Ruin deals damage to target creature equal to the number of lands you control.| Territorial Kavu|Modern Horizons 2|216|R|{R}{G}|Creature - Kavu|*|*|Domain — Territorial Kavu's power and toughness are each equal to the number of basic land types among lands you control.$Whenever Territorial Kavu attacks, choose one —$• Discard a card. If you do, draw a card.$• Exile up to one target card from a graveyard.| Yusri, Fortune's Flame|Modern Horizons 2|218|R|{1}{U}{R}|Legendary Creature - Efreet|2|3|Flying$Whenever Yusri, Fortune's Flame attacks, choose a number between 1 and 5. Flip that many coins. For each flip you win, draw a card. For each flip you lose, Yursi deals 2 damage to you. If you won five flips this way, you may cast spells from your hand this turn without paying their mana costs.| Academy Manufactor|Modern Horizons 2|219|R|{3}|Artifact Creature - Assembly-Worker|1|3|If you would create a Clue, Food, or Treasure token, instead create one of each.| Altar of the Goyf|Modern Horizons 2|220|U|{5}|Tribal Artifact - Lhurgoyf|||Whenever a creature you control attacks alone, it gets +X/+X until end of turn, where X is the number of card types among cards in all graveyard.$Lhurgoyf creatures you control have trample.| +Batterbone|Modern Horizons 2|221|U|{2}|Artifact - Equipment|||Living weapon$Equipped creature gets +1/+1 and has vigilance and lifelink.$Equip {5}| Bottle Golems|Modern Horizons 2|222|C|{4}|Artifact Creature - Golem|3|3|Trample$When Bottle Golems dies, you gain life equal to its power.| Brainstone|Modern Horizons 2|223|U|{1}|Artifact|||{2},{T}, Sacrifice Brainstone: Draw three cards, then put two cards from your hand on top of your library in any order.| Dermotaxi|Modern Horizons 2|224|R|{2}|Artifact - Vehicle|0|0|Imprint — As Dermotaxi enters the battlefield, exile a creature card from a graveyard.$Tap two untapped creatures you control: Until end of turn, Dermotaxi becomes a copy of the imprinted card, except it's a Vehicle artifact in addition to its other types.| Diamond Lion|Modern Horizons 2|225|R|{2}|Artifact Creature - Cat|2|2|{T}, Discard your hand, Sacrifice Diamond Lion: Add three mana of any one color. Activate only as an instant.| Kaldra Compleat|Modern Horizons 2|227|M|{7}|Legendary Artifact - Equipment|||Living weapon$Indestructible$Equipped creature gets +5/+5 and has first strike, trample, indestructible, haste, and "Whenever this creature deals combat damage to a creature, exile that creature."$Equip {7}| +Liquimetal Torque|Modern Horizons 2|228|U|{2}|Artifact|||{T}: Add {C}.${T}: Target nonland permanent becomes an artifact in addition to its other types until end of turn.| Monoskelion|Modern Horizons 2|229|U|{2}|Artifact Creature - Construct|1|1|Monoskelion enters the battlefield with a +1/+1 counter on it.${1}, Remove a +1/+1 counter from Monoskelion: Monoskelion deals 1 damage to any target.| +Nettlecyst|Modern Horizons 2|231|R|{3}|Artifact - Equipment|||Living weapon$Equipped creature gets +1/+1 for each artifact and/or enchantment you control.$Equip {2}| Sanctuary Raptor|Modern Horizons 2|233|U|{3}|Artifact Creature - Bird|2|1|Flying$Whenever Sanctuary Raptor attacks, if you control three or more tokens, Sanctuary Raptor gets +2/+0 and gains first strike until end of turn.| +Scion of Draco|Modern Horizons 2|234|M|{12}|Artifact Creature - Dragon|4|4|Domain — This spell costs {2} less to cast for each basic land type among lands you control.$Flying$Each creature you control has vigilance if it's white, hexproof if it's blue, lifelink if it's black, first strike if it's red, and trample if it's green.| +Steel Dromedary|Modern Horizons 2|237|U|{3}|Artifact Creature - Camel|2|2|Steel Dromedary enters the battlefield tapped with two +1/+1 counters on it.$Steel Dromedary doesn't untap during your untap step if it has a +1/+1 counter on it.$At the beginning of combat on your turn, you may move a +1/+1 counter from Steel Dromedary onto target creature.| Sword of Hearth and Home|Modern Horizons 2|238|M|{3}|Artifact - Equipment|||Equipped creature gets +2/+2 and has protection from green and from white.$Whenever equipped creature deals combat damage to a player, exile up to one target creature you own, then search your library for a basic land card. Put both cards onto the battlefield under your control, then shuffle.$Equip {2}| Tormod's Cryptkeeper|Modern Horizons 2|239|C|{3}|Artifact Creature - Golem|3|2|Vigilance${T}, Sacrifice Tormod's Cryptkeeper: Exile all cards from target player's graveyard.| The Underworld Cookbook|Modern Horizons 2|240|U|{1}|Artifact|||{T}, Discard a card: Create a Food token.${4}, {T}, Sacrifice The Underworld Cookbook: Return target creature card from your graveyard to your hand.| @@ -41466,11 +41491,13 @@ Tanglepool Bridge|Modern Horizons 2|257|C||Artifact Land|||Tanglepool Bridge ent Thornglint Bridge|Modern Horizons 2|258|C||Artifact Land|||Thornglint Bridge enters the battlefield tapped.$Indestructible${T}: Add {G} or {W}.| Urza's Saga|Modern Horizons 2|259|R||Enchantment Land - Urza’s Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I — Urza's Saga gains "{T}: Add {C}."$II — Urza's Saga gains "{2}, {T}: Create a 0/0 colorless Construct artifact creature token with 'This creature gets +1/+1 for each artifact you control.'"$III — Search your library for an artifact card with mana cost {0} or {1}, put it onto the battlefield, then shuffle.| Verdant Catacombs|Modern Horizons 2|260|R||Land|||{T}, Pay 1 life, Sacrifice Verdant Catacombs: Search your library for a Swamp or Forest card, put it onto the battlefield, then shuffle.| +Yavimaya, Cradle of Growth|Modern Horizons 2|261|R||Legendary Land|||Each land is a Forest in addition to its other land types.| Karmic Guide|Modern Horizons 2|263|R|{3}{W}{W}|Creature - Angel Spirit|2|2|Flying, protection from black$Echo {3}{W}{W}$When Karmic Guide enters the battlefield, return target creature card from your graveyard to the battlefield.| Seal of Cleansing|Modern Horizons 2|264|U|{1}{W}|Enchantment|||Sacrifice Seal of Cleansing: Destroy target artifact or enchantment.| Solitary Confinement|Modern Horizons 2|265|R|{2}{W}|Enchantment|||At the beginning of your upkeep, sacrifice Solitary Confinement unless you discard a card.$Skip your draw step.$You have shroud.$Prevent all damage that would be dealt to you.| Soul Snare|Modern Horizons 2|266|U|{W}|Enchantment|||{W}, Sacrifice Soul Snare: Exile target creature that's attacking you or a planeswalker you control.| Counterspell|Modern Horizons 2|267|U|{U}{U}|Instant|||Counter target spell.| +Sea Drake|Modern Horizons 2|268|R|{2}{U}|Creature - Drake|4|3|Flying$When Sea Drake enters the battlefield, return two target lands you control to their owner's hand.| Seal of Removal|Modern Horizons 2|269|U|{U}|Enchantment|||Sacrifice Seal of Removal: Return target creature to its owner's hand.| Upheaval|Modern Horizons 2|270|R|{4}{U}{U}|Sorcery|||Return all permanents to their owners' hands.| Wonder|Modern Horizons 2|271|R|{3}{U}|Creature - Incarnation|2|2|Flying$As long as Wonder is in your graveyard and you control an Island, creatures you control have flying.| @@ -41488,17 +41515,20 @@ Mogg Salvage|Modern Horizons 2|282|U|{2}{R}|Instant|||If an opponent controls an Enchantress's Presence|Modern Horizons 2|283|R|{2}{G}|Enchantment|||Whenever you cast an enchantment spell, draw a card.| Quirion Ranger|Modern Horizons 2|285|U|{G}|Creature - Elf|1|1|Return a Forest you control to its owner's hand: Untap target creature. Activate only once each turn.| Squirrel Mob|Modern Horizons 2|286|R|{1}{G}{G}|Creature - Squirrel|2|2|Squirrel Mob gets +1/+1 for each other Squirrel on the battlefield.| +Titania, Protector of Argoth|Modern Horizons 2|287|M|{3}{G}{G}|Legendary Creature - Elemental|5|3|When Titania, Protector of Argoth enters the battlefield, return target land card from your graveyard to the battlefield.$Whenever a land you control is put into a graveyard from the battlefield, create a 5/3 green Elemental creature token.| +Chainer, Nightmare Adept|Modern Horizons 2|289|R|{2}{B}{R}|Legendary Creature - Human Minion|3|2|Discard a card: You may cast a creature spell from your graveyard this turn. Activate only once each turn.$Whenever a nontoken creature enters the battlefield under your control, if you didn't cast it from your hand, it gains haste until your next turn.| Fire // Ice|Modern Horizons 2|290|R|{1}{R}|Instant|||Fire deals 2 damage divided as you choose among one or two targets.$Ice${1}{U}$Instant$Tap target permanent.$Draw a card.| Mirari's Wake|Modern Horizons 2|291|M|{3}{G}{W}|Enchantment|||Creatures you control get +1/+1.$Whenever you tap a land for mana, add one mana of any type that land produced.| Sterling Grove|Modern Horizons 2|293|R|{G}{W}|Enchantment|||Other enchantments you control have shroud.${1}, Sacrifice Sterling Grove: Search your library for an enchantment card, reveal it, then shuffle and put the card on top.| Vindicate|Modern Horizons 2|294|R|{1}{W}{B}|Sorcery|||Destroy target permanent.| +Cursed Totem|Modern Horizons 2|295|R|{2}|Artifact|||Activated abilities of creatures can't be activated.| Extruder|Modern Horizons 2|296|U|{4}|Artifact Creature - Juggernaut|4|3|Echo {4}$Sacrifice an artifact: Put a +1/+1 counter on target creature.| Millikin|Modern Horizons 2|297|U|{2}|Artifact Creature - Construct|0|1|{T}, Mill a card: Add {C}.| Nevinyrral's Disk|Modern Horizons 2|298|R|{4}|Artifact|||Nevinyrral's Disk enters the battlefield tapped.${1}, {T}: Destroy all artifacts, creatures, and enchantments.| Zuran Orb|Modern Horizons 2|300|U|{0}|Artifact|||Sacrifice a land: You gain 2 life.| Cabal Coffers|Modern Horizons 2|301|M||Land|||{2}, {T}: Add {B} for each Swamp you control.| Mishra's Factory|Modern Horizons 2|302|U||Land|||{T}: Add {C}.${1}: Mishra's Factory becomes a 2/2 Assembly-Worker artifact creature until end of turn. It's still a land.${T}: Target Assembly-Worker creature gets +1/+1 until end of turn.| -Persist|Modern Horizons 2|430|R|{1}{B}|Sorcery|||Return target nonlegendary creature card from your graveyard to the battlefield with a -1/-1 counter on it.| +Shardless Agent|Modern Horizons 2|321|R|{1}{G}{U}|Artifact Creature - Human Rogue|2|2|Cascade| Plains|Modern Horizons 2|481|C||Basic Land - Plains|||({T}: Add {W}.)| Island|Modern Horizons 2|483|C||Basic Land - Island|||({T}: Add {U}.)| Swamp|Modern Horizons 2|485|C||Basic Land - Swamp|||({T}: Add {B}.)| From 5814325e13a94c4ceafc23e38054a1084e61547b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 17:30:59 -0400 Subject: [PATCH 003/188] [MH2] Implemented Feast of Sanity --- Mage.Sets/src/mage/cards/f/FeastOfSanity.java | 37 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FeastOfSanity.java diff --git a/Mage.Sets/src/mage/cards/f/FeastOfSanity.java b/Mage.Sets/src/mage/cards/f/FeastOfSanity.java new file mode 100644 index 00000000000..42374ecda5c --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FeastOfSanity.java @@ -0,0 +1,37 @@ +package mage.cards.f; + +import mage.abilities.Ability; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DiscardCardControllerTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FeastOfSanity extends CardImpl { + + public FeastOfSanity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); + + // Whenever you discard a card, Feast of Sanity deals 1 damage to any target and you gain 1 life. + Ability ability = new DiscardCardControllerTriggeredAbility(new DamageTargetEffect(1), false); + ability.addEffect(new GainLifeEffect(1).concatBy("and")); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability); + } + + private FeastOfSanity(final FeastOfSanity card) { + super(card); + } + + @Override + public FeastOfSanity copy() { + return new FeastOfSanity(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 7987008e564..2cc6dc3dc94 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -63,6 +63,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Enchantress's Presence", 283, Rarity.RARE, mage.cards.e.EnchantresssPresence.class)); cards.add(new SetCardInfo("Endurance", 157, Rarity.MYTHIC, mage.cards.e.Endurance.class)); cards.add(new SetCardInfo("Extruder", 296, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); + cards.add(new SetCardInfo("Feast of Sanity", 84, Rarity.UNCOMMON, mage.cards.f.FeastOfSanity.class)); cards.add(new SetCardInfo("Fire // Ice", 290, Rarity.RARE, mage.cards.f.FireIce.class)); cards.add(new SetCardInfo("Flame Rift", 278, Rarity.UNCOMMON, mage.cards.f.FlameRift.class)); cards.add(new SetCardInfo("Flametongue Yearling", 125, Rarity.UNCOMMON, mage.cards.f.FlametongueYearling.class)); From 8ac73d7b84564e98914e30d5b0253081ecf30200 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 17:36:47 -0400 Subject: [PATCH 004/188] [MH2] Implemented Jade Avenger --- Mage.Sets/src/mage/cards/j/JadeAvenger.java | 37 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/j/JadeAvenger.java diff --git a/Mage.Sets/src/mage/cards/j/JadeAvenger.java b/Mage.Sets/src/mage/cards/j/JadeAvenger.java new file mode 100644 index 00000000000..b9457873081 --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JadeAvenger.java @@ -0,0 +1,37 @@ +package mage.cards.j; + +import mage.MageInt; +import mage.abilities.keyword.BushidoAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class JadeAvenger extends CardImpl { + + public JadeAvenger(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.FROG); + this.subtype.add(SubType.SAMURAI); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Bushido 2 + this.addAbility(new BushidoAbility(2)); + } + + private JadeAvenger(final JadeAvenger card) { + super(card); + } + + @Override + public JadeAvenger copy() { + return new JadeAvenger(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 2cc6dc3dc94..05fe6963b3a 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -81,6 +81,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Ignoble Hierarch", 166, Rarity.RARE, mage.cards.i.IgnobleHierarch.class)); cards.add(new SetCardInfo("Imperial Recruiter", 281, Rarity.MYTHIC, mage.cards.i.ImperialRecruiter.class)); cards.add(new SetCardInfo("Island", 483, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jade Avenger", 167, Rarity.COMMON, mage.cards.j.JadeAvenger.class)); cards.add(new SetCardInfo("Junk Winder", 48, Rarity.UNCOMMON, mage.cards.j.JunkWinder.class)); cards.add(new SetCardInfo("Karmic Guide", 263, Rarity.RARE, mage.cards.k.KarmicGuide.class)); cards.add(new SetCardInfo("Kitchen Imp", 89, Rarity.COMMON, mage.cards.k.KitchenImp.class)); From 3497337f3c85256623524547281147c3e2abe644 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 17:40:52 -0400 Subject: [PATCH 005/188] [MH2] Implemented Terramorph --- Mage.Sets/src/mage/cards/t/Terramorph.java | 38 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + Utils/mtg-cards-data.txt | 2 +- 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/t/Terramorph.java diff --git a/Mage.Sets/src/mage/cards/t/Terramorph.java b/Mage.Sets/src/mage/cards/t/Terramorph.java new file mode 100644 index 00000000000..5576991e4a7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/Terramorph.java @@ -0,0 +1,38 @@ +package mage.cards.t; + +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.abilities.keyword.ReboundAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Terramorph extends CardImpl { + + public Terramorph(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}"); + + // Search your library for a basic land card, put it into the battlefield, then shuffle. + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect( + new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), false + )); + + // Rebound + this.addAbility(new ReboundAbility()); + } + + private Terramorph(final Terramorph card) { + super(card); + } + + @Override + public Terramorph copy() { + return new Terramorph(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 05fe6963b3a..6b5c5d604ad 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -144,6 +144,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Sweep the Skies", 70, Rarity.UNCOMMON, mage.cards.s.SweepTheSkies.class)); cards.add(new SetCardInfo("Sylvan Anthem", 176, Rarity.RARE, mage.cards.s.SylvanAnthem.class)); cards.add(new SetCardInfo("Tanglepool Bridge", 257, Rarity.COMMON, mage.cards.t.TanglepoolBridge.class)); + cards.add(new SetCardInfo("Terramorph", 177, Rarity.UNCOMMON, mage.cards.t.Terramorph.class)); cards.add(new SetCardInfo("The Underworld Cookbook", 240, Rarity.UNCOMMON, mage.cards.t.TheUnderworldCookbook.class)); cards.add(new SetCardInfo("Thornglint Bridge", 258, Rarity.COMMON, mage.cards.t.ThornglintBridge.class)); cards.add(new SetCardInfo("Thrasta, Tempest's Roar", 178, Rarity.MYTHIC, mage.cards.t.ThrastaTempestsRoar.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 9c35b983e38..85289664fd6 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -41428,7 +41428,7 @@ Scurry Oak|Modern Horizons 2|172|U|{2}{G}|Creature - Treefolk|1|2|Evolve$Wheneve Squirrel Sanctuary|Modern Horizons 2|174|U|{G}|Enchantment|||When Squirrel Sanctuary enters the battlefield, create a 1/1 green Squirrel creature token.$Whenever a nontoken creature you control dies, you may pay {1}. If you do, return Squirrel Sanctuary to its owner's hand.| Squirrel Sovereign|Modern Horizons 2|175|U|{1}{G}|Creature - Squirrel Noble|2|2|Other Squirrels you control get +1/+1.| Sylvan Anthem|Modern Horizons 2|176|R|{G}{G}|Enchantment|||Green creatures you control get +1/+1.$Whenever a green creature enters the battlefield under your control, scry 1.| -Terarmorph|Modern Horizons 2|177|U|{3}{G}|Sorcery|||Search your library for a basic land card, put it into the battlefield, then shuffle.$Rebound| +Terramorph|Modern Horizons 2|177|U|{3}{G}|Sorcery|||Search your library for a basic land card, put it into the battlefield, then shuffle.$Rebound| Thrasta, Tempest's Roar|Modern Horizons 2|178|M|{10}{G}{G}|Legendary Creature - Dinosaur|7|7|This spell costs {3} less to cast for each other spell cast this turn.$Trample, haste$Trample over planeswalkers$Thrasta, Tempest's Roar has hexproof as long as it entered the battlefield this turn.| Timeless Witness|Modern Horizons 2|179|U|{2}{G}{G}|Creature - Human Shaman|2|1|When Timeless Witness enters the battlefield, return target card from your graveyard to your hand.$Eternalize {5}{G}{G}| Tireless Provisioner|Modern Horizons 2|180|U|{2}{G}|Creature - Elf Scout|3|2|Landfall — Whenever a land enters the battelfield under your control, create a Food token or a Treasure token.| From 91fc519671afc3ee80896250e1821c4e674ea5aa Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 17:45:26 -0400 Subject: [PATCH 006/188] [MH2] Implemented Tireless Provisioner --- .../src/mage/cards/t/TirelessProvisioner.java | 75 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 76 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TirelessProvisioner.java diff --git a/Mage.Sets/src/mage/cards/t/TirelessProvisioner.java b/Mage.Sets/src/mage/cards/t/TirelessProvisioner.java new file mode 100644 index 00000000000..8aefdf25bd5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TirelessProvisioner.java @@ -0,0 +1,75 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.LandfallAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.permanent.token.FoodToken; +import mage.game.permanent.token.Token; +import mage.game.permanent.token.TreasureToken; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TirelessProvisioner extends CardImpl { + + public TirelessProvisioner(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Landfall — Whenever a land enters the battelfield under your control, create a Food token or a Treasure token. + this.addAbility(new LandfallAbility(new TirelessProvisionerEffect())); + } + + private TirelessProvisioner(final TirelessProvisioner card) { + super(card); + } + + @Override + public TirelessProvisioner copy() { + return new TirelessProvisioner(this); + } +} + +class TirelessProvisionerEffect extends OneShotEffect { + + TirelessProvisionerEffect() { + super(Outcome.Benefit); + staticText = "create a Food token or a Treasure token"; + } + + private TirelessProvisionerEffect(final TirelessProvisionerEffect effect) { + super(effect); + } + + @Override + public TirelessProvisionerEffect copy() { + return new TirelessProvisionerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Token token = player.chooseUse( + outcome, "Create a Food token or a Treasure token?", + null, "Food", "Treasure", source, game + ) ? new FoodToken() : new TreasureToken(); + return token.putOntoBattlefield(1, game, source, source.getControllerId()); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 6b5c5d604ad..37f02eb7d89 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -150,6 +150,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Thrasta, Tempest's Roar", 178, Rarity.MYTHIC, mage.cards.t.ThrastaTempestsRoar.class)); cards.add(new SetCardInfo("Timeless Dragon", 35, Rarity.RARE, mage.cards.t.TimelessDragon.class)); cards.add(new SetCardInfo("Timeless Witness", 179, Rarity.UNCOMMON, mage.cards.t.TimelessWitness.class)); + cards.add(new SetCardInfo("Tireless Provisioner", 180, Rarity.UNCOMMON, mage.cards.t.TirelessProvisioner.class)); cards.add(new SetCardInfo("Titania, Protector of Argoth", 287, Rarity.MYTHIC, mage.cards.t.TitaniaProtectorOfArgoth.class)); cards.add(new SetCardInfo("Tormod's Cryptkeeper", 239, Rarity.COMMON, mage.cards.t.TormodsCryptkeeper.class)); cards.add(new SetCardInfo("Tourach's Canticle", 103, Rarity.COMMON, mage.cards.t.TourachsCanticle.class)); From 27214132ca522893e8d7299e456c5b56388e6e62 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 18:00:00 -0400 Subject: [PATCH 007/188] [MH2] Implemented Batterbone --- Mage.Sets/src/mage/cards/b/Batterbone.java | 54 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 55 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/Batterbone.java diff --git a/Mage.Sets/src/mage/cards/b/Batterbone.java b/Mage.Sets/src/mage/cards/b/Batterbone.java new file mode 100644 index 00000000000..a0c982d36a5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/Batterbone.java @@ -0,0 +1,54 @@ +package mage.cards.b; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.LivingWeaponAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Batterbone extends CardImpl { + + public Batterbone(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + this.subtype.add(SubType.EQUIPMENT); + + // Living weapon + this.addAbility(new LivingWeaponAbility()); + + // Equipped creature gets +1/+1 and has vigilance and lifelink. + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 1)); + ability.addEffect(new GainAbilityAttachedEffect( + VigilanceAbility.getInstance(), AttachmentType.EQUIPMENT + ).setText("and has vigilance")); + ability.addEffect(new GainAbilityAttachedEffect( + LifelinkAbility.getInstance(), AttachmentType.EQUIPMENT + ).setText("and lifelink")); + this.addAbility(ability); + + // Equip {5} + this.addAbility(new EquipAbility(5)); + } + + private Batterbone(final Batterbone card) { + super(card); + } + + @Override + public Batterbone copy() { + return new Batterbone(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 37f02eb7d89..2aca98510f5 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -36,6 +36,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Archfiend of Sorrows", 74, Rarity.UNCOMMON, mage.cards.a.ArchfiendOfSorrows.class)); cards.add(new SetCardInfo("Arid Mesa", 244, Rarity.RARE, mage.cards.a.AridMesa.class)); cards.add(new SetCardInfo("Asmoranomardicadaistinaculdacar", 186, Rarity.RARE, mage.cards.a.Asmoranomardicadaistinaculdacar.class)); + cards.add(new SetCardInfo("Batterbone", 221, Rarity.UNCOMMON, mage.cards.b.Batterbone.class)); cards.add(new SetCardInfo("Battle Plan", 114, Rarity.COMMON, mage.cards.b.BattlePlan.class)); cards.add(new SetCardInfo("Bone Shards", 76, Rarity.COMMON, mage.cards.b.BoneShards.class)); cards.add(new SetCardInfo("Bone Shredder", 272, Rarity.UNCOMMON, mage.cards.b.BoneShredder.class)); From e60b72fbc0c421a3952d641d1cc0b8951e4a97c9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 18:03:43 -0400 Subject: [PATCH 008/188] [MH2] Implemented Glinting Creeper --- .../src/mage/cards/g/GlintingCreeper.java | 50 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 51 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GlintingCreeper.java diff --git a/Mage.Sets/src/mage/cards/g/GlintingCreeper.java b/Mage.Sets/src/mage/cards/g/GlintingCreeper.java new file mode 100644 index 00000000000..bef75a80569 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GlintingCreeper.java @@ -0,0 +1,50 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.MultipliedValue; +import mage.abilities.dynamicvalue.common.ColorsOfManaSpentToCastCount; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.DauntAbility; +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 GlintingCreeper extends CardImpl { + + private static final DynamicValue xValue = new MultipliedValue(ColorsOfManaSpentToCastCount.getInstance(), 2); + + public GlintingCreeper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); + + this.subtype.add(SubType.PLANT); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // Converge — Glinting Creeper enters the battlefield with two +1/+1 counters on it for each color of mana spent to cast it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect( + CounterType.P1P1.createInstance(), xValue, true + ), null, "Converge — {this} enters the battlefield " + + "with two +1/+1 counters on it for each color of mana spent to cast it.", null)); + + // Glinting Creeper can't be blocked by creatures with power 2 or less. + this.addAbility(new DauntAbility()); + } + + private GlintingCreeper(final GlintingCreeper card) { + super(card); + } + + @Override + public GlintingCreeper copy() { + return new GlintingCreeper(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 2aca98510f5..69964758f39 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -72,6 +72,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Forest", 489, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); cards.add(new SetCardInfo("Gaea's Will", 162, Rarity.RARE, mage.cards.g.GaeasWill.class)); + cards.add(new SetCardInfo("Glinting Creeper", 164, Rarity.UNCOMMON, mage.cards.g.GlintingCreeper.class)); cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); cards.add(new SetCardInfo("Goblin Bombardment", 279, Rarity.RARE, mage.cards.g.GoblinBombardment.class)); cards.add(new SetCardInfo("Goldmire Bridge", 247, Rarity.COMMON, mage.cards.g.GoldmireBridge.class)); From f0bec669917526ba97b1823d698ebf0bebf551da Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 18:07:49 -0400 Subject: [PATCH 009/188] [MH2] Implemented Piru, the Volatile --- .../src/mage/cards/p/PiruTheVolatile.java | 67 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 68 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PiruTheVolatile.java diff --git a/Mage.Sets/src/mage/cards/p/PiruTheVolatile.java b/Mage.Sets/src/mage/cards/p/PiruTheVolatile.java new file mode 100644 index 00000000000..f2b8eaff643 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PiruTheVolatile.java @@ -0,0 +1,67 @@ +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; +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.constants.SuperType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PiruTheVolatile extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("nonlegendary creature"); + + static { + filter.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); + } + + public PiruTheVolatile(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}{W}{W}{B}{B}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ELDER); + this.subtype.add(SubType.DRAGON); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // At the beginning of your upkeep, sacrifice Piru, the Volatile unless you pay {R}{W}{B}. + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl<>("{R}{W}{B}")), + TargetController.YOU, false + )); + + // When Piru dies, it deals 7 damage to each nonlegendary creature. + this.addAbility(new DiesSourceTriggeredAbility(new DamageAllEffect(7, "it", filter))); + } + + private PiruTheVolatile(final PiruTheVolatile card) { + super(card); + } + + @Override + public PiruTheVolatile copy() { + return new PiruTheVolatile(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 69964758f39..32b85b6b751 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -109,6 +109,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Orchard Strider", 169, Rarity.COMMON, mage.cards.o.OrchardStrider.class)); cards.add(new SetCardInfo("Patriarch's Bidding", 275, Rarity.RARE, mage.cards.p.PatriarchsBidding.class)); cards.add(new SetCardInfo("Phantasmal Dreadmaw", 55, Rarity.COMMON, mage.cards.p.PhantasmalDreadmaw.class)); + cards.add(new SetCardInfo("Piru, the Volatile", 207, Rarity.RARE, mage.cards.p.PiruTheVolatile.class)); cards.add(new SetCardInfo("Plains", 481, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Priest of Fell Rites", 208, Rarity.RARE, mage.cards.p.PriestOfFellRites.class)); cards.add(new SetCardInfo("Prismatic Ending", 25, Rarity.UNCOMMON, mage.cards.p.PrismaticEnding.class)); From 173a713fa4f385746bffdc9894842b461529945c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 21:35:19 -0400 Subject: [PATCH 010/188] [MH2] Implemented Liquimetal Torque --- .../src/mage/cards/l/LiquimetalTorque.java | 43 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 44 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LiquimetalTorque.java diff --git a/Mage.Sets/src/mage/cards/l/LiquimetalTorque.java b/Mage.Sets/src/mage/cards/l/LiquimetalTorque.java new file mode 100644 index 00000000000..5bf593522cf --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LiquimetalTorque.java @@ -0,0 +1,43 @@ +package mage.cards.l; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetNonlandPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LiquimetalTorque extends CardImpl { + + public LiquimetalTorque(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + // {T}: Add {C}. + this.addAbility(new ColorlessManaAbility()); + + // {T}: Target nonland permanent becomes an artifact in addition to its other types until end of turn. + Ability ability = new SimpleActivatedAbility( + new AddCardTypeTargetEffect(Duration.EndOfTurn, CardType.ARTIFACT), new TapSourceCost() + ); + ability.addTarget(new TargetNonlandPermanent()); + this.addAbility(ability); + } + + private LiquimetalTorque(final LiquimetalTorque card) { + super(card); + } + + @Override + public LiquimetalTorque copy() { + return new LiquimetalTorque(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 32b85b6b751..393700907ba 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -90,6 +90,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Landscaper Colos", 18, Rarity.COMMON, mage.cards.l.LandscaperColos.class)); cards.add(new SetCardInfo("Late to Dinner", 19, Rarity.COMMON, mage.cards.l.LateToDinner.class)); cards.add(new SetCardInfo("Legion Vanguard", 90, Rarity.UNCOMMON, mage.cards.l.LegionVanguard.class)); + cards.add(new SetCardInfo("Liquimetal Torque", 228, Rarity.UNCOMMON, mage.cards.l.LiquimetalTorque.class)); cards.add(new SetCardInfo("Lose Focus", 49, Rarity.COMMON, mage.cards.l.LoseFocus.class)); cards.add(new SetCardInfo("Lucid Dreams", 50, Rarity.UNCOMMON, mage.cards.l.LucidDreams.class)); cards.add(new SetCardInfo("Marsh Flats", 248, Rarity.RARE, mage.cards.m.MarshFlats.class)); From 92ba606374a9578bac9bc4402f64a34c5951cf4a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 21:41:37 -0400 Subject: [PATCH 011/188] [MH2] Implemented Archon of Cruelty --- .../src/mage/cards/a/ArchonOfCruelty.java | 56 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 57 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/ArchonOfCruelty.java diff --git a/Mage.Sets/src/mage/cards/a/ArchonOfCruelty.java b/Mage.Sets/src/mage/cards/a/ArchonOfCruelty.java new file mode 100644 index 00000000000..e6268c86697 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArchonOfCruelty.java @@ -0,0 +1,56 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.common.TargetOpponent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ArchonOfCruelty extends CardImpl { + + public ArchonOfCruelty(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{B}{B}"); + + this.subtype.add(SubType.ARCHON); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever Archon of Cruelty enters the battlefield or attacks, target opponent sacrifices a creature or planeswalker, discards a card, and loses 3 life. You draw a card and gain 3 life. + Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new SacrificeEffect( + StaticFilters.FILTER_PERMANENT_CREATURE_OR_PLANESWALKER_A, 1, "target opponent" + )); + ability.addTarget(new TargetOpponent()); + ability.addEffect(new DiscardTargetEffect(1, false).setText(", discards a card")); + ability.addEffect(new LoseLifeTargetEffect(3).setText(", and loses 3 life.")); + ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("You")); + ability.addEffect(new GainLifeEffect(3).setText("and gain 3 life")); + this.addAbility(ability); + } + + private ArchonOfCruelty(final ArchonOfCruelty card) { + super(card); + } + + @Override + public ArchonOfCruelty copy() { + return new ArchonOfCruelty(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 393700907ba..c8f2b8ed602 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -34,6 +34,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Arcbound Shikari", 184, Rarity.UNCOMMON, mage.cards.a.ArcboundShikari.class)); cards.add(new SetCardInfo("Arcbound Whelp", 113, Rarity.UNCOMMON, mage.cards.a.ArcboundWhelp.class)); cards.add(new SetCardInfo("Archfiend of Sorrows", 74, Rarity.UNCOMMON, mage.cards.a.ArchfiendOfSorrows.class)); + cards.add(new SetCardInfo("Archon of Cruelty", 75, Rarity.MYTHIC, mage.cards.a.ArchonOfCruelty.class)); cards.add(new SetCardInfo("Arid Mesa", 244, Rarity.RARE, mage.cards.a.AridMesa.class)); cards.add(new SetCardInfo("Asmoranomardicadaistinaculdacar", 186, Rarity.RARE, mage.cards.a.Asmoranomardicadaistinaculdacar.class)); cards.add(new SetCardInfo("Batterbone", 221, Rarity.UNCOMMON, mage.cards.b.Batterbone.class)); From 5e5c843032689c465486e2a64e413bb60be71329 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 21:45:31 -0400 Subject: [PATCH 012/188] [MH2] Implemented Filigree Attendant --- .../src/mage/cards/f/FiligreeAttendant.java | 43 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 44 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FiligreeAttendant.java diff --git a/Mage.Sets/src/mage/cards/f/FiligreeAttendant.java b/Mage.Sets/src/mage/cards/f/FiligreeAttendant.java new file mode 100644 index 00000000000..a6cebf16be1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FiligreeAttendant.java @@ -0,0 +1,43 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.ArtifactYouControlCount; +import mage.abilities.effects.common.continuous.SetPowerSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FiligreeAttendant extends CardImpl { + + public FiligreeAttendant(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{U}{U}"); + + this.subtype.add(SubType.HOMUNCULUS); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Filigree Attendant's power is equal to the number of artifacts you control. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerSourceEffect( + ArtifactYouControlCount.instance, Duration.EndOfGame, SubLayer.CharacteristicDefining_7a + ))); + } + + private FiligreeAttendant(final FiligreeAttendant card) { + super(card); + } + + @Override + public FiligreeAttendant copy() { + return new FiligreeAttendant(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index c8f2b8ed602..45d0f0c5544 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -66,6 +66,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Endurance", 157, Rarity.MYTHIC, mage.cards.e.Endurance.class)); cards.add(new SetCardInfo("Extruder", 296, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); cards.add(new SetCardInfo("Feast of Sanity", 84, Rarity.UNCOMMON, mage.cards.f.FeastOfSanity.class)); + cards.add(new SetCardInfo("Filigree Attendant", 41, Rarity.UNCOMMON, mage.cards.f.FiligreeAttendant.class)); cards.add(new SetCardInfo("Fire // Ice", 290, Rarity.RARE, mage.cards.f.FireIce.class)); cards.add(new SetCardInfo("Flame Rift", 278, Rarity.UNCOMMON, mage.cards.f.FlameRift.class)); cards.add(new SetCardInfo("Flametongue Yearling", 125, Rarity.UNCOMMON, mage.cards.f.FlametongueYearling.class)); From 72e42dc31064f97b4697ac12892294930f7d8fe7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 21:55:51 -0400 Subject: [PATCH 013/188] [MH2] Implemented Thraben Watcher --- .../src/mage/cards/t/ThrabenWatcher.java | 63 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/ThrabenWatcher.java diff --git a/Mage.Sets/src/mage/cards/t/ThrabenWatcher.java b/Mage.Sets/src/mage/cards/t/ThrabenWatcher.java new file mode 100644 index 00000000000..ff86877b2b3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThrabenWatcher.java @@ -0,0 +1,63 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.TokenPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ThrabenWatcher extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creatures"); + + static { + filter.add(Predicates.not(TokenPredicate.instance)); + } + + public ThrabenWatcher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); + + this.subtype.add(SubType.ANGEL); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Other nontoken creatures you control get +1/+1 and have vigilance. + Ability ability = new SimpleStaticAbility(new BoostControlledEffect( + 1, 1, Duration.WhileOnBattlefield, filter, true + )); + ability.addEffect(new GainAbilityControlledEffect( + VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, filter, true + ).setText("and have vigilance")); + this.addAbility(ability); + } + + private ThrabenWatcher(final ThrabenWatcher card) { + super(card); + } + + @Override + public ThrabenWatcher copy() { + return new ThrabenWatcher(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 45d0f0c5544..5cb686ef1f6 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -153,6 +153,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Terramorph", 177, Rarity.UNCOMMON, mage.cards.t.Terramorph.class)); cards.add(new SetCardInfo("The Underworld Cookbook", 240, Rarity.UNCOMMON, mage.cards.t.TheUnderworldCookbook.class)); cards.add(new SetCardInfo("Thornglint Bridge", 258, Rarity.COMMON, mage.cards.t.ThornglintBridge.class)); + cards.add(new SetCardInfo("Thraben Watcher", 34, Rarity.UNCOMMON, mage.cards.t.ThrabenWatcher.class)); cards.add(new SetCardInfo("Thrasta, Tempest's Roar", 178, Rarity.MYTHIC, mage.cards.t.ThrastaTempestsRoar.class)); cards.add(new SetCardInfo("Timeless Dragon", 35, Rarity.RARE, mage.cards.t.TimelessDragon.class)); cards.add(new SetCardInfo("Timeless Witness", 179, Rarity.UNCOMMON, mage.cards.t.TimelessWitness.class)); From 503350673645391979d33b96c42ab54af0e59c82 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 30 May 2021 21:57:33 -0400 Subject: [PATCH 014/188] [MH2] Implemented Strike It Rich --- Mage.Sets/src/mage/cards/s/StrikeItRich.java | 37 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/StrikeItRich.java diff --git a/Mage.Sets/src/mage/cards/s/StrikeItRich.java b/Mage.Sets/src/mage/cards/s/StrikeItRich.java new file mode 100644 index 00000000000..27e974ad193 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StrikeItRich.java @@ -0,0 +1,37 @@ +package mage.cards.s; + +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.FlashbackAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TimingRule; +import mage.game.permanent.token.TreasureToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class StrikeItRich extends CardImpl { + + public StrikeItRich(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}"); + + // Create a Treasure token. + this.getSpellAbility().addEffect(new CreateTokenEffect(new TreasureToken())); + + // Flashback {2}{R} + this.addAbility(new FlashbackAbility(new ManaCostsImpl<>("{2}{R}"), TimingRule.SORCERY)); + } + + private StrikeItRich(final StrikeItRich card) { + super(card); + } + + @Override + public StrikeItRich copy() { + return new StrikeItRich(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 5cb686ef1f6..a79f7e133a1 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -144,6 +144,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Squirrel Sovereign", 175, Rarity.UNCOMMON, mage.cards.s.SquirrelSovereign.class)); cards.add(new SetCardInfo("Step Through", 66, Rarity.COMMON, mage.cards.s.StepThrough.class)); cards.add(new SetCardInfo("Sterling Grove", 293, Rarity.RARE, mage.cards.s.SterlingGrove.class)); + cards.add(new SetCardInfo("Strike It Rich", 141, Rarity.UNCOMMON, mage.cards.s.StrikeItRich.class)); cards.add(new SetCardInfo("Subtlety", 67, Rarity.MYTHIC, mage.cards.s.Subtlety.class)); cards.add(new SetCardInfo("Sudden Edict", 100, Rarity.UNCOMMON, mage.cards.s.SuddenEdict.class)); cards.add(new SetCardInfo("Swamp", 485, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); From b630f5e1dbc591fd6eb9bb72d479260ea1daa667 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 08:05:22 -0400 Subject: [PATCH 015/188] [MH2] Implemented Thought Monitor --- .../src/mage/cards/t/ThoughtMonitor.java | 45 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + Utils/mtg-cards-data.txt | 1 + 3 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/ThoughtMonitor.java diff --git a/Mage.Sets/src/mage/cards/t/ThoughtMonitor.java b/Mage.Sets/src/mage/cards/t/ThoughtMonitor.java new file mode 100644 index 00000000000..604ea385805 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThoughtMonitor.java @@ -0,0 +1,45 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.AffinityForArtifactsAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ThoughtMonitor extends CardImpl { + + public ThoughtMonitor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}{U}"); + + this.subtype.add(SubType.CONSTRUCT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Affinity for artifacts + this.addAbility(new AffinityForArtifactsAbility()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Thought Monitor enters the battlefield, draw two cards. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(2))); + } + + private ThoughtMonitor(final ThoughtMonitor card) { + super(card); + } + + @Override + public ThoughtMonitor copy() { + return new ThoughtMonitor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index a79f7e133a1..16328ff928c 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -154,6 +154,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Terramorph", 177, Rarity.UNCOMMON, mage.cards.t.Terramorph.class)); cards.add(new SetCardInfo("The Underworld Cookbook", 240, Rarity.UNCOMMON, mage.cards.t.TheUnderworldCookbook.class)); cards.add(new SetCardInfo("Thornglint Bridge", 258, Rarity.COMMON, mage.cards.t.ThornglintBridge.class)); + cards.add(new SetCardInfo("Thought Monitor", 71, Rarity.RARE, mage.cards.t.ThoughtMonitor.class)); cards.add(new SetCardInfo("Thraben Watcher", 34, Rarity.UNCOMMON, mage.cards.t.ThrabenWatcher.class)); cards.add(new SetCardInfo("Thrasta, Tempest's Roar", 178, Rarity.MYTHIC, mage.cards.t.ThrastaTempestsRoar.class)); cards.add(new SetCardInfo("Timeless Dragon", 35, Rarity.RARE, mage.cards.t.TimelessDragon.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 85289664fd6..a8a414afbd1 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -41370,6 +41370,7 @@ Subtlety|Modern Horizons 2|67|M|{2}{U}{U}|Creature - Elemental Incarnation|3|3|F Suspend|Modern Horizons 2|68|R|{U}|Instant|||Exile target creature and put two time counters on it. If it doesn't have suspend, it gains suspend.| Svyelun of Sea and Sky|Modern Horizons 2|69|M|{1}{U}{U}|Legendary Creature - Merfolk God|3|4|Svyelun of Sea and Sky has indestructible as long as you control at least two other Merfolk.$Whenever Svyelun attacks, draw a card.$Other Merfolk you control have ward {1}| Sweep the Skies|Modern Horizons 2|70|U|{X}{U}{U}|Sorcery|||Converge — Create a 1/1 colorless Thopter artifact creature token with flying for each color of mana spent to cast this spell.| +Thought Monitor|Modern Horizons 2|71|R|{6}{U}|Artifact Creature - Construct|2|2|Affinity for artifacts$Flying$When Thought Monitor enters the battlefield, draw two cards.| Vedalken Infiltrator|Modern Horizons 2|73|U|{1}{U}|Creature - Vedalken Rogue|1|3|Vedalken Infiltrator can't be blocked.$Metalcraft — Vedalken Infiltrator gets +1/+0 as long as you control three or more artifacts.| Archfiend of Sorrows|Modern Horizons 2|74|U|{5}{B}{B}|Creature - Demon|4|5|Flying$When Archfiend of Sorrows enters the battlefield, creatures your opponents control get -2/-2 until end of turn.$Unearth {3}{B}{B}| Archon of Cruelty|Modern Horizons 2|75|M|{6}{B}{B}|Creature - Archon|6|6|Flying$Whenever Archon of Cruelty enters the battlefield or attacks, target opponent sacrifices a creature or planeswalker, discards a card, and loses 3 life. You draw a card and gain 3 life.| From 318ff24f25e50973c34e98fdf0aff545d71d30bd Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 08:26:29 -0400 Subject: [PATCH 016/188] [MH2] Implemented Young Necromancer --- .../src/mage/cards/y/YoungNecromancer.java | 52 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 53 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/y/YoungNecromancer.java diff --git a/Mage.Sets/src/mage/cards/y/YoungNecromancer.java b/Mage.Sets/src/mage/cards/y/YoungNecromancer.java new file mode 100644 index 00000000000..e630791c55a --- /dev/null +++ b/Mage.Sets/src/mage/cards/y/YoungNecromancer.java @@ -0,0 +1,52 @@ +package mage.cards.y; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.costs.common.ExileFromGraveCost; +import mage.abilities.effects.common.DoWhenCostPaid; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class YoungNecromancer extends CardImpl { + + public YoungNecromancer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // When Young Necromancer enters the battlefield, you may exile two cards from your graveyard. When you do, return target creature card from your graveyard to the battlefield. + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( + new ReturnFromGraveyardToBattlefieldTargetEffect(), false, + "return target creature card from your graveyard to the battlefield" + ); + ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + this.addAbility(new EntersBattlefieldTriggeredAbility( + new DoWhenCostPaid(ability, new ExileFromGraveCost( + new TargetCardInYourGraveyard(2, StaticFilters.FILTER_CARD) + ), "Exile two cards from your graveyard?") + )); + } + + private YoungNecromancer(final YoungNecromancer card) { + super(card); + } + + @Override + public YoungNecromancer copy() { + return new YoungNecromancer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 16328ff928c..8f0670fbbc9 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -175,6 +175,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Void Mirror", 242, Rarity.RARE, mage.cards.v.VoidMirror.class)); cards.add(new SetCardInfo("Wonder", 271, Rarity.RARE, mage.cards.w.Wonder.class)); cards.add(new SetCardInfo("World-Weary", 109, Rarity.COMMON, mage.cards.w.WorldWeary.class)); + cards.add(new SetCardInfo("Young Necromancer", 110, Rarity.UNCOMMON, mage.cards.y.YoungNecromancer.class)); cards.add(new SetCardInfo("Yusri, Fortune's Flame", 218, Rarity.RARE, mage.cards.y.YusriFortunesFlame.class)); cards.add(new SetCardInfo("Zuran Orb", 300, Rarity.UNCOMMON, mage.cards.z.ZuranOrb.class)); } From 69cdc69e747249df9e0b70ec4e45e18058314828 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 08:49:26 -0400 Subject: [PATCH 017/188] [MH2] Implemented Sanctuary Raptor --- .../src/mage/cards/s/SanctuaryRaptor.java | 73 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 74 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SanctuaryRaptor.java diff --git a/Mage.Sets/src/mage/cards/s/SanctuaryRaptor.java b/Mage.Sets/src/mage/cards/s/SanctuaryRaptor.java new file mode 100644 index 00000000000..7ef4fa3ed01 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SanctuaryRaptor.java @@ -0,0 +1,73 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.TokenPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SanctuaryRaptor extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent(); + + static { + filter.add(TokenPredicate.instance); + } + + private static final Condition condition + = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.MORE_THAN, 2); + private static final Hint hint + = new ValueHint("Tokens you control", new PermanentsOnBattlefieldCount(filter)); + + public SanctuaryRaptor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); + + this.subtype.add(SubType.BIRD); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever Sanctuary Raptor attacks, if you control three or more tokens, Sanctuary Raptor gets +2/+0 and gains first strike until end of turn. + Ability ability = new ConditionalInterveningIfTriggeredAbility( + new AttacksTriggeredAbility( + new BoostSourceEffect(2, 0, Duration.EndOfTurn), false + ), condition, "Whenever {this} attacks, if you control three or more tokens, " + + "{this} gets +2/+0 and gains first strike until end of turn." + ); + ability.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn)); + this.addAbility(ability.addHint(hint)); + } + + private SanctuaryRaptor(final SanctuaryRaptor card) { + super(card); + } + + @Override + public SanctuaryRaptor copy() { + return new SanctuaryRaptor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 8f0670fbbc9..ae28f9129c4 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -123,6 +123,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Rift Sower", 170, Rarity.COMMON, mage.cards.r.RiftSower.class)); cards.add(new SetCardInfo("Rishadan Dockhand", 59, Rarity.RARE, mage.cards.r.RishadanDockhand.class)); cards.add(new SetCardInfo("Rustvale Bridge", 253, Rarity.COMMON, mage.cards.r.RustvaleBridge.class)); + cards.add(new SetCardInfo("Sanctuary Raptor", 233, Rarity.UNCOMMON, mage.cards.s.SanctuaryRaptor.class)); cards.add(new SetCardInfo("Sanctum Prelate", 491, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class)); cards.add(new SetCardInfo("Scalding Tarn", 254, Rarity.RARE, mage.cards.s.ScaldingTarn.class)); cards.add(new SetCardInfo("Scurry Oak", 172, Rarity.UNCOMMON, mage.cards.s.ScurryOak.class)); From 9e950b66cd007a666a532b276cd1e77a89849df5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 08:55:08 -0400 Subject: [PATCH 018/188] [MH2] Implemented Sanctum Weaver --- Mage.Sets/src/mage/cards/s/SanctumWeaver.java | 52 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 53 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SanctumWeaver.java diff --git a/Mage.Sets/src/mage/cards/s/SanctumWeaver.java b/Mage.Sets/src/mage/cards/s/SanctumWeaver.java new file mode 100644 index 00000000000..f2368e149ba --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SanctumWeaver.java @@ -0,0 +1,52 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.Mana; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.mana.DynamicManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledEnchantmentPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SanctumWeaver extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledEnchantmentPermanent(); + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter); + private static final Hint hint = new ValueHint("Enchantments you control", xValue); + + public SanctumWeaver(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.DRYAD); + this.power = new MageInt(0); + this.toughness = new MageInt(2); + + // {T}: Add X mana of any one color, where X is the number of enchantments you control. + this.addAbility(new DynamicManaAbility( + new Mana(0, 0, 0, 0, 0, 0, 1, 0), + xValue, new TapSourceCost(), "Add X mana of any one color, " + + "where X is the number of enchantments you control", true + ).addHint(hint)); + } + + private SanctumWeaver(final SanctumWeaver card) { + super(card); + } + + @Override + public SanctumWeaver copy() { + return new SanctumWeaver(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index ae28f9129c4..f6f3c25ddbc 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -125,6 +125,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Rustvale Bridge", 253, Rarity.COMMON, mage.cards.r.RustvaleBridge.class)); cards.add(new SetCardInfo("Sanctuary Raptor", 233, Rarity.UNCOMMON, mage.cards.s.SanctuaryRaptor.class)); cards.add(new SetCardInfo("Sanctum Prelate", 491, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class)); + cards.add(new SetCardInfo("Sanctum Weaver", 171, Rarity.RARE, mage.cards.s.SanctumWeaver.class)); cards.add(new SetCardInfo("Scalding Tarn", 254, Rarity.RARE, mage.cards.s.ScaldingTarn.class)); cards.add(new SetCardInfo("Scurry Oak", 172, Rarity.UNCOMMON, mage.cards.s.ScurryOak.class)); cards.add(new SetCardInfo("Scuttletide", 61, Rarity.UNCOMMON, mage.cards.s.Scuttletide.class)); From 93f5f1fe79ae09850e1897d9a03ae51a2d022171 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 09:05:28 -0400 Subject: [PATCH 019/188] [MH2] Implemented Scion of Draco --- Mage.Sets/src/mage/cards/s/ScionOfDraco.java | 101 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 102 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ScionOfDraco.java diff --git a/Mage.Sets/src/mage/cards/s/ScionOfDraco.java b/Mage.Sets/src/mage/cards/s/ScionOfDraco.java new file mode 100644 index 00000000000..7c60c360345 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScionOfDraco.java @@ -0,0 +1,101 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.DomainValue; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.cost.SpellCostReductionForEachSourceEffect; +import mage.abilities.hint.common.DomainHint; +import mage.abilities.keyword.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ScionOfDraco extends CardImpl { + + private static final DynamicValue xValue = new DomainValue(); + + public ScionOfDraco(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{12}"); + + this.subtype.add(SubType.DRAGON); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Domain — This spell costs {2} less to cast for each basic land type among lands you control. + this.addAbility(new SimpleStaticAbility(Zone.ALL, + new SpellCostReductionForEachSourceEffect(2, xValue) + ).addHint(DomainHint.instance).setAbilityWord(AbilityWord.DOMAIN)); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Each creature you control has vigilance if it's white, hexproof if it's blue, lifelink if it's black, first strike if it's red, and trample if it's green. + this.addAbility(new SimpleStaticAbility(new ScionOfDracoEffect())); + } + + private ScionOfDraco(final ScionOfDraco card) { + super(card); + } + + @Override + public ScionOfDraco copy() { + return new ScionOfDraco(this); + } +} + +class ScionOfDracoEffect extends ContinuousEffectImpl { + + ScionOfDracoEffect() { + super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.Benefit); + staticText = "each creature you control has vigilance if it's white, hexproof if it's blue, " + + "lifelink if it's black, first strike if it's red, and trample if it's green"; + this.addDependencyType(DependencyType.AddingAbility); + } + + private ScionOfDracoEffect(final ScionOfDracoEffect effect) { + super(effect); + } + + @Override + public ScionOfDracoEffect copy() { + return new ScionOfDracoEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (Permanent permanent : game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_CONTROLLED_CREATURE, + source.getControllerId(), source.getSourceId(), game + )) { + ObjectColor color = permanent.getColor(game); + if (color.isWhite()) { + permanent.addAbility(VigilanceAbility.getInstance(), source.getSourceId(), game); + } + if (color.isBlue()) { + permanent.addAbility(HexproofAbility.getInstance(), source.getSourceId(), game); + } + if (color.isBlack()) { + permanent.addAbility(LifelinkAbility.getInstance(), source.getSourceId(), game); + } + if (color.isRed()) { + permanent.addAbility(FirstStrikeAbility.getInstance(), source.getSourceId(), game); + } + if (color.isGreen()) { + permanent.addAbility(TrampleAbility.getInstance(), source.getSourceId(), game); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index f6f3c25ddbc..20979514f6e 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -127,6 +127,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Sanctum Prelate", 491, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class)); cards.add(new SetCardInfo("Sanctum Weaver", 171, Rarity.RARE, mage.cards.s.SanctumWeaver.class)); cards.add(new SetCardInfo("Scalding Tarn", 254, Rarity.RARE, mage.cards.s.ScaldingTarn.class)); + cards.add(new SetCardInfo("Scion of Draco", 234, Rarity.MYTHIC, mage.cards.s.ScionOfDraco.class)); cards.add(new SetCardInfo("Scurry Oak", 172, Rarity.UNCOMMON, mage.cards.s.ScurryOak.class)); cards.add(new SetCardInfo("Scuttletide", 61, Rarity.UNCOMMON, mage.cards.s.Scuttletide.class)); cards.add(new SetCardInfo("Sea Drake", 268, Rarity.RARE, mage.cards.s.SeaDrake.class)); From da9dba46fda647deb9e812895cc3d1bc06da8829 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 09:11:21 -0400 Subject: [PATCH 020/188] [MH2] Implemented Combine Chrysalis --- .../src/mage/cards/c/CombineChrysalis.java | 60 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 61 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CombineChrysalis.java diff --git a/Mage.Sets/src/mage/cards/c/CombineChrysalis.java b/Mage.Sets/src/mage/cards/c/CombineChrysalis.java new file mode 100644 index 00000000000..8885528e5d5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CombineChrysalis.java @@ -0,0 +1,60 @@ +package mage.cards.c; + +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.permanent.token.BeastToken2; +import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class CombineChrysalis extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a token"); + + static { + filter.add(TokenPredicate.instance); + } + + public CombineChrysalis(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{G}{U}"); + + // Creature tokens you control have flying. + this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + FlyingAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_CREATURE_TOKENS + ))); + + // {2}{G}{U}, {T}, Sacrifice a token: Create a 4/4 green Beast creature token. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + new CreateTokenEffect(new BeastToken2()), new ManaCostsImpl<>("{2}{G}{U}") + ); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + this.addAbility(ability); + } + + private CombineChrysalis(final CombineChrysalis card) { + super(card); + } + + @Override + public CombineChrysalis copy() { + return new CombineChrysalis(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 20979514f6e..1c37c6920d7 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -51,6 +51,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Chainer, Nightmare Adept", 289, Rarity.RARE, mage.cards.c.ChainerNightmareAdept.class)); cards.add(new SetCardInfo("Chance Encounter", 277, Rarity.RARE, mage.cards.c.ChanceEncounter.class)); cards.add(new SetCardInfo("Chatterstorm", 152, Rarity.COMMON, mage.cards.c.Chatterstorm.class)); + cards.add(new SetCardInfo("Combine Chrysalis", 191, Rarity.UNCOMMON, mage.cards.c.CombineChrysalis.class)); cards.add(new SetCardInfo("Constable of the Realm", 10, Rarity.UNCOMMON, mage.cards.c.ConstableOfTheRealm.class)); cards.add(new SetCardInfo("Counterspell", 267, Rarity.UNCOMMON, mage.cards.c.Counterspell.class)); cards.add(new SetCardInfo("Cursed Totem", 295, Rarity.RARE, mage.cards.c.CursedTotem.class)); From 3c614e1d3c049d33c7ba80e175d26b8716ade2e9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 09:12:41 -0400 Subject: [PATCH 021/188] [MH2] Implemented Flame Blitz --- Mage.Sets/src/mage/cards/f/FlameBlitz.java | 40 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 41 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FlameBlitz.java diff --git a/Mage.Sets/src/mage/cards/f/FlameBlitz.java b/Mage.Sets/src/mage/cards/f/FlameBlitz.java new file mode 100644 index 00000000000..8a1fc3bd7e0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FlameBlitz.java @@ -0,0 +1,40 @@ +package mage.cards.f; + +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FlameBlitz extends CardImpl { + + public FlameBlitz(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}"); + + // At the beginning of your end step, Flame Blitz deals 5 damage to each planeswalker. + this.addAbility(new BeginningOfEndStepTriggeredAbility(new DamageAllEffect( + 5, StaticFilters.FILTER_PERMANENT_PLANESWALKER + ), TargetController.YOU, false)); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}"))); + } + + private FlameBlitz(final FlameBlitz card) { + super(card); + } + + @Override + public FlameBlitz copy() { + return new FlameBlitz(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 1c37c6920d7..f81b5ee539a 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -69,6 +69,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Feast of Sanity", 84, Rarity.UNCOMMON, mage.cards.f.FeastOfSanity.class)); cards.add(new SetCardInfo("Filigree Attendant", 41, Rarity.UNCOMMON, mage.cards.f.FiligreeAttendant.class)); cards.add(new SetCardInfo("Fire // Ice", 290, Rarity.RARE, mage.cards.f.FireIce.class)); + cards.add(new SetCardInfo("Flame Blitz", 124, Rarity.UNCOMMON, mage.cards.f.FlameBlitz.class)); cards.add(new SetCardInfo("Flame Rift", 278, Rarity.UNCOMMON, mage.cards.f.FlameRift.class)); cards.add(new SetCardInfo("Flametongue Yearling", 125, Rarity.UNCOMMON, mage.cards.f.FlametongueYearling.class)); cards.add(new SetCardInfo("Flay Essence", 85, Rarity.UNCOMMON, mage.cards.f.FlayEssence.class)); From 870d0338f8705c64664205a6b1f0b29bca252d5c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 09:32:07 -0400 Subject: [PATCH 022/188] [MH2] Implemented Nettlecyst --- Mage.Sets/src/mage/cards/n/Nettlecyst.java | 61 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../keyword/LivingWeaponAbility.java | 42 ++----------- .../mage/game/permanent/token/GermToken.java | 11 ++-- 4 files changed, 72 insertions(+), 43 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/n/Nettlecyst.java diff --git a/Mage.Sets/src/mage/cards/n/Nettlecyst.java b/Mage.Sets/src/mage/cards/n/Nettlecyst.java new file mode 100644 index 00000000000..ea283a0a5fd --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/Nettlecyst.java @@ -0,0 +1,61 @@ +package mage.cards.n; + +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.LivingWeaponAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterArtifactOrEnchantmentPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Nettlecyst extends CardImpl { + + private static final FilterPermanent filter = new FilterArtifactOrEnchantmentPermanent(); + + static { + filter.add(TargetController.YOU.getControllerPredicate()); + } + + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter); + private static final Hint hint = new ValueHint("Artifacts and enchantments you control", xValue); + + public Nettlecyst(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + this.subtype.add(SubType.EQUIPMENT); + + // Living weapon + this.addAbility(new LivingWeaponAbility()); + + // Equipped creature gets +1/+1 for each artifact and/or enchantment you control. + this.addAbility(new SimpleStaticAbility( + new BoostEquippedEffect(xValue, xValue) + .setText("equipped creature gets +1/+1 for each artifact and/or enchantment you control") + ).addHint(hint)); + + // Equip {2} + this.addAbility(new EquipAbility(2)); + } + + private Nettlecyst(final Nettlecyst card) { + super(card); + } + + @Override + public Nettlecyst copy() { + return new Nettlecyst(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index f81b5ee539a..4f30c769108 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -109,6 +109,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 487, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mystic Redaction", 53, Rarity.UNCOMMON, mage.cards.m.MysticRedaction.class)); cards.add(new SetCardInfo("Necromancer's Familiar", 94, Rarity.UNCOMMON, mage.cards.n.NecromancersFamiliar.class)); + cards.add(new SetCardInfo("Nettlecyst", 231, Rarity.RARE, mage.cards.n.Nettlecyst.class)); cards.add(new SetCardInfo("Nevinyrral's Disk", 298, Rarity.RARE, mage.cards.n.NevinyrralsDisk.class)); cards.add(new SetCardInfo("Obsidian Charmaw", 137, Rarity.RARE, mage.cards.o.ObsidianCharmaw.class)); cards.add(new SetCardInfo("Orchard Strider", 169, Rarity.COMMON, mage.cards.o.OrchardStrider.class)); diff --git a/Mage/src/main/java/mage/abilities/keyword/LivingWeaponAbility.java b/Mage/src/main/java/mage/abilities/keyword/LivingWeaponAbility.java index 3ec2ea5bcde..624458a0c84 100644 --- a/Mage/src/main/java/mage/abilities/keyword/LivingWeaponAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/LivingWeaponAbility.java @@ -1,17 +1,13 @@ package mage.abilities.keyword; -import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.abilities.effects.common.CreateTokenAttachSourceEffect; import mage.game.permanent.token.GermToken; -import mage.players.Player; public class LivingWeaponAbility extends EntersBattlefieldTriggeredAbility { public LivingWeaponAbility() { - super(new LivingWeaponEffect()); + super(new CreateTokenAttachSourceEffect(new GermToken())); } public LivingWeaponAbility(final LivingWeaponAbility ability) { @@ -20,7 +16,8 @@ public class LivingWeaponAbility extends EntersBattlefieldTriggeredAbility { @Override public String getRule() { - return "Living weapon (When this Equipment enters the battlefield, create a 0/0 black Germ creature token, then attach this to it.)"; + return "Living weapon (When this Equipment enters the battlefield, " + + "create a 0/0 black Phyrexian Germ creature token, then attach this to it.)"; } @Override @@ -28,34 +25,3 @@ public class LivingWeaponAbility extends EntersBattlefieldTriggeredAbility { return new LivingWeaponAbility(this); } } - -class LivingWeaponEffect extends CreateTokenEffect { - - LivingWeaponEffect() { - super(new GermToken()); - } - - LivingWeaponEffect(final LivingWeaponEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - if (super.apply(game, source)) { - Permanent p = game.getPermanent(this.getLastAddedTokenId()); - if (p != null) { - p.addAttachment(source.getSourceId(), source, game); - return true; - } - } - } - return false; - } - - @Override - public LivingWeaponEffect copy() { - return new LivingWeaponEffect(this); - } -} diff --git a/Mage/src/main/java/mage/game/permanent/token/GermToken.java b/Mage/src/main/java/mage/game/permanent/token/GermToken.java index 7b8ed218af0..c8a15fa9eb4 100644 --- a/Mage/src/main/java/mage/game/permanent/token/GermToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/GermToken.java @@ -1,12 +1,12 @@ - package mage.game.permanent.token; +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import mage.MageInt; -import mage.constants.CardType; -import mage.constants.SubType; /** * @author spjspj @@ -28,11 +28,12 @@ public final class GermToken extends TokenImpl { } public GermToken(String setCode, int tokenType) { - super("Germ", "0/0 black Germ creature token"); + super("Germ", "0/0 black Phyrexian Germ creature token"); availableImageSetCodes = tokenImageSets; setOriginalExpansionSetCode(setCode); cardType.add(CardType.CREATURE); color.setBlack(true); + subtype.add(SubType.PHYREXIAN); subtype.add(SubType.GERM); power = new MageInt(0); toughness = new MageInt(0); From 7b61da989bf34cd46818518bc6f07f9b0ae08892 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 09:44:32 -0400 Subject: [PATCH 023/188] [MH2] Implemented Prophetic Titan --- .../src/mage/cards/p/PropheticTitan.java | 87 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 88 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PropheticTitan.java diff --git a/Mage.Sets/src/mage/cards/p/PropheticTitan.java b/Mage.Sets/src/mage/cards/p/PropheticTitan.java new file mode 100644 index 00000000000..27c1c2e6bcb --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PropheticTitan.java @@ -0,0 +1,87 @@ +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.Mode; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.DeliriumCondition; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; +import mage.abilities.hint.common.CardTypesInGraveyardHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PropheticTitan extends CardImpl { + + public PropheticTitan(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{R}"); + + this.subtype.add(SubType.GIANT); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Delirium — When Prophetic Titan enters the battlefield, choose one. If there are four or more card types among cards in your graveyard, choose both. + // • Prophetic Titan deals 4 damage to any target. + // • Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in a random order. + this.addAbility(new PropheticTitanTriggeredAbility()); + } + + private PropheticTitan(final PropheticTitan card) { + super(card); + } + + @Override + public PropheticTitan copy() { + return new PropheticTitan(this); + } +} + +class PropheticTitanTriggeredAbility extends EntersBattlefieldTriggeredAbility { + + public PropheticTitanTriggeredAbility() { + super(new DamageTargetEffect(4), false, "Delirium — "); + this.addTarget(new TargetAnyTarget()); + this.addMode(new Mode(new LookLibraryAndPickControllerEffect( + StaticValue.get(4), false, StaticValue.get(1), + StaticFilters.FILTER_CARD, Zone.LIBRARY, false, false + ).setBackInRandomOrder(true).setText("look at the top four cards of your library. " + + "Put one of them into your hand and the rest on the bottom of your library in a random order"))); + this.getModes().setChooseText( + "choose one. If there are four or more card types among cards in your graveyard, choose both." + ); + this.addHint(CardTypesInGraveyardHint.YOU); + } + + private PropheticTitanTriggeredAbility(final PropheticTitanTriggeredAbility ability) { + super(ability); + } + + @Override + public PropheticTitanTriggeredAbility copy() { + return new PropheticTitanTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!super.checkTrigger(event, game)) { + return false; + } + int modes = DeliriumCondition.instance.apply(game, this) ? 2 : 1; + this.getModes().setMinModes(modes); + this.getModes().setMaxModes(modes); + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 4f30c769108..d826c0bd5fd 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -120,6 +120,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Priest of Fell Rites", 208, Rarity.RARE, mage.cards.p.PriestOfFellRites.class)); cards.add(new SetCardInfo("Prismatic Ending", 25, Rarity.UNCOMMON, mage.cards.p.PrismaticEnding.class)); cards.add(new SetCardInfo("Profane Tutor", 97, Rarity.RARE, mage.cards.p.ProfaneTutor.class)); + cards.add(new SetCardInfo("Prophetic Titan", 209, Rarity.UNCOMMON, mage.cards.p.PropheticTitan.class)); cards.add(new SetCardInfo("Quirion Ranger", 285, Rarity.UNCOMMON, mage.cards.q.QuirionRanger.class)); cards.add(new SetCardInfo("Ravenous Squirrel", 211, Rarity.UNCOMMON, mage.cards.r.RavenousSquirrel.class)); cards.add(new SetCardInfo("Razortide Bridge", 252, Rarity.COMMON, mage.cards.r.RazortideBridge.class)); From cd0c1231723a93b8354c53b033cd5a9749f1631a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 09:50:24 -0400 Subject: [PATCH 024/188] [MH2] Implemented Shattered Ego --- Mage.Sets/src/mage/cards/s/ShatteredEgo.java | 86 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 87 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ShatteredEgo.java diff --git a/Mage.Sets/src/mage/cards/s/ShatteredEgo.java b/Mage.Sets/src/mage/cards/s/ShatteredEgo.java new file mode 100644 index 00000000000..0a9df3f3a15 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShatteredEgo.java @@ -0,0 +1,86 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ShatteredEgo extends CardImpl { + + public ShatteredEgo(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets -3/-0. + this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(-3, 0))); + + // {3}{U}{U}: Put enchanted creature into its owner's library third from the top. + this.addAbility(new SimpleActivatedAbility(new ShatteredEgoEffect(), new ManaCostsImpl<>("{3}{U}{U}"))); + } + + private ShatteredEgo(final ShatteredEgo card) { + super(card); + } + + @Override + public ShatteredEgo copy() { + return new ShatteredEgo(this); + } +} + +class ShatteredEgoEffect extends OneShotEffect { + + ShatteredEgoEffect() { + super(Outcome.Benefit); + staticText = "put enchanted creature into its owner's library third from the top"; + } + + private ShatteredEgoEffect(final ShatteredEgoEffect effect) { + super(effect); + } + + @Override + public ShatteredEgoEffect copy() { + return new ShatteredEgoEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent aura = source.getSourcePermanentOrLKI(game); + if (player == null || aura == null) { + return false; + } + Permanent permanent = game.getPermanent(aura.getAttachedTo()); + return permanent != null && player.putCardOnTopXOfLibrary( + permanent, game, source, 3, true + ); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index d826c0bd5fd..c628fb36b4b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -138,6 +138,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Seal of Cleansing", 264, Rarity.UNCOMMON, mage.cards.s.SealOfCleansing.class)); cards.add(new SetCardInfo("Seal of Removal", 269, Rarity.UNCOMMON, mage.cards.s.SealOfRemoval.class)); cards.add(new SetCardInfo("Shardless Agent", 321, Rarity.RARE, mage.cards.s.ShardlessAgent.class)); + cards.add(new SetCardInfo("Shattered Ego", 62, Rarity.COMMON, mage.cards.s.ShatteredEgo.class)); cards.add(new SetCardInfo("Silverbluff Bridge", 255, Rarity.COMMON, mage.cards.s.SilverbluffBridge.class)); cards.add(new SetCardInfo("Skirge Familiar", 276, Rarity.UNCOMMON, mage.cards.s.SkirgeFamiliar.class)); cards.add(new SetCardInfo("Skophos Reaver", 140, Rarity.COMMON, mage.cards.s.SkophosReaver.class)); From deae90b58298ac0d4efc37da06e07e7f2809fed3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 09:58:24 -0400 Subject: [PATCH 025/188] [MH2] Implemented Fast // Furious --- Mage.Sets/src/mage/cards/f/FastFurious.java | 56 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 57 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FastFurious.java diff --git a/Mage.Sets/src/mage/cards/f/FastFurious.java b/Mage.Sets/src/mage/cards/f/FastFurious.java new file mode 100644 index 00000000000..fb5eba6aff3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FastFurious.java @@ -0,0 +1,56 @@ +package mage.cards.f; + +import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.discard.DiscardControllerEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardSetInfo; +import mage.cards.SplitCard; +import mage.constants.CardType; +import mage.constants.SpellAbilityType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FastFurious extends SplitCard { + + private static final FilterPermanent filter = new FilterCreaturePermanent("creature without flying"); + + static { + filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); + } + + public FastFurious(UUID ownerId, CardSetInfo setInfo) { + super( + ownerId, setInfo, + new CardType[]{CardType.INSTANT}, new CardType[]{CardType.SORCERY}, + "{2}{R}", "{3}{R}{R}", SpellAbilityType.SPLIT + ); + + // Fast + // Discard a card, then draw two cards. + this.getLeftHalfCard().getSpellAbility().addEffect(new DiscardControllerEffect(1)); + this.getLeftHalfCard().getSpellAbility().addEffect( + new DrawCardSourceControllerEffect(2).concatBy(", then") + ); + + // Furious + // Furious deals 3 damage to each creature without flying. + this.getRightHalfCard().getSpellAbility().addEffect(new DamageAllEffect(3, filter)); + } + + private FastFurious(final FastFurious card) { + super(card); + } + + @Override + public FastFurious copy() { + return new FastFurious(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index c628fb36b4b..ba9cdb36463 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -66,6 +66,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Enchantress's Presence", 283, Rarity.RARE, mage.cards.e.EnchantresssPresence.class)); cards.add(new SetCardInfo("Endurance", 157, Rarity.MYTHIC, mage.cards.e.Endurance.class)); cards.add(new SetCardInfo("Extruder", 296, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); + cards.add(new SetCardInfo("Fast // Furious", 123, Rarity.UNCOMMON, mage.cards.f.FastFurious.class)); cards.add(new SetCardInfo("Feast of Sanity", 84, Rarity.UNCOMMON, mage.cards.f.FeastOfSanity.class)); cards.add(new SetCardInfo("Filigree Attendant", 41, Rarity.UNCOMMON, mage.cards.f.FiligreeAttendant.class)); cards.add(new SetCardInfo("Fire // Ice", 290, Rarity.RARE, mage.cards.f.FireIce.class)); From ca7a732c5c1d22bf631bd4b05c24b2d726d3d639 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 10:22:31 -0400 Subject: [PATCH 026/188] [MH2] Implemented Fae Offering --- Mage.Sets/src/mage/cards/f/FaeOffering.java | 107 +++++++++++++++++++ Mage.Sets/src/mage/cards/l/Leapfrog.java | 4 +- Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 3 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/f/FaeOffering.java diff --git a/Mage.Sets/src/mage/cards/f/FaeOffering.java b/Mage.Sets/src/mage/cards/f/FaeOffering.java new file mode 100644 index 00000000000..b9941d402ad --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FaeOffering.java @@ -0,0 +1,107 @@ +package mage.cards.f; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.hint.Hint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.game.Game; +import mage.game.permanent.token.ClueArtifactToken; +import mage.game.permanent.token.FoodToken; +import mage.game.permanent.token.TreasureToken; +import mage.game.stack.Spell; +import mage.watchers.common.SpellsCastWatcher; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class FaeOffering extends CardImpl { + + public FaeOffering(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + + // At the beginning of each end step, if you've cast both a creature spell and a noncreature spell this turn, create a Clue token, a Food token, and a Treasure token. + Ability ability = new ConditionalInterveningIfTriggeredAbility( + new BeginningOfEndStepTriggeredAbility( + new CreateTokenEffect(new ClueArtifactToken()), TargetController.ANY, false + ), FaeOfferingCondition.instance, "At the beginning of each end step, " + + "if you've cast both a creature spell and a noncreature spell this turn, " + + "create a Clue token, a Food token, and a Treasure token." + ); + ability.addEffect(new CreateTokenEffect(new FoodToken())); + ability.addEffect(new CreateTokenEffect(new TreasureToken())); + this.addAbility(ability.addHint(FaeOfferingHint.instance), new SpellsCastWatcher()); + } + + private FaeOffering(final FaeOffering card) { + super(card); + } + + @Override + public FaeOffering copy() { + return new FaeOffering(this); + } +} + +enum FaeOfferingCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); + if (watcher == null) { + return false; + } + List spells = watcher.getSpellsCastThisTurn(source.getControllerId()); + return spells != null && spells + .stream() + .filter(Objects::nonNull) + .map(MageObject::isCreature) + .distinct() + .count() == 2; + } +} + +enum FaeOfferingHint implements Hint { + instance; + + @Override + public String getText(Game game, Ability ability) { + SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); + if (watcher == null) { + return null; + } + List spells = watcher.getSpellsCastThisTurn(ability.getControllerId()); + if (spells == null) { + return null; + } + List messages = spells + .stream() + .filter(Objects::nonNull) + .map(MageObject::isCreature) + .distinct() + .map(b -> b ? "Creature spell" : "Noncreature spell") + .sorted() + .collect(Collectors.toList()); + if (messages.size() == 0) { + return "You have not cast any spells this turn"; + } + return "You have cast a " + String.join(" and a ", messages) + " this turn"; + } + + @Override + public FaeOfferingHint copy() { + return instance; + } +} diff --git a/Mage.Sets/src/mage/cards/l/Leapfrog.java b/Mage.Sets/src/mage/cards/l/Leapfrog.java index b0f2cd6f660..9ddeea02e31 100644 --- a/Mage.Sets/src/mage/cards/l/Leapfrog.java +++ b/Mage.Sets/src/mage/cards/l/Leapfrog.java @@ -65,8 +65,6 @@ enum LeapfrogCondition implements Condition { return spells != null && spells .stream() .filter(Objects::nonNull) - .filter(MageObject::isInstantOrSorcery) - .map(Spell::getSourceId) - .anyMatch(source.getSourceId()::equals); + .anyMatch(MageObject::isInstantOrSorcery); } } diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index ba9cdb36463..e52d73a7074 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -66,6 +66,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Enchantress's Presence", 283, Rarity.RARE, mage.cards.e.EnchantresssPresence.class)); cards.add(new SetCardInfo("Endurance", 157, Rarity.MYTHIC, mage.cards.e.Endurance.class)); cards.add(new SetCardInfo("Extruder", 296, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); + cards.add(new SetCardInfo("Fae Offering", 158, Rarity.UNCOMMON, mage.cards.f.FaeOffering.class)); cards.add(new SetCardInfo("Fast // Furious", 123, Rarity.UNCOMMON, mage.cards.f.FastFurious.class)); cards.add(new SetCardInfo("Feast of Sanity", 84, Rarity.UNCOMMON, mage.cards.f.FeastOfSanity.class)); cards.add(new SetCardInfo("Filigree Attendant", 41, Rarity.UNCOMMON, mage.cards.f.FiligreeAttendant.class)); From 9770882c21a6f19b77015cd52621c06f5ecba0ed Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 10:28:29 -0400 Subject: [PATCH 027/188] [MH2] Implemented Territorial Kavu --- .../src/mage/cards/t/TerritorialKavu.java | 67 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 68 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TerritorialKavu.java diff --git a/Mage.Sets/src/mage/cards/t/TerritorialKavu.java b/Mage.Sets/src/mage/cards/t/TerritorialKavu.java new file mode 100644 index 00000000000..136ee8f1b1c --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TerritorialKavu.java @@ -0,0 +1,67 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.DomainValue; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; +import mage.abilities.hint.common.DomainHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.target.common.TargetCardInGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TerritorialKavu extends CardImpl { + + private static final DynamicValue xValue = new DomainValue(); + + public TerritorialKavu(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}"); + + this.subtype.add(SubType.KAVU); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // Domain — Territorial Kavu's power and toughness are each equal to the number of basic land types among lands you control. + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new SetPowerToughnessSourceEffect(xValue, Duration.EndOfGame) + ).addHint(DomainHint.instance)); + + // Whenever Territorial Kavu attacks, choose one — + // • Discard a card. If you do, draw a card. + Ability ability = new AttacksTriggeredAbility(new DoIfCostPaid( + new DrawCardSourceControllerEffect(1), + null, new DiscardCardCost(), false + ), false); + + // • Exile up to one target card from a graveyard. + Mode mode = new Mode(new ExileTargetEffect()); + mode.addTarget(new TargetCardInGraveyard(0, 1)); + ability.addMode(mode); + this.addAbility(ability); + } + + private TerritorialKavu(final TerritorialKavu card) { + super(card); + } + + @Override + public TerritorialKavu copy() { + return new TerritorialKavu(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index e52d73a7074..f70126eed00 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -162,6 +162,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Sylvan Anthem", 176, Rarity.RARE, mage.cards.s.SylvanAnthem.class)); cards.add(new SetCardInfo("Tanglepool Bridge", 257, Rarity.COMMON, mage.cards.t.TanglepoolBridge.class)); cards.add(new SetCardInfo("Terramorph", 177, Rarity.UNCOMMON, mage.cards.t.Terramorph.class)); + cards.add(new SetCardInfo("Territorial Kavu", 216, Rarity.RARE, mage.cards.t.TerritorialKavu.class)); cards.add(new SetCardInfo("The Underworld Cookbook", 240, Rarity.UNCOMMON, mage.cards.t.TheUnderworldCookbook.class)); cards.add(new SetCardInfo("Thornglint Bridge", 258, Rarity.COMMON, mage.cards.t.ThornglintBridge.class)); cards.add(new SetCardInfo("Thought Monitor", 71, Rarity.RARE, mage.cards.t.ThoughtMonitor.class)); From c092989c6fb9c08b8e7e824a19bc6e65de5761ef Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 10:34:00 -0400 Subject: [PATCH 028/188] [MH2] Implemented Master of Death --- Mage.Sets/src/mage/cards/m/MasterOfDeath.java | 54 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 55 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MasterOfDeath.java diff --git a/Mage.Sets/src/mage/cards/m/MasterOfDeath.java b/Mage.Sets/src/mage/cards/m/MasterOfDeath.java new file mode 100644 index 00000000000..d4fbc80a7dd --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MasterOfDeath.java @@ -0,0 +1,54 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; +import mage.abilities.effects.keyword.SurveilEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MasterOfDeath extends CardImpl { + + public MasterOfDeath(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{B}"); + + this.subtype.add(SubType.ZOMBIE); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // When Master of Death enters the battlefield, surveil 2. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SurveilEffect(2))); + + // At the beginning of your upkeep, if Master of Death is in your graveyard, you may pay 1 life. If you do, return it to your hand. + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + Zone.GRAVEYARD, + new DoIfCostPaid( + new ReturnSourceFromGraveyardToHandEffect() + .setText("return it to your hand"), + new PayLifeCost(1) + ), TargetController.YOU, false + )); + } + + private MasterOfDeath(final MasterOfDeath card) { + super(card); + } + + @Override + public MasterOfDeath copy() { + return new MasterOfDeath(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index f70126eed00..89ebc0ee757 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -100,6 +100,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Lose Focus", 49, Rarity.COMMON, mage.cards.l.LoseFocus.class)); cards.add(new SetCardInfo("Lucid Dreams", 50, Rarity.UNCOMMON, mage.cards.l.LucidDreams.class)); cards.add(new SetCardInfo("Marsh Flats", 248, Rarity.RARE, mage.cards.m.MarshFlats.class)); + cards.add(new SetCardInfo("Master of Death", 205, Rarity.RARE, mage.cards.m.MasterOfDeath.class)); cards.add(new SetCardInfo("Mental Journey", 51, Rarity.COMMON, mage.cards.m.MentalJourney.class)); cards.add(new SetCardInfo("Millikin", 297, Rarity.UNCOMMON, mage.cards.m.Millikin.class)); cards.add(new SetCardInfo("Mirari's Wake", 291, Rarity.MYTHIC, mage.cards.m.MirarisWake.class)); From 53a68abfff22ac440dc5bde9f376937ecc1d8df3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 10:36:07 -0400 Subject: [PATCH 029/188] [MH2] Implemented Moderation --- Mage.Sets/src/mage/cards/m/Moderation.java | 39 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 40 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/Moderation.java diff --git a/Mage.Sets/src/mage/cards/m/Moderation.java b/Mage.Sets/src/mage/cards/m/Moderation.java new file mode 100644 index 00000000000..9ed71375f9b --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/Moderation.java @@ -0,0 +1,39 @@ +package mage.cards.m; + +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.CantCastMoreThanOneSpellEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Moderation extends CardImpl { + + public Moderation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{U}"); + + // You can't cast more than one spell each turn. + this.addAbility(new SimpleStaticAbility(new CantCastMoreThanOneSpellEffect(TargetController.YOU))); + + // Whenever you cast a spell, draw a card. + this.addAbility(new SpellCastControllerTriggeredAbility( + new DrawCardSourceControllerEffect(1), false + )); + } + + private Moderation(final Moderation card) { + super(card); + } + + @Override + public Moderation copy() { + return new Moderation(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 89ebc0ee757..a4dc3dbcd40 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -107,6 +107,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Mishra's Factory", 302, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class)); cards.add(new SetCardInfo("Mistvault Bridge", 249, Rarity.COMMON, mage.cards.m.MistvaultBridge.class)); cards.add(new SetCardInfo("Misty Rainforest", 250, Rarity.RARE, mage.cards.m.MistyRainforest.class)); + cards.add(new SetCardInfo("Moderation", 206, Rarity.RARE, mage.cards.m.Moderation.class)); cards.add(new SetCardInfo("Mogg Salvage", 282, Rarity.UNCOMMON, mage.cards.m.MoggSalvage.class)); cards.add(new SetCardInfo("Monoskelion", 229, Rarity.UNCOMMON, mage.cards.m.Monoskelion.class)); cards.add(new SetCardInfo("Mountain", 487, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); From 0d163f6afd029f5e93a946b1cd03b182ad526bca Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 11:06:48 -0400 Subject: [PATCH 030/188] [MH2] updated spoiler and reprints --- Mage.Sets/src/mage/sets/ModernHorizons2.java | 5 +++-- Utils/mtg-cards-data.txt | 14 ++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index a4dc3dbcd40..98a2ba92cce 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -129,6 +129,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Ravenous Squirrel", 211, Rarity.UNCOMMON, mage.cards.r.RavenousSquirrel.class)); cards.add(new SetCardInfo("Razortide Bridge", 252, Rarity.COMMON, mage.cards.r.RazortideBridge.class)); cards.add(new SetCardInfo("Rift Sower", 170, Rarity.COMMON, mage.cards.r.RiftSower.class)); + cards.add(new SetCardInfo("Riptide Laboratory", 303, Rarity.RARE, mage.cards.r.RiptideLaboratory.class)); cards.add(new SetCardInfo("Rishadan Dockhand", 59, Rarity.RARE, mage.cards.r.RishadanDockhand.class)); cards.add(new SetCardInfo("Rustvale Bridge", 253, Rarity.COMMON, mage.cards.r.RustvaleBridge.class)); cards.add(new SetCardInfo("Sanctuary Raptor", 233, Rarity.UNCOMMON, mage.cards.s.SanctuaryRaptor.class)); @@ -138,10 +139,10 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Scion of Draco", 234, Rarity.MYTHIC, mage.cards.s.ScionOfDraco.class)); cards.add(new SetCardInfo("Scurry Oak", 172, Rarity.UNCOMMON, mage.cards.s.ScurryOak.class)); cards.add(new SetCardInfo("Scuttletide", 61, Rarity.UNCOMMON, mage.cards.s.Scuttletide.class)); - cards.add(new SetCardInfo("Sea Drake", 268, Rarity.RARE, mage.cards.s.SeaDrake.class)); + cards.add(new SetCardInfo("Sea Drake", 268, Rarity.UNCOMMON, mage.cards.s.SeaDrake.class)); cards.add(new SetCardInfo("Seal of Cleansing", 264, Rarity.UNCOMMON, mage.cards.s.SealOfCleansing.class)); cards.add(new SetCardInfo("Seal of Removal", 269, Rarity.UNCOMMON, mage.cards.s.SealOfRemoval.class)); - cards.add(new SetCardInfo("Shardless Agent", 321, Rarity.RARE, mage.cards.s.ShardlessAgent.class)); + cards.add(new SetCardInfo("Shardless Agent", 292, Rarity.RARE, mage.cards.s.ShardlessAgent.class)); cards.add(new SetCardInfo("Shattered Ego", 62, Rarity.COMMON, mage.cards.s.ShatteredEgo.class)); cards.add(new SetCardInfo("Silverbluff Bridge", 255, Rarity.COMMON, mage.cards.s.SilverbluffBridge.class)); cards.add(new SetCardInfo("Skirge Familiar", 276, Rarity.UNCOMMON, mage.cards.s.SkirgeFamiliar.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index a8a414afbd1..9e0a978e2e2 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -41360,6 +41360,7 @@ Lucid Dreams|Modern Horizons 2|50|U|{3}{U}{U}|Sorcery|||Draw X cards, where X is Mental Journey|Modern Horizons 2|51|C|{4}{U}{U}|Instant|||Draw three cards.$Basic landcycling {1}{U}| Mystic Redaction|Modern Horizons 2|53|U|{2}{U}|Enchantment|||At the beginning of your upkeep, scry 1.$Whenever you discard a card, each opponent mills two cards.| Phantasmal Dreadmaw|Modern Horizons 2|55|C|{2}{U}{U}|Creature - Dinosaur Illusion|6|6|Trample$When Phantasmal Dreadmaw becomes the target of a spell or ability, sacrifice it.| +Raving Visionary|Modern Horizons 2|56|U|{1}{U}|Creature - Merfolk Wizard|1|1|{U}, {T}: Draw a card, then discard a card.$Delirium — {2}{U}, {T}: Draw a card. Activate only if there are four or more card types among cards in your graveyard.| Rise and Shine|Modern Horizons 2|58|R|{1}{U}|Sorcery|||Target noncreature artifact you control becomes a 0/0 artifact creature. Put four +1/+1 counters on each artifact that became a creature this way.$Overload {4}{U}{U}| Rishadan Dockhand|Modern Horizons 2|59|R|{U}|Creature - Merfolk|1|2|Islandwalk${1}, {T}: Tap target land.| Scuttletide|Modern Horizons 2|61|U|{1}{U}|Enchantment|||{1}, Discard a card: Create a 0/3 blue Crab creature token.$Delirium — Crabs you control get +1/+1 as long as there are four or more card types among cards in your graveyard.| @@ -41368,15 +41369,17 @@ So Shiny|Modern Horizons 2|63|C|{2}{U}|Enchantment - Aura|||Enchant creature$Whe Step Through|Modern Horizons 2|66|C|{3}{U}{U}|Sorcery|||Return two target creatures to their owners' hands.$Wizardcycling {2}| Subtlety|Modern Horizons 2|67|M|{2}{U}{U}|Creature - Elemental Incarnation|3|3|Flash$Flying$When Subtlety enters the battlefield, choose up to one target creature spell or planeswalker spell. Its owner puts it on the top or bottom of their library.$Evoke—Exile a blue card from your hand.| Suspend|Modern Horizons 2|68|R|{U}|Instant|||Exile target creature and put two time counters on it. If it doesn't have suspend, it gains suspend.| -Svyelun of Sea and Sky|Modern Horizons 2|69|M|{1}{U}{U}|Legendary Creature - Merfolk God|3|4|Svyelun of Sea and Sky has indestructible as long as you control at least two other Merfolk.$Whenever Svyelun attacks, draw a card.$Other Merfolk you control have ward {1}| +Svyelun of Sea and Sky|Modern Horizons 2|69|M|{1}{U}{U}|Legendary Creature - Merfolk God|3|4|Svyelun of Sea and Sky has indestructible as long as you control at least two other Merfolk.$Whenever Svyelun attacks, draw a card.$Other Merfolk you control have ward {1}.| Sweep the Skies|Modern Horizons 2|70|U|{X}{U}{U}|Sorcery|||Converge — Create a 1/1 colorless Thopter artifact creature token with flying for each color of mana spent to cast this spell.| Thought Monitor|Modern Horizons 2|71|R|{6}{U}|Artifact Creature - Construct|2|2|Affinity for artifacts$Flying$When Thought Monitor enters the battlefield, draw two cards.| +Tide Shaper|Modern Horizons 2|72|U|{U}|Creature - Merfolk Wizard|1|1|Kicker {1}$When Tide Shaper enters the battlefield, if it was kicked, target land becomes an Island for as long as Tide Shaper remains on the battlefield.$Tide Shaper gets +1/+1 as long as an opponent controls an Island.| Vedalken Infiltrator|Modern Horizons 2|73|U|{1}{U}|Creature - Vedalken Rogue|1|3|Vedalken Infiltrator can't be blocked.$Metalcraft — Vedalken Infiltrator gets +1/+0 as long as you control three or more artifacts.| Archfiend of Sorrows|Modern Horizons 2|74|U|{5}{B}{B}|Creature - Demon|4|5|Flying$When Archfiend of Sorrows enters the battlefield, creatures your opponents control get -2/-2 until end of turn.$Unearth {3}{B}{B}| Archon of Cruelty|Modern Horizons 2|75|M|{6}{B}{B}|Creature - Archon|6|6|Flying$Whenever Archon of Cruelty enters the battlefield or attacks, target opponent sacrifices a creature or planeswalker, discards a card, and loses 3 life. You draw a card and gain 3 life.| Bone Shards|Modern Horizons 2|76|C|{B}|Sorcery|||As an additional cost to cast this spell, sacrifice a creature or discard a card.$Destroy target creature or planeswalker.| Clattering Augur|Modern Horizons 2|79|U|{1}{B}|Creature - Skeleton Shaman|1|1|Clattering Augur can't block.$When Clattering Augur enters the battlefield, you draw a card and you lose 1 life.${2}{B}{B}: Return Clattering Augur from your graveyard to your hand.| Damn|Modern Horizons 2|80|R|{B}{B}|Sorcery|||Destroy target creature. A creature destroyed this way can't be regenerated.$Overload {2}{W}{W}| +Dauthi Voidwalker|Modern Horizons 2|81|R|{B}{B}|Creature - Dauthi Rogue|3|2|Shadow$If a card would be put into an opponent's graveyard from anywhere, instead exile it with a void counter on it.${T}, Sacrifice Dauthi Voidwalker: Choose an exiled card an opponent owns with a void counter on it. You may play it this turn without paying its mana cost.| Discerning Taste|Modern Horizons 2|82|C|{2}{B}|Sorcery|||Look at the top four cards of your library. Put one of them into your hand and the rest into your graveyard. You gain life equal to the greatest power among creature cards put into your graveyard this way.| Feast of Sanity|Modern Horizons 2|84|U|{3}{B}|Enchantment|||Whenever you discard a card, Feast of Sanity deals 1 damage to any target and you gain 1 life.| Flay Essence|Modern Horizons 2|85|U|{1}{B}{B}|Sorcery|||Exile target creature or planeswalker. You gain life equal to the number of counters on it.| @@ -41415,6 +41418,7 @@ Abundant Harvest|Modern Horizons 2|147|C|{G}|Sorcery|||Choose land or nonland. R Aeve, Progenitor Ooze|Modern Horizons 2|148|R|{2}{G}{G}{G}|Legendary Creature - Ooze|2|2|Storm$Aeve, Progenitor Ooze isn't legendary as long as it's a token.$Aeve enters the battlefield with a +1/+1 counter on it for each Ooze you control.| Chatterfang, Squirrel General|Modern Horizons 2|151|M|{2}{G}|Legendary Creature - Squirrel Warrior|3|3|Forestwalk$If one or more tokens would be created under your control, those tokens plus that many 1/1 green Squirrel creature tokens are created instead.${B}, Sacrifice X Squirrels: Target creature gets +X/-X until end of turn.| Chatterstorm|Modern Horizons 2|152|C|{1}{G}|Sorcery|||Create a 1/1 green Squirrel creature token.$Storm| +Chitterspitter|Modern Horizons 2|153|R|{2}{G}|Artifact|||At the beginning of your upkeep, you may sacrifice a token. If you do, put an acorn counter on Chitterspitter.$Squirrels you control get +1/+1 for each acorn counter on Chitterspitter.${G}, {T}: Createa 1/1 green Squirrel creature token.| Endurance|Modern Horizons 2|157|M|{1}{G}{G}|Creature - Elemental Incarnation|3|4|Flash$Reach$When Endurance enters the battlefield, up to one target player puts all the cards from their graveyard on the bottom of their library in a random order.$Evoke—Exile a green card from your hand.| Fae Offering|Modern Horizons 2|158|U|{2}{G}|Enchantment|||At the beginning of each end step, if you've cast both a creature spell and a noncreature spell this turn, create a Clue token, a Food token, and a Treasure token.| Gaea's Will|Modern Horizons 2|162|R||Sorcery|||Suspend 4—{G}$Until end of turn, you may play land cards and cast spells from your graveyard.$If a card would be put into your graveyard from anywhere this turn, exile that card instead.| @@ -41438,10 +41442,11 @@ Verdant Command|Modern Horizons 2|182|R|{1}{G}|Instant|||Choose two —$• Targ Arcbound Shikari|Modern Horizons 2|184|U|{1}{R}{W}|Artifact Creature - Cat Soldier|0|0|First Strike$When Arcbound Shikari enters the battlefield, put a +1/+1 counter on each other artifact creature you control.$Modular 2| Asmoranomardicadaistinaculdacar|Modern Horizons 2|186|R||Legendary Creature - Human Wizard|3|3|As long as you've discarded a card this turn, you may pay {B/R} to cast this spell.$When Asmoranomardicadaistinaculdacar enters the battlefield, you may search your library for a card named The Underworld Cookbook, reveal it, put it into your hand, then shuffle.$Sacrifice two Foods: Target creature deals 6 damage to itself.| Carth the Lion|Modern Horizons 2|189|R|{2}{B}{G}|Legendary Creature - Human Warrior|3|5|Whenever Carth the Lion enters the battlefield or a planeswalker you control dies, look at the top seven cards of your library. You may reveal a planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.$Planeswalkers' loyalty abilities you activate cost an additional {+1} to activate.| +Chrome Courier|Modern Horizons 2|190|C|{1}{W}{U}|Artifact Creature - Thopter|1|1|Flying$When Chrome Courier enters the battlefield, reveal the top two cards of your library. Put one of them into your hand and the other into your graveyard. If you put an artifact card into your hand this way, you gain 3 life.| Combine Chrysalis|Modern Horizons 2|191|U|{G}{U}|Artifact|||Creature tokens you control have flying.${2}{G}{U}, {T}, Sacrifice a token: Create a 4/4 green Beast creature token. Activate only as a sorcery.| Dakkon, Shadow Slayer|Modern Horizons 2|192|M|{W}{U}{B}|Legendary Planeswalker - Dakkon|0|Dakkon, Shadow Slayer enters the battlefield with a number of loyalty counters on him equal to the number of lands you control.$+1: Surveil 2.$−3: Exile target creature.$−6: You may put an artifact card from your hand or graveyard onto the battlefield.| Drey Keeper|Modern Horizons 2|194|C|{3}{B}{G}|Creature - Elf Druid|2|2|When Drey Keeper enters the battlefield, create two 1/1 green Squirrel creature tokens.${3}{B}: Squirrels you control get +1/+0 and gain menace until end of turn.| -Garth One-Eye|Modern Horizons 2|197|M|{W}{U}{B}{R}{G}|Legendary Creature - Human Wizard|5|5|{T}: Choose a card name that hasn't been chosen from among Disenchant, Braingeyser, Terror, Shivan Dragon, Regrowth, or Black Lotus. Create a copy of the card with the chosen name. You may cast the copy.| +Garth One-Eye|Modern Horizons 2|197|M|{W}{U}{B}{R}{G}|Legendary Creature - Human Wizard|5|5|{T}: Choose a card name that hasn't been chosen from among Disenchant, Braingeyser, Terror, Shivan Dragon, Regrowth, and Black Lotus. Create a copy of the card with the chosen name. You may cast the copy.| General Ferrous Rokiric|Modern Horizons 2|198|R|{1}{R}{W}|Legendary Creature - Human Soldier|3|1|Hexproof from monocolored$Whenever you cast a multicolored spell, create a 4/4 red and white Golem artifact creature token.| Geyadrone Dihada|Modern Horizons 2|199|M|{1}{U}{B}{R}|Legendary Planeswalker - Dihada|4|Protection from permanents with corruption counters on them$+1: Each opponent loses 2 life and you gain 2 life. Put a corruption counter on up to one other target creature or planeswalker.$−3: Gain control of target creature or planeswalker until end of tun. Untap it and put a corruption counter on it. It gains haste until end of turn.$−7: Gain control of each permanent with a corruption counter on it.| Graceful Restoration|Modern Horizons 2|201|U|{3}{W}{B}|Sorcery|||Choose one —$• Return target creature card from your graveyard to the battlefield with an additional +1/+1 counter on it.$• Return up to two target creature cards with power 2 or less from your graveyard to the battlefield.| @@ -41498,7 +41503,7 @@ Seal of Cleansing|Modern Horizons 2|264|U|{1}{W}|Enchantment|||Sacrifice Seal of Solitary Confinement|Modern Horizons 2|265|R|{2}{W}|Enchantment|||At the beginning of your upkeep, sacrifice Solitary Confinement unless you discard a card.$Skip your draw step.$You have shroud.$Prevent all damage that would be dealt to you.| Soul Snare|Modern Horizons 2|266|U|{W}|Enchantment|||{W}, Sacrifice Soul Snare: Exile target creature that's attacking you or a planeswalker you control.| Counterspell|Modern Horizons 2|267|U|{U}{U}|Instant|||Counter target spell.| -Sea Drake|Modern Horizons 2|268|R|{2}{U}|Creature - Drake|4|3|Flying$When Sea Drake enters the battlefield, return two target lands you control to their owner's hand.| +Sea Drake|Modern Horizons 2|268|U|{2}{U}|Creature - Drake|4|3|Flying$When Sea Drake enters the battlefield, return two target lands you control to their owner's hand.| Seal of Removal|Modern Horizons 2|269|U|{U}|Enchantment|||Sacrifice Seal of Removal: Return target creature to its owner's hand.| Upheaval|Modern Horizons 2|270|R|{4}{U}{U}|Sorcery|||Return all permanents to their owners' hands.| Wonder|Modern Horizons 2|271|R|{3}{U}|Creature - Incarnation|2|2|Flying$As long as Wonder is in your graveyard and you control an Island, creatures you control have flying.| @@ -41520,6 +41525,7 @@ Titania, Protector of Argoth|Modern Horizons 2|287|M|{3}{G}{G}|Legendary Creatur Chainer, Nightmare Adept|Modern Horizons 2|289|R|{2}{B}{R}|Legendary Creature - Human Minion|3|2|Discard a card: You may cast a creature spell from your graveyard this turn. Activate only once each turn.$Whenever a nontoken creature enters the battlefield under your control, if you didn't cast it from your hand, it gains haste until your next turn.| Fire // Ice|Modern Horizons 2|290|R|{1}{R}|Instant|||Fire deals 2 damage divided as you choose among one or two targets.$Ice${1}{U}$Instant$Tap target permanent.$Draw a card.| Mirari's Wake|Modern Horizons 2|291|M|{3}{G}{W}|Enchantment|||Creatures you control get +1/+1.$Whenever you tap a land for mana, add one mana of any type that land produced.| +Shardless Agent|Modern Horizons 2|292|R|{1}{G}{U}|Artifact Creature - Human Rogue|2|2|Cascade| Sterling Grove|Modern Horizons 2|293|R|{G}{W}|Enchantment|||Other enchantments you control have shroud.${1}, Sacrifice Sterling Grove: Search your library for an enchantment card, reveal it, then shuffle and put the card on top.| Vindicate|Modern Horizons 2|294|R|{1}{W}{B}|Sorcery|||Destroy target permanent.| Cursed Totem|Modern Horizons 2|295|R|{2}|Artifact|||Activated abilities of creatures can't be activated.| @@ -41529,7 +41535,7 @@ Nevinyrral's Disk|Modern Horizons 2|298|R|{4}|Artifact|||Nevinyrral's Disk enter Zuran Orb|Modern Horizons 2|300|U|{0}|Artifact|||Sacrifice a land: You gain 2 life.| Cabal Coffers|Modern Horizons 2|301|M||Land|||{2}, {T}: Add {B} for each Swamp you control.| Mishra's Factory|Modern Horizons 2|302|U||Land|||{T}: Add {C}.${1}: Mishra's Factory becomes a 2/2 Assembly-Worker artifact creature until end of turn. It's still a land.${T}: Target Assembly-Worker creature gets +1/+1 until end of turn.| -Shardless Agent|Modern Horizons 2|321|R|{1}{G}{U}|Artifact Creature - Human Rogue|2|2|Cascade| +Riptide Laboratory|Modern Horizons 2|303|R||Land|||{T}: Add {C}.${1}{U}, {T}: Return target Wizard you control to its owner's hand.| Plains|Modern Horizons 2|481|C||Basic Land - Plains|||({T}: Add {W}.)| Island|Modern Horizons 2|483|C||Basic Land - Island|||({T}: Add {U}.)| Swamp|Modern Horizons 2|485|C||Basic Land - Swamp|||({T}: Add {B}.)| From ed0f921a770e61561bd44e9737537abd457f96ee Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 15:12:59 -0400 Subject: [PATCH 031/188] [CHK] fixed Nine-Ringed Bo ability being sorcery speed (fixes #7863) --- Mage.Sets/src/mage/cards/n/NineRingedBo.java | 21 ++++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/Mage.Sets/src/mage/cards/n/NineRingedBo.java b/Mage.Sets/src/mage/cards/n/NineRingedBo.java index 70fdc0e87f7..9820975f238 100644 --- a/Mage.Sets/src/mage/cards/n/NineRingedBo.java +++ b/Mage.Sets/src/mage/cards/n/NineRingedBo.java @@ -1,9 +1,7 @@ - package mage.cards.n; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.ExileTargetIfDiesEffect; @@ -11,29 +9,26 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; +import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; -import mage.target.common.TargetCreaturePermanent; +import mage.target.TargetPermanent; + +import java.util.UUID; /** - * * @author LevelX */ public final class NineRingedBo extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("spirit"); - - static { - filter.add(SubType.SPIRIT.getPredicate()); - } + private static final FilterPermanent filter = new FilterCreaturePermanent(SubType.SPIRIT, "Spirit creature"); public NineRingedBo(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // {T}: Nine-Ringed Bo deals 1 damage to target Spirit creature. If that creature would die this turn, exile it instead. - Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new TapSourceCost()); ability.addEffect(new ExileTargetIfDiesEffect()); - ability.addTarget(new TargetCreaturePermanent(filter)); + ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); } From 65c4ed7e5b9b3ed64e7b0b7ee308ace01de2c852 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 15:19:10 -0400 Subject: [PATCH 032/188] [RAV] fixed an error with Bottled Cloiser (fixes #7849) --- Mage.Sets/src/mage/cards/b/BottledCloister.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BottledCloister.java b/Mage.Sets/src/mage/cards/b/BottledCloister.java index c031230a58d..d64cea6e22f 100644 --- a/Mage.Sets/src/mage/cards/b/BottledCloister.java +++ b/Mage.Sets/src/mage/cards/b/BottledCloister.java @@ -12,7 +12,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; -import mage.game.ExileZone; import mage.game.Game; import mage.players.Player; import mage.util.CardUtil; @@ -103,12 +102,12 @@ class BottledCloisterReturnEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)); - Cards cards = new CardsImpl(exileZone); - cards.removeIf(uuid -> !player.getId().equals(game.getOwnerId(uuid))); - if (!cards.isEmpty()) { - player.moveCards(cards, Zone.HAND, source, game); + if (player == null) { + return false; } + Cards cards = new CardsImpl(game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)).getCards(game)); + cards.removeIf(uuid -> !player.getId().equals(game.getOwnerId(uuid))); + player.moveCards(cards, Zone.HAND, source, game); player.drawCards(1, source, game); return true; } From 65b34ac6b49d1bc8b5c02a2bc2d0ac5e9b552a3d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 15:38:49 -0400 Subject: [PATCH 033/188] removed temporary test skips --- Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index befcac06a88..4d2711bb889 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -89,7 +89,6 @@ public class VerifyCardDataTest { skipListCreate(SKIP_LIST_PT); skipListAddName(SKIP_LIST_PT, "UST", "Garbage Elemental"); skipListAddName(SKIP_LIST_PT, "UST", "Infinity Elemental"); - skipListAddName(SKIP_LIST_PT, "MH2", "Archfiend of Sorrows"); // temporary // color skipListCreate(SKIP_LIST_COLOR); @@ -115,7 +114,6 @@ public class VerifyCardDataTest { // subtype skipListCreate(SKIP_LIST_SUBTYPE); skipListAddName(SKIP_LIST_SUBTYPE, "UGL", "Miss Demeanor"); - skipListAddName(SKIP_LIST_SUBTYPE, "MH2", "Squirrel Sovereign"); // temporary subtypesToIgnore.add("Phyrexian"); // large errata incoming, adding this for now // number From d1f31fb1d0432a37764d1c72ded5ebbf897df6e6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 15:47:58 -0400 Subject: [PATCH 034/188] [MH2] Implemented Ghost-Lit Drifter --- .../src/mage/cards/g/GhostLitDrifter.java | 81 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GhostLitDrifter.java diff --git a/Mage.Sets/src/mage/cards/g/GhostLitDrifter.java b/Mage.Sets/src/mage/cards/g/GhostLitDrifter.java new file mode 100644 index 00000000000..cd740e80522 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GhostLitDrifter.java @@ -0,0 +1,81 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.ChannelAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.Game; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GhostLitDrifter extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("another creature"); + + static { + filter.add(AnotherPredicate.instance); + } + + public GhostLitDrifter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.SPIRIT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {2}{U}: Another target creature gains flying until end of turn. + Ability ability = new SimpleActivatedAbility(new GainAbilityTargetEffect( + FlyingAbility.getInstance(), Duration.EndOfTurn, + "another target creature gains flying until end of turn" + ), new ManaCostsImpl<>("{2}{U}")); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + + // Channel — {X}{U}, Discard Ghost-Lit Drifter: X target creatures gain flying until end of turn. + ability = new ChannelAbility("{X}{U}", new GainAbilityTargetEffect( + FlyingAbility.getInstance(), Duration.EndOfTurn, + "X target creatures gain flying until end of turn" + )); + ability.setTargetAdjuster(GhostLitDrifterAdjuster.instance); + this.addAbility(ability); + } + + private GhostLitDrifter(final GhostLitDrifter card) { + super(card); + } + + @Override + public GhostLitDrifter copy() { + return new GhostLitDrifter(this); + } +} + +enum GhostLitDrifterAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 98a2ba92cce..132a013571b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -78,6 +78,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Forest", 489, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); cards.add(new SetCardInfo("Gaea's Will", 162, Rarity.RARE, mage.cards.g.GaeasWill.class)); + cards.add(new SetCardInfo("Ghost-Lit Drifter", 45, Rarity.UNCOMMON, mage.cards.g.GhostLitDrifter.class)); cards.add(new SetCardInfo("Glinting Creeper", 164, Rarity.UNCOMMON, mage.cards.g.GlintingCreeper.class)); cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); cards.add(new SetCardInfo("Goblin Bombardment", 279, Rarity.RARE, mage.cards.g.GoblinBombardment.class)); From 7607d69015dabf9ede5b04c2a2e6a3c04a6d04ce Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 16:08:37 -0400 Subject: [PATCH 035/188] [MH2] Implemented Chrome Courier --- Mage.Sets/src/mage/cards/c/ChromeCourier.java | 97 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 98 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ChromeCourier.java diff --git a/Mage.Sets/src/mage/cards/c/ChromeCourier.java b/Mage.Sets/src/mage/cards/c/ChromeCourier.java new file mode 100644 index 00000000000..7ce54a0867e --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChromeCourier.java @@ -0,0 +1,97 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ChromeCourier extends CardImpl { + + public ChromeCourier(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{W}{U}"); + + this.subtype.add(SubType.THOPTER); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Chrome Courier enters the battlefield, reveal the top two cards of your library. Put one of them into your hand and the other into your graveyard. If you put an artifact card into your hand this way, you gain 3 life. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ChromeCourierEffect())); + } + + private ChromeCourier(final ChromeCourier card) { + super(card); + } + + @Override + public ChromeCourier copy() { + return new ChromeCourier(this); + } +} + +class ChromeCourierEffect extends OneShotEffect { + + ChromeCourierEffect() { + super(Outcome.Benefit); + staticText = "reveal the top two cards of your library. " + + "Put one of them into your hand and the other into your graveyard. " + + "If you put an artifact card into your hand this way, you gain 3 life"; + } + + private ChromeCourierEffect(final ChromeCourierEffect effect) { + super(effect); + } + + @Override + public ChromeCourierEffect copy() { + return new ChromeCourierEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 2)); + player.revealCards(source, cards, game); + Card card; + switch (cards.size()) { + case 0: + card = null; + break; + case 1: + card = cards.getRandom(game); + break; + default: + TargetCard target = new TargetCardInLibrary(); + target.withChooseHint("to hand"); + player.choose(outcome, cards, target, game); + card = cards.get(target.getFirstTarget(), game); + } + player.moveCards(card, Zone.HAND, source, game); + cards.remove(card); + player.moveCards(cards, Zone.GRAVEYARD, source, game); + if (card != null && card.isArtifact()) { + player.gainLife(3, game, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 132a013571b..cf8f3cf7bbc 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -51,6 +51,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Chainer, Nightmare Adept", 289, Rarity.RARE, mage.cards.c.ChainerNightmareAdept.class)); cards.add(new SetCardInfo("Chance Encounter", 277, Rarity.RARE, mage.cards.c.ChanceEncounter.class)); cards.add(new SetCardInfo("Chatterstorm", 152, Rarity.COMMON, mage.cards.c.Chatterstorm.class)); + cards.add(new SetCardInfo("Chrome Courier", 190, Rarity.COMMON, mage.cards.c.ChromeCourier.class)); cards.add(new SetCardInfo("Combine Chrysalis", 191, Rarity.UNCOMMON, mage.cards.c.CombineChrysalis.class)); cards.add(new SetCardInfo("Constable of the Realm", 10, Rarity.UNCOMMON, mage.cards.c.ConstableOfTheRealm.class)); cards.add(new SetCardInfo("Counterspell", 267, Rarity.UNCOMMON, mage.cards.c.Counterspell.class)); From bb7b23051339d5bbda6bc2e832742dd10d7fa622 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 16:17:15 -0400 Subject: [PATCH 036/188] [MH2] Implemented Harmonic Prodigy --- .../src/mage/cards/h/HarmonicProdigy.java | 91 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 92 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HarmonicProdigy.java diff --git a/Mage.Sets/src/mage/cards/h/HarmonicProdigy.java b/Mage.Sets/src/mage/cards/h/HarmonicProdigy.java new file mode 100644 index 00000000000..4dd99d3a18a --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HarmonicProdigy.java @@ -0,0 +1,91 @@ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.keyword.ProwessAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.NumberOfTriggersEvent; +import mage.game.permanent.Permanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HarmonicProdigy extends CardImpl { + + public HarmonicProdigy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Prowess + this.addAbility(new ProwessAbility()); + + // If an ability of a Shaman or another Wizard you control triggers, that ability triggers an additional time. + this.addAbility(new SimpleStaticAbility(new HarmonicProdigyEffect())); + } + + private HarmonicProdigy(final HarmonicProdigy card) { + super(card); + } + + @Override + public HarmonicProdigy copy() { + return new HarmonicProdigy(this); + } +} + +class HarmonicProdigyEffect extends ReplacementEffectImpl { + + HarmonicProdigyEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "if an ability of a Shaman or another Wizard you control triggers, " + + "that ability triggers an additional time"; + } + + HarmonicProdigyEffect(final HarmonicProdigyEffect effect) { + super(effect); + } + + @Override + public HarmonicProdigyEffect copy() { + return new HarmonicProdigyEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.NUMBER_OF_TRIGGERS; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (!(event instanceof NumberOfTriggersEvent)) { + return false; + } + Permanent permanent = game.getPermanent(((NumberOfTriggersEvent) event).getSourceId()); + return permanent != null + && permanent.isControlledBy(source.getControllerId()) + && (permanent.hasSubtype(SubType.SHAMAN, game) + || (permanent.hasSubtype(SubType.WIZARD, game) + && !permanent.getId().equals(source.getSourceId()))); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setAmount(event.getAmount() + 1); + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index cf8f3cf7bbc..0df0c2b4351 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -87,6 +87,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Gorilla Shaman", 280, Rarity.UNCOMMON, mage.cards.g.GorillaShaman.class)); cards.add(new SetCardInfo("Greed", 274, Rarity.UNCOMMON, mage.cards.g.Greed.class)); cards.add(new SetCardInfo("Grief", 87, Rarity.MYTHIC, mage.cards.g.Grief.class)); + cards.add(new SetCardInfo("Harmonic Prodigy", 132, Rarity.RARE, mage.cards.h.HarmonicProdigy.class)); cards.add(new SetCardInfo("Herd Baloth", 165, Rarity.UNCOMMON, mage.cards.h.HerdBaloth.class)); cards.add(new SetCardInfo("Ignoble Hierarch", 166, Rarity.RARE, mage.cards.i.IgnobleHierarch.class)); cards.add(new SetCardInfo("Imperial Recruiter", 281, Rarity.MYTHIC, mage.cards.i.ImperialRecruiter.class)); From 1715cb85bc2a4e3e08988f442f01a7c18821faf1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 16:21:37 -0400 Subject: [PATCH 037/188] [MH2] Implemented Raving Visionary --- .../src/mage/cards/r/RavingVisionary.java | 58 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 59 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RavingVisionary.java diff --git a/Mage.Sets/src/mage/cards/r/RavingVisionary.java b/Mage.Sets/src/mage/cards/r/RavingVisionary.java new file mode 100644 index 00000000000..e5086f98889 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RavingVisionary.java @@ -0,0 +1,58 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.DeliriumCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.abilities.hint.common.CardTypesInGraveyardHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RavingVisionary extends CardImpl { + + public RavingVisionary(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {U}, {T}: Draw a card, then discard a card. + Ability ability = new SimpleActivatedAbility( + new DrawDiscardControllerEffect(1, 1), new ManaCostsImpl<>("{U}") + ); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + + // Delirium — {2}{U}, {T}: Draw a card. Activate only if there are four or more card types among cards in your graveyard. + ability = new ActivateIfConditionActivatedAbility( + Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), + new ManaCostsImpl<>("{2}{U}"), DeliriumCondition.instance + ); + ability.addCost(new TapSourceCost()); + this.addAbility(ability.addHint(CardTypesInGraveyardHint.YOU)); + } + + private RavingVisionary(final RavingVisionary card) { + super(card); + } + + @Override + public RavingVisionary copy() { + return new RavingVisionary(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 0df0c2b4351..f858efc1043 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -130,6 +130,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Prophetic Titan", 209, Rarity.UNCOMMON, mage.cards.p.PropheticTitan.class)); cards.add(new SetCardInfo("Quirion Ranger", 285, Rarity.UNCOMMON, mage.cards.q.QuirionRanger.class)); cards.add(new SetCardInfo("Ravenous Squirrel", 211, Rarity.UNCOMMON, mage.cards.r.RavenousSquirrel.class)); + cards.add(new SetCardInfo("Raving Visionary", 56, Rarity.UNCOMMON, mage.cards.r.RavingVisionary.class)); cards.add(new SetCardInfo("Razortide Bridge", 252, Rarity.COMMON, mage.cards.r.RazortideBridge.class)); cards.add(new SetCardInfo("Rift Sower", 170, Rarity.COMMON, mage.cards.r.RiftSower.class)); cards.add(new SetCardInfo("Riptide Laboratory", 303, Rarity.RARE, mage.cards.r.RiptideLaboratory.class)); From 90c891d1f8c499f8f2b0e5c4a8df180190424efb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 18:48:12 -0400 Subject: [PATCH 038/188] [MH2] updated spoiler and reprints --- Mage.Sets/src/mage/sets/ModernHorizons2.java | 4 +++- Utils/mtg-cards-data.txt | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index f858efc1043..5bb0f8d6e81 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -89,6 +89,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Grief", 87, Rarity.MYTHIC, mage.cards.g.Grief.class)); cards.add(new SetCardInfo("Harmonic Prodigy", 132, Rarity.RARE, mage.cards.h.HarmonicProdigy.class)); cards.add(new SetCardInfo("Herd Baloth", 165, Rarity.UNCOMMON, mage.cards.h.HerdBaloth.class)); + cards.add(new SetCardInfo("Hunting Pack", 284, Rarity.COMMON, mage.cards.h.HuntingPack.class)); cards.add(new SetCardInfo("Ignoble Hierarch", 166, Rarity.RARE, mage.cards.i.IgnobleHierarch.class)); cards.add(new SetCardInfo("Imperial Recruiter", 281, Rarity.MYTHIC, mage.cards.i.ImperialRecruiter.class)); cards.add(new SetCardInfo("Island", 483, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); @@ -161,7 +162,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Squirrel Sovereign", 175, Rarity.UNCOMMON, mage.cards.s.SquirrelSovereign.class)); cards.add(new SetCardInfo("Step Through", 66, Rarity.COMMON, mage.cards.s.StepThrough.class)); cards.add(new SetCardInfo("Sterling Grove", 293, Rarity.RARE, mage.cards.s.SterlingGrove.class)); - cards.add(new SetCardInfo("Strike It Rich", 141, Rarity.UNCOMMON, mage.cards.s.StrikeItRich.class)); + cards.add(new SetCardInfo("Strike It Rich", 143, Rarity.UNCOMMON, mage.cards.s.StrikeItRich.class)); cards.add(new SetCardInfo("Subtlety", 67, Rarity.MYTHIC, mage.cards.s.Subtlety.class)); cards.add(new SetCardInfo("Sudden Edict", 100, Rarity.UNCOMMON, mage.cards.s.SuddenEdict.class)); cards.add(new SetCardInfo("Swamp", 485, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); @@ -193,6 +194,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Void Mirror", 242, Rarity.RARE, mage.cards.v.VoidMirror.class)); cards.add(new SetCardInfo("Wonder", 271, Rarity.RARE, mage.cards.w.Wonder.class)); cards.add(new SetCardInfo("World-Weary", 109, Rarity.COMMON, mage.cards.w.WorldWeary.class)); + cards.add(new SetCardInfo("Yavimaya Elder", 288, Rarity.UNCOMMON, mage.cards.y.YavimayaElder.class)); cards.add(new SetCardInfo("Young Necromancer", 110, Rarity.UNCOMMON, mage.cards.y.YoungNecromancer.class)); cards.add(new SetCardInfo("Yusri, Fortune's Flame", 218, Rarity.RARE, mage.cards.y.YusriFortunesFlame.class)); cards.add(new SetCardInfo("Zuran Orb", 300, Rarity.UNCOMMON, mage.cards.z.ZuranOrb.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 9e0a978e2e2..f0c0d4936ac 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -41334,6 +41334,7 @@ Swamp|Adventures in the Forgotten Realms|273|C||Basic Land - Swamp|||({T}: Add { Mountain|Adventures in the Forgotten Realms|277|C||Basic Land - Mountain|||({T}: Add {R}.)| Forest|Adventures in the Forgotten Realms|281|C||Basic Land - Forest|||({T}: Add {G}.)| Abiding Grace|Modern Horizons 2|1|U|{2}{W}|Enchantment|||At the beginning of your end step, choose one —$• You gain 1 life.$• Return target creature card with mana value 1 from your graveyard to the battlefield.| +Archbound Javelineer|Modern Horizons 2|2|U|{W}|Artifact Creature - Soldier|0|1|{T}, Remove X +1/+1 counters from Archbound Javelineer: It deals X damage to target attacking or blocking creature.$Modular 1| Arcbound Mouser|Modern Horizons 2|3|C|{W}|Artifact Creature - Cat|0|0|Lifelink$Modular 1| Break Ties|Modern Horizons 2|8|C|{2}{W}|Instant|||Choose one —$• Destroy target artifact.$• Destroy target enchantment.$• Exile target card from a graveyard.$Reinforce 1—{W}| Constable of the Realm|Modern Horizons 2|10|U|{4}{W}|Creature - Giant Soldier|3|3|Renown 2$Whenever one or more +1/+1 counters are put on Constable of the Realm, exile up to one other target nonland permanent until Constable of the Realm leaves the battlefield.| @@ -41366,6 +41367,7 @@ Rishadan Dockhand|Modern Horizons 2|59|R|{U}|Creature - Merfolk|1|2|Islandwalk${ Scuttletide|Modern Horizons 2|61|U|{1}{U}|Enchantment|||{1}, Discard a card: Create a 0/3 blue Crab creature token.$Delirium — Crabs you control get +1/+1 as long as there are four or more card types among cards in your graveyard.| Shattered Ego|Modern Horizons 2|62|C|{U}|Enchantment - Aura|||Enchant creature$Enchanted creature gets -3/-0.${3}{U}{U}: Put enchanted creature into its owner's library third from the top.| So Shiny|Modern Horizons 2|63|C|{2}{U}|Enchantment - Aura|||Enchant creature$When So Shiny enters the battlefield, if you control a token, tap enchanted creature, then scry 2.$Enchanted creature doesn't untap during its controller's untap step.| +Specimen Collector|Modern Horizons 2|64|U|{4}{U}|Creature - Vedalken Wizard|2|1|When Specimen Collector enters the battlefield, create a 1/1 green Squirrel creature token and a 0/3 blue Crab creature token.$When Specimen Collector dies, create a token that's a copy of target token you control.| Step Through|Modern Horizons 2|66|C|{3}{U}{U}|Sorcery|||Return two target creatures to their owners' hands.$Wizardcycling {2}| Subtlety|Modern Horizons 2|67|M|{2}{U}{U}|Creature - Elemental Incarnation|3|3|Flash$Flying$When Subtlety enters the battlefield, choose up to one target creature spell or planeswalker spell. Its owner puts it on the top or bottom of their library.$Evoke—Exile a blue card from your hand.| Suspend|Modern Horizons 2|68|R|{U}|Instant|||Exile target creature and put two time counters on it. If it doesn't have suspend, it gains suspend.| @@ -41389,6 +41391,7 @@ Legion Vanguard|Modern Horizons 2|90|U|{1}{B}|Creature - Vampire Soldier|2|2|{1} Necromancer's Familiar|Modern Horizons 2|94|U|{3}{B}|Creature - Bird Spirit|3|1|Flying$Hellbent — Necromancer's Familiar has lifelink as long as you have no cards in hand.${B}, Discard a card: Necromancer's Familiar gains indestructible until end of turn. Tap it.| Persist|Modern Horizons 2|96|R|{1}{B}|Sorcery|||Return target nonlegendary creature card from your graveyard to the battlefield with a -1/-1 counter on it.| Profane Tutor|Modern Horizons 2|97|R||Sorcery|||Suspend 2—{1}{B}$Search your library for a card, put that card into your hand, then shuffle.| +Radiant Epicure|Modern Horizons 2|98|U|{4}{B}|Creature - Vampire Wizard|5|5|Converge — When Radiant Epicure enters the battlefield, each opponent loses X life and you gain X life, where X is the number of colors of mana spent to cast this spell.| Sudden Edict|Modern Horizons 2|100|U|{1}{B}|Instant|||Split second$Target player sacrifices a creature.| Tourach, Dread Cantor|Modern Horizons 2|102|M|{1}{B}|Legendary Creature - Human Cleric|2|1|Kicker {B}{B}$Protection from white$Whenever an opponent discards a card, put a +1/+1 counter on Tourach, Dread Cantor.$When Tourach enters the battelfield, if it was kicked, target opponent discards two cards at random.| Tourach's Canticle|Modern Horizons 2|103|C|{3}{B}|Sorcery|||Target opponent reveals their hand. You choose a card from it. That player discards that card, then discards a card at random.| @@ -41399,8 +41402,10 @@ Young Necromancer|Modern Horizons 2|110|U|{4}{B}|Creature - Human Warlock|2|3|Wh Arcbound Whelp|Modern Horizons 2|113|U|{3}{R}|Artifact Creature - Dragon|0|0|Flying${R}: Arcbound Whelp gets +1/+0 until end of turn.$Modular 2| Battle Plan|Modern Horizons 2|114|C|{3}{R}|Enchantment|||At the beginning of combat on your turn, target creature you control gets +2/+0 until end of turn.$Basic landcycling {1}{R}| Blazing Rootwalla|Modern Horizons 2|115|U|{R}|Creature - Lizard|1|1|{R}: Blazing Rootwalla gets +2/+0 until end of turn. Activate only once each turn.$Madness {0}| +Bloodbraid Marauder|Modern Horizons 2|116|R|{1}{R}|Creature - Human Beserker|3|1|Bloodbraid Marauder can't block.$Delirium — This spell has cascade as long as there are four or more card types amont cards in your graveyard.| Breya's Apprentice|Modern Horizons 2|117|R|{2}{R}|Artifact Creature - Human Artificer|2|3|When Breya's Apprentice enters the battlefield, create a 1/1 colorless Thopter artifact creature token with flying.${T}, Sacrifice an artifact: Choose one —$• Exile the top card of your library. Until the end of your next turn, you may play that card.$• Target creature gets +2/+0 until end of turn.| Calibrated Blast|Modern Horizons 2|118|R|{2}{R}|Instant|||Reveal cards from the top of your library until you reveal a nonland card. Put the revealed cards on the bottom of your library in a random order. When you reveal a nonland card this way, Calibrated Blast deals damage equal to that card's mana value to any target.$Flashback {3}{R}{R}| +Captain Ripley Vance|Modern Horizons 2|119|U|{2}{R}|Legendary Creature - Human Pirate|3|2|Whenever you cast your third spell each turn, put a +1/+1 counter on Captain Ripley Vance, then it deals damage equal to its power to any target.| Chef's Kiss|Modern Horizons 2|120|R|{1}{R}{R}|Instant|||Gain control of target spell that targets only a single permanent or player. Copy it, then reselect the targets at random for the spell and the copy. The new targets can't be you or a permanent you control.| Dragon's Rage Channeler|Modern Horizons 2|121|U|{R}|Creature - Human Shaman|1|1|Whenever you cast a noncreature spell, surveil 1.$Delirium — As long as there are four or more card types among cards in your graveyard, Dragon's Rage Channeler gets +2/+2, has flying, and attacks each combat if able.| Fast // Furious|Modern Horizons 2|123|U|{2}{R}|Instant|||Discard a card, then draw two cards.$Furious${3}{R}{R}$Sorcery$Furious deals 3 damage to each creature without flying.| @@ -41412,16 +41417,19 @@ Harmonic Prodigy|Modern Horizons 2|132|R|{1}{R}|Creature - Human Wizard|1|3|Prow Obsidian Charmaw|Modern Horizons 2|137|R|{3}{R}{R}|Creature - Dragon|4|4|This spell costs {1} less to cast for each land your opponents control that could produce {C}.$Flying$When Obsidian Charmaw enters the battlefield, destroy target nonbasic land an opponent controls.| Ragavan, Nimble Pilferer|Modern Horizons 2|138|M|{R}|Legendary Creature - Monkey Pirate|2|1|Whenever Ragavan, Nimble Pilferer deals combat damage to a player, create a Treasure token and exile the top card of that player's library. Until end of turn, you may cast that card.$Dash {1}{R}| Skophos Reaver|Modern Horizons 2|140|C|{2}{R}|Creature - Minotaur Warrior|2|3|As long as it's your turn, Skophos Reaver gets +2/+0.$Madness {1}{R}| -Strike It Rich|Modern Horizons 2|141|U|{R}|Sorcery|||Create a Treasure token.$Flashback {2}{R}| +Slag Strider|Modern Horizons 2|141|U|{5}{R}{R}|Creature - Elemental|3|3|Affinity for artifacts${1}, Sacrifice an artifact: Slag Strider deals 1 damage to any target.| Spreading Insurrection|Modern Horizons 2|142|U|{4}{R}|Sorcery|||Gain control of target creature you don't control until end of turn. Untap that creature. It gains haste until end of turn.$Storm| +Strike It Rich|Modern Horizons 2|143|U|{R}|Sorcery|||Create a Treasure token.$Flashback {2}{R}| Abundant Harvest|Modern Horizons 2|147|C|{G}|Sorcery|||Choose land or nonland. Reveal cards from the top of your library until you reveal a card of the chosen kind. Put that card into your hand and the rest on the bottom of your library in a random order.| Aeve, Progenitor Ooze|Modern Horizons 2|148|R|{2}{G}{G}{G}|Legendary Creature - Ooze|2|2|Storm$Aeve, Progenitor Ooze isn't legendary as long as it's a token.$Aeve enters the battlefield with a +1/+1 counter on it for each Ooze you control.| Chatterfang, Squirrel General|Modern Horizons 2|151|M|{2}{G}|Legendary Creature - Squirrel Warrior|3|3|Forestwalk$If one or more tokens would be created under your control, those tokens plus that many 1/1 green Squirrel creature tokens are created instead.${B}, Sacrifice X Squirrels: Target creature gets +X/-X until end of turn.| Chatterstorm|Modern Horizons 2|152|C|{1}{G}|Sorcery|||Create a 1/1 green Squirrel creature token.$Storm| -Chitterspitter|Modern Horizons 2|153|R|{2}{G}|Artifact|||At the beginning of your upkeep, you may sacrifice a token. If you do, put an acorn counter on Chitterspitter.$Squirrels you control get +1/+1 for each acorn counter on Chitterspitter.${G}, {T}: Createa 1/1 green Squirrel creature token.| +Chitterspitter|Modern Horizons 2|153|R|{2}{G}|Artifact|||At the beginning of your upkeep, you may sacrifice a token. If you do, put an acorn counter on Chitterspitter.$Squirrels you control get +1/+1 for each acorn counter on Chitterspitter.${G}, {T}: Create a 1/1 green Squirrel creature token.| Endurance|Modern Horizons 2|157|M|{1}{G}{G}|Creature - Elemental Incarnation|3|4|Flash$Reach$When Endurance enters the battlefield, up to one target player puts all the cards from their graveyard on the bottom of their library in a random order.$Evoke—Exile a green card from your hand.| Fae Offering|Modern Horizons 2|158|U|{2}{G}|Enchantment|||At the beginning of each end step, if you've cast both a creature spell and a noncreature spell this turn, create a Clue token, a Food token, and a Treasure token.| +Foundation Breaker|Modern Horizons 2|160|U|{3}{G}|Creature - Elemental|2|2|When Foundation Breaker enters the battlefield, you may destroy target artifact or enchantment.$Evoke {1}{G}| Gaea's Will|Modern Horizons 2|162|R||Sorcery|||Suspend 4—{G}$Until end of turn, you may play land cards and cast spells from your graveyard.$If a card would be put into your graveyard from anywhere this turn, exile that card instead.| +Wren's Run Hydra|Modern Horizons 2|163|U|{X}{G}|Creature - Hydra|0|0|Reach$Wren's Run Hydra enters the battlefield with X +1/+1 counters on it.$Reinforce X—{X}{G}{G}| Glinting Creeper|Modern Horizons 2|164|U|{4}{G}|Creature - Plant|0|0|Converge — Glinting Creeper enters the battlefield with two +1/+1 counters on it for each color of mana spent to cast it.$Glinting Creeper can't be blocked by creatures with power 2 or less.| Herd Baloth|Modern Horizons 2|165|U|{3}{G}{G}|Creature - Beast|4|4|Whenever one or more +1/+1 counters are put on Herd Baloth, you may create a 4/4 green Beast creature token.| Ignoble Hierarch|Modern Horizons 2|166|R|{G}|Creature - Goblin Shaman|0|1|Exalted${T}: Add {B}, {R}, or {G}.| @@ -41446,6 +41454,7 @@ Chrome Courier|Modern Horizons 2|190|C|{1}{W}{U}|Artifact Creature - Thopter|1|1 Combine Chrysalis|Modern Horizons 2|191|U|{G}{U}|Artifact|||Creature tokens you control have flying.${2}{G}{U}, {T}, Sacrifice a token: Create a 4/4 green Beast creature token. Activate only as a sorcery.| Dakkon, Shadow Slayer|Modern Horizons 2|192|M|{W}{U}{B}|Legendary Planeswalker - Dakkon|0|Dakkon, Shadow Slayer enters the battlefield with a number of loyalty counters on him equal to the number of lands you control.$+1: Surveil 2.$−3: Exile target creature.$−6: You may put an artifact card from your hand or graveyard onto the battlefield.| Drey Keeper|Modern Horizons 2|194|C|{3}{B}{G}|Creature - Elf Druid|2|2|When Drey Keeper enters the battlefield, create two 1/1 green Squirrel creature tokens.${3}{B}: Squirrels you control get +1/+0 and gain menace until end of turn.| +Ethersworn Sphinx|Modern Horizons 2|195|U|{7}{W}{U}|Artifact Creature - Sphinx|4|4|Affinity for artifacts$Flying$Cascade| Garth One-Eye|Modern Horizons 2|197|M|{W}{U}{B}{R}{G}|Legendary Creature - Human Wizard|5|5|{T}: Choose a card name that hasn't been chosen from among Disenchant, Braingeyser, Terror, Shivan Dragon, Regrowth, and Black Lotus. Create a copy of the card with the chosen name. You may cast the copy.| General Ferrous Rokiric|Modern Horizons 2|198|R|{1}{R}{W}|Legendary Creature - Human Soldier|3|1|Hexproof from monocolored$Whenever you cast a multicolored spell, create a 4/4 red and white Golem artifact creature token.| Geyadrone Dihada|Modern Horizons 2|199|M|{1}{U}{B}{R}|Legendary Planeswalker - Dihada|4|Protection from permanents with corruption counters on them$+1: Each opponent loses 2 life and you gain 2 life. Put a corruption counter on up to one other target creature or planeswalker.$−3: Gain control of target creature or planeswalker until end of tun. Untap it and put a corruption counter on it. It gains haste until end of turn.$−7: Gain control of each permanent with a corruption counter on it.| @@ -41457,6 +41466,7 @@ Moderation|Modern Horizons 2|206|R|{1}{W}{U}|Enchantment|||You can't cast more t Piru, the Volatile|Modern Horizons 2|207|R|{2}{R}{R}{W}{W}{B}{B}|Legendary Creature - Elder Dragon|7|7|Flying, lifelink$At the beginning of your upkeep, sacrifice Piru, the Volatile unless you pay {R}{W}{B}.$When Piru dies, it deals 7 damage to each nonlegendary creature.| Priest of Fell Rites|Modern Horizons 2|208|R|{W}{B}|Creature - Human Warlock|2|2|{T}, Pay 3 life, Sacrifice Priest of Fell Rites: Return target creature card from your graveyard to the battlefield. Activate only as a sorcery.$Unearth {3}{W}{B}| Prophetic Titan|Modern Horizons 2|209|U|{4}{U}{R}|Creature - Giant Wizard|4|4|Delirium — When Prophetic Titan enters the battlefield, choose one. If there are four or more card types among cards in your graveyard, choose both.$• Prophetic Titan deals 4 damage to any target.$• Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in a random order.| +Rakdos Headliner|Modern Horizons 2|210|U|{B}{R}|Creature - Devil|3|3|Haste$Echo—Discard a card.| Ravenous Squirrel|Modern Horizons 2|211|U|{B/G}|Creature - Squirrel|1|1|Whenever you sacrifice an artifact or creature, put a +1/+1 counter on Ravenous Squirrel.${1}{B}{G}, Sacrifice an artifact or creature: You gain 1 life and draw a card.| Road // Ruin|Modern Horizons 2|212|U|{2}{G}|Instant|||Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.$Ruin${1}{R}{R}$Sorcery$Aftermath$Ruin deals damage to target creature equal to the number of lands you control.| Territorial Kavu|Modern Horizons 2|216|R|{R}{G}|Creature - Kavu|*|*|Domain — Territorial Kavu's power and toughness are each equal to the number of basic land types among lands you control.$Whenever Territorial Kavu attacks, choose one —$• Discard a card. If you do, draw a card.$• Exile up to one target card from a graveyard.| @@ -41519,9 +41529,11 @@ Gorilla Shaman|Modern Horizons 2|280|U|{R}|Creature - Ape Shaman|1|1|{X}{X}{1}: Imperial Recruiter|Modern Horizons 2|281|M|{2}{R}|Creature - Human Advisor|1|1|When Imperial Recruiter enters the battlefield, search your library for a creature card with power 2 or less, reveal it, put it into your hand, then shuffle.| Mogg Salvage|Modern Horizons 2|282|U|{2}{R}|Instant|||If an opponent controls an Island and you control a Mountain, you may cast this spell without paying its mana cost.$Destroy target artifact.| Enchantress's Presence|Modern Horizons 2|283|R|{2}{G}|Enchantment|||Whenever you cast an enchantment spell, draw a card.| +Hunting Pack|Modern Horizons 2|284|C|{5}{G}{G}|Instant|||Create a 4/4 green Beast creature token.$Storm| Quirion Ranger|Modern Horizons 2|285|U|{G}|Creature - Elf|1|1|Return a Forest you control to its owner's hand: Untap target creature. Activate only once each turn.| Squirrel Mob|Modern Horizons 2|286|R|{1}{G}{G}|Creature - Squirrel|2|2|Squirrel Mob gets +1/+1 for each other Squirrel on the battlefield.| Titania, Protector of Argoth|Modern Horizons 2|287|M|{3}{G}{G}|Legendary Creature - Elemental|5|3|When Titania, Protector of Argoth enters the battlefield, return target land card from your graveyard to the battlefield.$Whenever a land you control is put into a graveyard from the battlefield, create a 5/3 green Elemental creature token.| +Yavimaya Elder|Modern Horizons 2|288|U|{1}{G}{G}|Creature - Human Druid|2|1|When Yavimaya Elder dies, you may search your library for up to two basic land cards, reveal them, put them into your hand, then shuffle.${2}, Sacrifice Yavimaya Elder: Draw a card.| Chainer, Nightmare Adept|Modern Horizons 2|289|R|{2}{B}{R}|Legendary Creature - Human Minion|3|2|Discard a card: You may cast a creature spell from your graveyard this turn. Activate only once each turn.$Whenever a nontoken creature enters the battlefield under your control, if you didn't cast it from your hand, it gains haste until your next turn.| Fire // Ice|Modern Horizons 2|290|R|{1}{R}|Instant|||Fire deals 2 damage divided as you choose among one or two targets.$Ice${1}{U}$Instant$Tap target permanent.$Draw a card.| Mirari's Wake|Modern Horizons 2|291|M|{3}{G}{W}|Enchantment|||Creatures you control get +1/+1.$Whenever you tap a land for mana, add one mana of any type that land produced.| @@ -41536,6 +41548,7 @@ Zuran Orb|Modern Horizons 2|300|U|{0}|Artifact|||Sacrifice a land: You gain 2 li Cabal Coffers|Modern Horizons 2|301|M||Land|||{2}, {T}: Add {B} for each Swamp you control.| Mishra's Factory|Modern Horizons 2|302|U||Land|||{T}: Add {C}.${1}: Mishra's Factory becomes a 2/2 Assembly-Worker artifact creature until end of turn. It's still a land.${T}: Target Assembly-Worker creature gets +1/+1 until end of turn.| Riptide Laboratory|Modern Horizons 2|303|R||Land|||{T}: Add {C}.${1}{U}, {T}: Return target Wizard you control to its owner's hand.| +Sol Talisman|Modern Horizons 2|472|R||Artifact|||Suspend 3—{1}${T}: Add {C}{C}.| Plains|Modern Horizons 2|481|C||Basic Land - Plains|||({T}: Add {W}.)| Island|Modern Horizons 2|483|C||Basic Land - Island|||({T}: Add {U}.)| Swamp|Modern Horizons 2|485|C||Basic Land - Swamp|||({T}: Add {B}.)| From 4972e050ddd2fcce15ce47e086eb39cdf892429e Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Mon, 31 May 2021 17:50:24 -0500 Subject: [PATCH 039/188] [MH2] Implemented General Ferrous Rokiric (#7868) Co-authored-by: Evan Kranzler --- .../mage/cards/g/GeneralFerrousRokiric.java | 53 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../permanent/token/RedWhiteGolemToken.java | 27 ++++++++++ 3 files changed, 81 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GeneralFerrousRokiric.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/RedWhiteGolemToken.java diff --git a/Mage.Sets/src/mage/cards/g/GeneralFerrousRokiric.java b/Mage.Sets/src/mage/cards/g/GeneralFerrousRokiric.java new file mode 100644 index 00000000000..73d3c14582a --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GeneralFerrousRokiric.java @@ -0,0 +1,53 @@ +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.HexproofFromMonocoloredAbility; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterSpell; +import mage.filter.predicate.mageobject.MulticoloredPredicate; +import mage.game.permanent.token.RedWhiteGolemToken; + +/** + * + * @author weirddan455 + */ +public final class GeneralFerrousRokiric extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("a multicolored spell"); + + static { + filter.add(MulticoloredPredicate.instance); + } + + public GeneralFerrousRokiric(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{W}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Hexproof from monocolored + this.addAbility(HexproofFromMonocoloredAbility.getInstance()); + + // Whenever you cast a multicolored spell, create a 4/4 red and white Golem artifact creature token. + this.addAbility(new SpellCastControllerTriggeredAbility(new CreateTokenEffect(new RedWhiteGolemToken()), filter, false)); + } + + private GeneralFerrousRokiric(final GeneralFerrousRokiric card) { + super(card); + } + + @Override + public GeneralFerrousRokiric copy() { + return new GeneralFerrousRokiric(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 5bb0f8d6e81..82141e8dd7f 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -79,6 +79,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Forest", 489, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); cards.add(new SetCardInfo("Gaea's Will", 162, Rarity.RARE, mage.cards.g.GaeasWill.class)); + cards.add(new SetCardInfo("General Ferrous Rokiric", 198, Rarity.RARE, mage.cards.g.GeneralFerrousRokiric.class)); cards.add(new SetCardInfo("Ghost-Lit Drifter", 45, Rarity.UNCOMMON, mage.cards.g.GhostLitDrifter.class)); cards.add(new SetCardInfo("Glinting Creeper", 164, Rarity.UNCOMMON, mage.cards.g.GlintingCreeper.class)); cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/RedWhiteGolemToken.java b/Mage/src/main/java/mage/game/permanent/token/RedWhiteGolemToken.java new file mode 100644 index 00000000000..f57f1c7945f --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/RedWhiteGolemToken.java @@ -0,0 +1,27 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +public class RedWhiteGolemToken extends TokenImpl { + + public RedWhiteGolemToken() { + super("Golem", "4/4 red and white Golem artifact creature token"); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + subtype.add(SubType.GOLEM); + color.setRed(true); + color.setWhite(true); + power = new MageInt(4); + toughness = new MageInt(4); + } + + private RedWhiteGolemToken(final RedWhiteGolemToken token) { + super(token); + } + + public RedWhiteGolemToken copy() { + return new RedWhiteGolemToken(this); + } +} From a522eca984518da0f7b030e13d77f6e247d70354 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Mon, 31 May 2021 17:51:01 -0500 Subject: [PATCH 040/188] [MH2] Implemented Chitterspitter (#7867) Co-authored-by: Evan Kranzler --- .../src/mage/cards/c/Chitterspitter.java | 76 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../main/java/mage/counters/CounterType.java | 1 + 3 files changed, 78 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/Chitterspitter.java diff --git a/Mage.Sets/src/mage/cards/c/Chitterspitter.java b/Mage.Sets/src/mage/cards/c/Chitterspitter.java new file mode 100644 index 00000000000..1fb9aeca25d --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/Chitterspitter.java @@ -0,0 +1,76 @@ +package mage.cards.c; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.permanent.token.SquirrelToken; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author weirddan455 + */ +public final class Chitterspitter extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a token"); + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent(SubType.SQUIRREL, "Squirrels"); + + static { + filter.add(TokenPredicate.instance); + } + + public Chitterspitter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{G}"); + + // At the beginning of your upkeep, you may sacrifice a token. If you do, put an acorn counter on Chitterspitter. + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + new DoIfCostPaid( + new AddCountersSourceEffect(CounterType.ACORN.createInstance()), + new SacrificeTargetCost(new TargetControlledPermanent(filter)) + ), + TargetController.YOU, + false + )); + + // Squirrels you control get +1/+1 for each acorn counter on Chitterspitter. + CountersSourceCount counterValue = new CountersSourceCount(CounterType.ACORN); + this.addAbility(new SimpleStaticAbility( + new BoostControlledEffect(counterValue, counterValue, Duration.WhileOnBattlefield, filter2, false) + )); + + // {G}, {T}: Create a 1/1 green Squirrel creature token. + Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new SquirrelToken()), new ManaCostsImpl<>("{G}")); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + private Chitterspitter(final Chitterspitter card) { + super(card); + } + + @Override + public Chitterspitter copy() { + return new Chitterspitter(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 82141e8dd7f..2e22ac653ab 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -51,6 +51,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Chainer, Nightmare Adept", 289, Rarity.RARE, mage.cards.c.ChainerNightmareAdept.class)); cards.add(new SetCardInfo("Chance Encounter", 277, Rarity.RARE, mage.cards.c.ChanceEncounter.class)); cards.add(new SetCardInfo("Chatterstorm", 152, Rarity.COMMON, mage.cards.c.Chatterstorm.class)); + cards.add(new SetCardInfo("Chitterspitter", 153, Rarity.RARE, mage.cards.c.Chitterspitter.class)); cards.add(new SetCardInfo("Chrome Courier", 190, Rarity.COMMON, mage.cards.c.ChromeCourier.class)); cards.add(new SetCardInfo("Combine Chrysalis", 191, Rarity.UNCOMMON, mage.cards.c.CombineChrysalis.class)); cards.add(new SetCardInfo("Constable of the Realm", 10, Rarity.UNCOMMON, mage.cards.c.ConstableOfTheRealm.class)); diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index 7bbfa35e0aa..35198b0b05f 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -12,6 +12,7 @@ import mage.game.Game; */ public enum CounterType { + ACORN("acorn"), AEGIS("aegis"), AGE("age"), AIM("aim"), From 4b0036d6a779d2347f160ce933c36acb17f2db4a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 18:56:16 -0400 Subject: [PATCH 041/188] [MH2] Implemented Ethersworn Sphinx --- .../src/mage/cards/e/EtherswornSphinx.java | 44 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 45 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EtherswornSphinx.java diff --git a/Mage.Sets/src/mage/cards/e/EtherswornSphinx.java b/Mage.Sets/src/mage/cards/e/EtherswornSphinx.java new file mode 100644 index 00000000000..e3d1cd94d6f --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EtherswornSphinx.java @@ -0,0 +1,44 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.keyword.AffinityForArtifactsAbility; +import mage.abilities.keyword.CascadeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EtherswornSphinx extends CardImpl { + + public EtherswornSphinx(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}{W}{U}"); + + this.subtype.add(SubType.SPHINX); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Affinity for artifacts + this.addAbility(new AffinityForArtifactsAbility()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Cascade + this.addAbility(new CascadeAbility()); + } + + private EtherswornSphinx(final EtherswornSphinx card) { + super(card); + } + + @Override + public EtherswornSphinx copy() { + return new EtherswornSphinx(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 2e22ac653ab..f48299b6527 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -67,6 +67,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Drossforge Bridge", 246, Rarity.COMMON, mage.cards.d.DrossforgeBridge.class)); cards.add(new SetCardInfo("Enchantress's Presence", 283, Rarity.RARE, mage.cards.e.EnchantresssPresence.class)); cards.add(new SetCardInfo("Endurance", 157, Rarity.MYTHIC, mage.cards.e.Endurance.class)); + cards.add(new SetCardInfo("Ethersworn Sphinx", 195, Rarity.UNCOMMON, mage.cards.e.EtherswornSphinx.class)); cards.add(new SetCardInfo("Extruder", 296, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); cards.add(new SetCardInfo("Fae Offering", 158, Rarity.UNCOMMON, mage.cards.f.FaeOffering.class)); cards.add(new SetCardInfo("Fast // Furious", 123, Rarity.UNCOMMON, mage.cards.f.FastFurious.class)); From 47fb7cb6dfa592321160ea5575176950427d9ef2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 18:59:17 -0400 Subject: [PATCH 042/188] [MH2] Implemented Foundation Breaker --- .../src/mage/cards/f/FoundationBreaker.java | 46 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + Utils/keywords.txt | 2 +- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/f/FoundationBreaker.java diff --git a/Mage.Sets/src/mage/cards/f/FoundationBreaker.java b/Mage.Sets/src/mage/cards/f/FoundationBreaker.java new file mode 100644 index 00000000000..719cd5bd64d --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FoundationBreaker.java @@ -0,0 +1,46 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.EvokeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FoundationBreaker extends CardImpl { + + public FoundationBreaker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Foundation Breaker enters the battlefield, you may destroy target artifact or enchantment. + Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect(), true); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); + this.addAbility(ability); + + // Evoke {1}{G} + this.addAbility(new EvokeAbility("{1}{G}")); + } + + private FoundationBreaker(final FoundationBreaker card) { + super(card); + } + + @Override + public FoundationBreaker copy() { + return new FoundationBreaker(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index f48299b6527..ce3a7d2a66d 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -79,6 +79,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Flametongue Yearling", 125, Rarity.UNCOMMON, mage.cards.f.FlametongueYearling.class)); cards.add(new SetCardInfo("Flay Essence", 85, Rarity.UNCOMMON, mage.cards.f.FlayEssence.class)); cards.add(new SetCardInfo("Forest", 489, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Foundation Breaker", 160, Rarity.UNCOMMON, mage.cards.f.FoundationBreaker.class)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); cards.add(new SetCardInfo("Gaea's Will", 162, Rarity.RARE, mage.cards.g.GaeasWill.class)); cards.add(new SetCardInfo("General Ferrous Rokiric", 198, Rarity.RARE, mage.cards.g.GeneralFerrousRokiric.class)); diff --git a/Utils/keywords.txt b/Utils/keywords.txt index 74d6b1364bd..16a9dd078ae 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -31,7 +31,7 @@ Enchant|type| Encore|cost| Entwine|manaString| Eternalize|cost, card| -Evoke|card, manaString| +Evoke|manaString| Evolve|new| Exalted|new| Exploit|new| From 02a2c30c99328757a4be388761958d324c74939c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 19:11:07 -0400 Subject: [PATCH 043/188] [MH2] Implemented Radiant Epicure --- .../src/mage/cards/r/RadiantEpicure.java | 83 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 84 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RadiantEpicure.java diff --git a/Mage.Sets/src/mage/cards/r/RadiantEpicure.java b/Mage.Sets/src/mage/cards/r/RadiantEpicure.java new file mode 100644 index 00000000000..479a818cbe3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RadiantEpicure.java @@ -0,0 +1,83 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.game.Game; +import mage.players.Player; +import mage.watchers.common.ManaSpentToCastWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RadiantEpicure extends CardImpl { + + public RadiantEpicure(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Converge — When Radiant Epicure enters the battlefield, each opponent loses X life and you gain X life, where X is the number of colors of mana spent to cast this spell. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new RadiantEpicureEffect(), false, "Converge — " + ), new ManaSpentToCastWatcher()); + } + + private RadiantEpicure(final RadiantEpicure card) { + super(card); + } + + @Override + public RadiantEpicure copy() { + return new RadiantEpicure(this); + } +} + +class RadiantEpicureEffect extends OneShotEffect { + + RadiantEpicureEffect() { + super(Outcome.Benefit); + staticText = "each opponent loses X life and you gain X life, " + + "where X is the number of colors of mana spent to cast this spell"; + } + + private RadiantEpicureEffect(final RadiantEpicureEffect effect) { + super(effect); + } + + @Override + public RadiantEpicureEffect copy() { + return new RadiantEpicureEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + ManaSpentToCastWatcher watcher = game.getState().getWatcher(ManaSpentToCastWatcher.class, source.getSourceId()); + if (player == null || watcher == null) { + return false; + } + Mana payment = watcher.getAndResetLastPayment(); + if (payment == null) { + return false; + } + int xValue = payment.getDifferentColors(); + new DamagePlayersEffect(xValue, TargetController.OPPONENT).apply(game, source); + player.gainLife(xValue, game, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index ce3a7d2a66d..bed4885d206 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -134,6 +134,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Profane Tutor", 97, Rarity.RARE, mage.cards.p.ProfaneTutor.class)); cards.add(new SetCardInfo("Prophetic Titan", 209, Rarity.UNCOMMON, mage.cards.p.PropheticTitan.class)); cards.add(new SetCardInfo("Quirion Ranger", 285, Rarity.UNCOMMON, mage.cards.q.QuirionRanger.class)); + cards.add(new SetCardInfo("Radiant Epicure", 98, Rarity.UNCOMMON, mage.cards.r.RadiantEpicure.class)); cards.add(new SetCardInfo("Ravenous Squirrel", 211, Rarity.UNCOMMON, mage.cards.r.RavenousSquirrel.class)); cards.add(new SetCardInfo("Raving Visionary", 56, Rarity.UNCOMMON, mage.cards.r.RavingVisionary.class)); cards.add(new SetCardInfo("Razortide Bridge", 252, Rarity.COMMON, mage.cards.r.RazortideBridge.class)); From a071d39364de759c451f5ebef518f1dd04a02a1b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 19:13:19 -0400 Subject: [PATCH 044/188] [MH2] Implemented Rakdos Headliner --- .../src/mage/cards/r/RakdosHeadliner.java | 41 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 42 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RakdosHeadliner.java diff --git a/Mage.Sets/src/mage/cards/r/RakdosHeadliner.java b/Mage.Sets/src/mage/cards/r/RakdosHeadliner.java new file mode 100644 index 00000000000..40925264ced --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RakdosHeadliner.java @@ -0,0 +1,41 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.keyword.EchoAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RakdosHeadliner extends CardImpl { + + public RakdosHeadliner(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{R}"); + + this.subtype.add(SubType.DEVIL); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // Echo—Discard a card. + this.addAbility(new EchoAbility(new DiscardCardCost())); + } + + private RakdosHeadliner(final RakdosHeadliner card) { + super(card); + } + + @Override + public RakdosHeadliner copy() { + return new RakdosHeadliner(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index bed4885d206..a626b4670e5 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -135,6 +135,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Prophetic Titan", 209, Rarity.UNCOMMON, mage.cards.p.PropheticTitan.class)); cards.add(new SetCardInfo("Quirion Ranger", 285, Rarity.UNCOMMON, mage.cards.q.QuirionRanger.class)); cards.add(new SetCardInfo("Radiant Epicure", 98, Rarity.UNCOMMON, mage.cards.r.RadiantEpicure.class)); + cards.add(new SetCardInfo("Rakdos Headliner", 210, Rarity.UNCOMMON, mage.cards.r.RakdosHeadliner.class)); cards.add(new SetCardInfo("Ravenous Squirrel", 211, Rarity.UNCOMMON, mage.cards.r.RavenousSquirrel.class)); cards.add(new SetCardInfo("Raving Visionary", 56, Rarity.UNCOMMON, mage.cards.r.RavingVisionary.class)); cards.add(new SetCardInfo("Razortide Bridge", 252, Rarity.COMMON, mage.cards.r.RazortideBridge.class)); From 7458e86b3fc003cf6fb7473f32fcbe73ad21946c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 19:16:26 -0400 Subject: [PATCH 045/188] [MH2] Implemented Slag Strider --- Mage.Sets/src/mage/cards/s/SlagStrider.java | 52 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 53 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SlagStrider.java diff --git a/Mage.Sets/src/mage/cards/s/SlagStrider.java b/Mage.Sets/src/mage/cards/s/SlagStrider.java new file mode 100644 index 00000000000..015eff9257e --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SlagStrider.java @@ -0,0 +1,52 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.AffinityForArtifactsAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.common.TargetAnyTarget; +import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SlagStrider extends CardImpl { + + public SlagStrider(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Affinity for artifacts + this.addAbility(new AffinityForArtifactsAbility()); + + // {1}, Sacrifice an artifact: Slag Strider deals 1 damage to any target. + Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new GenericManaCost(1)); + ability.addCost(new SacrificeTargetCost( + new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN) + )); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability); + } + + private SlagStrider(final SlagStrider card) { + super(card); + } + + @Override + public SlagStrider copy() { + return new SlagStrider(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index a626b4670e5..9da2f40e90d 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -158,6 +158,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Silverbluff Bridge", 255, Rarity.COMMON, mage.cards.s.SilverbluffBridge.class)); cards.add(new SetCardInfo("Skirge Familiar", 276, Rarity.UNCOMMON, mage.cards.s.SkirgeFamiliar.class)); cards.add(new SetCardInfo("Skophos Reaver", 140, Rarity.COMMON, mage.cards.s.SkophosReaver.class)); + cards.add(new SetCardInfo("Slag Strider", 141, Rarity.UNCOMMON, mage.cards.s.SlagStrider.class)); cards.add(new SetCardInfo("Slagwoods Bridge", 256, Rarity.COMMON, mage.cards.s.SlagwoodsBridge.class)); cards.add(new SetCardInfo("Solitary Confinement", 265, Rarity.RARE, mage.cards.s.SolitaryConfinement.class)); cards.add(new SetCardInfo("Solitude", 32, Rarity.MYTHIC, mage.cards.s.Solitude.class)); From 879f44b8e3f4c651dffd5720c69de0646f228673 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 19:17:49 -0400 Subject: [PATCH 046/188] [MH2] Implemented Sol Talisman --- Mage.Sets/src/mage/cards/s/SolTalisman.java | 38 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 39 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SolTalisman.java diff --git a/Mage.Sets/src/mage/cards/s/SolTalisman.java b/Mage.Sets/src/mage/cards/s/SolTalisman.java new file mode 100644 index 00000000000..d37547f7f88 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SolTalisman.java @@ -0,0 +1,38 @@ +package mage.cards.s; + +import mage.Mana; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.keyword.SuspendAbility; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SolTalisman extends CardImpl { + + public SolTalisman(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); + + // Suspend 3—{1} + this.addAbility(new SuspendAbility(3, new GenericManaCost(1), this)); + + // {T}: Add {C}{C}. + this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.ColorlessMana(2), new TapSourceCost())); + } + + private SolTalisman(final SolTalisman card) { + super(card); + } + + @Override + public SolTalisman copy() { + return new SolTalisman(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 9da2f40e90d..e9e7ca8d4b4 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -160,6 +160,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Skophos Reaver", 140, Rarity.COMMON, mage.cards.s.SkophosReaver.class)); cards.add(new SetCardInfo("Slag Strider", 141, Rarity.UNCOMMON, mage.cards.s.SlagStrider.class)); cards.add(new SetCardInfo("Slagwoods Bridge", 256, Rarity.COMMON, mage.cards.s.SlagwoodsBridge.class)); + cards.add(new SetCardInfo("Sol Talisman", 472, Rarity.RARE, mage.cards.s.SolTalisman.class)); cards.add(new SetCardInfo("Solitary Confinement", 265, Rarity.RARE, mage.cards.s.SolitaryConfinement.class)); cards.add(new SetCardInfo("Solitude", 32, Rarity.MYTHIC, mage.cards.s.Solitude.class)); cards.add(new SetCardInfo("Soul Snare", 266, Rarity.UNCOMMON, mage.cards.s.SoulSnare.class)); From 6ab5c4e03be8be1888cc8a50765b812865822c9a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 19:23:23 -0400 Subject: [PATCH 047/188] [MH2] Implemented Wren's Run Hydra --- Mage.Sets/src/mage/cards/w/WrensRunHydra.java | 48 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 49 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WrensRunHydra.java diff --git a/Mage.Sets/src/mage/cards/w/WrensRunHydra.java b/Mage.Sets/src/mage/cards/w/WrensRunHydra.java new file mode 100644 index 00000000000..2f915f4644c --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WrensRunHydra.java @@ -0,0 +1,48 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect; +import mage.abilities.keyword.ReachAbility; +import mage.abilities.keyword.ReinforceAbility; +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 WrensRunHydra extends CardImpl { + + public WrensRunHydra(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{X}{G}"); + + this.subtype.add(SubType.HYDRA); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // Wren's Run Hydra enters the battlefield with X +1/+1 counters on it. + this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.P1P1.createInstance()))); + + // Reinforce X—{X}{G}{G} + this.addAbility(new ReinforceAbility(ManacostVariableValue.instance, new ManaCostsImpl<>("{X}{G}{G}"))); + } + + private WrensRunHydra(final WrensRunHydra card) { + super(card); + } + + @Override + public WrensRunHydra copy() { + return new WrensRunHydra(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index e9e7ca8d4b4..b3a9c32e0d3 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -202,6 +202,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Void Mirror", 242, Rarity.RARE, mage.cards.v.VoidMirror.class)); cards.add(new SetCardInfo("Wonder", 271, Rarity.RARE, mage.cards.w.Wonder.class)); cards.add(new SetCardInfo("World-Weary", 109, Rarity.COMMON, mage.cards.w.WorldWeary.class)); + cards.add(new SetCardInfo("Wren's Run Hydra", 163, Rarity.UNCOMMON, mage.cards.w.WrensRunHydra.class)); cards.add(new SetCardInfo("Yavimaya Elder", 288, Rarity.UNCOMMON, mage.cards.y.YavimayaElder.class)); cards.add(new SetCardInfo("Young Necromancer", 110, Rarity.UNCOMMON, mage.cards.y.YoungNecromancer.class)); cards.add(new SetCardInfo("Yusri, Fortune's Flame", 218, Rarity.RARE, mage.cards.y.YusriFortunesFlame.class)); From 70dfb0e24103065b47b8a47ccf1cc6762270a0c6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 31 May 2021 19:37:03 -0400 Subject: [PATCH 048/188] [MH2] Implemented Specimen Collector --- .../src/mage/cards/s/SpecimenCollector.java | 60 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 61 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SpecimenCollector.java diff --git a/Mage.Sets/src/mage/cards/s/SpecimenCollector.java b/Mage.Sets/src/mage/cards/s/SpecimenCollector.java new file mode 100644 index 00000000000..91011f520ce --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpecimenCollector.java @@ -0,0 +1,60 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.permanent.token.CrabToken; +import mage.game.permanent.token.SquirrelToken; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SpecimenCollector extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent("token you control"); + + static { + filter.add(TokenPredicate.instance); + } + + public SpecimenCollector(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}"); + + this.subtype.add(SubType.VEDALKEN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // When Specimen Collector enters the battlefield, create a 1/1 green Squirrel creature token and a 0/3 blue Crab creature token. + Ability ability = new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new SquirrelToken())); + ability.addEffect(new CreateTokenEffect(new CrabToken()).setText("and a 0/3 blue Crab creature token")); + this.addAbility(ability); + + // When Specimen Collector dies, create a token that's a copy of target token you control. + ability = new DiesSourceTriggeredAbility(new CreateTokenCopyTargetEffect()); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + private SpecimenCollector(final SpecimenCollector card) { + super(card); + } + + @Override + public SpecimenCollector copy() { + return new SpecimenCollector(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index b3a9c32e0d3..ee59857fb31 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -164,6 +164,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Solitary Confinement", 265, Rarity.RARE, mage.cards.s.SolitaryConfinement.class)); cards.add(new SetCardInfo("Solitude", 32, Rarity.MYTHIC, mage.cards.s.Solitude.class)); cards.add(new SetCardInfo("Soul Snare", 266, Rarity.UNCOMMON, mage.cards.s.SoulSnare.class)); + cards.add(new SetCardInfo("Specimen Collector", 64, Rarity.UNCOMMON, mage.cards.s.SpecimenCollector.class)); cards.add(new SetCardInfo("Spreading Insurrection", 142, Rarity.UNCOMMON, mage.cards.s.SpreadingInsurrection.class)); cards.add(new SetCardInfo("Squirrel Mob", 286, Rarity.RARE, mage.cards.s.SquirrelMob.class)); cards.add(new SetCardInfo("Squirrel Sanctuary", 174, Rarity.UNCOMMON, mage.cards.s.SquirrelSanctuary.class)); From 479f2d46e612f0b5abe329b100bfce2128e3b1ed Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Mon, 31 May 2021 18:44:01 -0500 Subject: [PATCH 049/188] [MH2] Implemented Graceful Restoration (#7869) --- .../src/mage/cards/g/GracefulRestoration.java | 99 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 100 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GracefulRestoration.java diff --git a/Mage.Sets/src/mage/cards/g/GracefulRestoration.java b/Mage.Sets/src/mage/cards/g/GracefulRestoration.java new file mode 100644 index 00000000000..565b523f0e7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GracefulRestoration.java @@ -0,0 +1,99 @@ +package mage.cards.g; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author weirddan455 + */ +public final class GracefulRestoration extends CardImpl { + + private static final FilterCreatureCard filter = new FilterCreatureCard("creature cards with power 2 or less from your graveyard"); + + static { + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3)); + } + + public GracefulRestoration(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{W}{B}"); + + // Choose one — + // • Return target creature card from your graveyard to the battlefield with an additional +1/+1 counter on it. + this.getSpellAbility().addEffect(new GracefulRestorationReplacementEffect()); + this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); + this.getSpellAbility().addEffect(new InfoEffect("with an additional +1/+1 counter on it")); + 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. + Mode mode = new Mode(new ReturnFromGraveyardToBattlefieldTargetEffect()); + mode.addTarget(new TargetCardInYourGraveyard(0, 2, filter)); + this.getSpellAbility().addMode(mode); + } + + private GracefulRestoration(final GracefulRestoration card) { + super(card); + } + + @Override + public GracefulRestoration copy() { + return new GracefulRestoration(this); + } +} + +class GracefulRestorationReplacementEffect extends ReplacementEffectImpl { + + public GracefulRestorationReplacementEffect() { + super(Duration.EndOfStep, Outcome.BoostCreature); + } + + private GracefulRestorationReplacementEffect(final GracefulRestorationReplacementEffect effect) { + super(effect); + } + + @Override + public GracefulRestorationReplacementEffect copy() { + return new GracefulRestorationReplacementEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return event.getTargetId().equals(getTargetPointer().getFirst(game, source)); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); + if (creature == null) { + return false; + } + creature.addCounters(CounterType.P1P1.createInstance(), source.getControllerId(), source, game, event.getAppliedEffects()); + discard(); + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index ee59857fb31..b5e30396615 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -89,6 +89,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Goblin Bombardment", 279, Rarity.RARE, mage.cards.g.GoblinBombardment.class)); cards.add(new SetCardInfo("Goldmire Bridge", 247, Rarity.COMMON, mage.cards.g.GoldmireBridge.class)); cards.add(new SetCardInfo("Gorilla Shaman", 280, Rarity.UNCOMMON, mage.cards.g.GorillaShaman.class)); + cards.add(new SetCardInfo("Graceful Restoration", 201, Rarity.UNCOMMON, mage.cards.g.GracefulRestoration.class)); cards.add(new SetCardInfo("Greed", 274, Rarity.UNCOMMON, mage.cards.g.Greed.class)); cards.add(new SetCardInfo("Grief", 87, Rarity.MYTHIC, mage.cards.g.Grief.class)); cards.add(new SetCardInfo("Harmonic Prodigy", 132, Rarity.RARE, mage.cards.h.HarmonicProdigy.class)); From e51cbb0f7910bd1ca88f4af6b7b78fb0e33ee545 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 08:47:04 -0400 Subject: [PATCH 050/188] [MH2] Implemented Svyelun of Sea and Sky --- .../src/mage/cards/s/SvyelunOfSeaAndSky.java | 75 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 76 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SvyelunOfSeaAndSky.java diff --git a/Mage.Sets/src/mage/cards/s/SvyelunOfSeaAndSky.java b/Mage.Sets/src/mage/cards/s/SvyelunOfSeaAndSky.java new file mode 100644 index 00000000000..c626f4c3ba9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SvyelunOfSeaAndSky.java @@ -0,0 +1,75 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.IndestructibleAbility; +import mage.abilities.keyword.WardAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SvyelunOfSeaAndSky extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.MERFOLK, "other Merfolk"); + + static { + filter.add(AnotherPredicate.instance); + } + + private static final Condition condition + = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.MORE_THAN, 1); + private static final Hint hint + = new ValueHint("Other Merfolk you control", new PermanentsOnBattlefieldCount(filter)); + + public SvyelunOfSeaAndSky(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.GOD); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Svyelun of Sea and Sky has indestructible as long as you control at least two other Merfolk. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Duration.WhileOnBattlefield), + condition, "{this} has indestructible as long as you control at least two other Merfolk" + ))); + + // Whenever Svyelun attacks, draw a card. + this.addAbility(new AttacksTriggeredAbility(new DrawCardSourceControllerEffect(1), false)); + + // Other Merfolk you control have ward {1}. + this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + new WardAbility(new GenericManaCost(1)), Duration.WhileOnBattlefield, filter + ))); + } + + private SvyelunOfSeaAndSky(final SvyelunOfSeaAndSky card) { + super(card); + } + + @Override + public SvyelunOfSeaAndSky copy() { + return new SvyelunOfSeaAndSky(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index b5e30396615..0eae88859b1 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -175,6 +175,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Strike It Rich", 143, Rarity.UNCOMMON, mage.cards.s.StrikeItRich.class)); cards.add(new SetCardInfo("Subtlety", 67, Rarity.MYTHIC, mage.cards.s.Subtlety.class)); cards.add(new SetCardInfo("Sudden Edict", 100, Rarity.UNCOMMON, mage.cards.s.SuddenEdict.class)); + cards.add(new SetCardInfo("Svyelun of Sea and Sky", 69, Rarity.MYTHIC, mage.cards.s.SvyelunOfSeaAndSky.class)); cards.add(new SetCardInfo("Swamp", 485, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sweep the Skies", 70, Rarity.UNCOMMON, mage.cards.s.SweepTheSkies.class)); cards.add(new SetCardInfo("Sylvan Anthem", 176, Rarity.RARE, mage.cards.s.SylvanAnthem.class)); From 3ff314610757e5e762846e163cea3fb3d46cfb48 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 09:00:20 -0400 Subject: [PATCH 051/188] [MH2] Implemented Tide Shaper --- Mage.Sets/src/mage/cards/t/TideShaper.java | 110 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 111 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TideShaper.java diff --git a/Mage.Sets/src/mage/cards/t/TideShaper.java b/Mage.Sets/src/mage/cards/t/TideShaper.java new file mode 100644 index 00000000000..2c42a2c3154 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TideShaper.java @@ -0,0 +1,110 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesBasicLandTargetEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.game.Game; +import mage.target.common.TargetLandPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TideShaper extends CardImpl { + + private static final FilterPermanent filter + = new FilterPermanent(SubType.ISLAND, "An opponent controls an Island"); + + static { + filter.add(TargetController.OPPONENT.getControllerPredicate()); + } + + private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.MORE_THAN, 0, false); + private static final Hint hint = new ConditionHint(condition); + + public TideShaper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Kicker {1} + this.addAbility(new KickerAbility("{1}")); + + // When Tide Shaper enters the battlefield, if it was kicked, target land becomes an Island for as long as Tide Shaper remains on the battlefield. + Ability ability = new ConditionalInterveningIfTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new TideShaperEffect()), + KickedCondition.instance, "When {this} enters the battlefield, if it was kicked, " + + "target land becomes an Island for as long as {this} remains on the battlefield." + ); + ability.addTarget(new TargetLandPermanent()); + this.addAbility(ability); + + // Tide Shaper gets +1/+1 as long as an opponent controls an Island. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), + condition, "{this} gets +1/+1 as long as an opponent controls an Island" + )).addHint(hint)); + } + + private TideShaper(final TideShaper card) { + super(card); + } + + @Override + public TideShaper copy() { + return new TideShaper(this); + } +} + +class TideShaperEffect extends BecomesBasicLandTargetEffect { + + TideShaperEffect() { + super(Duration.Custom, false, true, SubType.ISLAND); + } + + private TideShaperEffect(final TideShaperEffect effect) { + super(effect); + } + + @Override + public TideShaperEffect copy() { + return new TideShaperEffect(this); + } + + @Override + public void init(Ability source, Game game) { + if (source.getSourcePermanentIfItStillExists(game) == null) { + discard(); + return; + } + super.init(source, game); + } + + @Override + public boolean apply(Game game, Ability source) { + if (source.getSourcePermanentIfItStillExists(game) == null) { + discard(); + return false; + } + return super.apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 0eae88859b1..9212199186c 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -187,6 +187,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Thought Monitor", 71, Rarity.RARE, mage.cards.t.ThoughtMonitor.class)); cards.add(new SetCardInfo("Thraben Watcher", 34, Rarity.UNCOMMON, mage.cards.t.ThrabenWatcher.class)); cards.add(new SetCardInfo("Thrasta, Tempest's Roar", 178, Rarity.MYTHIC, mage.cards.t.ThrastaTempestsRoar.class)); + cards.add(new SetCardInfo("Tide Shaper", 72, Rarity.UNCOMMON, mage.cards.t.TideShaper.class)); cards.add(new SetCardInfo("Timeless Dragon", 35, Rarity.RARE, mage.cards.t.TimelessDragon.class)); cards.add(new SetCardInfo("Timeless Witness", 179, Rarity.UNCOMMON, mage.cards.t.TimelessWitness.class)); cards.add(new SetCardInfo("Tireless Provisioner", 180, Rarity.UNCOMMON, mage.cards.t.TirelessProvisioner.class)); From e1d462e18047a46a14a6c4d00f8188d756ccfdd1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 09:15:27 -0400 Subject: [PATCH 052/188] [MH2] Implemented Verdant Command --- .../src/mage/cards/v/VerdantCommand.java | 85 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 86 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VerdantCommand.java diff --git a/Mage.Sets/src/mage/cards/v/VerdantCommand.java b/Mage.Sets/src/mage/cards/v/VerdantCommand.java new file mode 100644 index 00000000000..e31df3f6825 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VerdantCommand.java @@ -0,0 +1,85 @@ +package mage.cards.v; + +import mage.abilities.LoyaltyAbility; +import mage.abilities.Mode; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.GainLifeTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterStackObject; +import mage.filter.predicate.Predicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.SquirrelToken; +import mage.game.stack.StackObject; +import mage.target.TargetPlayer; +import mage.target.TargetStackObject; +import mage.target.common.TargetCardInGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class VerdantCommand extends CardImpl { + + private static final FilterStackObject filter = new FilterStackObject("loyalty ability of a planeswalker"); + + static { + filter.add(VerdantCommandPredicate.instance); + } + + public VerdantCommand(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); + + // Choose two — + this.getSpellAbility().getModes().setMinModes(2); + this.getSpellAbility().getModes().setMaxModes(2); + + // • Target player creates two tapped 1/1 green Squirrel creature tokens. + this.getSpellAbility().addEffect(new CreateTokenTargetEffect( + new SquirrelToken(), StaticValue.get(2), true, false + )); + + // • Counter target loyalty ability of a planeswalker. + Mode mode = new Mode(new CounterTargetEffect()); + mode.addTarget(new TargetStackObject(filter)); + this.getSpellAbility().addMode(mode); + + // • Exile target card from a graveyard. + mode = new Mode(new ExileTargetEffect()); + mode.addTarget(new TargetCardInGraveyard()); + this.getSpellAbility().addMode(mode); + + // • Target player gains 3 life. + mode = new Mode(new GainLifeTargetEffect(3)); + mode.addTarget(new TargetPlayer()); + this.getSpellAbility().addMode(mode); + } + + private VerdantCommand(final VerdantCommand card) { + super(card); + } + + @Override + public VerdantCommand copy() { + return new VerdantCommand(this); + } +} + +enum VerdantCommandPredicate implements Predicate { + instance; + + @Override + public boolean apply(StackObject input, Game game) { + if (!(input instanceof LoyaltyAbility)) { + return false; + } + Permanent permanent = ((LoyaltyAbility) input).getSourcePermanentOrLKI(game); + return permanent != null && permanent.isPlaneswalker(); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 9212199186c..631a1e1961e 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -202,6 +202,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Vectis Gloves", 241, Rarity.UNCOMMON, mage.cards.v.VectisGloves.class)); cards.add(new SetCardInfo("Vedalken Infiltrator", 73, Rarity.UNCOMMON, mage.cards.v.VedalkenInfiltrator.class)); cards.add(new SetCardInfo("Verdant Catacombs", 260, Rarity.RARE, mage.cards.v.VerdantCatacombs.class)); + cards.add(new SetCardInfo("Verdant Command", 182, Rarity.RARE, mage.cards.v.VerdantCommand.class)); cards.add(new SetCardInfo("Vindicate", 294, Rarity.RARE, mage.cards.v.Vindicate.class)); cards.add(new SetCardInfo("Void Mirror", 242, Rarity.RARE, mage.cards.v.VoidMirror.class)); cards.add(new SetCardInfo("Wonder", 271, Rarity.RARE, mage.cards.w.Wonder.class)); From ce3f69c5d96533953e8e819b34f50cee2f296571 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 09:21:04 -0400 Subject: [PATCH 053/188] [MH2] Implemented Road // Ruin --- Mage.Sets/src/mage/cards/r/RoadRuin.java | 54 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 55 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RoadRuin.java diff --git a/Mage.Sets/src/mage/cards/r/RoadRuin.java b/Mage.Sets/src/mage/cards/r/RoadRuin.java new file mode 100644 index 00000000000..24c67e0ac38 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RoadRuin.java @@ -0,0 +1,54 @@ +package mage.cards.r; + +import mage.abilities.dynamicvalue.common.LandsYouControlCount; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.abilities.hint.common.LandsYouControlHint; +import mage.abilities.keyword.AftermathAbility; +import mage.cards.CardSetInfo; +import mage.cards.SplitCard; +import mage.constants.CardType; +import mage.constants.SpellAbilityType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RoadRuin extends SplitCard { + public RoadRuin(UUID ownerId, CardSetInfo setInfo) { + super( + ownerId, setInfo, + new CardType[]{CardType.INSTANT}, new CardType[]{CardType.SORCERY}, + "{2}{G}", "{1}{R}{R}", SpellAbilityType.SPLIT_AFTERMATH + ); + + // Road + // Search your library for a basic land card, put it onto the battlefield tapped, then shuffle. + this.getLeftHalfCard().getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect( + new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true + )); + + // Ruin + // Aftermath + this.getRightHalfCard().addAbility(new AftermathAbility().setRuleAtTheTop(true)); + + // Ruin deals damage to target creature equal to the number of lands you control. + this.getRightHalfCard().getSpellAbility().addEffect(new DamageTargetEffect(LandsYouControlCount.instance) + .setText("{this} deals damage to target creature equal to the number of lands you control")); + this.getRightHalfCard().getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getRightHalfCard().getSpellAbility().addHint(LandsYouControlHint.instance); + } + + private RoadRuin(final RoadRuin card) { + super(card); + } + + @Override + public RoadRuin copy() { + return new RoadRuin(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 631a1e1961e..aa4f4bdf388 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -143,6 +143,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Rift Sower", 170, Rarity.COMMON, mage.cards.r.RiftSower.class)); cards.add(new SetCardInfo("Riptide Laboratory", 303, Rarity.RARE, mage.cards.r.RiptideLaboratory.class)); cards.add(new SetCardInfo("Rishadan Dockhand", 59, Rarity.RARE, mage.cards.r.RishadanDockhand.class)); + cards.add(new SetCardInfo("Road // Ruin", 212, Rarity.UNCOMMON, mage.cards.r.RoadRuin.class)); cards.add(new SetCardInfo("Rustvale Bridge", 253, Rarity.COMMON, mage.cards.r.RustvaleBridge.class)); cards.add(new SetCardInfo("Sanctuary Raptor", 233, Rarity.UNCOMMON, mage.cards.s.SanctuaryRaptor.class)); cards.add(new SetCardInfo("Sanctum Prelate", 491, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class)); From f7c3d15ed2eb3776d2b20b30e61dd0dd345a2ad3 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Tue, 1 Jun 2021 17:02:53 -0500 Subject: [PATCH 054/188] [MH2] Implemented Captain Ripley Vance (#7872) --- .../src/mage/cards/c/CaptainRipleyVance.java | 85 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 86 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CaptainRipleyVance.java diff --git a/Mage.Sets/src/mage/cards/c/CaptainRipleyVance.java b/Mage.Sets/src/mage/cards/c/CaptainRipleyVance.java new file mode 100644 index 00000000000..aff5da06d64 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CaptainRipleyVance.java @@ -0,0 +1,85 @@ +package mage.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.common.TargetAnyTarget; +import mage.watchers.common.SpellsCastWatcher; + +/** + * + * @author weirddan455 + */ +public final class CaptainRipleyVance extends CardImpl { + + public CaptainRipleyVance(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Whenever you cast your third spell each turn, put a +1/+1 counter on Captain Ripley Vance, then it deals damage equal to its power to any target. + this.addAbility(new CaptainRipleyVanceTriggeredAbility(), new SpellsCastWatcher()); + } + + private CaptainRipleyVance(final CaptainRipleyVance card) { + super(card); + } + + @Override + public CaptainRipleyVance copy() { + return new CaptainRipleyVance(this); + } +} + +class CaptainRipleyVanceTriggeredAbility extends TriggeredAbilityImpl { + + public CaptainRipleyVanceTriggeredAbility() { + super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance())); + addEffect(new DamageTargetEffect(new SourcePermanentPowerCount()).setText("it deals damage equal to its power to any target").concatBy(", then")); + addTarget(new TargetAnyTarget()); + } + + private CaptainRipleyVanceTriggeredAbility(final CaptainRipleyVanceTriggeredAbility ability) { + super(ability); + } + + @Override + public CaptainRipleyVanceTriggeredAbility copy() { + return new CaptainRipleyVanceTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getPlayerId().equals(this.getControllerId())) { + SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); + return watcher != null && watcher.getSpellsCastThisTurn(this.getControllerId()).size() == 3; + } + return false; + } + + @Override + public String getRule() { + return "Whenever you cast your third spell each turn, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index aa4f4bdf388..c32a6f006eb 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -48,6 +48,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Breya's Apprentice", 117, Rarity.RARE, mage.cards.b.BreyasApprentice.class)); cards.add(new SetCardInfo("Cabal Coffers", 301, Rarity.MYTHIC, mage.cards.c.CabalCoffers.class)); cards.add(new SetCardInfo("Calibrated Blast", 118, Rarity.RARE, mage.cards.c.CalibratedBlast.class)); + cards.add(new SetCardInfo("Captain Ripley Vance", 119, Rarity.UNCOMMON, mage.cards.c.CaptainRipleyVance.class)); cards.add(new SetCardInfo("Chainer, Nightmare Adept", 289, Rarity.RARE, mage.cards.c.ChainerNightmareAdept.class)); cards.add(new SetCardInfo("Chance Encounter", 277, Rarity.RARE, mage.cards.c.ChanceEncounter.class)); cards.add(new SetCardInfo("Chatterstorm", 152, Rarity.COMMON, mage.cards.c.Chatterstorm.class)); From 03db612f83848d550c6c9e12606db7da1c2b7718 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Tue, 1 Jun 2021 17:04:06 -0500 Subject: [PATCH 055/188] [MH2] Implemented Geyadrone Dihada (#7873) --- .../src/mage/cards/g/GeyadroneDihada.java | 92 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../src/main/java/mage/constants/SubType.java | 1 + .../main/java/mage/counters/CounterType.java | 1 + 4 files changed, 95 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GeyadroneDihada.java diff --git a/Mage.Sets/src/mage/cards/g/GeyadroneDihada.java b/Mage.Sets/src/mage/cards/g/GeyadroneDihada.java new file mode 100644 index 00000000000..67bc26f82ce --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GeyadroneDihada.java @@ -0,0 +1,92 @@ +package mage.cards.g; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.continuous.GainControlAllEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.constants.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreatureOrPlaneswalker; + +/** + * + * @author weirddan455 + */ +public final class GeyadroneDihada extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("permanents with corruption counters on them"); + private static final FilterCreatureOrPlaneswalkerPermanent filter2 = new FilterCreatureOrPlaneswalkerPermanent("other creature or planeswalker"); + private static final FilterPermanent filter3 = new FilterPermanent("each permanent with a corruption counter on it"); + + static { + filter.add(CorruptionCounterPredicate.instance); + filter2.add(AnotherPredicate.instance); + filter3.add(CorruptionCounterPredicate.instance); + } + + public GeyadroneDihada(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{1}{U}{B}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.DIHADA); + this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4)); + + // Protection from permanents with corruption counters on them + this.addAbility(new ProtectionAbility(filter)); + + // +1: Each opponent loses 2 life and you gain 2 life. Put a corruption counter on up to one other target creature or planeswalker. + Ability ability = new LoyaltyAbility(new LoseLifeOpponentsEffect(2), 1); + ability.addEffect(new GainLifeEffect(2).concatBy("and")); + ability.addEffect(new AddCountersTargetEffect(CounterType.CORRUPTION.createInstance(), Outcome.Detriment) + .setText("Put a corruption counter on up to one other target creature or planeswalker")); + ability.addTarget(new TargetCreatureOrPlaneswalker(0, 1, filter2, false)); + this.addAbility(ability); + + // −3: Gain control of target creature or planeswalker until end of tun. Untap it and put a corruption counter on it. It gains haste until end of turn. + ability = new LoyaltyAbility(new GainControlTargetEffect(Duration.EndOfTurn), -3); + ability.addEffect(new UntapTargetEffect().setText("Untap it")); + ability.addEffect(new AddCountersTargetEffect(CounterType.CORRUPTION.createInstance(), Outcome.Detriment).setText("and put a corruption counter on it")); + ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn")); + ability.addTarget(new TargetCreatureOrPlaneswalker()); + this.addAbility(ability); + + // −7: Gain control of each permanent with a corruption counter on it. + this.addAbility(new LoyaltyAbility(new GainControlAllEffect(Duration.Custom, filter3), -7)); + } + + private GeyadroneDihada(final GeyadroneDihada card) { + super(card); + } + + @Override + public GeyadroneDihada copy() { + return new GeyadroneDihada(this); + } +} + +enum CorruptionCounterPredicate implements Predicate { + instance; + + @Override + public boolean apply(Permanent input, Game game) { + return input.getCounters(game).getCount(CounterType.CORRUPTION) > 0; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index c32a6f006eb..487d5f4e533 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -84,6 +84,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); cards.add(new SetCardInfo("Gaea's Will", 162, Rarity.RARE, mage.cards.g.GaeasWill.class)); cards.add(new SetCardInfo("General Ferrous Rokiric", 198, Rarity.RARE, mage.cards.g.GeneralFerrousRokiric.class)); + cards.add(new SetCardInfo("Geyadrone Dihada", 199, Rarity.MYTHIC, mage.cards.g.GeyadroneDihada.class)); cards.add(new SetCardInfo("Ghost-Lit Drifter", 45, Rarity.UNCOMMON, mage.cards.g.GhostLitDrifter.class)); cards.add(new SetCardInfo("Glinting Creeper", 164, Rarity.UNCOMMON, mage.cards.g.GlintingCreeper.class)); cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 81406cf6342..9bc5596f8bf 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -403,6 +403,7 @@ public enum SubType { DAKKON("Dakkon", SubTypeSet.PlaneswalkerType), DARETTI("Daretti", SubTypeSet.PlaneswalkerType), DAVRIEL("Davriel", SubTypeSet.PlaneswalkerType), + DIHADA("Dihada", SubTypeSet.PlaneswalkerType), DOMRI("Domri", SubTypeSet.PlaneswalkerType), DOOKU("Dooku", SubTypeSet.PlaneswalkerType, true), // Star Wars DOVIN("Dovin", SubTypeSet.PlaneswalkerType), diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index 35198b0b05f..f84c7895b75 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -31,6 +31,7 @@ public enum CounterType { CHIP("chip"), COIN("coin"), CORPSE("corpse"), + CORRUPTION("corruption"), CREDIT("credit"), CRYSTAL("crystal"), CUBE("cube"), From ecf23e5e315354da76a99251fdc4bb174d23f974 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Tue, 1 Jun 2021 17:04:24 -0500 Subject: [PATCH 056/188] [MH2] Implemented Arcbound Javelineer (#7870) --- .../src/mage/cards/a/ArcboundJavelineer.java | 50 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 51 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/ArcboundJavelineer.java diff --git a/Mage.Sets/src/mage/cards/a/ArcboundJavelineer.java b/Mage.Sets/src/mage/cards/a/ArcboundJavelineer.java new file mode 100644 index 00000000000..9ee1d8e3bb8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArcboundJavelineer.java @@ -0,0 +1,50 @@ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveVariableCountersSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.common.GetXValue; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.ModularAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.target.common.TargetAttackingOrBlockingCreature; + +/** + * + * @author weirddan455 + */ +public final class ArcboundJavelineer extends CardImpl { + + public ArcboundJavelineer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{W}"); + + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(0); + this.toughness = new MageInt(1); + + // {T}, Remove X +1/+1 counters from Arcbound Javelineer: It deals X damage to target attacking or blocking creature. + Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(GetXValue.instance, "It"), new TapSourceCost()); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetAttackingOrBlockingCreature()); + this.addAbility(ability); + + // Modular 1 + this.addAbility(new ModularAbility(this, 1)); + } + + private ArcboundJavelineer(final ArcboundJavelineer card) { + super(card); + } + + @Override + public ArcboundJavelineer copy() { + return new ArcboundJavelineer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 487d5f4e533..570bf45af40 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -30,6 +30,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Abiding Grace", 1, Rarity.UNCOMMON, mage.cards.a.AbidingGrace.class)); cards.add(new SetCardInfo("Abundant Harvest", 147, Rarity.COMMON, mage.cards.a.AbundantHarvest.class)); cards.add(new SetCardInfo("Aeromoeba", 37, Rarity.COMMON, mage.cards.a.Aeromoeba.class)); + cards.add(new SetCardInfo("Arcbound Javelineer", 2, Rarity.UNCOMMON, mage.cards.a.ArcboundJavelineer.class)); cards.add(new SetCardInfo("Arcbound Mouser", 3, Rarity.COMMON, mage.cards.a.ArcboundMouser.class)); cards.add(new SetCardInfo("Arcbound Shikari", 184, Rarity.UNCOMMON, mage.cards.a.ArcboundShikari.class)); cards.add(new SetCardInfo("Arcbound Whelp", 113, Rarity.UNCOMMON, mage.cards.a.ArcboundWhelp.class)); From 97856898329716c39921fcec9851cc605c7ff5dc Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Tue, 1 Jun 2021 17:04:57 -0500 Subject: [PATCH 057/188] [MH2] Implemented Esper Sentinel (#7866) Co-authored-by: Evan Kranzler --- Mage.Sets/src/mage/cards/e/EsperSentinel.java | 131 ++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 132 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EsperSentinel.java diff --git a/Mage.Sets/src/mage/cards/e/EsperSentinel.java b/Mage.Sets/src/mage/cards/e/EsperSentinel.java new file mode 100644 index 00000000000..2bb832a3331 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EsperSentinel.java @@ -0,0 +1,131 @@ +package mage.cards.e; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.costs.Cost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.util.ManaUtil; +import mage.watchers.common.SpellsCastWatcher; + +/** + * + * @author weirddan455 + */ +public final class EsperSentinel extends CardImpl { + + public EsperSentinel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Whenever an opponent casts their first noncreature spell each turn, draw a card unless that player pays {X}, where X is Esper Sentinel's power. + this.addAbility(new EsperSentinelTriggeredAbility(), new SpellsCastWatcher()); + } + + private EsperSentinel(final EsperSentinel card) { + super(card); + } + + @Override + public EsperSentinel copy() { + return new EsperSentinel(this); + } +} + +class EsperSentinelTriggeredAbility extends TriggeredAbilityImpl { + + public EsperSentinelTriggeredAbility() { + super(Zone.BATTLEFIELD, new EsperSentinelEffect()); + } + + private EsperSentinelTriggeredAbility(final EsperSentinelTriggeredAbility ability) { + super(ability); + } + + @Override + public EsperSentinelTriggeredAbility copy() { + return new EsperSentinelTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Player controller = game.getPlayer(getControllerId()); + Spell spell = game.getSpell(event.getTargetId()); + SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); + if (controller != null && spell != null && watcher != null && !spell.isCreature() && controller.hasOpponent(spell.getControllerId(), game)) { + int nonCreatureSpells = 0; + for (Spell spellCastThisTurn : watcher.getSpellsCastThisTurn(spell.getControllerId())) { + if (!spellCastThisTurn.isCreature() && ++nonCreatureSpells > 1) { + break; + } + } + if (nonCreatureSpells == 1) { + for (Effect effect : getEffects()) { + effect.setTargetPointer(new FixedTarget(spell.getControllerId())); + } + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever an opponent casts their first noncreature spell each turn, draw a card unless that player pays {X}, where X is Esper Sentinel's power."; + } +} + +class EsperSentinelEffect extends OneShotEffect { + + public EsperSentinelEffect() { + super(Outcome.DrawCard); + } + + private EsperSentinelEffect(final EsperSentinelEffect effect) { + super(effect); + } + + @Override + public EsperSentinelEffect copy() { + return new EsperSentinelEffect(this); + } + + @Override + public boolean apply (Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source)); + Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (controller != null && opponent != null && permanent != null) { + Cost cost = ManaUtil.createManaCost(permanent.getPower().getValue(), false); + if (!opponent.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "?", source, game) + || !cost.pay(source, game, source, opponent.getId(), false)) { + controller.drawCards(1, source, game); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 570bf45af40..4556778cb96 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -69,6 +69,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Drossforge Bridge", 246, Rarity.COMMON, mage.cards.d.DrossforgeBridge.class)); cards.add(new SetCardInfo("Enchantress's Presence", 283, Rarity.RARE, mage.cards.e.EnchantresssPresence.class)); cards.add(new SetCardInfo("Endurance", 157, Rarity.MYTHIC, mage.cards.e.Endurance.class)); + cards.add(new SetCardInfo("Esper Sentinel", 12, Rarity.RARE, mage.cards.e.EsperSentinel.class)); cards.add(new SetCardInfo("Ethersworn Sphinx", 195, Rarity.UNCOMMON, mage.cards.e.EtherswornSphinx.class)); cards.add(new SetCardInfo("Extruder", 296, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); cards.add(new SetCardInfo("Fae Offering", 158, Rarity.UNCOMMON, mage.cards.f.FaeOffering.class)); From 261b09c7113bf2a659cea59f26f90a7cef2406d0 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Tue, 1 Jun 2021 19:13:14 -0500 Subject: [PATCH 058/188] [MH2] Implemented Bloodbraid Marauder (#7871) * [MH2] Implemented Bloodbraid Marauder * [MH2] Bloodbraid Marauder - Use gain ability effect --- .../src/mage/cards/b/BloodbraidMarauder.java | 59 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 60 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BloodbraidMarauder.java diff --git a/Mage.Sets/src/mage/cards/b/BloodbraidMarauder.java b/Mage.Sets/src/mage/cards/b/BloodbraidMarauder.java new file mode 100644 index 00000000000..60fbd087b47 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BloodbraidMarauder.java @@ -0,0 +1,59 @@ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.CantBlockAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.DeliriumCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.hint.common.CardTypesInGraveyardHint; +import mage.abilities.keyword.CascadeAbility; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author weirddan455 + */ +public final class BloodbraidMarauder extends CardImpl { + + private static final String REMINDER_TEXT = " (When you cast this spell, " + + "exile cards from the top of your library until you exile a " + + "nonland card whose mana value is less than this spell's mana value. " + + "You may cast that spell without paying its mana cost " + + "if its mana value is less than this spell's mana value. " + + "Then put all cards exiled this way that weren't cast on the bottom of your library in a random order.)"; + + public BloodbraidMarauder(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.BERSERKER); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Bloodbraid Marauder can't block. + this.addAbility(new CantBlockAbility()); + + // Delirium — This spell has cascade as long as there are four or more card types among cards in your graveyard. + this.addAbility(new SimpleStaticAbility(Zone.STACK, new ConditionalContinuousEffect( + new GainAbilitySourceEffect(new CascadeAbility(), Duration.WhileOnStack, true), + DeliriumCondition.instance, + "Delirium — This spell has cascade as long as there are four or more card types among cards in your graveyard." + REMINDER_TEXT + )).addHint(CardTypesInGraveyardHint.YOU)); + } + + private BloodbraidMarauder(final BloodbraidMarauder card) { + super(card); + } + + @Override + public BloodbraidMarauder copy() { + return new BloodbraidMarauder(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 4556778cb96..77e6a13ff10 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -40,6 +40,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Asmoranomardicadaistinaculdacar", 186, Rarity.RARE, mage.cards.a.Asmoranomardicadaistinaculdacar.class)); cards.add(new SetCardInfo("Batterbone", 221, Rarity.UNCOMMON, mage.cards.b.Batterbone.class)); cards.add(new SetCardInfo("Battle Plan", 114, Rarity.COMMON, mage.cards.b.BattlePlan.class)); + cards.add(new SetCardInfo("Bloodbraid Marauder", 116, Rarity.RARE, mage.cards.b.BloodbraidMarauder.class)); cards.add(new SetCardInfo("Bone Shards", 76, Rarity.COMMON, mage.cards.b.BoneShards.class)); cards.add(new SetCardInfo("Bone Shredder", 272, Rarity.UNCOMMON, mage.cards.b.BoneShredder.class)); cards.add(new SetCardInfo("Bottle Golems", 222, Rarity.COMMON, mage.cards.b.BottleGolems.class)); From e7efc5c918fcff244fcc1f069e06017f3d3f278b Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Tue, 1 Jun 2021 19:14:40 -0500 Subject: [PATCH 059/188] [MH2] Implemented Aeve, Progenitor Ooze (#7850) * [MH2] Implemented Aeve, Progenitor Ooze * [MH2] Aeve, Progenitor Ooze - Made requested changes --- .../src/mage/cards/a/AeveProgenitorOoze.java | 90 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 91 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AeveProgenitorOoze.java diff --git a/Mage.Sets/src/mage/cards/a/AeveProgenitorOoze.java b/Mage.Sets/src/mage/cards/a/AeveProgenitorOoze.java new file mode 100644 index 00000000000..4afd352c443 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AeveProgenitorOoze.java @@ -0,0 +1,90 @@ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.*; +import mage.abilities.keyword.StormAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.PermanentToken; + +/** + * + * @author weirddan455 + */ +public final class AeveProgenitorOoze extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.OOZE); + + static { + filter.add(AnotherPredicate.instance); + } + + public AeveProgenitorOoze(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}{G}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.OOZE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Storm + this.addAbility(new StormAbility()); + + // Aeve, Progenitor Ooze isn't legendary as long as it's a token. + this.addAbility(new SimpleStaticAbility(new AeveProgenitorOozeNonLegendaryEffect())); + + // Aeve enters the battlefield with a +1/+1 counter on it for each other Ooze you control. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect( + CounterType.P1P1.createInstance(), new PermanentsOnBattlefieldCount(filter), true + ), "with a +1/+1 counter on it for each other Ooze you control" + )); + } + + private AeveProgenitorOoze(final AeveProgenitorOoze card) { + super(card); + } + + @Override + public AeveProgenitorOoze copy() { + return new AeveProgenitorOoze(this); + } +} + +class AeveProgenitorOozeNonLegendaryEffect extends ContinuousEffectImpl { + + public AeveProgenitorOozeNonLegendaryEffect() { + super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); + this.staticText = "{this} isn't legendary as long as it's a token"; + } + + private AeveProgenitorOozeNonLegendaryEffect(final AeveProgenitorOozeNonLegendaryEffect effect) { + super(effect); + } + + @Override + public AeveProgenitorOozeNonLegendaryEffect copy() { + return new AeveProgenitorOozeNonLegendaryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent instanceof PermanentToken) { + permanent.getSuperType().remove(SuperType.LEGENDARY); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 77e6a13ff10..4a8a360cdb3 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -30,6 +30,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Abiding Grace", 1, Rarity.UNCOMMON, mage.cards.a.AbidingGrace.class)); cards.add(new SetCardInfo("Abundant Harvest", 147, Rarity.COMMON, mage.cards.a.AbundantHarvest.class)); cards.add(new SetCardInfo("Aeromoeba", 37, Rarity.COMMON, mage.cards.a.Aeromoeba.class)); + cards.add(new SetCardInfo("Aeve, Progenitor Ooze", 148, Rarity.RARE, mage.cards.a.AeveProgenitorOoze.class)); cards.add(new SetCardInfo("Arcbound Javelineer", 2, Rarity.UNCOMMON, mage.cards.a.ArcboundJavelineer.class)); cards.add(new SetCardInfo("Arcbound Mouser", 3, Rarity.COMMON, mage.cards.a.ArcboundMouser.class)); cards.add(new SetCardInfo("Arcbound Shikari", 184, Rarity.UNCOMMON, mage.cards.a.ArcboundShikari.class)); From 7e09a973c6072b8e79114ce79830a7479dffd587 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 19:11:10 -0400 Subject: [PATCH 060/188] [MH2] Implemented Ornithopter of Paradise --- .../mage/cards/o/OrnithopterOfParadise.java | 40 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + Utils/mtg-cards-data.txt | 1 + 3 files changed, 42 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OrnithopterOfParadise.java diff --git a/Mage.Sets/src/mage/cards/o/OrnithopterOfParadise.java b/Mage.Sets/src/mage/cards/o/OrnithopterOfParadise.java new file mode 100644 index 00000000000..fd045c2c3c4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OrnithopterOfParadise.java @@ -0,0 +1,40 @@ +package mage.cards.o; + +import mage.MageInt; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class OrnithopterOfParadise extends CardImpl { + + public OrnithopterOfParadise(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); + + this.subtype.add(SubType.THOPTER); + this.power = new MageInt(0); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {T}: Add one mana of any color. + this.addAbility(new AnyColorManaAbility()); + } + + private OrnithopterOfParadise(final OrnithopterOfParadise card) { + super(card); + } + + @Override + public OrnithopterOfParadise copy() { + return new OrnithopterOfParadise(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 4a8a360cdb3..4b62fd10a5c 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -132,6 +132,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Nevinyrral's Disk", 298, Rarity.RARE, mage.cards.n.NevinyrralsDisk.class)); cards.add(new SetCardInfo("Obsidian Charmaw", 137, Rarity.RARE, mage.cards.o.ObsidianCharmaw.class)); cards.add(new SetCardInfo("Orchard Strider", 169, Rarity.COMMON, mage.cards.o.OrchardStrider.class)); + cards.add(new SetCardInfo("Ornithopter of Paradise", 232, Rarity.COMMON, mage.cards.o.OrnithopterOfParadise.class)); cards.add(new SetCardInfo("Patriarch's Bidding", 275, Rarity.RARE, mage.cards.p.PatriarchsBidding.class)); cards.add(new SetCardInfo("Phantasmal Dreadmaw", 55, Rarity.COMMON, mage.cards.p.PhantasmalDreadmaw.class)); cards.add(new SetCardInfo("Piru, the Volatile", 207, Rarity.RARE, mage.cards.p.PiruTheVolatile.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index f0c0d4936ac..bfcbccf61ae 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -41482,6 +41482,7 @@ Kaldra Compleat|Modern Horizons 2|227|M|{7}|Legendary Artifact - Equipment|||Liv Liquimetal Torque|Modern Horizons 2|228|U|{2}|Artifact|||{T}: Add {C}.${T}: Target nonland permanent becomes an artifact in addition to its other types until end of turn.| Monoskelion|Modern Horizons 2|229|U|{2}|Artifact Creature - Construct|1|1|Monoskelion enters the battlefield with a +1/+1 counter on it.${1}, Remove a +1/+1 counter from Monoskelion: Monoskelion deals 1 damage to any target.| Nettlecyst|Modern Horizons 2|231|R|{3}|Artifact - Equipment|||Living weapon$Equipped creature gets +1/+1 for each artifact and/or enchantment you control.$Equip {2}| +Ornithopter of Paradise|Modern Horizons 2|232|C|{2}|Artifact Creature - Thopter|0|2|Flying${T}: Add one mana of any color.| Sanctuary Raptor|Modern Horizons 2|233|U|{3}|Artifact Creature - Bird|2|1|Flying$Whenever Sanctuary Raptor attacks, if you control three or more tokens, Sanctuary Raptor gets +2/+0 and gains first strike until end of turn.| Scion of Draco|Modern Horizons 2|234|M|{12}|Artifact Creature - Dragon|4|4|Domain — This spell costs {2} less to cast for each basic land type among lands you control.$Flying$Each creature you control has vigilance if it's white, hexproof if it's blue, lifelink if it's black, first strike if it's red, and trample if it's green.| Steel Dromedary|Modern Horizons 2|237|U|{3}|Artifact Creature - Camel|2|2|Steel Dromedary enters the battlefield tapped with two +1/+1 counters on it.$Steel Dromedary doesn't untap during your untap step if it has a +1/+1 counter on it.$At the beginning of combat on your turn, you may move a +1/+1 counter from Steel Dromedary onto target creature.| From 1326c635f94591ac6c77bebe30815d25f9e69611 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 20:18:03 -0400 Subject: [PATCH 061/188] [MH2] updated spoiler and reprints --- .../src/mage/cards/p/PropheticTitan.java | 2 +- Mage.Sets/src/mage/sets/ModernHorizons2.java | 4 +- Utils/mtg-cards-data.txt | 39 +++++++++++++++---- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Mage.Sets/src/mage/cards/p/PropheticTitan.java b/Mage.Sets/src/mage/cards/p/PropheticTitan.java index 27c1c2e6bcb..91489e77086 100644 --- a/Mage.Sets/src/mage/cards/p/PropheticTitan.java +++ b/Mage.Sets/src/mage/cards/p/PropheticTitan.java @@ -60,7 +60,7 @@ class PropheticTitanTriggeredAbility extends EntersBattlefieldTriggeredAbility { ).setBackInRandomOrder(true).setText("look at the top four cards of your library. " + "Put one of them into your hand and the rest on the bottom of your library in a random order"))); this.getModes().setChooseText( - "choose one. If there are four or more card types among cards in your graveyard, choose both." + "choose one. If there are four or more card types among cards in your graveyard, choose both instead." ); this.addHint(CardTypesInGraveyardHint.YOU); } diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 4b62fd10a5c..dbb383e3f05 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -100,7 +100,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Grief", 87, Rarity.MYTHIC, mage.cards.g.Grief.class)); cards.add(new SetCardInfo("Harmonic Prodigy", 132, Rarity.RARE, mage.cards.h.HarmonicProdigy.class)); cards.add(new SetCardInfo("Herd Baloth", 165, Rarity.UNCOMMON, mage.cards.h.HerdBaloth.class)); - cards.add(new SetCardInfo("Hunting Pack", 284, Rarity.COMMON, mage.cards.h.HuntingPack.class)); + cards.add(new SetCardInfo("Hunting Pack", 284, Rarity.UNCOMMON, mage.cards.h.HuntingPack.class)); cards.add(new SetCardInfo("Ignoble Hierarch", 166, Rarity.RARE, mage.cards.i.IgnobleHierarch.class)); cards.add(new SetCardInfo("Imperial Recruiter", 281, Rarity.MYTHIC, mage.cards.i.ImperialRecruiter.class)); cards.add(new SetCardInfo("Island", 483, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); @@ -169,7 +169,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Skophos Reaver", 140, Rarity.COMMON, mage.cards.s.SkophosReaver.class)); cards.add(new SetCardInfo("Slag Strider", 141, Rarity.UNCOMMON, mage.cards.s.SlagStrider.class)); cards.add(new SetCardInfo("Slagwoods Bridge", 256, Rarity.COMMON, mage.cards.s.SlagwoodsBridge.class)); - cards.add(new SetCardInfo("Sol Talisman", 472, Rarity.RARE, mage.cards.s.SolTalisman.class)); + cards.add(new SetCardInfo("Sol Talisman", 236, Rarity.RARE, mage.cards.s.SolTalisman.class)); cards.add(new SetCardInfo("Solitary Confinement", 265, Rarity.RARE, mage.cards.s.SolitaryConfinement.class)); cards.add(new SetCardInfo("Solitude", 32, Rarity.MYTHIC, mage.cards.s.Solitude.class)); cards.add(new SetCardInfo("Soul Snare", 266, Rarity.UNCOMMON, mage.cards.s.SoulSnare.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index bfcbccf61ae..c0212adc11a 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -41334,8 +41334,10 @@ Swamp|Adventures in the Forgotten Realms|273|C||Basic Land - Swamp|||({T}: Add { Mountain|Adventures in the Forgotten Realms|277|C||Basic Land - Mountain|||({T}: Add {R}.)| Forest|Adventures in the Forgotten Realms|281|C||Basic Land - Forest|||({T}: Add {G}.)| Abiding Grace|Modern Horizons 2|1|U|{2}{W}|Enchantment|||At the beginning of your end step, choose one —$• You gain 1 life.$• Return target creature card with mana value 1 from your graveyard to the battlefield.| -Archbound Javelineer|Modern Horizons 2|2|U|{W}|Artifact Creature - Soldier|0|1|{T}, Remove X +1/+1 counters from Archbound Javelineer: It deals X damage to target attacking or blocking creature.$Modular 1| +Arcbound Javelineer|Modern Horizons 2|2|U|{W}|Artifact Creature - Soldier|0|1|{T}, Remove X +1/+1 counters from Arcbound Javelineer: It deals X damage to target attacking or blocking creature.$Modular 1| Arcbound Mouser|Modern Horizons 2|3|C|{W}|Artifact Creature - Cat|0|0|Lifelink$Modular 1| +Blacksmith's Skill|Modern Horizons 2|6|C|{W}|Instant|||Target permanent gains hexproof and indestructible until end of turn. If it's an artifact creature, it gets +2/+2 until end of turn.| +Blossoming Calm|Modern Horizons 2|7|U|{W}|Instant|||You gain hexproof until your next turn. You gain 2 life.$Rebound| Break Ties|Modern Horizons 2|8|C|{2}{W}|Instant|||Choose one —$• Destroy target artifact.$• Destroy target enchantment.$• Exile target card from a graveyard.$Reinforce 1—{W}| Constable of the Realm|Modern Horizons 2|10|U|{4}{W}|Creature - Giant Soldier|3|3|Renown 2$Whenever one or more +1/+1 counters are put on Constable of the Realm, exile up to one other target nonland permanent until Constable of the Realm leaves the battlefield.| Esper Sentinel|Modern Horizons 2|12|R|{W}|Artifact Creature - Human Soldier|1|1|Whenever an opponent casts their first noncreature spell each turn, draw a card unless that player pays {X}, where X is Esper Sentinel's power.| @@ -41345,20 +41347,26 @@ Late to Dinner|Modern Horizons 2|19|C|{3}{W}|Sorcery|||Return target creature ca Out of Time|Modern Horizons 2|23|R|{1}{W}{W}|Enchantment|||When Out of Time enters the battlefield, untap all creatures, then phase them out until Out of Time leaves the battlefield. Put a time counter on Out of Time for each creature phased out this way.$Vanishing| Prismatic Ending|Modern Horizons 2|25|U|{X}{W}|Sorcery|||Converge — Exile target nonland permanent if its mana value is less than or equal to the number of colors of mana spent to cast this spell.| Sanctifier en-Vec|Modern Horizons 2|27|R|{W}{W}|Creature - Human Cleric|2|2|Protection from black and from red$When Sanctifier en-Vec enters the battlefield, exile all cards that are black and red from all graveyards.$If a black or red permanent, spell, or card not on the battlefield would be put into a graveyard, exile it instead.| +Search the Premises|Modern Horizons 2|29|R|{3}{W}|Enchantment|||Whenever a creature attacks you or a planeswalker you control, investigate.| Serra's Emissary|Modern Horizons 2|30|M|{4}{W}{W}{W}|Creature - Angel|7|7|Flying$As Serra's Emissary enters the battlefield, choose a card type.$You and creatures you control have protection from the chosen card type.| Skyblade's Boon|Modern Horizons 2|31|U|{1}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +1/+1 and has flying.${2}{W}: Return Skyblade's Boon to its owner's hand. Activate only if Skyblade's Boon is on the battlefield or in your graveyard.| Solitude|Modern Horizons 2|32|M|{3}{W}{W}|Creature - Elemental Incarnation|3|2|Flash$Lifelink$When Solitude enters the battlefield, exile up to one other target creature. That creature's controller gains life equal to its power.$Evoke—Exile a white card from your hand.| Thraben Watcher|Modern Horizons 2|34|U|{2}{W}{W}|Creature - Angel|2|2|Flying, vigilance$Other nontoken creatures you control get +1/+1 and have vigilance.| Timeless Dragon|Modern Horizons 2|35|R|{3}{W}{W}|Creature - Dragon|5|5|Flying$Plainscycling {2}$Eternalize {2}{W}{W}| +Unbounded Potential|Modern Horizons 2|36|C|{1}{W}|Instant|||Choose one —$• Put a +1/+1 counter on each of up to two target creatures.$• Proliferate.$Entwine {3}{W}| Aeromoeba|Modern Horizons 2|37|C|{3}{U}|Creature - Elemental Beast|2|4|Flying$Discard a card: Switch Aeromoeba's power and toughness until end of turn.| Dress Down|Modern Horizons 2|39|R|{1}{U}|Enchantment|||Flash$When Dress Down enters the battlefield, draw a card.$Creatures lose all abilities.$At the beginning of the end step, sacrifice Dress Down.| Filigree Attendant|Modern Horizons 2|41|U|{2}{U}{U}|Artifact Creature - Homunculus|*|3|Flying$Filigree Attendant's power is equal to the number of artifacts you control.| +Floodhound|Modern Horizons 2|42|C|{U}|Creature - Elemental Dog|1|2|{3}, {T}: Investigate.| Fractured Sanity|Modern Horizons 2|44|R|{U}{U}{U}|Sorcery|||Each opponent mills fourteen cards.$Cycling {1}{U}$When you cycle Fractured Sanity, each opponent mills four cards.| Ghost-Lit Drifter|Modern Horizons 2|45|U|{2}{U}|Creature - Spirit|2|2|Flying${2}{U}: Another target creature gains flying until end of turn.$Channel — {X}{U}, Discard Ghost-Lit Drifter: X target creatures gain flying until end of turn.| +Hard Evidence|Modern Horizons 2|46|C|{U}|Sorcery|||Create a 0/3 blue Crab creature token.$Investigate.| +Inevitable Betrayal|Modern Horizons 2|47|R||Sorcery|||Suspend 3—{1}{U}{U}$Search target opponent's library for a creature card and put that card onto the battlefield under your control. Then that player shuffles.| Junk Winder|Modern Horizons 2|48|U|{5}{U}{U}|Creature - Serpent|5|6|Affinity for tokens$Whenever a token enters the battlefield under your control, tap target nonland permanent an opponent controls. It doesn't untap during its controller's next untap step.| Lose Focus|Modern Horizons 2|49|C|{1}{U}|Instant|||Replicate {U}$Counter target spell unless its controller pays {2}.| Lucid Dreams|Modern Horizons 2|50|U|{3}{U}{U}|Sorcery|||Draw X cards, where X is the number of card types among cards in your graveyard.| Mental Journey|Modern Horizons 2|51|C|{4}{U}{U}|Instant|||Draw three cards.$Basic landcycling {1}{U}| +Murktide Regent|Modern Horizons 2|52|M|{5}{U}{U}|Creature - Dragon|3|3|Delve$Flying$Murktide Regent enters the battlefield with a +1/+1 counter on it for each instant or sorcery card exiled with it.$Whenever an instant or sorcery card leaves your graveyard, put a +1/+1 counter on Murktide Regent.| Mystic Redaction|Modern Horizons 2|53|U|{2}{U}|Enchantment|||At the beginning of your upkeep, scry 1.$Whenever you discard a card, each opponent mills two cards.| Phantasmal Dreadmaw|Modern Horizons 2|55|C|{2}{U}{U}|Creature - Dinosaur Illusion|6|6|Trample$When Phantasmal Dreadmaw becomes the target of a spell or ability, sacrifice it.| Raving Visionary|Modern Horizons 2|56|U|{1}{U}|Creature - Merfolk Wizard|1|1|{U}, {T}: Draw a card, then discard a card.$Delirium — {2}{U}, {T}: Draw a card. Activate only if there are four or more card types among cards in your graveyard.| @@ -41368,6 +41376,7 @@ Scuttletide|Modern Horizons 2|61|U|{1}{U}|Enchantment|||{1}, Discard a card: Cre Shattered Ego|Modern Horizons 2|62|C|{U}|Enchantment - Aura|||Enchant creature$Enchanted creature gets -3/-0.${3}{U}{U}: Put enchanted creature into its owner's library third from the top.| So Shiny|Modern Horizons 2|63|C|{2}{U}|Enchantment - Aura|||Enchant creature$When So Shiny enters the battlefield, if you control a token, tap enchanted creature, then scry 2.$Enchanted creature doesn't untap during its controller's untap step.| Specimen Collector|Modern Horizons 2|64|U|{4}{U}|Creature - Vedalken Wizard|2|1|When Specimen Collector enters the battlefield, create a 1/1 green Squirrel creature token and a 0/3 blue Crab creature token.$When Specimen Collector dies, create a token that's a copy of target token you control.| +Steelfin Whale|Modern Horizons 2|65|C|{5}{U}|Creature - Whale|3|4|Affinity for artifacts$Whenever an artifact enters the battlefield under your control, untap Steelfin Whale.| Step Through|Modern Horizons 2|66|C|{3}{U}{U}|Sorcery|||Return two target creatures to their owners' hands.$Wizardcycling {2}| Subtlety|Modern Horizons 2|67|M|{2}{U}{U}|Creature - Elemental Incarnation|3|3|Flash$Flying$When Subtlety enters the battlefield, choose up to one target creature spell or planeswalker spell. Its owner puts it on the top or bottom of their library.$Evoke—Exile a blue card from your hand.| Suspend|Modern Horizons 2|68|R|{U}|Instant|||Exile target creature and put two time counters on it. If it doesn't have suspend, it gains suspend.| @@ -41379,19 +41388,23 @@ Vedalken Infiltrator|Modern Horizons 2|73|U|{1}{U}|Creature - Vedalken Rogue|1|3 Archfiend of Sorrows|Modern Horizons 2|74|U|{5}{B}{B}|Creature - Demon|4|5|Flying$When Archfiend of Sorrows enters the battlefield, creatures your opponents control get -2/-2 until end of turn.$Unearth {3}{B}{B}| Archon of Cruelty|Modern Horizons 2|75|M|{6}{B}{B}|Creature - Archon|6|6|Flying$Whenever Archon of Cruelty enters the battlefield or attacks, target opponent sacrifices a creature or planeswalker, discards a card, and loses 3 life. You draw a card and gain 3 life.| Bone Shards|Modern Horizons 2|76|C|{B}|Sorcery|||As an additional cost to cast this spell, sacrifice a creature or discard a card.$Destroy target creature or planeswalker.| +Break the Ice|Modern Horizons 2|77|U|{B}{B}|Sorcery|||Destroy target land that is snow or could produce {C}.$Overload {4}{B}{B}| Clattering Augur|Modern Horizons 2|79|U|{1}{B}|Creature - Skeleton Shaman|1|1|Clattering Augur can't block.$When Clattering Augur enters the battlefield, you draw a card and you lose 1 life.${2}{B}{B}: Return Clattering Augur from your graveyard to your hand.| Damn|Modern Horizons 2|80|R|{B}{B}|Sorcery|||Destroy target creature. A creature destroyed this way can't be regenerated.$Overload {2}{W}{W}| Dauthi Voidwalker|Modern Horizons 2|81|R|{B}{B}|Creature - Dauthi Rogue|3|2|Shadow$If a card would be put into an opponent's graveyard from anywhere, instead exile it with a void counter on it.${T}, Sacrifice Dauthi Voidwalker: Choose an exiled card an opponent owns with a void counter on it. You may play it this turn without paying its mana cost.| Discerning Taste|Modern Horizons 2|82|C|{2}{B}|Sorcery|||Look at the top four cards of your library. Put one of them into your hand and the rest into your graveyard. You gain life equal to the greatest power among creature cards put into your graveyard this way.| +Echoing Return|Modern Horizons 2|83|C|{B}|Sorcery|||Return target creature card and all other cards with the same name as that card from your graveyard to your hand.| Feast of Sanity|Modern Horizons 2|84|U|{3}{B}|Enchantment|||Whenever you discard a card, Feast of Sanity deals 1 damage to any target and you gain 1 life.| Flay Essence|Modern Horizons 2|85|U|{1}{B}{B}|Sorcery|||Exile target creature or planeswalker. You gain life equal to the number of counters on it.| Grief|Modern Horizons 2|87|M|{2}{B}{B}|Creature - Elemental Incarnation|3|2|Menace$When Grief enters the battlefield, target opponent reveals their hand. You choose a nonland card from it. That player discards that card.$Evoke—Exile a black card from your hand.| Kitchen Imp|Modern Horizons 2|89|C|{3}{B}|Creature - Imp|2|2|Flying, haste$Madness {B}| Legion Vanguard|Modern Horizons 2|90|U|{1}{B}|Creature - Vampire Soldier|2|2|{1}, Sacrifice another creature: Legion Vanguard explores.| +Magus of the Bridge|Modern Horizons 2|92|R|{B}{B}{B}|Creature - Human Wizard|4|4|Whenever a nontoken creature is put into your graveyard from the battlefield, create a 2/2 black Zombie creature token.$When a creature is put into an opponent's graveyard from the battlefield, exile Magus of the Bridge.| Necromancer's Familiar|Modern Horizons 2|94|U|{3}{B}|Creature - Bird Spirit|3|1|Flying$Hellbent — Necromancer's Familiar has lifelink as long as you have no cards in hand.${B}, Discard a card: Necromancer's Familiar gains indestructible until end of turn. Tap it.| Persist|Modern Horizons 2|96|R|{1}{B}|Sorcery|||Return target nonlegendary creature card from your graveyard to the battlefield with a -1/-1 counter on it.| Profane Tutor|Modern Horizons 2|97|R||Sorcery|||Suspend 2—{1}{B}$Search your library for a card, put that card into your hand, then shuffle.| Radiant Epicure|Modern Horizons 2|98|U|{4}{B}|Creature - Vampire Wizard|5|5|Converge — When Radiant Epicure enters the battlefield, each opponent loses X life and you gain X life, where X is the number of colors of mana spent to cast this spell.| +Sinister Starfish|Modern Horizons 2|99|C|{1}{B}|Creature - Starfish|0|3|{T}: Surveil 1.| Sudden Edict|Modern Horizons 2|100|U|{1}{B}|Instant|||Split second$Target player sacrifices a creature.| Tourach, Dread Cantor|Modern Horizons 2|102|M|{1}{B}|Legendary Creature - Human Cleric|2|1|Kicker {B}{B}$Protection from white$Whenever an opponent discards a card, put a +1/+1 counter on Tourach, Dread Cantor.$When Tourach enters the battelfield, if it was kicked, target opponent discards two cards at random.| Tourach's Canticle|Modern Horizons 2|103|C|{3}{B}|Sorcery|||Target opponent reveals their hand. You choose a card from it. That player discards that card, then discards a card at random.| @@ -41399,18 +41412,21 @@ Underworld Hermit|Modern Horizons 2|105|U|{4}{B}{B}|Creature - Human Peasant|3|3 Unmarked Grave|Modern Horizons 2|106|R|{1}{B}|Sorcery|||Search your library for a nonlegendary card, put that card into your graveyard, then shuffle.| World-Weary|Modern Horizons 2|109|C|{3}{B}{B}|Enchantment - Aura|||Enchant creature$Enchanted creature gets -4/-4.$Basic landcycling {1}{B}| Young Necromancer|Modern Horizons 2|110|U|{4}{B}|Creature - Human Warlock|2|3|When Young Necromancer enters the battlefield, you may exile two cards from your graveyard. When you do, return target creature card from your graveyard to the battlefield.| +Arcbound Slasher|Modern Horizons 2|111|C|{4}{R}|Artifact Creature - Cat|0|0|Modular 4$Riot| Arcbound Whelp|Modern Horizons 2|113|U|{3}{R}|Artifact Creature - Dragon|0|0|Flying${R}: Arcbound Whelp gets +1/+0 until end of turn.$Modular 2| Battle Plan|Modern Horizons 2|114|C|{3}{R}|Enchantment|||At the beginning of combat on your turn, target creature you control gets +2/+0 until end of turn.$Basic landcycling {1}{R}| Blazing Rootwalla|Modern Horizons 2|115|U|{R}|Creature - Lizard|1|1|{R}: Blazing Rootwalla gets +2/+0 until end of turn. Activate only once each turn.$Madness {0}| -Bloodbraid Marauder|Modern Horizons 2|116|R|{1}{R}|Creature - Human Beserker|3|1|Bloodbraid Marauder can't block.$Delirium — This spell has cascade as long as there are four or more card types amont cards in your graveyard.| +Bloodbraid Marauder|Modern Horizons 2|116|R|{1}{R}|Creature - Human Berserker|3|1|Bloodbraid Marauder can't block.$Delirium — This spell has cascade as long as there are four or more card types among cards in your graveyard.| Breya's Apprentice|Modern Horizons 2|117|R|{2}{R}|Artifact Creature - Human Artificer|2|3|When Breya's Apprentice enters the battlefield, create a 1/1 colorless Thopter artifact creature token with flying.${T}, Sacrifice an artifact: Choose one —$• Exile the top card of your library. Until the end of your next turn, you may play that card.$• Target creature gets +2/+0 until end of turn.| Calibrated Blast|Modern Horizons 2|118|R|{2}{R}|Instant|||Reveal cards from the top of your library until you reveal a nonland card. Put the revealed cards on the bottom of your library in a random order. When you reveal a nonland card this way, Calibrated Blast deals damage equal to that card's mana value to any target.$Flashback {3}{R}{R}| Captain Ripley Vance|Modern Horizons 2|119|U|{2}{R}|Legendary Creature - Human Pirate|3|2|Whenever you cast your third spell each turn, put a +1/+1 counter on Captain Ripley Vance, then it deals damage equal to its power to any target.| Chef's Kiss|Modern Horizons 2|120|R|{1}{R}{R}|Instant|||Gain control of target spell that targets only a single permanent or player. Copy it, then reselect the targets at random for the spell and the copy. The new targets can't be you or a permanent you control.| Dragon's Rage Channeler|Modern Horizons 2|121|U|{R}|Creature - Human Shaman|1|1|Whenever you cast a noncreature spell, surveil 1.$Delirium — As long as there are four or more card types among cards in your graveyard, Dragon's Rage Channeler gets +2/+2, has flying, and attacks each combat if able.| +Faithless Salvaging|Modern Horizons 2|122|C|{1}{R}|Instant|||Discard a card, then draw a card.$Rebound| Fast // Furious|Modern Horizons 2|123|U|{2}{R}|Instant|||Discard a card, then draw two cards.$Furious${3}{R}{R}$Sorcery$Furious deals 3 damage to each creature without flying.| Flame Blitz|Modern Horizons 2|124|U|{R}|Enchantment|||At the beginning of your end step, Flame Blitz deals 5 damage to each planeswalker.$Cycling {2}| Flametongue Yearling|Modern Horizons 2|125|U|{R}{R}|Creature - Kavu|2|1|Multikicker {2}$Flametongue Yearling enters the battlefield with a +1/+1 counter on it for each time it was kicked.$When Flametongue Yearling enters the battlefield, it deals damage equal to its power to target creature.| +Fury|Modern Horizons 2|126|M|{3}{R}{R}|Creature - Elemental Incarnation|3|3|Double strike$When Fury enters the battlefield, it deals 4 damage divided as you choose among any number of target creatures and/or planeswalkers.$Evoke—Exile a red card from your hand.| Galvanic Relay|Modern Horizons 2|127|C|{2}{R}|Sorcery|||Exile the top card of your library. During your next turn, you may play that card.$Storm| Glimpse of Tomorrow|Modern Horizons 2|129|R||Sorcery|||Suspend 3—{R}{R}$Shuffle all permanents you own into your library, then reveal that many cards from the top of your library. Put all non-Aura permanent cards revealed this way onto the battlefield, then do the same for Aura cards, then put the rest on the bottom of your library in a random order.| Harmonic Prodigy|Modern Horizons 2|132|R|{1}{R}|Creature - Human Wizard|1|3|Prowess$If an ability of a Shaman or another Wizard you control triggers, that ability triggers an additional time.| @@ -41428,7 +41444,8 @@ Chitterspitter|Modern Horizons 2|153|R|{2}{G}|Artifact|||At the beginning of you Endurance|Modern Horizons 2|157|M|{1}{G}{G}|Creature - Elemental Incarnation|3|4|Flash$Reach$When Endurance enters the battlefield, up to one target player puts all the cards from their graveyard on the bottom of their library in a random order.$Evoke—Exile a green card from your hand.| Fae Offering|Modern Horizons 2|158|U|{2}{G}|Enchantment|||At the beginning of each end step, if you've cast both a creature spell and a noncreature spell this turn, create a Clue token, a Food token, and a Treasure token.| Foundation Breaker|Modern Horizons 2|160|U|{3}{G}|Creature - Elemental|2|2|When Foundation Breaker enters the battlefield, you may destroy target artifact or enchantment.$Evoke {1}{G}| -Gaea's Will|Modern Horizons 2|162|R||Sorcery|||Suspend 4—{G}$Until end of turn, you may play land cards and cast spells from your graveyard.$If a card would be put into your graveyard from anywhere this turn, exile that card instead.| +Funnel-Web Recluse|Modern Horizons 2|161|C|{4}{G}|Creature - Spider|3|5|Reach$Morbid — When Funnel-Web Recluse enters the battlefield, if a creature died this turn, investigate.| +Gaea's Will|Modern Horizons 2|162|R||Sorcery|||Suspend 4—{G}$Until end of turn, you may play lands and cast spells from your graveyard.$If a card would be put into your graveyard from anywhere this turn, exile that card instead.| Wren's Run Hydra|Modern Horizons 2|163|U|{X}{G}|Creature - Hydra|0|0|Reach$Wren's Run Hydra enters the battlefield with X +1/+1 counters on it.$Reinforce X—{X}{G}{G}| Glinting Creeper|Modern Horizons 2|164|U|{4}{G}|Creature - Plant|0|0|Converge — Glinting Creeper enters the battlefield with two +1/+1 counters on it for each color of mana spent to cast it.$Glinting Creeper can't be blocked by creatures with power 2 or less.| Herd Baloth|Modern Horizons 2|165|U|{3}{G}{G}|Creature - Beast|4|4|Whenever one or more +1/+1 counters are put on Herd Baloth, you may create a 4/4 green Beast creature token.| @@ -41441,14 +41458,16 @@ Scurry Oak|Modern Horizons 2|172|U|{2}{G}|Creature - Treefolk|1|2|Evolve$Wheneve Squirrel Sanctuary|Modern Horizons 2|174|U|{G}|Enchantment|||When Squirrel Sanctuary enters the battlefield, create a 1/1 green Squirrel creature token.$Whenever a nontoken creature you control dies, you may pay {1}. If you do, return Squirrel Sanctuary to its owner's hand.| Squirrel Sovereign|Modern Horizons 2|175|U|{1}{G}|Creature - Squirrel Noble|2|2|Other Squirrels you control get +1/+1.| Sylvan Anthem|Modern Horizons 2|176|R|{G}{G}|Enchantment|||Green creatures you control get +1/+1.$Whenever a green creature enters the battlefield under your control, scry 1.| -Terramorph|Modern Horizons 2|177|U|{3}{G}|Sorcery|||Search your library for a basic land card, put it into the battlefield, then shuffle.$Rebound| +Terramorph|Modern Horizons 2|177|U|{3}{G}|Sorcery|||Search your library for a basic land card, put it onto the battlefield, then shuffle.$Rebound| Thrasta, Tempest's Roar|Modern Horizons 2|178|M|{10}{G}{G}|Legendary Creature - Dinosaur|7|7|This spell costs {3} less to cast for each other spell cast this turn.$Trample, haste$Trample over planeswalkers$Thrasta, Tempest's Roar has hexproof as long as it entered the battlefield this turn.| Timeless Witness|Modern Horizons 2|179|U|{2}{G}{G}|Creature - Human Shaman|2|1|When Timeless Witness enters the battlefield, return target card from your graveyard to your hand.$Eternalize {5}{G}{G}| Tireless Provisioner|Modern Horizons 2|180|U|{2}{G}|Creature - Elf Scout|3|2|Landfall — Whenever a land enters the battelfield under your control, create a Food token or a Treasure token.| Urban Daggertooth|Modern Horizons 2|181|C|{2}{G}{G}|Creature - Dinosaur|4|3|Vigilance$Enrage — Whenever Urban Daggertooth is dealt damage, proliferate.| Verdant Command|Modern Horizons 2|182|R|{1}{G}|Instant|||Choose two —$• Target player creates two tapped 1/1 green Squirrel creature tokens.$• Counter target loyalty ability of a planeswalker.$• Exile target card from a graveyard.$• Target player gains 3 life.| -Arcbound Shikari|Modern Horizons 2|184|U|{1}{R}{W}|Artifact Creature - Cat Soldier|0|0|First Strike$When Arcbound Shikari enters the battlefield, put a +1/+1 counter on each other artifact creature you control.$Modular 2| +Arcbound Shikari|Modern Horizons 2|184|U|{1}{R}{W}|Artifact Creature - Cat Soldier|0|0|First strike$When Arcbound Shikari enters the battlefield, put a +1/+1 counter on each other artifact creature you control.$Modular 2| +Arcus Acolyte|Modern Horizons 2|185|U|{G}{W}|Creature - Human Cleric Archer|2|2|Reach, lifelink$Outlast {G/W}$Each other creature you control without a +1/+1 counter on it has outlast {G/W}.| Asmoranomardicadaistinaculdacar|Modern Horizons 2|186|R||Legendary Creature - Human Wizard|3|3|As long as you've discarded a card this turn, you may pay {B/R} to cast this spell.$When Asmoranomardicadaistinaculdacar enters the battlefield, you may search your library for a card named The Underworld Cookbook, reveal it, put it into your hand, then shuffle.$Sacrifice two Foods: Target creature deals 6 damage to itself.| +Breathless Knight|Modern Horizons 2|187|C|{1}{W}{B}|Creature - Spirit Knight|2|2|Flying, lifelink$Whenever Breathless Knight or another creature enters the battlefield under your control, if that creature entered from a graveyard or you cast it from a graveyard, put a +1/+1 counter on Breathless Knight.| Carth the Lion|Modern Horizons 2|189|R|{2}{B}{G}|Legendary Creature - Human Warrior|3|5|Whenever Carth the Lion enters the battlefield or a planeswalker you control dies, look at the top seven cards of your library. You may reveal a planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.$Planeswalkers' loyalty abilities you activate cost an additional {+1} to activate.| Chrome Courier|Modern Horizons 2|190|C|{1}{W}{U}|Artifact Creature - Thopter|1|1|Flying$When Chrome Courier enters the battlefield, reveal the top two cards of your library. Put one of them into your hand and the other into your graveyard. If you put an artifact card into your hand this way, you gain 3 life.| Combine Chrysalis|Modern Horizons 2|191|U|{G}{U}|Artifact|||Creature tokens you control have flying.${2}{G}{U}, {T}, Sacrifice a token: Create a 4/4 green Beast creature token. Activate only as a sorcery.| @@ -41460,15 +41479,17 @@ General Ferrous Rokiric|Modern Horizons 2|198|R|{1}{R}{W}|Legendary Creature - H Geyadrone Dihada|Modern Horizons 2|199|M|{1}{U}{B}{R}|Legendary Planeswalker - Dihada|4|Protection from permanents with corruption counters on them$+1: Each opponent loses 2 life and you gain 2 life. Put a corruption counter on up to one other target creature or planeswalker.$−3: Gain control of target creature or planeswalker until end of tun. Untap it and put a corruption counter on it. It gains haste until end of turn.$−7: Gain control of each permanent with a corruption counter on it.| Graceful Restoration|Modern Horizons 2|201|U|{3}{W}{B}|Sorcery|||Choose one —$• Return target creature card from your graveyard to the battlefield with an additional +1/+1 counter on it.$• Return up to two target creature cards with power 2 or less from your graveyard to the battlefield.| Grist, the Hunger Tide|Modern Horizons 2|202|M|{1}{B}{G}|Legendary Planeswalker - Grist|3|As long as Grist, the Hunger Tide isn't on the battlefield, it's a 1/1 Insect creature in addition to its other types.$+1: Create a 1/1 black and green Insect creature token, then mill a card. If an Insect card was milled this way, put a loyalty counter on Grist and repeat this process.$−2: You may sacrifice a creature. When you do, destroy target creature or planeswalker.$−5: Each opponent loses life equal to the number of creature cards in your graveyard.| +Lazotep Chancellor|Modern Horizons 2|203|U|{U}{B}|Creature - Zombie Wizard|1|3|Whenever you discard a card, you may pay {1}. If you do, amass 2.| Lonis, Cryptozoologist|Modern Horizons 2|204|R|{G}{U}|Legendary Creature - Snake Elf Scout|1|2|Whenever another nontoken creature enters the battlefield under your control, investigate.${T}, Sacrifice X Clues: Target opponent reveals the top X cards of their library. You may put a nonland permanent card with mana value X or less from among them onto the battlefield under your control. That player puts the rest on the bottom of their library in a random order.| Master of Death|Modern Horizons 2|205|R|{1}{U}{B}|Creature - Zombie Wizard|3|1|When Master of Death enters the battlefield, surveil 2.$At the beginning of your upkeep, if Master of Death is in your graveyard, you may pay 1 life. If you do, return it to your hand.| Moderation|Modern Horizons 2|206|R|{1}{W}{U}|Enchantment|||You can't cast more than one spell each turn.$Whenever you cast a spell, draw a card.| Piru, the Volatile|Modern Horizons 2|207|R|{2}{R}{R}{W}{W}{B}{B}|Legendary Creature - Elder Dragon|7|7|Flying, lifelink$At the beginning of your upkeep, sacrifice Piru, the Volatile unless you pay {R}{W}{B}.$When Piru dies, it deals 7 damage to each nonlegendary creature.| Priest of Fell Rites|Modern Horizons 2|208|R|{W}{B}|Creature - Human Warlock|2|2|{T}, Pay 3 life, Sacrifice Priest of Fell Rites: Return target creature card from your graveyard to the battlefield. Activate only as a sorcery.$Unearth {3}{W}{B}| -Prophetic Titan|Modern Horizons 2|209|U|{4}{U}{R}|Creature - Giant Wizard|4|4|Delirium — When Prophetic Titan enters the battlefield, choose one. If there are four or more card types among cards in your graveyard, choose both.$• Prophetic Titan deals 4 damage to any target.$• Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in a random order.| +Prophetic Titan|Modern Horizons 2|209|U|{4}{U}{R}|Creature - Giant Wizard|4|4|Delirium — When Prophetic Titan enters the battlefield, choose one. If there are four or more card types among cards in your graveyard, choose both instead.$• Prophetic Titan deals 4 damage to any target.$• Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in a random order.| Rakdos Headliner|Modern Horizons 2|210|U|{B}{R}|Creature - Devil|3|3|Haste$Echo—Discard a card.| Ravenous Squirrel|Modern Horizons 2|211|U|{B/G}|Creature - Squirrel|1|1|Whenever you sacrifice an artifact or creature, put a +1/+1 counter on Ravenous Squirrel.${1}{B}{G}, Sacrifice an artifact or creature: You gain 1 life and draw a card.| Road // Ruin|Modern Horizons 2|212|U|{2}{G}|Instant|||Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.$Ruin${1}{R}{R}$Sorcery$Aftermath$Ruin deals damage to target creature equal to the number of lands you control.| +Sythis, Harvest's Hand|Modern Horizons 2|214|R|{G}{W}|Legendary Enchantment Creature - Nymph|1|2|Whenever you cast an enchantment spell, you gain 1 life and draw a card.| Territorial Kavu|Modern Horizons 2|216|R|{R}{G}|Creature - Kavu|*|*|Domain — Territorial Kavu's power and toughness are each equal to the number of basic land types among lands you control.$Whenever Territorial Kavu attacks, choose one —$• Discard a card. If you do, draw a card.$• Exile up to one target card from a graveyard.| Yusri, Fortune's Flame|Modern Horizons 2|218|R|{1}{U}{R}|Legendary Creature - Efreet|2|3|Flying$Whenever Yusri, Fortune's Flame attacks, choose a number between 1 and 5. Flip that many coins. For each flip you win, draw a card. For each flip you lose, Yursi deals 2 damage to you. If you won five flips this way, you may cast spells from your hand this turn without paying their mana costs.| Academy Manufactor|Modern Horizons 2|219|R|{3}|Artifact Creature - Assembly-Worker|1|3|If you would create a Clue, Food, or Treasure token, instead create one of each.| @@ -41485,6 +41506,7 @@ Nettlecyst|Modern Horizons 2|231|R|{3}|Artifact - Equipment|||Living weapon$Equi Ornithopter of Paradise|Modern Horizons 2|232|C|{2}|Artifact Creature - Thopter|0|2|Flying${T}: Add one mana of any color.| Sanctuary Raptor|Modern Horizons 2|233|U|{3}|Artifact Creature - Bird|2|1|Flying$Whenever Sanctuary Raptor attacks, if you control three or more tokens, Sanctuary Raptor gets +2/+0 and gains first strike until end of turn.| Scion of Draco|Modern Horizons 2|234|M|{12}|Artifact Creature - Dragon|4|4|Domain — This spell costs {2} less to cast for each basic land type among lands you control.$Flying$Each creature you control has vigilance if it's white, hexproof if it's blue, lifelink if it's black, first strike if it's red, and trample if it's green.| +Sol Talisman|Modern Horizons 2|236|R||Artifact|||Suspend 3—{1}${T}: Add {C}{C}.| Steel Dromedary|Modern Horizons 2|237|U|{3}|Artifact Creature - Camel|2|2|Steel Dromedary enters the battlefield tapped with two +1/+1 counters on it.$Steel Dromedary doesn't untap during your untap step if it has a +1/+1 counter on it.$At the beginning of combat on your turn, you may move a +1/+1 counter from Steel Dromedary onto target creature.| Sword of Hearth and Home|Modern Horizons 2|238|M|{3}|Artifact - Equipment|||Equipped creature gets +2/+2 and has protection from green and from white.$Whenever equipped creature deals combat damage to a player, exile up to one target creature you own, then search your library for a basic land card. Put both cards onto the battlefield under your control, then shuffle.$Equip {2}| Tormod's Cryptkeeper|Modern Horizons 2|239|C|{3}|Artifact Creature - Golem|3|2|Vigilance${T}, Sacrifice Tormod's Cryptkeeper: Exile all cards from target player's graveyard.| @@ -41530,7 +41552,7 @@ Gorilla Shaman|Modern Horizons 2|280|U|{R}|Creature - Ape Shaman|1|1|{X}{X}{1}: Imperial Recruiter|Modern Horizons 2|281|M|{2}{R}|Creature - Human Advisor|1|1|When Imperial Recruiter enters the battlefield, search your library for a creature card with power 2 or less, reveal it, put it into your hand, then shuffle.| Mogg Salvage|Modern Horizons 2|282|U|{2}{R}|Instant|||If an opponent controls an Island and you control a Mountain, you may cast this spell without paying its mana cost.$Destroy target artifact.| Enchantress's Presence|Modern Horizons 2|283|R|{2}{G}|Enchantment|||Whenever you cast an enchantment spell, draw a card.| -Hunting Pack|Modern Horizons 2|284|C|{5}{G}{G}|Instant|||Create a 4/4 green Beast creature token.$Storm| +Hunting Pack|Modern Horizons 2|284|U|{5}{G}{G}|Instant|||Create a 4/4 green Beast creature token.$Storm| Quirion Ranger|Modern Horizons 2|285|U|{G}|Creature - Elf|1|1|Return a Forest you control to its owner's hand: Untap target creature. Activate only once each turn.| Squirrel Mob|Modern Horizons 2|286|R|{1}{G}{G}|Creature - Squirrel|2|2|Squirrel Mob gets +1/+1 for each other Squirrel on the battlefield.| Titania, Protector of Argoth|Modern Horizons 2|287|M|{3}{G}{G}|Legendary Creature - Elemental|5|3|When Titania, Protector of Argoth enters the battlefield, return target land card from your graveyard to the battlefield.$Whenever a land you control is put into a graveyard from the battlefield, create a 5/3 green Elemental creature token.| @@ -41549,7 +41571,8 @@ Zuran Orb|Modern Horizons 2|300|U|{0}|Artifact|||Sacrifice a land: You gain 2 li Cabal Coffers|Modern Horizons 2|301|M||Land|||{2}, {T}: Add {B} for each Swamp you control.| Mishra's Factory|Modern Horizons 2|302|U||Land|||{T}: Add {C}.${1}: Mishra's Factory becomes a 2/2 Assembly-Worker artifact creature until end of turn. It's still a land.${T}: Target Assembly-Worker creature gets +1/+1 until end of turn.| Riptide Laboratory|Modern Horizons 2|303|R||Land|||{T}: Add {C}.${1}{U}, {T}: Return target Wizard you control to its owner's hand.| -Sol Talisman|Modern Horizons 2|472|R||Artifact|||Suspend 3—{1}${T}: Add {C}{C}.| +Vile Entomber|Modern Horizons 2|403|U|{2}{B}{B}|Creature - Zombie Warlock|2|2|Deathtouch$When Vile Entomber enters the battlefield, search your library for a card, put that card into your graveyard, then shuffle.| +Glimmer Bairn|Modern Horizons 2|413|C|{G}|Creature - Ouphe|1|2|Sacrifice a token: Glimmer Bairn gets +2/+2 until end of turn.| Plains|Modern Horizons 2|481|C||Basic Land - Plains|||({T}: Add {W}.)| Island|Modern Horizons 2|483|C||Basic Land - Island|||({T}: Add {U}.)| Swamp|Modern Horizons 2|485|C||Basic Land - Swamp|||({T}: Add {B}.)| From 3206ce77b448a57e6f01467dc710bd649e714ee0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 20:25:05 -0400 Subject: [PATCH 062/188] [MH2] Implemented Break the Ice --- Mage.Sets/src/mage/cards/b/BreakTheIce.java | 66 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 67 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BreakTheIce.java diff --git a/Mage.Sets/src/mage/cards/b/BreakTheIce.java b/Mage.Sets/src/mage/cards/b/BreakTheIce.java new file mode 100644 index 00000000000..172b63c99da --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BreakTheIce.java @@ -0,0 +1,66 @@ +package mage.cards.b; + +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.OverloadAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ManaType; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.Predicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BreakTheIce extends CardImpl { + + private static final FilterPermanent filter + = new FilterLandPermanent("land that is snow or could produce {C}"); + + static { + filter.add(BreakTheIcePredicate.instance); + } + + public BreakTheIce(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}{B}"); + + // Destroy target land that is snow or could produce {C}. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + + // Overload {4}{B}{B} + this.addAbility(new OverloadAbility(this, new DestroyAllEffect(filter), new ManaCostsImpl<>("{4}{B}{B}"))); + } + + private BreakTheIce(final BreakTheIce card) { + super(card); + } + + @Override + public BreakTheIce copy() { + return new BreakTheIce(this); + } +} + +enum BreakTheIcePredicate implements Predicate { + instance; + + @Override + public boolean apply(Permanent input, Game game) { + return input.isSnow() + || input + .getAbilities() + .getActivatedManaAbilities(Zone.BATTLEFIELD) + .stream() + .anyMatch(ability -> ability.getProducableManaTypes(game).contains(ManaType.COLORLESS)); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index dbb383e3f05..d8471818fe6 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -48,6 +48,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Braids, Cabal Minion", 273, Rarity.RARE, mage.cards.b.BraidsCabalMinion.class)); cards.add(new SetCardInfo("Brainstone", 223, Rarity.UNCOMMON, mage.cards.b.Brainstone.class)); cards.add(new SetCardInfo("Break Ties", 8, Rarity.COMMON, mage.cards.b.BreakTies.class)); + cards.add(new SetCardInfo("Break the Ice", 77, Rarity.UNCOMMON, mage.cards.b.BreakTheIce.class)); cards.add(new SetCardInfo("Breya's Apprentice", 117, Rarity.RARE, mage.cards.b.BreyasApprentice.class)); cards.add(new SetCardInfo("Cabal Coffers", 301, Rarity.MYTHIC, mage.cards.c.CabalCoffers.class)); cards.add(new SetCardInfo("Calibrated Blast", 118, Rarity.RARE, mage.cards.c.CalibratedBlast.class)); From 876aa42b3d127881252dfa9bb1c3f9a35c2ad481 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 20:26:06 -0400 Subject: [PATCH 063/188] [MH2] Implemented Floodhound --- Mage.Sets/src/mage/cards/f/Floodhound.java | 43 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 44 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/Floodhound.java diff --git a/Mage.Sets/src/mage/cards/f/Floodhound.java b/Mage.Sets/src/mage/cards/f/Floodhound.java new file mode 100644 index 00000000000..33a078f594e --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/Floodhound.java @@ -0,0 +1,43 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.keyword.InvestigateEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Floodhound extends CardImpl { + + public Floodhound(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.DOG); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // {3}, {T}: Investigate. + Ability ability = new SimpleActivatedAbility(new InvestigateEffect(), new GenericManaCost(3)); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + private Floodhound(final Floodhound card) { + super(card); + } + + @Override + public Floodhound copy() { + return new Floodhound(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index d8471818fe6..3478ec6b980 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -84,6 +84,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Flame Rift", 278, Rarity.UNCOMMON, mage.cards.f.FlameRift.class)); cards.add(new SetCardInfo("Flametongue Yearling", 125, Rarity.UNCOMMON, mage.cards.f.FlametongueYearling.class)); cards.add(new SetCardInfo("Flay Essence", 85, Rarity.UNCOMMON, mage.cards.f.FlayEssence.class)); + cards.add(new SetCardInfo("Floodhound", 42, Rarity.COMMON, mage.cards.f.Floodhound.class)); cards.add(new SetCardInfo("Forest", 489, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Foundation Breaker", 160, Rarity.UNCOMMON, mage.cards.f.FoundationBreaker.class)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); From 1e70a7436b580dd5075f0854b1b5911bb329069e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 20:27:02 -0400 Subject: [PATCH 064/188] [MH2] Implemented Hard Evidence --- Mage.Sets/src/mage/cards/h/HardEvidence.java | 35 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 36 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HardEvidence.java diff --git a/Mage.Sets/src/mage/cards/h/HardEvidence.java b/Mage.Sets/src/mage/cards/h/HardEvidence.java new file mode 100644 index 00000000000..bfeecec1af6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HardEvidence.java @@ -0,0 +1,35 @@ +package mage.cards.h; + +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.keyword.InvestigateEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.CrabToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HardEvidence extends CardImpl { + + public HardEvidence(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}"); + + // Create a 0/3 blue Crab creature token. + this.getSpellAbility().addEffect(new CreateTokenEffect(new CrabToken())); + + // Investigate. + this.getSpellAbility().addEffect(new InvestigateEffect().concatBy("
")); + } + + private HardEvidence(final HardEvidence card) { + super(card); + } + + @Override + public HardEvidence copy() { + return new HardEvidence(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 3478ec6b980..483821b94d0 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -100,6 +100,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Graceful Restoration", 201, Rarity.UNCOMMON, mage.cards.g.GracefulRestoration.class)); cards.add(new SetCardInfo("Greed", 274, Rarity.UNCOMMON, mage.cards.g.Greed.class)); cards.add(new SetCardInfo("Grief", 87, Rarity.MYTHIC, mage.cards.g.Grief.class)); + cards.add(new SetCardInfo("Hard Evidence", 46, Rarity.COMMON, mage.cards.h.HardEvidence.class)); cards.add(new SetCardInfo("Harmonic Prodigy", 132, Rarity.RARE, mage.cards.h.HarmonicProdigy.class)); cards.add(new SetCardInfo("Herd Baloth", 165, Rarity.UNCOMMON, mage.cards.h.HerdBaloth.class)); cards.add(new SetCardInfo("Hunting Pack", 284, Rarity.UNCOMMON, mage.cards.h.HuntingPack.class)); From 7b508b9fa3b0838ff5bcb1dddf5626553e355d66 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 20:28:28 -0400 Subject: [PATCH 065/188] [MH2] Implemented Faithless Salvaging --- .../src/mage/cards/f/FaithlessSalvaging.java | 36 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 37 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FaithlessSalvaging.java diff --git a/Mage.Sets/src/mage/cards/f/FaithlessSalvaging.java b/Mage.Sets/src/mage/cards/f/FaithlessSalvaging.java new file mode 100644 index 00000000000..eabbdf161bc --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FaithlessSalvaging.java @@ -0,0 +1,36 @@ +package mage.cards.f; + +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.discard.DiscardControllerEffect; +import mage.abilities.keyword.ReboundAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FaithlessSalvaging extends CardImpl { + + public FaithlessSalvaging(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}"); + + // Discard a card, then draw a card. + this.getSpellAbility().addEffect(new DiscardControllerEffect(1)); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy(", then")); + + // Rebound + this.addAbility(new ReboundAbility()); + } + + private FaithlessSalvaging(final FaithlessSalvaging card) { + super(card); + } + + @Override + public FaithlessSalvaging copy() { + return new FaithlessSalvaging(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 483821b94d0..35a645beb2d 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -76,6 +76,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Ethersworn Sphinx", 195, Rarity.UNCOMMON, mage.cards.e.EtherswornSphinx.class)); cards.add(new SetCardInfo("Extruder", 296, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); cards.add(new SetCardInfo("Fae Offering", 158, Rarity.UNCOMMON, mage.cards.f.FaeOffering.class)); + cards.add(new SetCardInfo("Faithless Salvaging", 122, Rarity.COMMON, mage.cards.f.FaithlessSalvaging.class)); cards.add(new SetCardInfo("Fast // Furious", 123, Rarity.UNCOMMON, mage.cards.f.FastFurious.class)); cards.add(new SetCardInfo("Feast of Sanity", 84, Rarity.UNCOMMON, mage.cards.f.FeastOfSanity.class)); cards.add(new SetCardInfo("Filigree Attendant", 41, Rarity.UNCOMMON, mage.cards.f.FiligreeAttendant.class)); From 470e906faa6825b960d11950fe56e066fc537305 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 20:33:00 -0400 Subject: [PATCH 066/188] [MH2] Implemented Arcbound Slasher --- .../src/mage/cards/a/ArcboundSlasher.java | 40 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + Utils/gen-card.pl | 3 ++ Utils/keywords.txt | 1 + 4 files changed, 45 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/ArcboundSlasher.java diff --git a/Mage.Sets/src/mage/cards/a/ArcboundSlasher.java b/Mage.Sets/src/mage/cards/a/ArcboundSlasher.java new file mode 100644 index 00000000000..f7e46f4da31 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArcboundSlasher.java @@ -0,0 +1,40 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.keyword.ModularAbility; +import mage.abilities.keyword.RiotAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ArcboundSlasher extends CardImpl { + + public ArcboundSlasher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}{R}"); + + this.subtype.add(SubType.CAT); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // Modular 4 + this.addAbility(new ModularAbility(this, 4)); + + // Riot + this.addAbility(new RiotAbility()); + } + + private ArcboundSlasher(final ArcboundSlasher card) { + super(card); + } + + @Override + public ArcboundSlasher copy() { + return new ArcboundSlasher(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 35a645beb2d..d84f4a87122 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -34,6 +34,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Arcbound Javelineer", 2, Rarity.UNCOMMON, mage.cards.a.ArcboundJavelineer.class)); cards.add(new SetCardInfo("Arcbound Mouser", 3, Rarity.COMMON, mage.cards.a.ArcboundMouser.class)); cards.add(new SetCardInfo("Arcbound Shikari", 184, Rarity.UNCOMMON, mage.cards.a.ArcboundShikari.class)); + cards.add(new SetCardInfo("Arcbound Slasher", 111, Rarity.COMMON, mage.cards.a.ArcboundSlasher.class)); cards.add(new SetCardInfo("Arcbound Whelp", 113, Rarity.UNCOMMON, mage.cards.a.ArcboundWhelp.class)); cards.add(new SetCardInfo("Archfiend of Sorrows", 74, Rarity.UNCOMMON, mage.cards.a.ArchfiendOfSorrows.class)); cards.add(new SetCardInfo("Archon of Cruelty", 75, Rarity.MYTHIC, mage.cards.a.ArchonOfCruelty.class)); diff --git a/Utils/gen-card.pl b/Utils/gen-card.pl index 582c7ab13bf..eaa8bca4fc1 100755 --- a/Utils/gen-card.pl +++ b/Utils/gen-card.pl @@ -249,6 +249,9 @@ foreach my $ability (@abilities) { } elsif ($keywords{$kw} eq 'number') { $ability =~ m/(\b\d+?\b)/g; $vars{'abilities'} .= "\n this.addAbility(new " . $kw . 'Ability(' . $1 . '));'; + } elsif ($keywords{$kw} eq 'card, number') { + $ability =~ m/(\b\d+?\b)/g; + $vars{'abilities'} .= "\n this.addAbility(new " . $kw . 'Ability(this, ' . $1 . '));'; } elsif ($keywords{$kw} eq 'cost') { $ability =~ m/({.*})/g; $vars{'abilities'} .= "\n this.addAbility(new " . $kw . 'Ability(new ManaCostsImpl<>("' . fixCost($1) . '")));'; diff --git a/Utils/keywords.txt b/Utils/keywords.txt index 16a9dd078ae..78a41c48734 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -65,6 +65,7 @@ Melee|new| Menace|new| Mentor|new| Miracle|cost| +Modular|card, number| Mountaincycling|cost| Mountainwalk|new| Morph|card, cost| From ac6bf3274f29ca3db95c85ec3d1ab3e7bca44b58 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 20:34:16 -0400 Subject: [PATCH 067/188] [MH2] Implemented Sinister Starfish --- .../src/mage/cards/s/SinisterStarfish.java | 38 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 39 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SinisterStarfish.java diff --git a/Mage.Sets/src/mage/cards/s/SinisterStarfish.java b/Mage.Sets/src/mage/cards/s/SinisterStarfish.java new file mode 100644 index 00000000000..c66a927851a --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SinisterStarfish.java @@ -0,0 +1,38 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.keyword.SurveilEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SinisterStarfish extends CardImpl { + + public SinisterStarfish(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add(SubType.STARFISH); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // {T}: Surveil 1. + this.addAbility(new SimpleActivatedAbility(new SurveilEffect(1), new TapSourceCost())); + } + + private SinisterStarfish(final SinisterStarfish card) { + super(card); + } + + @Override + public SinisterStarfish copy() { + return new SinisterStarfish(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index d84f4a87122..e4789cba702 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -170,6 +170,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Shardless Agent", 292, Rarity.RARE, mage.cards.s.ShardlessAgent.class)); cards.add(new SetCardInfo("Shattered Ego", 62, Rarity.COMMON, mage.cards.s.ShatteredEgo.class)); cards.add(new SetCardInfo("Silverbluff Bridge", 255, Rarity.COMMON, mage.cards.s.SilverbluffBridge.class)); + cards.add(new SetCardInfo("Sinister Starfish", 99, Rarity.COMMON, mage.cards.s.SinisterStarfish.class)); cards.add(new SetCardInfo("Skirge Familiar", 276, Rarity.UNCOMMON, mage.cards.s.SkirgeFamiliar.class)); cards.add(new SetCardInfo("Skophos Reaver", 140, Rarity.COMMON, mage.cards.s.SkophosReaver.class)); cards.add(new SetCardInfo("Slag Strider", 141, Rarity.UNCOMMON, mage.cards.s.SlagStrider.class)); From a6eafe4d4acb7c7995164c8187d8bdd0063b04d9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 1 Jun 2021 23:12:15 -0400 Subject: [PATCH 068/188] [MH2] updated spoiler and reprints --- Mage.Sets/src/mage/sets/ModernHorizons2.java | 2 ++ Utils/mtg-cards-data.txt | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index e4789cba702..971864ac055 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -31,6 +31,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Abundant Harvest", 147, Rarity.COMMON, mage.cards.a.AbundantHarvest.class)); cards.add(new SetCardInfo("Aeromoeba", 37, Rarity.COMMON, mage.cards.a.Aeromoeba.class)); cards.add(new SetCardInfo("Aeve, Progenitor Ooze", 148, Rarity.RARE, mage.cards.a.AeveProgenitorOoze.class)); + cards.add(new SetCardInfo("Angelic Curator", 262, Rarity.COMMON, mage.cards.a.AngelicCurator.class)); cards.add(new SetCardInfo("Arcbound Javelineer", 2, Rarity.UNCOMMON, mage.cards.a.ArcboundJavelineer.class)); cards.add(new SetCardInfo("Arcbound Mouser", 3, Rarity.COMMON, mage.cards.a.ArcboundMouser.class)); cards.add(new SetCardInfo("Arcbound Shikari", 184, Rarity.UNCOMMON, mage.cards.a.ArcboundShikari.class)); @@ -138,6 +139,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Obsidian Charmaw", 137, Rarity.RARE, mage.cards.o.ObsidianCharmaw.class)); cards.add(new SetCardInfo("Orchard Strider", 169, Rarity.COMMON, mage.cards.o.OrchardStrider.class)); cards.add(new SetCardInfo("Ornithopter of Paradise", 232, Rarity.COMMON, mage.cards.o.OrnithopterOfParadise.class)); + cards.add(new SetCardInfo("Patchwork Gnomes", 299, Rarity.COMMON, mage.cards.p.PatchworkGnomes.class)); cards.add(new SetCardInfo("Patriarch's Bidding", 275, Rarity.RARE, mage.cards.p.PatriarchsBidding.class)); cards.add(new SetCardInfo("Phantasmal Dreadmaw", 55, Rarity.COMMON, mage.cards.p.PhantasmalDreadmaw.class)); cards.add(new SetCardInfo("Piru, the Volatile", 207, Rarity.RARE, mage.cards.p.PiruTheVolatile.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index c0212adc11a..94593c879e1 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -41336,9 +41336,11 @@ Forest|Adventures in the Forgotten Realms|281|C||Basic Land - Forest|||({T}: Add Abiding Grace|Modern Horizons 2|1|U|{2}{W}|Enchantment|||At the beginning of your end step, choose one —$• You gain 1 life.$• Return target creature card with mana value 1 from your graveyard to the battlefield.| Arcbound Javelineer|Modern Horizons 2|2|U|{W}|Artifact Creature - Soldier|0|1|{T}, Remove X +1/+1 counters from Arcbound Javelineer: It deals X damage to target attacking or blocking creature.$Modular 1| Arcbound Mouser|Modern Horizons 2|3|C|{W}|Artifact Creature - Cat|0|0|Lifelink$Modular 1| +Barbed Spike|Modern Horizons 2|5|U|{1}{W}|Artifact - Equipment|||When Barbed Spike enters the battlefield, create a 1/1 colorless Thopter artifact creature token with flying and attach Barbed Spike to it.$Equipped creature gets +1/+0.$Equip {2}| Blacksmith's Skill|Modern Horizons 2|6|C|{W}|Instant|||Target permanent gains hexproof and indestructible until end of turn. If it's an artifact creature, it gets +2/+2 until end of turn.| Blossoming Calm|Modern Horizons 2|7|U|{W}|Instant|||You gain hexproof until your next turn. You gain 2 life.$Rebound| Break Ties|Modern Horizons 2|8|C|{2}{W}|Instant|||Choose one —$• Destroy target artifact.$• Destroy target enchantment.$• Exile target card from a graveyard.$Reinforce 1—{W}| +Caprichrome|Modern Horizons 2|9|U|{3}{W}|Artifact Creature - Goat|2|2|Flash$Vigilance$Devour artifact 1| Constable of the Realm|Modern Horizons 2|10|U|{4}{W}|Creature - Giant Soldier|3|3|Renown 2$Whenever one or more +1/+1 counters are put on Constable of the Realm, exile up to one other target nonland permanent until Constable of the Realm leaves the battlefield.| Esper Sentinel|Modern Horizons 2|12|R|{W}|Artifact Creature - Human Soldier|1|1|Whenever an opponent casts their first noncreature spell each turn, draw a card unless that player pays {X}, where X is Esper Sentinel's power.| Glorious Enforcer|Modern Horizons 2|14|U|{5}{W}{W}|Creature - Angel|5|5|Flying, lifelink$At the beginning of each combat, if you have more life than an opponent, Glorious Enforcer gains double strike until end of turn.| @@ -41347,6 +41349,7 @@ Late to Dinner|Modern Horizons 2|19|C|{3}{W}|Sorcery|||Return target creature ca Out of Time|Modern Horizons 2|23|R|{1}{W}{W}|Enchantment|||When Out of Time enters the battlefield, untap all creatures, then phase them out until Out of Time leaves the battlefield. Put a time counter on Out of Time for each creature phased out this way.$Vanishing| Prismatic Ending|Modern Horizons 2|25|U|{X}{W}|Sorcery|||Converge — Exile target nonland permanent if its mana value is less than or equal to the number of colors of mana spent to cast this spell.| Sanctifier en-Vec|Modern Horizons 2|27|R|{W}{W}|Creature - Human Cleric|2|2|Protection from black and from red$When Sanctifier en-Vec enters the battlefield, exile all cards that are black and red from all graveyards.$If a black or red permanent, spell, or card not on the battlefield would be put into a graveyard, exile it instead.| +Scour the Desert|Modern Horizons 2|28|U|{3}{W}{W}|Sorcery|||Exile target creature card from your graveyard. Create X 1/1 white Bird creature tokens with flying, where X is the exiled card's toughness.| Search the Premises|Modern Horizons 2|29|R|{3}{W}|Enchantment|||Whenever a creature attacks you or a planeswalker you control, investigate.| Serra's Emissary|Modern Horizons 2|30|M|{4}{W}{W}{W}|Creature - Angel|7|7|Flying$As Serra's Emissary enters the battlefield, choose a card type.$You and creatures you control have protection from the chosen card type.| Skyblade's Boon|Modern Horizons 2|31|U|{1}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +1/+1 and has flying.${2}{W}: Return Skyblade's Boon to its owner's hand. Activate only if Skyblade's Boon is on the battlefield or in your graveyard.| @@ -41430,12 +41433,14 @@ Fury|Modern Horizons 2|126|M|{3}{R}{R}|Creature - Elemental Incarnation|3|3|Doub Galvanic Relay|Modern Horizons 2|127|C|{2}{R}|Sorcery|||Exile the top card of your library. During your next turn, you may play that card.$Storm| Glimpse of Tomorrow|Modern Horizons 2|129|R||Sorcery|||Suspend 3—{R}{R}$Shuffle all permanents you own into your library, then reveal that many cards from the top of your library. Put all non-Aura permanent cards revealed this way onto the battlefield, then do the same for Aura cards, then put the rest on the bottom of your library in a random order.| Harmonic Prodigy|Modern Horizons 2|132|R|{1}{R}|Creature - Human Wizard|1|3|Prowess$If an ability of a Shaman or another Wizard you control triggers, that ability triggers an additional time.| +Kaleidoscorch|Modern Horizons 2|133|U|{1}{R}|Sorcery|||Converge — Kaleidoscorch deals X damage to any target, where X is the number of colors of mana spent to cast this spell.$Flashback {4}{R}| Obsidian Charmaw|Modern Horizons 2|137|R|{3}{R}{R}|Creature - Dragon|4|4|This spell costs {1} less to cast for each land your opponents control that could produce {C}.$Flying$When Obsidian Charmaw enters the battlefield, destroy target nonbasic land an opponent controls.| Ragavan, Nimble Pilferer|Modern Horizons 2|138|M|{R}|Legendary Creature - Monkey Pirate|2|1|Whenever Ragavan, Nimble Pilferer deals combat damage to a player, create a Treasure token and exile the top card of that player's library. Until end of turn, you may cast that card.$Dash {1}{R}| Skophos Reaver|Modern Horizons 2|140|C|{2}{R}|Creature - Minotaur Warrior|2|3|As long as it's your turn, Skophos Reaver gets +2/+0.$Madness {1}{R}| Slag Strider|Modern Horizons 2|141|U|{5}{R}{R}|Creature - Elemental|3|3|Affinity for artifacts${1}, Sacrifice an artifact: Slag Strider deals 1 damage to any target.| Spreading Insurrection|Modern Horizons 2|142|U|{4}{R}|Sorcery|||Gain control of target creature you don't control until end of turn. Untap that creature. It gains haste until end of turn.$Storm| Strike It Rich|Modern Horizons 2|143|U|{R}|Sorcery|||Create a Treasure token.$Flashback {2}{R}| +Tavern Scoundrel|Modern Horizons 2|144|C|{1}{R}|Creature - Human Rogue|1|3|Whenever you win a coin flip, create two Treasure tokens.${1}, {T}, Sacrifice another permanent: Flip a coin.| Abundant Harvest|Modern Horizons 2|147|C|{G}|Sorcery|||Choose land or nonland. Reveal cards from the top of your library until you reveal a card of the chosen kind. Put that card into your hand and the rest on the bottom of your library in a random order.| Aeve, Progenitor Ooze|Modern Horizons 2|148|R|{2}{G}{G}{G}|Legendary Creature - Ooze|2|2|Storm$Aeve, Progenitor Ooze isn't legendary as long as it's a token.$Aeve enters the battlefield with a +1/+1 counter on it for each Ooze you control.| Chatterfang, Squirrel General|Modern Horizons 2|151|M|{2}{G}|Legendary Creature - Squirrel Warrior|3|3|Forestwalk$If one or more tokens would be created under your control, those tokens plus that many 1/1 green Squirrel creature tokens are created instead.${B}, Sacrifice X Squirrels: Target creature gets +X/-X until end of turn.| @@ -41468,6 +41473,7 @@ Arcbound Shikari|Modern Horizons 2|184|U|{1}{R}{W}|Artifact Creature - Cat Soldi Arcus Acolyte|Modern Horizons 2|185|U|{G}{W}|Creature - Human Cleric Archer|2|2|Reach, lifelink$Outlast {G/W}$Each other creature you control without a +1/+1 counter on it has outlast {G/W}.| Asmoranomardicadaistinaculdacar|Modern Horizons 2|186|R||Legendary Creature - Human Wizard|3|3|As long as you've discarded a card this turn, you may pay {B/R} to cast this spell.$When Asmoranomardicadaistinaculdacar enters the battlefield, you may search your library for a card named The Underworld Cookbook, reveal it, put it into your hand, then shuffle.$Sacrifice two Foods: Target creature deals 6 damage to itself.| Breathless Knight|Modern Horizons 2|187|C|{1}{W}{B}|Creature - Spirit Knight|2|2|Flying, lifelink$Whenever Breathless Knight or another creature enters the battlefield under your control, if that creature entered from a graveyard or you cast it from a graveyard, put a +1/+1 counter on Breathless Knight.| +Captured by Lagacs|Modern Horizons 2|188|C|{1}{G}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature can't attack or block.$When Captured by Lagacs enters the battlefield, support 2.| Carth the Lion|Modern Horizons 2|189|R|{2}{B}{G}|Legendary Creature - Human Warrior|3|5|Whenever Carth the Lion enters the battlefield or a planeswalker you control dies, look at the top seven cards of your library. You may reveal a planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.$Planeswalkers' loyalty abilities you activate cost an additional {+1} to activate.| Chrome Courier|Modern Horizons 2|190|C|{1}{W}{U}|Artifact Creature - Thopter|1|1|Flying$When Chrome Courier enters the battlefield, reveal the top two cards of your library. Put one of them into your hand and the other into your graveyard. If you put an artifact card into your hand this way, you gain 3 life.| Combine Chrysalis|Modern Horizons 2|191|U|{G}{U}|Artifact|||Creature tokens you control have flying.${2}{G}{U}, {T}, Sacrifice a token: Create a 4/4 green Beast creature token. Activate only as a sorcery.| @@ -41531,6 +41537,7 @@ Thornglint Bridge|Modern Horizons 2|258|C||Artifact Land|||Thornglint Bridge ent Urza's Saga|Modern Horizons 2|259|R||Enchantment Land - Urza’s Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I — Urza's Saga gains "{T}: Add {C}."$II — Urza's Saga gains "{2}, {T}: Create a 0/0 colorless Construct artifact creature token with 'This creature gets +1/+1 for each artifact you control.'"$III — Search your library for an artifact card with mana cost {0} or {1}, put it onto the battlefield, then shuffle.| Verdant Catacombs|Modern Horizons 2|260|R||Land|||{T}, Pay 1 life, Sacrifice Verdant Catacombs: Search your library for a Swamp or Forest card, put it onto the battlefield, then shuffle.| Yavimaya, Cradle of Growth|Modern Horizons 2|261|R||Legendary Land|||Each land is a Forest in addition to its other land types.| +Angelic Curator|Modern Horizons 2|262|C|{1}{W}|Creature - Angel Spirit|1|1|Flying, protection from artifacts| Karmic Guide|Modern Horizons 2|263|R|{3}{W}{W}|Creature - Angel Spirit|2|2|Flying, protection from black$Echo {3}{W}{W}$When Karmic Guide enters the battlefield, return target creature card from your graveyard to the battlefield.| Seal of Cleansing|Modern Horizons 2|264|U|{1}{W}|Enchantment|||Sacrifice Seal of Cleansing: Destroy target artifact or enchantment.| Solitary Confinement|Modern Horizons 2|265|R|{2}{W}|Enchantment|||At the beginning of your upkeep, sacrifice Solitary Confinement unless you discard a card.$Skip your draw step.$You have shroud.$Prevent all damage that would be dealt to you.| @@ -41567,6 +41574,7 @@ Cursed Totem|Modern Horizons 2|295|R|{2}|Artifact|||Activated abilities of creat Extruder|Modern Horizons 2|296|U|{4}|Artifact Creature - Juggernaut|4|3|Echo {4}$Sacrifice an artifact: Put a +1/+1 counter on target creature.| Millikin|Modern Horizons 2|297|U|{2}|Artifact Creature - Construct|0|1|{T}, Mill a card: Add {C}.| Nevinyrral's Disk|Modern Horizons 2|298|R|{4}|Artifact|||Nevinyrral's Disk enters the battlefield tapped.${1}, {T}: Destroy all artifacts, creatures, and enchantments.| +Patchwork Gnomes|Modern Horizons 2|299|C|{3}|Artifact Creature - Gnome|2|1|Discard a card: Regenerate Patchwork Gnomes.| Zuran Orb|Modern Horizons 2|300|U|{0}|Artifact|||Sacrifice a land: You gain 2 life.| Cabal Coffers|Modern Horizons 2|301|M||Land|||{2}, {T}: Add {B} for each Swamp you control.| Mishra's Factory|Modern Horizons 2|302|U||Land|||{T}: Add {C}.${1}: Mishra's Factory becomes a 2/2 Assembly-Worker artifact creature until end of turn. It's still a land.${T}: Target Assembly-Worker creature gets +1/+1 until end of turn.| From 0a8410950f9e4737e1b54ba8cb64e281603c425f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 07:28:17 -0400 Subject: [PATCH 069/188] [MH2] Implemented Barbed Spike --- Mage.Sets/src/mage/cards/b/BarbedSpike.java | 46 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BarbedSpike.java diff --git a/Mage.Sets/src/mage/cards/b/BarbedSpike.java b/Mage.Sets/src/mage/cards/b/BarbedSpike.java new file mode 100644 index 00000000000..dd91d3419d2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BarbedSpike.java @@ -0,0 +1,46 @@ +package mage.cards.b; + +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.CreateTokenAttachSourceEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.ThopterColorlessToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BarbedSpike extends CardImpl { + + public BarbedSpike(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{W}"); + + this.subtype.add(SubType.EQUIPMENT); + + // When Barbed Spike enters the battlefield, create a 1/1 colorless Thopter artifact creature token with flying and attach Barbed Spike to it. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new CreateTokenAttachSourceEffect(new ThopterColorlessToken()) + )); + + // Equipped creature gets +1/+0. + this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(1, 0))); + + // Equip {2} + this.addAbility(new EquipAbility(1)); + } + + private BarbedSpike(final BarbedSpike card) { + super(card); + } + + @Override + public BarbedSpike copy() { + return new BarbedSpike(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 971864ac055..ca15780140c 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -41,6 +41,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Archon of Cruelty", 75, Rarity.MYTHIC, mage.cards.a.ArchonOfCruelty.class)); cards.add(new SetCardInfo("Arid Mesa", 244, Rarity.RARE, mage.cards.a.AridMesa.class)); cards.add(new SetCardInfo("Asmoranomardicadaistinaculdacar", 186, Rarity.RARE, mage.cards.a.Asmoranomardicadaistinaculdacar.class)); + cards.add(new SetCardInfo("Barbed Spike", 5, Rarity.UNCOMMON, mage.cards.b.BarbedSpike.class)); cards.add(new SetCardInfo("Batterbone", 221, Rarity.UNCOMMON, mage.cards.b.Batterbone.class)); cards.add(new SetCardInfo("Battle Plan", 114, Rarity.COMMON, mage.cards.b.BattlePlan.class)); cards.add(new SetCardInfo("Bloodbraid Marauder", 116, Rarity.RARE, mage.cards.b.BloodbraidMarauder.class)); From 9da4c491f45e93a26008cfd3a612906a437ee4d3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 07:34:06 -0400 Subject: [PATCH 070/188] [MH2] Implemented Arcus Acolyte --- Mage.Sets/src/mage/cards/a/ArcusAcolyte.java | 66 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 67 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/ArcusAcolyte.java diff --git a/Mage.Sets/src/mage/cards/a/ArcusAcolyte.java b/Mage.Sets/src/mage/cards/a/ArcusAcolyte.java new file mode 100644 index 00000000000..0ae973f2d09 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArcusAcolyte.java @@ -0,0 +1,66 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.OutlastAbility; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ArcusAcolyte extends CardImpl { + + private static final FilterPermanent filter + = new FilterControlledCreaturePermanent("creature you control without a +1/+1 counter on it"); + + static { + filter.add(CounterType.P1P1.getPredicate()); + } + + public ArcusAcolyte(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.subtype.add(SubType.ARCHER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // Outlast {G/W} + this.addAbility(new OutlastAbility(new ManaCostsImpl<>("{G/W}"))); + + // Each other creature you control without a +1/+1 counter on it has outlast {G/W}. + this.addAbility(new SimpleStaticAbility(new GainAbilityAllEffect( + new OutlastAbility(new ManaCostsImpl<>("{G/W}")), + Duration.WhileOnBattlefield, filter, true + ))); + } + + private ArcusAcolyte(final ArcusAcolyte card) { + super(card); + } + + @Override + public ArcusAcolyte copy() { + return new ArcusAcolyte(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index ca15780140c..f38b0e5161a 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -39,6 +39,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Arcbound Whelp", 113, Rarity.UNCOMMON, mage.cards.a.ArcboundWhelp.class)); cards.add(new SetCardInfo("Archfiend of Sorrows", 74, Rarity.UNCOMMON, mage.cards.a.ArchfiendOfSorrows.class)); cards.add(new SetCardInfo("Archon of Cruelty", 75, Rarity.MYTHIC, mage.cards.a.ArchonOfCruelty.class)); + cards.add(new SetCardInfo("Arcus Acolyte", 185, Rarity.UNCOMMON, mage.cards.a.ArcusAcolyte.class)); cards.add(new SetCardInfo("Arid Mesa", 244, Rarity.RARE, mage.cards.a.AridMesa.class)); cards.add(new SetCardInfo("Asmoranomardicadaistinaculdacar", 186, Rarity.RARE, mage.cards.a.Asmoranomardicadaistinaculdacar.class)); cards.add(new SetCardInfo("Barbed Spike", 5, Rarity.UNCOMMON, mage.cards.b.BarbedSpike.class)); From 9886dbb442df38e3ae951be4006be1477935e17c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 07:41:30 -0400 Subject: [PATCH 071/188] [MH2] Implemented Blacksmith's Skill --- .../src/mage/cards/b/BlacksmithsSkill.java | 74 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 75 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BlacksmithsSkill.java diff --git a/Mage.Sets/src/mage/cards/b/BlacksmithsSkill.java b/Mage.Sets/src/mage/cards/b/BlacksmithsSkill.java new file mode 100644 index 00000000000..ad83eeceacd --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BlacksmithsSkill.java @@ -0,0 +1,74 @@ +package mage.cards.b; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.HexproofAbility; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BlacksmithsSkill extends CardImpl { + + public BlacksmithsSkill(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); + + // Target permanent gains hexproof and indestructible until end of turn. If it's an artifact creature, it gets +2/+2 until end of turn. + this.getSpellAbility().addEffect(new GainAbilityTargetEffect( + HexproofAbility.getInstance(), Duration.EndOfTurn + ).setText("target permanent gains hexproof")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect( + IndestructibleAbility.getInstance(), Duration.EndOfTurn + ).setText("and indestructible until end of turn.")); + this.getSpellAbility().addEffect(new BlacksmithsSkillEffect()); + this.getSpellAbility().addTarget(new TargetPermanent()); + } + + private BlacksmithsSkill(final BlacksmithsSkill card) { + super(card); + } + + @Override + public BlacksmithsSkill copy() { + return new BlacksmithsSkill(this); + } +} + +class BlacksmithsSkillEffect extends OneShotEffect { + + BlacksmithsSkillEffect() { + super(Outcome.Benefit); + staticText = "If it's an artifact creature, it gets +2/+2 until end of turn"; + } + + private BlacksmithsSkillEffect(final BlacksmithsSkillEffect effect) { + super(effect); + } + + @Override + public BlacksmithsSkillEffect copy() { + return new BlacksmithsSkillEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent != null && permanent.isArtifact() && permanent.isCreature()) { + game.addEffect(new BoostTargetEffect(2, 2), source); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index f38b0e5161a..d81fbbb216d 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -45,6 +45,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Barbed Spike", 5, Rarity.UNCOMMON, mage.cards.b.BarbedSpike.class)); cards.add(new SetCardInfo("Batterbone", 221, Rarity.UNCOMMON, mage.cards.b.Batterbone.class)); cards.add(new SetCardInfo("Battle Plan", 114, Rarity.COMMON, mage.cards.b.BattlePlan.class)); + cards.add(new SetCardInfo("Blacksmith's Skill", 6, Rarity.COMMON, mage.cards.b.BlacksmithsSkill.class)); cards.add(new SetCardInfo("Bloodbraid Marauder", 116, Rarity.RARE, mage.cards.b.BloodbraidMarauder.class)); cards.add(new SetCardInfo("Bone Shards", 76, Rarity.COMMON, mage.cards.b.BoneShards.class)); cards.add(new SetCardInfo("Bone Shredder", 272, Rarity.UNCOMMON, mage.cards.b.BoneShredder.class)); From bf48ce1e544073227abe8167909bb919b59c5f08 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 07:51:33 -0400 Subject: [PATCH 072/188] [MH2] Implemented Blossoming Calm --- .../src/mage/cards/b/BlossomingCalm.java | 40 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 41 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BlossomingCalm.java diff --git a/Mage.Sets/src/mage/cards/b/BlossomingCalm.java b/Mage.Sets/src/mage/cards/b/BlossomingCalm.java new file mode 100644 index 00000000000..dbdfc171051 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BlossomingCalm.java @@ -0,0 +1,40 @@ +package mage.cards.b; + +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.continuous.GainAbilityControllerEffect; +import mage.abilities.keyword.HexproofAbility; +import mage.abilities.keyword.ReboundAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BlossomingCalm extends CardImpl { + + public BlossomingCalm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); + + // You gain hexproof until your next turn. You gain 2 life. + this.getSpellAbility().addEffect(new GainAbilityControllerEffect( + HexproofAbility.getInstance(), Duration.UntilYourNextTurn + ).setText("you gain hexproof until your next turn.")); + this.getSpellAbility().addEffect(new GainLifeEffect(2)); + + // Rebound + this.addAbility(new ReboundAbility()); + } + + private BlossomingCalm(final BlossomingCalm card) { + super(card); + } + + @Override + public BlossomingCalm copy() { + return new BlossomingCalm(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index d81fbbb216d..9bdacee1651 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -47,6 +47,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Battle Plan", 114, Rarity.COMMON, mage.cards.b.BattlePlan.class)); cards.add(new SetCardInfo("Blacksmith's Skill", 6, Rarity.COMMON, mage.cards.b.BlacksmithsSkill.class)); cards.add(new SetCardInfo("Bloodbraid Marauder", 116, Rarity.RARE, mage.cards.b.BloodbraidMarauder.class)); + cards.add(new SetCardInfo("Blossoming Calm", 7, Rarity.UNCOMMON, mage.cards.b.BlossomingCalm.class)); cards.add(new SetCardInfo("Bone Shards", 76, Rarity.COMMON, mage.cards.b.BoneShards.class)); cards.add(new SetCardInfo("Bone Shredder", 272, Rarity.UNCOMMON, mage.cards.b.BoneShredder.class)); cards.add(new SetCardInfo("Bottle Golems", 222, Rarity.COMMON, mage.cards.b.BottleGolems.class)); From e261c138422f9969899e7b5b7e27e17425bcb630 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 07:54:44 -0400 Subject: [PATCH 073/188] [MH2] Implemented Captured by Lagacs --- .../src/mage/cards/c/CapturedByLagacs.java | 52 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 53 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CapturedByLagacs.java diff --git a/Mage.Sets/src/mage/cards/c/CapturedByLagacs.java b/Mage.Sets/src/mage/cards/c/CapturedByLagacs.java new file mode 100644 index 00000000000..e0b0c66e398 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CapturedByLagacs.java @@ -0,0 +1,52 @@ +package mage.cards.c; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.combat.CantAttackBlockAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.SupportAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class CapturedByLagacs extends CardImpl { + + public CapturedByLagacs(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{W}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature can't attack or block. + this.addAbility(new SimpleStaticAbility(new CantAttackBlockAttachedEffect(AttachmentType.AURA))); + + // When Captured by Lagacs enters the battlefield, support 2. + this.addAbility(new SupportAbility(this, 2, false)); + } + + private CapturedByLagacs(final CapturedByLagacs card) { + super(card); + } + + @Override + public CapturedByLagacs copy() { + return new CapturedByLagacs(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 9bdacee1651..1858a10b86d 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -59,6 +59,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Cabal Coffers", 301, Rarity.MYTHIC, mage.cards.c.CabalCoffers.class)); cards.add(new SetCardInfo("Calibrated Blast", 118, Rarity.RARE, mage.cards.c.CalibratedBlast.class)); cards.add(new SetCardInfo("Captain Ripley Vance", 119, Rarity.UNCOMMON, mage.cards.c.CaptainRipleyVance.class)); + cards.add(new SetCardInfo("Captured by Lagacs", 188, Rarity.COMMON, mage.cards.c.CapturedByLagacs.class)); cards.add(new SetCardInfo("Chainer, Nightmare Adept", 289, Rarity.RARE, mage.cards.c.ChainerNightmareAdept.class)); cards.add(new SetCardInfo("Chance Encounter", 277, Rarity.RARE, mage.cards.c.ChanceEncounter.class)); cards.add(new SetCardInfo("Chatterstorm", 152, Rarity.COMMON, mage.cards.c.Chatterstorm.class)); From d978718759cedf65a6ea8932e38caa8a139d0445 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:00:17 -0400 Subject: [PATCH 074/188] [MH2] Implemented Funnel-Web Recluse --- .../src/mage/cards/f/FunnelWebRecluse.java | 48 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 49 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FunnelWebRecluse.java diff --git a/Mage.Sets/src/mage/cards/f/FunnelWebRecluse.java b/Mage.Sets/src/mage/cards/f/FunnelWebRecluse.java new file mode 100644 index 00000000000..226041ff3d0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FunnelWebRecluse.java @@ -0,0 +1,48 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.MorbidCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.keyword.InvestigateEffect; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FunnelWebRecluse extends CardImpl { + + public FunnelWebRecluse(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); + + this.subtype.add(SubType.SPIDER); + this.power = new MageInt(3); + this.toughness = new MageInt(5); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // Morbid — When Funnel-Web Recluse enters the battlefield, if a creature died this turn, investigate. + this.addAbility(new ConditionalInterveningIfTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new InvestigateEffect()), + MorbidCondition.instance, "Morbid — When {this} enters the battlefield, " + + "if a creature died this turn, investigate. (Create a colorless Clue artifact token " + + "with \"{2}, Sacrifice this artifact: Draw a card.\")" + )); + } + + private FunnelWebRecluse(final FunnelWebRecluse card) { + super(card); + } + + @Override + public FunnelWebRecluse copy() { + return new FunnelWebRecluse(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 1858a10b86d..9deb749810a 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -96,6 +96,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Forest", 489, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Foundation Breaker", 160, Rarity.UNCOMMON, mage.cards.f.FoundationBreaker.class)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); + cards.add(new SetCardInfo("Funnel-Web Recluse", 161, Rarity.COMMON, mage.cards.f.FunnelWebRecluse.class)); cards.add(new SetCardInfo("Gaea's Will", 162, Rarity.RARE, mage.cards.g.GaeasWill.class)); cards.add(new SetCardInfo("General Ferrous Rokiric", 198, Rarity.RARE, mage.cards.g.GeneralFerrousRokiric.class)); cards.add(new SetCardInfo("Geyadrone Dihada", 199, Rarity.MYTHIC, mage.cards.g.GeyadroneDihada.class)); From fde045da69c120f9efb7d1767b887510dbeee409 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:05:10 -0400 Subject: [PATCH 075/188] [MH2] Implemented Echoing Return --- Mage.Sets/src/mage/cards/e/EchoingReturn.java | 72 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 73 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EchoingReturn.java diff --git a/Mage.Sets/src/mage/cards/e/EchoingReturn.java b/Mage.Sets/src/mage/cards/e/EchoingReturn.java new file mode 100644 index 00000000000..3b70cf1ae35 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EchoingReturn.java @@ -0,0 +1,72 @@ +package mage.cards.e; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EchoingReturn extends CardImpl { + + public EchoingReturn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}"); + + // Return target creature card and all other cards with the same name as that card from your graveyard to your hand. + this.getSpellAbility().addEffect(new EchoingReturnEffect()); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + } + + private EchoingReturn(final EchoingReturn card) { + super(card); + } + + @Override + public EchoingReturn copy() { + return new EchoingReturn(this); + } +} + +class EchoingReturnEffect extends OneShotEffect { + + EchoingReturnEffect() { + super(Outcome.Benefit); + staticText = "return target creature card and all other cards " + + "with the same name as that card from your graveyard to your hand"; + } + + private EchoingReturnEffect(final EchoingReturnEffect effect) { + super(effect); + } + + @Override + public EchoingReturnEffect copy() { + return new EchoingReturnEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Card card = game.getCard(source.getFirstTarget()); + if (player == null || card == null) { + return false; + } + Cards cards = new CardsImpl(card); + player.getGraveyard() + .getCards(game) + .stream() + .filter(c -> CardUtil.haveSameNames(c.getName(), card.getName())) + .forEach(cards::add); + return player.moveCards(cards, Zone.HAND, source, game); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 9deb749810a..bd16f18d2f0 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -77,6 +77,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Dress Down", 39, Rarity.RARE, mage.cards.d.DressDown.class)); cards.add(new SetCardInfo("Drey Keeper", 194, Rarity.COMMON, mage.cards.d.DreyKeeper.class)); cards.add(new SetCardInfo("Drossforge Bridge", 246, Rarity.COMMON, mage.cards.d.DrossforgeBridge.class)); + cards.add(new SetCardInfo("Echoing Return", 83, Rarity.COMMON, mage.cards.e.EchoingReturn.class)); cards.add(new SetCardInfo("Enchantress's Presence", 283, Rarity.RARE, mage.cards.e.EnchantresssPresence.class)); cards.add(new SetCardInfo("Endurance", 157, Rarity.MYTHIC, mage.cards.e.Endurance.class)); cards.add(new SetCardInfo("Esper Sentinel", 12, Rarity.RARE, mage.cards.e.EsperSentinel.class)); From e3cbe28e5bf05ab4ec6c590f0ec15f1cd8447058 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:07:46 -0400 Subject: [PATCH 076/188] [MH2] Implemented Fury --- Mage.Sets/src/mage/cards/f/Fury.java | 63 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/Fury.java diff --git a/Mage.Sets/src/mage/cards/f/Fury.java b/Mage.Sets/src/mage/cards/f/Fury.java new file mode 100644 index 00000000000..03c3ef9a723 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/Fury.java @@ -0,0 +1,63 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.ExileFromHandCost; +import mage.abilities.effects.common.DamageMultiEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.EvokeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCreatureOrPlaneswalkerAmount; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Fury extends CardImpl { + + private static final FilterCard filter = new FilterCard("a red card from your hand"); + + static { + filter.add(new ColorPredicate(ObjectColor.RED)); + } + + public Fury(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.INCARNATION); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Double strike + this.addAbility(DoubleStrikeAbility.getInstance()); + + // When Fury enters the battlefield, it deals 4 damage divided as you choose among any number of target creatures and/or planeswalkers. + Ability ability = new EntersBattlefieldTriggeredAbility( + new DamageMultiEffect(4, "it") + ); + ability.addTarget(new TargetCreatureOrPlaneswalkerAmount(4)); + this.addAbility(ability); + + // Evoke—Exile a red card from your hand. + this.addAbility(new EvokeAbility(new ExileFromHandCost(new TargetCardInHand(filter)))); + } + + private Fury(final Fury card) { + super(card); + } + + @Override + public Fury copy() { + return new Fury(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index bd16f18d2f0..0bc0655da93 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -98,6 +98,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Foundation Breaker", 160, Rarity.UNCOMMON, mage.cards.f.FoundationBreaker.class)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); cards.add(new SetCardInfo("Funnel-Web Recluse", 161, Rarity.COMMON, mage.cards.f.FunnelWebRecluse.class)); + cards.add(new SetCardInfo("Fury", 126, Rarity.MYTHIC, mage.cards.f.Fury.class)); cards.add(new SetCardInfo("Gaea's Will", 162, Rarity.RARE, mage.cards.g.GaeasWill.class)); cards.add(new SetCardInfo("General Ferrous Rokiric", 198, Rarity.RARE, mage.cards.g.GeneralFerrousRokiric.class)); cards.add(new SetCardInfo("Geyadrone Dihada", 199, Rarity.MYTHIC, mage.cards.g.GeyadroneDihada.class)); From fe3615fc03c8f83f97e07c6f424246d339ffe36e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:10:38 -0400 Subject: [PATCH 077/188] [MH2] Implemented Glimmer Bairn --- Mage.Sets/src/mage/cards/g/GlimmerBairn.java | 51 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 52 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GlimmerBairn.java diff --git a/Mage.Sets/src/mage/cards/g/GlimmerBairn.java b/Mage.Sets/src/mage/cards/g/GlimmerBairn.java new file mode 100644 index 00000000000..8985d02afc7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GlimmerBairn.java @@ -0,0 +1,51 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GlimmerBairn extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a token"); + + static { + filter.add(TokenPredicate.instance); + } + + public GlimmerBairn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); + + this.subtype.add(SubType.OUPHE); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Sacrifice a token: Glimmer Bairn gets +2/+2 until end of turn. + this.addAbility(new SimpleActivatedAbility( + new BoostSourceEffect(2, 2, Duration.EndOfTurn), + new SacrificeTargetCost(new TargetControlledPermanent(filter)) + )); + } + + private GlimmerBairn(final GlimmerBairn card) { + super(card); + } + + @Override + public GlimmerBairn copy() { + return new GlimmerBairn(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 0bc0655da93..21c5b6bd525 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -103,6 +103,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("General Ferrous Rokiric", 198, Rarity.RARE, mage.cards.g.GeneralFerrousRokiric.class)); cards.add(new SetCardInfo("Geyadrone Dihada", 199, Rarity.MYTHIC, mage.cards.g.GeyadroneDihada.class)); cards.add(new SetCardInfo("Ghost-Lit Drifter", 45, Rarity.UNCOMMON, mage.cards.g.GhostLitDrifter.class)); + cards.add(new SetCardInfo("Glimmer Bairn", 413, Rarity.COMMON, mage.cards.g.GlimmerBairn.class)); cards.add(new SetCardInfo("Glinting Creeper", 164, Rarity.UNCOMMON, mage.cards.g.GlintingCreeper.class)); cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); cards.add(new SetCardInfo("Goblin Bombardment", 279, Rarity.RARE, mage.cards.g.GoblinBombardment.class)); From 9ce916e75a6eeaa94997e378115382c01896ffdd Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:13:31 -0400 Subject: [PATCH 078/188] [MH2] Implemented Kaleidoscorch --- Mage.Sets/src/mage/cards/k/Kaleidoscorch.java | 41 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 42 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/Kaleidoscorch.java diff --git a/Mage.Sets/src/mage/cards/k/Kaleidoscorch.java b/Mage.Sets/src/mage/cards/k/Kaleidoscorch.java new file mode 100644 index 00000000000..b33c8799e4e --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/Kaleidoscorch.java @@ -0,0 +1,41 @@ +package mage.cards.k; + +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.ColorsOfManaSpentToCastCount; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.FlashbackAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.TimingRule; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Kaleidoscorch extends CardImpl { + + public Kaleidoscorch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}"); + + // Converge — Kaleidoscorch deals X damage to any target, where X is the number of colors of mana spent to cast this spell. + this.getSpellAbility().addEffect(new DamageTargetEffect(ColorsOfManaSpentToCastCount.getInstance())); + this.getSpellAbility().addTarget(new TargetAnyTarget()); + this.getSpellAbility().setAbilityWord(AbilityWord.CONVERGE); + + // Flashback {4}{R} + this.addAbility(new FlashbackAbility(new ManaCostsImpl<>("{4}{R}"), TimingRule.SORCERY)); + } + + private Kaleidoscorch(final Kaleidoscorch card) { + super(card); + } + + @Override + public Kaleidoscorch copy() { + return new Kaleidoscorch(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 21c5b6bd525..c67fb7339af 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -121,6 +121,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Island", 483, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jade Avenger", 167, Rarity.COMMON, mage.cards.j.JadeAvenger.class)); cards.add(new SetCardInfo("Junk Winder", 48, Rarity.UNCOMMON, mage.cards.j.JunkWinder.class)); + cards.add(new SetCardInfo("Kaleidoscorch", 133, Rarity.UNCOMMON, mage.cards.k.Kaleidoscorch.class)); cards.add(new SetCardInfo("Karmic Guide", 263, Rarity.RARE, mage.cards.k.KarmicGuide.class)); cards.add(new SetCardInfo("Kitchen Imp", 89, Rarity.COMMON, mage.cards.k.KitchenImp.class)); cards.add(new SetCardInfo("Landscaper Colos", 18, Rarity.COMMON, mage.cards.l.LandscaperColos.class)); From f0ecefd9559468aa3da5316ac8db5288366cbf0d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:16:14 -0400 Subject: [PATCH 079/188] [MH2] Implemented Steelfin Whale --- Mage.Sets/src/mage/cards/s/SteelfinWhale.java | 44 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 45 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SteelfinWhale.java diff --git a/Mage.Sets/src/mage/cards/s/SteelfinWhale.java b/Mage.Sets/src/mage/cards/s/SteelfinWhale.java new file mode 100644 index 00000000000..fbaa7cf5ccb --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SteelfinWhale.java @@ -0,0 +1,44 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.effects.common.UntapSourceEffect; +import mage.abilities.keyword.AffinityForArtifactsAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SteelfinWhale extends CardImpl { + + public SteelfinWhale(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}"); + + this.subtype.add(SubType.WHALE); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Affinity for artifacts + this.addAbility(new AffinityForArtifactsAbility()); + + // Whenever an artifact enters the battlefield under your control, untap Steelfin Whale. + this.addAbility(new EntersBattlefieldControlledTriggeredAbility( + new UntapSourceEffect(), StaticFilters.FILTER_PERMANENT_ARTIFACT_AN + )); + } + + private SteelfinWhale(final SteelfinWhale card) { + super(card); + } + + @Override + public SteelfinWhale copy() { + return new SteelfinWhale(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index c67fb7339af..cc06b902a4b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -196,6 +196,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Squirrel Mob", 286, Rarity.RARE, mage.cards.s.SquirrelMob.class)); cards.add(new SetCardInfo("Squirrel Sanctuary", 174, Rarity.UNCOMMON, mage.cards.s.SquirrelSanctuary.class)); cards.add(new SetCardInfo("Squirrel Sovereign", 175, Rarity.UNCOMMON, mage.cards.s.SquirrelSovereign.class)); + cards.add(new SetCardInfo("Steelfin Whale", 65, Rarity.COMMON, mage.cards.s.SteelfinWhale.class)); cards.add(new SetCardInfo("Step Through", 66, Rarity.COMMON, mage.cards.s.StepThrough.class)); cards.add(new SetCardInfo("Sterling Grove", 293, Rarity.RARE, mage.cards.s.SterlingGrove.class)); cards.add(new SetCardInfo("Strike It Rich", 143, Rarity.UNCOMMON, mage.cards.s.StrikeItRich.class)); From 22a14f430f933af8acdc6126ab0619ef3ec71e50 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:19:52 -0400 Subject: [PATCH 080/188] [MH2] Implemented Sythis, Harvest's Hand --- .../src/mage/cards/s/SythisHarvestsHand.java | 50 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 51 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SythisHarvestsHand.java diff --git a/Mage.Sets/src/mage/cards/s/SythisHarvestsHand.java b/Mage.Sets/src/mage/cards/s/SythisHarvestsHand.java new file mode 100644 index 00000000000..9c2aa9cf337 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SythisHarvestsHand.java @@ -0,0 +1,50 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterSpell; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SythisHarvestsHand extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("an enchantment spell"); + + static { + filter.add(CardType.ENCHANTMENT.getPredicate()); + } + + public SythisHarvestsHand(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{G}{W}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.NYMPH); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Whenever you cast an enchantment spell, you gain 1 life and draw a card. + Ability ability = new SpellCastControllerTriggeredAbility(new GainLifeEffect(1), filter, false); + ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and")); + this.addAbility(ability); + } + + private SythisHarvestsHand(final SythisHarvestsHand card) { + super(card); + } + + @Override + public SythisHarvestsHand copy() { + return new SythisHarvestsHand(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index cc06b902a4b..583c06a450d 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -206,6 +206,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 485, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sweep the Skies", 70, Rarity.UNCOMMON, mage.cards.s.SweepTheSkies.class)); cards.add(new SetCardInfo("Sylvan Anthem", 176, Rarity.RARE, mage.cards.s.SylvanAnthem.class)); + cards.add(new SetCardInfo("Sythis, Harvest's Hand", 214, Rarity.RARE, mage.cards.s.SythisHarvestsHand.class)); cards.add(new SetCardInfo("Tanglepool Bridge", 257, Rarity.COMMON, mage.cards.t.TanglepoolBridge.class)); cards.add(new SetCardInfo("Terramorph", 177, Rarity.UNCOMMON, mage.cards.t.Terramorph.class)); cards.add(new SetCardInfo("Territorial Kavu", 216, Rarity.RARE, mage.cards.t.TerritorialKavu.class)); From f653ba91fc20f515e7657fb6aca4bc89f1718221 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:28:18 -0400 Subject: [PATCH 081/188] [MH2] Implemented Scour the Desert --- .../src/mage/cards/s/ScourTheDesert.java | 73 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 74 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ScourTheDesert.java diff --git a/Mage.Sets/src/mage/cards/s/ScourTheDesert.java b/Mage.Sets/src/mage/cards/s/ScourTheDesert.java new file mode 100644 index 00000000000..2b2124b6eca --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScourTheDesert.java @@ -0,0 +1,73 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.token.BirdToken; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ScourTheDesert extends CardImpl { + + public ScourTheDesert(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{W}{W}"); + + // Exile target creature card from your graveyard. Create X 1/1 white Bird creature tokens with flying, where X is the exiled card's toughness. + this.getSpellAbility().addEffect(new ScourTheDesertEffect()); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + } + + private ScourTheDesert(final ScourTheDesert card) { + super(card); + } + + @Override + public ScourTheDesert copy() { + return new ScourTheDesert(this); + } +} + +class ScourTheDesertEffect extends OneShotEffect { + + ScourTheDesertEffect() { + super(Outcome.Benefit); + staticText = "exile target creature card from your graveyard. " + + "Create X 1/1 white Bird creature tokens with flying, where X is the exiled card's toughness"; + } + + private ScourTheDesertEffect(final ScourTheDesertEffect effect) { + super(effect); + } + + @Override + public ScourTheDesertEffect copy() { + return new ScourTheDesertEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + Card card = game.getCard(source.getFirstTarget()); + if (player == null || card == null) { + return false; + } + int toughness = card.getToughness().getValue(); + player.moveCards(card, Zone.EXILED, source, game); + if (toughness > 0) { + new BirdToken().putOntoBattlefield(toughness, game, source, source.getControllerId()); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 583c06a450d..ddf39f8b43b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -174,6 +174,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Sanctum Weaver", 171, Rarity.RARE, mage.cards.s.SanctumWeaver.class)); cards.add(new SetCardInfo("Scalding Tarn", 254, Rarity.RARE, mage.cards.s.ScaldingTarn.class)); cards.add(new SetCardInfo("Scion of Draco", 234, Rarity.MYTHIC, mage.cards.s.ScionOfDraco.class)); + cards.add(new SetCardInfo("Scour the Desert", 28, Rarity.UNCOMMON, mage.cards.s.ScourTheDesert.class)); cards.add(new SetCardInfo("Scurry Oak", 172, Rarity.UNCOMMON, mage.cards.s.ScurryOak.class)); cards.add(new SetCardInfo("Scuttletide", 61, Rarity.UNCOMMON, mage.cards.s.Scuttletide.class)); cards.add(new SetCardInfo("Sea Drake", 268, Rarity.UNCOMMON, mage.cards.s.SeaDrake.class)); From 8a5b9a601803efb5a300348b1414fcef9d995d74 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:34:47 -0400 Subject: [PATCH 082/188] [MH2] Implemented Search the Premises --- .../src/mage/cards/s/SearchThePremises.java | 33 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 34 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SearchThePremises.java diff --git a/Mage.Sets/src/mage/cards/s/SearchThePremises.java b/Mage.Sets/src/mage/cards/s/SearchThePremises.java new file mode 100644 index 00000000000..c79173124be --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SearchThePremises.java @@ -0,0 +1,33 @@ +package mage.cards.s; + +import mage.abilities.common.AttacksAllTriggeredAbility; +import mage.abilities.effects.keyword.InvestigateEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SearchThePremises extends CardImpl { + + public SearchThePremises(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // Whenever a creature attacks you or a planeswalker you control, investigate. + this.addAbility(new AttacksAllTriggeredAbility( + new InvestigateEffect(), false, true + )); + } + + private SearchThePremises(final SearchThePremises card) { + super(card); + } + + @Override + public SearchThePremises copy() { + return new SearchThePremises(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index ddf39f8b43b..62532eedc56 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -180,6 +180,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Sea Drake", 268, Rarity.UNCOMMON, mage.cards.s.SeaDrake.class)); cards.add(new SetCardInfo("Seal of Cleansing", 264, Rarity.UNCOMMON, mage.cards.s.SealOfCleansing.class)); cards.add(new SetCardInfo("Seal of Removal", 269, Rarity.UNCOMMON, mage.cards.s.SealOfRemoval.class)); + cards.add(new SetCardInfo("Search the Premises", 29, Rarity.RARE, mage.cards.s.SearchThePremises.class)); cards.add(new SetCardInfo("Shardless Agent", 292, Rarity.RARE, mage.cards.s.ShardlessAgent.class)); cards.add(new SetCardInfo("Shattered Ego", 62, Rarity.COMMON, mage.cards.s.ShatteredEgo.class)); cards.add(new SetCardInfo("Silverbluff Bridge", 255, Rarity.COMMON, mage.cards.s.SilverbluffBridge.class)); From e7adae42eff387221c4cab281c2822f78062b6ee Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:48:49 -0400 Subject: [PATCH 083/188] [MH2] Implemented Tavern Scoundrel --- .../src/mage/cards/t/TavernScoundrel.java | 98 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../effects/common/FlipCoinEffect.java | 35 ++++--- .../mage/game/events/CoinFlippedEvent.java | 4 + 4 files changed, 123 insertions(+), 15 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/t/TavernScoundrel.java diff --git a/Mage.Sets/src/mage/cards/t/TavernScoundrel.java b/Mage.Sets/src/mage/cards/t/TavernScoundrel.java new file mode 100644 index 00000000000..986956ba18d --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TavernScoundrel.java @@ -0,0 +1,98 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.FlipCoinEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.Game; +import mage.game.events.CoinFlippedEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.token.TreasureToken; +import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TavernScoundrel extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("another permanent"); + + static { + filter.add(AnotherPredicate.instance); + } + + public TavernScoundrel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Whenever you win a coin flip, create two Treasure tokens. + this.addAbility(new TavernScoundrelTriggeredAbility()); + + // {1}, {T}, Sacrifice another permanent: Flip a coin. + Ability ability = new SimpleActivatedAbility(new FlipCoinEffect(), new GenericManaCost(1)); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + this.addAbility(ability); + } + + private TavernScoundrel(final TavernScoundrel card) { + super(card); + } + + @Override + public TavernScoundrel copy() { + return new TavernScoundrel(this); + } +} + +class TavernScoundrelTriggeredAbility extends TriggeredAbilityImpl { + + TavernScoundrelTriggeredAbility() { + super(Zone.BATTLEFIELD, new CreateTokenEffect(new TreasureToken(), 2), false); + } + + private TavernScoundrelTriggeredAbility(final TavernScoundrelTriggeredAbility ability) { + super(ability); + } + + @Override + public TavernScoundrelTriggeredAbility copy() { + return new TavernScoundrelTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.COIN_FLIPPED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + CoinFlippedEvent flipEvent = (CoinFlippedEvent) event; + return isControlledBy(event.getPlayerId()) + && flipEvent.isWinnable() + && flipEvent.wasWon(); + } + + @Override + public String getRule() { + return "Whenever you win a coin flip, create two Treasure tokens."; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 62532eedc56..bebf6bf23de 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -210,6 +210,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Sylvan Anthem", 176, Rarity.RARE, mage.cards.s.SylvanAnthem.class)); cards.add(new SetCardInfo("Sythis, Harvest's Hand", 214, Rarity.RARE, mage.cards.s.SythisHarvestsHand.class)); cards.add(new SetCardInfo("Tanglepool Bridge", 257, Rarity.COMMON, mage.cards.t.TanglepoolBridge.class)); + cards.add(new SetCardInfo("Tavern Scoundrel", 144, Rarity.COMMON, mage.cards.t.TavernScoundrel.class)); cards.add(new SetCardInfo("Terramorph", 177, Rarity.UNCOMMON, mage.cards.t.Terramorph.class)); cards.add(new SetCardInfo("Territorial Kavu", 216, Rarity.RARE, mage.cards.t.TerritorialKavu.class)); cards.add(new SetCardInfo("The Underworld Cookbook", 240, Rarity.UNCOMMON, mage.cards.t.TheUnderworldCookbook.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java b/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java index afa980f0390..ba3fa167c6a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java @@ -1,4 +1,3 @@ - package mage.abilities.effects.common; import mage.MageObject; @@ -13,7 +12,6 @@ import mage.game.Game; import mage.players.Player; /** - * * @author LevelX2 */ public class FlipCoinEffect extends OneShotEffect { @@ -21,6 +19,10 @@ public class FlipCoinEffect extends OneShotEffect { protected Effects executingEffectsWon = new Effects(); protected Effects executingEffectsLost = new Effects(); + public FlipCoinEffect() { + this(null); + } + public FlipCoinEffect(Effect effectWon) { this(effectWon, null); } @@ -58,19 +60,19 @@ public class FlipCoinEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject mageObject = game.getObject(source.getSourceId()); - if (controller != null && mageObject != null) { - boolean result = true; - for (Effect effect : controller.flipCoin(source, game, true) ? executingEffectsWon : executingEffectsLost) { - effect.setTargetPointer(this.targetPointer); - if (effect instanceof OneShotEffect) { - result &= effect.apply(game, source); - } else { - game.addEffect((ContinuousEffect) effect, source); - } - } - return result; + if (controller == null || mageObject == null) { + return false; } - return false; + boolean result = true; + for (Effect effect : controller.flipCoin(source, game, true) ? executingEffectsWon : executingEffectsLost) { + effect.setTargetPointer(this.targetPointer); + if (effect instanceof OneShotEffect) { + result &= effect.apply(game, source); + } else { + game.addEffect((ContinuousEffect) effect, source); + } + } + return result; } @Override @@ -78,7 +80,10 @@ public class FlipCoinEffect extends OneShotEffect { if (!staticText.isEmpty()) { return staticText; } - StringBuilder sb = new StringBuilder("Flip a coin. If you win the flip, ").append(executingEffectsWon.getText(mode)); + StringBuilder sb = new StringBuilder("flip a coin"); + if (!executingEffectsWon.isEmpty()) { + sb.append(". If you win the flip, ").append(executingEffectsWon.getText(mode)); + } if (!executingEffectsLost.isEmpty()) { sb.append(" If you lose the flip, ").append(executingEffectsLost.getText(mode)); } diff --git a/Mage/src/main/java/mage/game/events/CoinFlippedEvent.java b/Mage/src/main/java/mage/game/events/CoinFlippedEvent.java index 554be49a9b0..b5d391449d5 100644 --- a/Mage/src/main/java/mage/game/events/CoinFlippedEvent.java +++ b/Mage/src/main/java/mage/game/events/CoinFlippedEvent.java @@ -40,4 +40,8 @@ public class CoinFlippedEvent extends GameEvent { public boolean isWinnable() { return winnable; } + + public boolean wasWon() { + return result == chosen; + } } From 1fb3f91d844c6d6f29db1979c7fbe5bfdf764df7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:50:12 -0400 Subject: [PATCH 084/188] [MH2] Implemented Lazotep Chancellor --- .../src/mage/cards/l/LazotepChancellor.java | 42 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 43 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LazotepChancellor.java diff --git a/Mage.Sets/src/mage/cards/l/LazotepChancellor.java b/Mage.Sets/src/mage/cards/l/LazotepChancellor.java new file mode 100644 index 00000000000..6cd2eb63b70 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LazotepChancellor.java @@ -0,0 +1,42 @@ +package mage.cards.l; + +import mage.MageInt; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DiscardCardControllerTriggeredAbility; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.keyword.AmassEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LazotepChancellor extends CardImpl { + + public LazotepChancellor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{B}"); + + this.subtype.add(SubType.ZOMBIE); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Whenever you discard a card, you may pay {1}. If you do, amass 2. + this.addAbility(new DiscardCardControllerTriggeredAbility( + new DoIfCostPaid(new AmassEffect(2), new GenericManaCost(1)), false + )); + } + + private LazotepChancellor(final LazotepChancellor card) { + super(card); + } + + @Override + public LazotepChancellor copy() { + return new LazotepChancellor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index bebf6bf23de..614c48dccce 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -126,6 +126,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Kitchen Imp", 89, Rarity.COMMON, mage.cards.k.KitchenImp.class)); cards.add(new SetCardInfo("Landscaper Colos", 18, Rarity.COMMON, mage.cards.l.LandscaperColos.class)); cards.add(new SetCardInfo("Late to Dinner", 19, Rarity.COMMON, mage.cards.l.LateToDinner.class)); + cards.add(new SetCardInfo("Lazotep Chancellor", 203, Rarity.UNCOMMON, mage.cards.l.LazotepChancellor.class)); cards.add(new SetCardInfo("Legion Vanguard", 90, Rarity.UNCOMMON, mage.cards.l.LegionVanguard.class)); cards.add(new SetCardInfo("Liquimetal Torque", 228, Rarity.UNCOMMON, mage.cards.l.LiquimetalTorque.class)); cards.add(new SetCardInfo("Lose Focus", 49, Rarity.COMMON, mage.cards.l.LoseFocus.class)); From 37009e85bb486959414197a55a7cf5b08854d475 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 08:54:36 -0400 Subject: [PATCH 085/188] [MH2] Implemented Goblin Anarchomancer --- .../src/mage/cards/g/GoblinAnarchomancer.java | 52 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + Utils/mtg-cards-data.txt | 1 + 3 files changed, 54 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GoblinAnarchomancer.java diff --git a/Mage.Sets/src/mage/cards/g/GoblinAnarchomancer.java b/Mage.Sets/src/mage/cards/g/GoblinAnarchomancer.java new file mode 100644 index 00000000000..9786d11815d --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoblinAnarchomancer.java @@ -0,0 +1,52 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GoblinAnarchomancer extends CardImpl { + + private static final FilterCard filter = new FilterCard(); + + static { + filter.add(Predicates.or( + new ColorPredicate(ObjectColor.RED), + new ColorPredicate(ObjectColor.GREEN) + )); + } + + public GoblinAnarchomancer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.SHAMAN); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Each spell you cast that's red or green costs {1} less to cast. + this.addAbility(new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 1) + .setText("each spell you cast that's red or green costs {1} less to cast"))); + } + + private GoblinAnarchomancer(final GoblinAnarchomancer card) { + super(card); + } + + @Override + public GoblinAnarchomancer copy() { + return new GoblinAnarchomancer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 614c48dccce..d0a65893c67 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -106,6 +106,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Glimmer Bairn", 413, Rarity.COMMON, mage.cards.g.GlimmerBairn.class)); cards.add(new SetCardInfo("Glinting Creeper", 164, Rarity.UNCOMMON, mage.cards.g.GlintingCreeper.class)); cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); + cards.add(new SetCardInfo("Goblin Anarchomancer", 200, Rarity.COMMON, mage.cards.g.GoblinAnarchomancer.class)); cards.add(new SetCardInfo("Goblin Bombardment", 279, Rarity.RARE, mage.cards.g.GoblinBombardment.class)); cards.add(new SetCardInfo("Goldmire Bridge", 247, Rarity.COMMON, mage.cards.g.GoldmireBridge.class)); cards.add(new SetCardInfo("Gorilla Shaman", 280, Rarity.UNCOMMON, mage.cards.g.GorillaShaman.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 94593c879e1..bf3abd4d6ed 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -41483,6 +41483,7 @@ Ethersworn Sphinx|Modern Horizons 2|195|U|{7}{W}{U}|Artifact Creature - Sphinx|4 Garth One-Eye|Modern Horizons 2|197|M|{W}{U}{B}{R}{G}|Legendary Creature - Human Wizard|5|5|{T}: Choose a card name that hasn't been chosen from among Disenchant, Braingeyser, Terror, Shivan Dragon, Regrowth, and Black Lotus. Create a copy of the card with the chosen name. You may cast the copy.| General Ferrous Rokiric|Modern Horizons 2|198|R|{1}{R}{W}|Legendary Creature - Human Soldier|3|1|Hexproof from monocolored$Whenever you cast a multicolored spell, create a 4/4 red and white Golem artifact creature token.| Geyadrone Dihada|Modern Horizons 2|199|M|{1}{U}{B}{R}|Legendary Planeswalker - Dihada|4|Protection from permanents with corruption counters on them$+1: Each opponent loses 2 life and you gain 2 life. Put a corruption counter on up to one other target creature or planeswalker.$−3: Gain control of target creature or planeswalker until end of tun. Untap it and put a corruption counter on it. It gains haste until end of turn.$−7: Gain control of each permanent with a corruption counter on it.| +Goblin Anarchomancer|Modern Horizons 2|200|C|{R}{G}|Creature - Goblin Shaman|2|2|Each spell you cast that's red or green costs {1} less to cast.| Graceful Restoration|Modern Horizons 2|201|U|{3}{W}{B}|Sorcery|||Choose one —$• Return target creature card from your graveyard to the battlefield with an additional +1/+1 counter on it.$• Return up to two target creature cards with power 2 or less from your graveyard to the battlefield.| Grist, the Hunger Tide|Modern Horizons 2|202|M|{1}{B}{G}|Legendary Planeswalker - Grist|3|As long as Grist, the Hunger Tide isn't on the battlefield, it's a 1/1 Insect creature in addition to its other types.$+1: Create a 1/1 black and green Insect creature token, then mill a card. If an Insect card was milled this way, put a loyalty counter on Grist and repeat this process.$−2: You may sacrifice a creature. When you do, destroy target creature or planeswalker.$−5: Each opponent loses life equal to the number of creature cards in your graveyard.| Lazotep Chancellor|Modern Horizons 2|203|U|{U}{B}|Creature - Zombie Wizard|1|3|Whenever you discard a card, you may pay {1}. If you do, amass 2.| From 58a297ec5c667e810fb156dea00b0b3716a727a6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 09:11:12 -0400 Subject: [PATCH 086/188] fixed a test failure --- .../main/java/mage/abilities/effects/common/FlipCoinEffect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java b/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java index ba3fa167c6a..21036b14f8b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java @@ -20,7 +20,7 @@ public class FlipCoinEffect extends OneShotEffect { protected Effects executingEffectsLost = new Effects(); public FlipCoinEffect() { - this(null); + this((Effect) null); } public FlipCoinEffect(Effect effectWon) { From 8879a5fdf7cb336ab73ea26f4a111ed021eda518 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Wed, 2 Jun 2021 17:01:55 -0500 Subject: [PATCH 087/188] [MH2] Implemented Breathless Knight (#7876) --- .../src/mage/cards/b/BreathlessKnight.java | 96 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 97 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BreathlessKnight.java diff --git a/Mage.Sets/src/mage/cards/b/BreathlessKnight.java b/Mage.Sets/src/mage/cards/b/BreathlessKnight.java new file mode 100644 index 00000000000..50c3dca10bc --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BreathlessKnight.java @@ -0,0 +1,96 @@ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.SubType; +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.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.watchers.common.CastFromGraveyardWatcher; + +/** + * + * @author weirddan455 + */ +public final class BreathlessKnight extends CardImpl { + + public BreathlessKnight(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{B}"); + + this.subtype.add(SubType.SPIRIT); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // Whenever Breathless Knight or another creature enters the battlefield under your control, if that creature entered from a graveyard or you cast it from a graveyard, put a +1/+1 counter on Breathless Knight. + this.addAbility(new BreathlessKnightTriggeredAbility(), new CastFromGraveyardWatcher()); + } + + private BreathlessKnight(final BreathlessKnight card) { + super(card); + } + + @Override + public BreathlessKnight copy() { + return new BreathlessKnight(this); + } +} + +class BreathlessKnightTriggeredAbility extends TriggeredAbilityImpl { + + public BreathlessKnightTriggeredAbility() { + super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance())); + } + + private BreathlessKnightTriggeredAbility(final BreathlessKnightTriggeredAbility ability) { + super(ability); + } + + @Override + public BreathlessKnightTriggeredAbility copy() { + return new BreathlessKnightTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event instanceof EntersTheBattlefieldEvent) { + EntersTheBattlefieldEvent entersEvent = (EntersTheBattlefieldEvent) event; + Permanent permanent = entersEvent.getTarget(); + if (permanent != null && permanent.isCreature() && permanent.isControlledBy(this.getControllerId())) { + if (entersEvent.getFromZone() == Zone.GRAVEYARD) { + return true; + } + CastFromGraveyardWatcher watcher = game.getState().getWatcher(CastFromGraveyardWatcher.class); + int zcc = game.getState().getZoneChangeCounter(entersEvent.getSourceId()); + return watcher != null && watcher.spellWasCastFromGraveyard(entersEvent.getSourceId(), zcc - 1); + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever {this} or another creature enters the battlefield under your control, if that creature entered from a graveyard or you cast it from a graveyard, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index d0a65893c67..d0de0f36dfd 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -55,6 +55,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Brainstone", 223, Rarity.UNCOMMON, mage.cards.b.Brainstone.class)); cards.add(new SetCardInfo("Break Ties", 8, Rarity.COMMON, mage.cards.b.BreakTies.class)); cards.add(new SetCardInfo("Break the Ice", 77, Rarity.UNCOMMON, mage.cards.b.BreakTheIce.class)); + cards.add(new SetCardInfo("Breathless Knight", 187, Rarity.COMMON, mage.cards.b.BreathlessKnight.class)); cards.add(new SetCardInfo("Breya's Apprentice", 117, Rarity.RARE, mage.cards.b.BreyasApprentice.class)); cards.add(new SetCardInfo("Cabal Coffers", 301, Rarity.MYTHIC, mage.cards.c.CabalCoffers.class)); cards.add(new SetCardInfo("Calibrated Blast", 118, Rarity.RARE, mage.cards.c.CalibratedBlast.class)); From 23e1eb1d58b8b01115c606d0304b3b061e4fa121 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:03:36 -0400 Subject: [PATCH 088/188] [MH2] updated spoiler and reprints --- Mage.Sets/src/mage/sets/ModernHorizons2.java | 6 +- Utils/mtg-cards-data.txt | 60 ++++++++++++++++++-- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index d0de0f36dfd..726caede758 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -31,7 +31,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Abundant Harvest", 147, Rarity.COMMON, mage.cards.a.AbundantHarvest.class)); cards.add(new SetCardInfo("Aeromoeba", 37, Rarity.COMMON, mage.cards.a.Aeromoeba.class)); cards.add(new SetCardInfo("Aeve, Progenitor Ooze", 148, Rarity.RARE, mage.cards.a.AeveProgenitorOoze.class)); - cards.add(new SetCardInfo("Angelic Curator", 262, Rarity.COMMON, mage.cards.a.AngelicCurator.class)); + cards.add(new SetCardInfo("Angelic Curator", 262, Rarity.UNCOMMON, mage.cards.a.AngelicCurator.class)); cards.add(new SetCardInfo("Arcbound Javelineer", 2, Rarity.UNCOMMON, mage.cards.a.ArcboundJavelineer.class)); cards.add(new SetCardInfo("Arcbound Mouser", 3, Rarity.COMMON, mage.cards.a.ArcboundMouser.class)); cards.add(new SetCardInfo("Arcbound Shikari", 184, Rarity.UNCOMMON, mage.cards.a.ArcboundShikari.class)); @@ -104,7 +104,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("General Ferrous Rokiric", 198, Rarity.RARE, mage.cards.g.GeneralFerrousRokiric.class)); cards.add(new SetCardInfo("Geyadrone Dihada", 199, Rarity.MYTHIC, mage.cards.g.GeyadroneDihada.class)); cards.add(new SetCardInfo("Ghost-Lit Drifter", 45, Rarity.UNCOMMON, mage.cards.g.GhostLitDrifter.class)); - cards.add(new SetCardInfo("Glimmer Bairn", 413, Rarity.COMMON, mage.cards.g.GlimmerBairn.class)); + cards.add(new SetCardInfo("Glimmer Bairn", 163, Rarity.COMMON, mage.cards.g.GlimmerBairn.class)); cards.add(new SetCardInfo("Glinting Creeper", 164, Rarity.UNCOMMON, mage.cards.g.GlintingCreeper.class)); cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); cards.add(new SetCardInfo("Goblin Anarchomancer", 200, Rarity.COMMON, mage.cards.g.GoblinAnarchomancer.class)); @@ -241,7 +241,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Void Mirror", 242, Rarity.RARE, mage.cards.v.VoidMirror.class)); cards.add(new SetCardInfo("Wonder", 271, Rarity.RARE, mage.cards.w.Wonder.class)); cards.add(new SetCardInfo("World-Weary", 109, Rarity.COMMON, mage.cards.w.WorldWeary.class)); - cards.add(new SetCardInfo("Wren's Run Hydra", 163, Rarity.UNCOMMON, mage.cards.w.WrensRunHydra.class)); + cards.add(new SetCardInfo("Wren's Run Hydra", 183, Rarity.UNCOMMON, mage.cards.w.WrensRunHydra.class)); cards.add(new SetCardInfo("Yavimaya Elder", 288, Rarity.UNCOMMON, mage.cards.y.YavimayaElder.class)); cards.add(new SetCardInfo("Young Necromancer", 110, Rarity.UNCOMMON, mage.cards.y.YoungNecromancer.class)); cards.add(new SetCardInfo("Yusri, Fortune's Flame", 218, Rarity.RARE, mage.cards.y.YusriFortunesFlame.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index bf3abd4d6ed..0f84eba9fed 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -41336,31 +41336,45 @@ Forest|Adventures in the Forgotten Realms|281|C||Basic Land - Forest|||({T}: Add Abiding Grace|Modern Horizons 2|1|U|{2}{W}|Enchantment|||At the beginning of your end step, choose one —$• You gain 1 life.$• Return target creature card with mana value 1 from your graveyard to the battlefield.| Arcbound Javelineer|Modern Horizons 2|2|U|{W}|Artifact Creature - Soldier|0|1|{T}, Remove X +1/+1 counters from Arcbound Javelineer: It deals X damage to target attacking or blocking creature.$Modular 1| Arcbound Mouser|Modern Horizons 2|3|C|{W}|Artifact Creature - Cat|0|0|Lifelink$Modular 1| +Arcbound Prototype|Modern Horizons 2|4|C|{1}{W}|Artifact Creature - Assembly-Worker|0|0|Modular 2| Barbed Spike|Modern Horizons 2|5|U|{1}{W}|Artifact - Equipment|||When Barbed Spike enters the battlefield, create a 1/1 colorless Thopter artifact creature token with flying and attach Barbed Spike to it.$Equipped creature gets +1/+0.$Equip {2}| Blacksmith's Skill|Modern Horizons 2|6|C|{W}|Instant|||Target permanent gains hexproof and indestructible until end of turn. If it's an artifact creature, it gets +2/+2 until end of turn.| Blossoming Calm|Modern Horizons 2|7|U|{W}|Instant|||You gain hexproof until your next turn. You gain 2 life.$Rebound| Break Ties|Modern Horizons 2|8|C|{2}{W}|Instant|||Choose one —$• Destroy target artifact.$• Destroy target enchantment.$• Exile target card from a graveyard.$Reinforce 1—{W}| Caprichrome|Modern Horizons 2|9|U|{3}{W}|Artifact Creature - Goat|2|2|Flash$Vigilance$Devour artifact 1| Constable of the Realm|Modern Horizons 2|10|U|{4}{W}|Creature - Giant Soldier|3|3|Renown 2$Whenever one or more +1/+1 counters are put on Constable of the Realm, exile up to one other target nonland permanent until Constable of the Realm leaves the battlefield.| +Disciple of the Sun|Modern Horizons 2|11|C|{4}{W}|Creature - Human Cleric|3|3|Lifelink$When Disciple of the Sun enters the battlefield, return target permanent card with mana value 3 or less from your graveyard to your hand.| Esper Sentinel|Modern Horizons 2|12|R|{W}|Artifact Creature - Human Soldier|1|1|Whenever an opponent casts their first noncreature spell each turn, draw a card unless that player pays {X}, where X is Esper Sentinel's power.| +Fairgrounds Patrol|Modern Horizons 2|13|C|{1}{W}|Creature - Human Soldier|2|1|{1}{W}, Exile Fairgrounds Patrol from your graveyard: Create a 1/1 colorless Thopter creature token with flying. Activate only as a sorcery.| Glorious Enforcer|Modern Horizons 2|14|U|{5}{W}{W}|Creature - Angel|5|5|Flying, lifelink$At the beginning of each combat, if you have more life than an opponent, Glorious Enforcer gains double strike until end of turn.| +Guardian Kirin|Modern Horizons 2|15|C|{3}{W}|Creature - Kirin|2|3|Flying$Whenever another creature you control dies, put a +1/+1 counter on Guardian Kirin.| +Knighted Myr|Modern Horizons 2|17|C|{2}{W}|Artifact Creature - Myr Knight|2|2|{2}{W}: Adapt 1.$Whenever one or more +1/+1 counters are put on Knighted Myr, it gains double strike until end of turn.| Landscaper Colos|Modern Horizons 2|18|C|{5}{W}|Creature - Goat Beast|4|6|When Landscaper Colos enters the battlefield, put target card from an opponent's graveyard on the bottom of their library.$Basic landcycling {1}{W}| Late to Dinner|Modern Horizons 2|19|C|{3}{W}|Sorcery|||Return target creature card from your graveyard to the battlefield. Create a Food token.| +Lens Flare|Modern Horizons 2|20|C|{4}{W}|Instant|||Affinity for artifacts$"Lens Flare" deals 5 damage to target attacking or blocking creature.| +Marble Gargoyle|Modern Horizons 2|21|C|{2}{W}|Artifact Creature - Gargoyle|2|2|Flying${W}: Marble Gargoyle gets +0/+1 until end of turn.| +Nykthos Paragon|Modern Horizons 2|22|R|{4}{W}{W}|Enchantment Creature - Human Soldier|4|6|Whenever you gain life, you may put that many +1/+1 counters on each creature you control. You may do this only once each turn.| Out of Time|Modern Horizons 2|23|R|{1}{W}{W}|Enchantment|||When Out of Time enters the battlefield, untap all creatures, then phase them out until Out of Time leaves the battlefield. Put a time counter on Out of Time for each creature phased out this way.$Vanishing| +Piercing Rays|Modern Horizons 2|24|C|{1}{W}|Sorcery|||Exile target tapped creature.$Forecast—{2}{W}, Reveal Piercing Rays from your hand: Tap target untapped creature.| Prismatic Ending|Modern Horizons 2|25|U|{X}{W}|Sorcery|||Converge — Exile target nonland permanent if its mana value is less than or equal to the number of colors of mana spent to cast this spell.| +Resurgent Belief|Modern Horizons 2|26|R||Sorcery|||Suspend 2—{1}{W}$Return all enchantment cards from your graveyard to the battlefield.| Sanctifier en-Vec|Modern Horizons 2|27|R|{W}{W}|Creature - Human Cleric|2|2|Protection from black and from red$When Sanctifier en-Vec enters the battlefield, exile all cards that are black and red from all graveyards.$If a black or red permanent, spell, or card not on the battlefield would be put into a graveyard, exile it instead.| Scour the Desert|Modern Horizons 2|28|U|{3}{W}{W}|Sorcery|||Exile target creature card from your graveyard. Create X 1/1 white Bird creature tokens with flying, where X is the exiled card's toughness.| Search the Premises|Modern Horizons 2|29|R|{3}{W}|Enchantment|||Whenever a creature attacks you or a planeswalker you control, investigate.| Serra's Emissary|Modern Horizons 2|30|M|{4}{W}{W}{W}|Creature - Angel|7|7|Flying$As Serra's Emissary enters the battlefield, choose a card type.$You and creatures you control have protection from the chosen card type.| Skyblade's Boon|Modern Horizons 2|31|U|{1}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +1/+1 and has flying.${2}{W}: Return Skyblade's Boon to its owner's hand. Activate only if Skyblade's Boon is on the battlefield or in your graveyard.| Solitude|Modern Horizons 2|32|M|{3}{W}{W}|Creature - Elemental Incarnation|3|2|Flash$Lifelink$When Solitude enters the battlefield, exile up to one other target creature. That creature's controller gains life equal to its power.$Evoke—Exile a white card from your hand.| +Soul of Migration|Modern Horizons 2|33|C|{5}{W}{W}|Creature - Elemental|2|4|Flying$When Soul of Migration enters the battlefield, create two 1/1 white Bird creature tokens with flying.$Evoke {3}{W}| Thraben Watcher|Modern Horizons 2|34|U|{2}{W}{W}|Creature - Angel|2|2|Flying, vigilance$Other nontoken creatures you control get +1/+1 and have vigilance.| Timeless Dragon|Modern Horizons 2|35|R|{3}{W}{W}|Creature - Dragon|5|5|Flying$Plainscycling {2}$Eternalize {2}{W}{W}| Unbounded Potential|Modern Horizons 2|36|C|{1}{W}|Instant|||Choose one —$• Put a +1/+1 counter on each of up to two target creatures.$• Proliferate.$Entwine {3}{W}| Aeromoeba|Modern Horizons 2|37|C|{3}{U}|Creature - Elemental Beast|2|4|Flying$Discard a card: Switch Aeromoeba's power and toughness until end of turn.| +Burdened Aerialist|Modern Horizons 2|38|C|{2}{U}|Creature - Human Pirate|3|1|When Burdened Aerialist enters the battlefield, create a Treasure token.$Whenever you sacrifice a token, Burdened Aerialist gains flying until end of turn.| Dress Down|Modern Horizons 2|39|R|{1}{U}|Enchantment|||Flash$When Dress Down enters the battlefield, draw a card.$Creatures lose all abilities.$At the beginning of the end step, sacrifice Dress Down.| +Etherium Spinner|Modern Horizons 2|40|C|{2}{U}|Artifact Creature - Human Wizard|2|1|Whenever you cast a spell with mana value 4 or greater, create a 1/1 colorless Thopter artifact creature token with flying.| Filigree Attendant|Modern Horizons 2|41|U|{2}{U}{U}|Artifact Creature - Homunculus|*|3|Flying$Filigree Attendant's power is equal to the number of artifacts you control.| Floodhound|Modern Horizons 2|42|C|{U}|Creature - Elemental Dog|1|2|{3}, {T}: Investigate.| +Foul Watcher|Modern Horizons 2|43|C|{1}{U}|Creature - Nightmare Bird|1|2|Flying$When Foul Watcher enters the battlefield, surveil 1.$Delirium — Foul Watcher gets +1/+0 as long as there are four more card types among cards in your graveyard.| Fractured Sanity|Modern Horizons 2|44|R|{U}{U}{U}|Sorcery|||Each opponent mills fourteen cards.$Cycling {1}{U}$When you cycle Fractured Sanity, each opponent mills four cards.| Ghost-Lit Drifter|Modern Horizons 2|45|U|{2}{U}|Creature - Spirit|2|2|Flying${2}{U}: Another target creature gains flying until end of turn.$Channel — {X}{U}, Discard Ghost-Lit Drifter: X target creatures gain flying until end of turn.| Hard Evidence|Modern Horizons 2|46|C|{U}|Sorcery|||Create a 0/3 blue Crab creature token.$Investigate.| @@ -41371,8 +41385,10 @@ Lucid Dreams|Modern Horizons 2|50|U|{3}{U}{U}|Sorcery|||Draw X cards, where X is Mental Journey|Modern Horizons 2|51|C|{4}{U}{U}|Instant|||Draw three cards.$Basic landcycling {1}{U}| Murktide Regent|Modern Horizons 2|52|M|{5}{U}{U}|Creature - Dragon|3|3|Delve$Flying$Murktide Regent enters the battlefield with a +1/+1 counter on it for each instant or sorcery card exiled with it.$Whenever an instant or sorcery card leaves your graveyard, put a +1/+1 counter on Murktide Regent.| Mystic Redaction|Modern Horizons 2|53|U|{2}{U}|Enchantment|||At the beginning of your upkeep, scry 1.$Whenever you discard a card, each opponent mills two cards.| +Parcel Myr|Modern Horizons 2|54|C|{1}{U}|Artifact Creature - Clue Myr|2|1|{2}, Sacrifice Parcel Myr: Draw a card.| Phantasmal Dreadmaw|Modern Horizons 2|55|C|{2}{U}{U}|Creature - Dinosaur Illusion|6|6|Trample$When Phantasmal Dreadmaw becomes the target of a spell or ability, sacrifice it.| Raving Visionary|Modern Horizons 2|56|U|{1}{U}|Creature - Merfolk Wizard|1|1|{U}, {T}: Draw a card, then discard a card.$Delirium — {2}{U}, {T}: Draw a card. Activate only if there are four or more card types among cards in your graveyard.| +Recalibrate|Modern Horizons 2|57|C|{1}{U}|Instant|||Return target creature to its owner's hand. If you've discarded a card this turn, draw a card.| Rise and Shine|Modern Horizons 2|58|R|{1}{U}|Sorcery|||Target noncreature artifact you control becomes a 0/0 artifact creature. Put four +1/+1 counters on each artifact that became a creature this way.$Overload {4}{U}{U}| Rishadan Dockhand|Modern Horizons 2|59|R|{U}|Creature - Merfolk|1|2|Islandwalk${1}, {T}: Tap target land.| Scuttletide|Modern Horizons 2|61|U|{1}{U}|Enchantment|||{1}, Discard a card: Create a 0/3 blue Crab creature token.$Delirium — Crabs you control get +1/+1 as long as there are four or more card types among cards in your graveyard.| @@ -41392,6 +41408,7 @@ Archfiend of Sorrows|Modern Horizons 2|74|U|{5}{B}{B}|Creature - Demon|4|5|Flyin Archon of Cruelty|Modern Horizons 2|75|M|{6}{B}{B}|Creature - Archon|6|6|Flying$Whenever Archon of Cruelty enters the battlefield or attacks, target opponent sacrifices a creature or planeswalker, discards a card, and loses 3 life. You draw a card and gain 3 life.| Bone Shards|Modern Horizons 2|76|C|{B}|Sorcery|||As an additional cost to cast this spell, sacrifice a creature or discard a card.$Destroy target creature or planeswalker.| Break the Ice|Modern Horizons 2|77|U|{B}{B}|Sorcery|||Destroy target land that is snow or could produce {C}.$Overload {4}{B}{B}| +Cabal Initiate|Modern Horizons 2|78|C|{1}{B}|Creature - Human Warlock|2|1|Discard a card: Cabal Initiate gains lifelink until end of turn.$Threshold — Cabal Initiate get +1/+2 as long as seven or more cards are in your graveyard.| Clattering Augur|Modern Horizons 2|79|U|{1}{B}|Creature - Skeleton Shaman|1|1|Clattering Augur can't block.$When Clattering Augur enters the battlefield, you draw a card and you lose 1 life.${2}{B}{B}: Return Clattering Augur from your graveyard to your hand.| Damn|Modern Horizons 2|80|R|{B}{B}|Sorcery|||Destroy target creature. A creature destroyed this way can't be regenerated.$Overload {2}{W}{W}| Dauthi Voidwalker|Modern Horizons 2|81|R|{B}{B}|Creature - Dauthi Rogue|3|2|Shadow$If a card would be put into an opponent's graveyard from anywhere, instead exile it with a void counter on it.${T}, Sacrifice Dauthi Voidwalker: Choose an exiled card an opponent owns with a void counter on it. You may play it this turn without paying its mana cost.| @@ -41399,23 +41416,33 @@ Discerning Taste|Modern Horizons 2|82|C|{2}{B}|Sorcery|||Look at the top four ca Echoing Return|Modern Horizons 2|83|C|{B}|Sorcery|||Return target creature card and all other cards with the same name as that card from your graveyard to your hand.| Feast of Sanity|Modern Horizons 2|84|U|{3}{B}|Enchantment|||Whenever you discard a card, Feast of Sanity deals 1 damage to any target and you gain 1 life.| Flay Essence|Modern Horizons 2|85|U|{1}{B}{B}|Sorcery|||Exile target creature or planeswalker. You gain life equal to the number of counters on it.| +Gilt-Blade Prowler|Modern Horizons 2|86|C|{2}{B}|Creature - Human Rogue|2|3|{1}, {T}, Pay 1 life: Draw a card. Activate only if you've discarded a card this turn.| Grief|Modern Horizons 2|87|M|{2}{B}{B}|Creature - Elemental Incarnation|3|2|Menace$When Grief enters the battlefield, target opponent reveals their hand. You choose a nonland card from it. That player discards that card.$Evoke—Exile a black card from your hand.| +Hell Mongrel|Modern Horizons 2|88|C|{3}{B}|Creature - Nightmare Dog|4|3|Discard a card: Hell Mongrel gets +1/+1 until end of turn.$Madness {2}{B}| Kitchen Imp|Modern Horizons 2|89|C|{3}{B}|Creature - Imp|2|2|Flying, haste$Madness {B}| Legion Vanguard|Modern Horizons 2|90|U|{1}{B}|Creature - Vampire Soldier|2|2|{1}, Sacrifice another creature: Legion Vanguard explores.| +Loathsome Curator|Modern Horizons 2|91|C|{4}{B}|Creature - Gorgon Wizard|5|4|Exploit$Menace$When Loathsome Curator exploits a creature, destroy target creature you don't control with mana value 3 or less.| Magus of the Bridge|Modern Horizons 2|92|R|{B}{B}{B}|Creature - Human Wizard|4|4|Whenever a nontoken creature is put into your graveyard from the battlefield, create a 2/2 black Zombie creature token.$When a creature is put into an opponent's graveyard from the battlefield, exile Magus of the Bridge.| +Necrogoyf|Modern Horizons 2|93|R|{3}{B}{B}|Creature - Lhurgoyf|*|4|Necrogoyf's power is equal to the number of creature cards in all graveyards.$At the beginning of each player's upkeep, that player discards a card.$Madness {1}{B}{B}| Necromancer's Familiar|Modern Horizons 2|94|U|{3}{B}|Creature - Bird Spirit|3|1|Flying$Hellbent — Necromancer's Familiar has lifelink as long as you have no cards in hand.${B}, Discard a card: Necromancer's Familiar gains indestructible until end of turn. Tap it.| +Nested Shambler|Modern Horizons 2|95|C|{B}|Creature - Zombie|1|1|When Nested Shambler dies, create X tapped 1/1 green Squirrel creature tokens, where X is Nested Shambler's power.| Persist|Modern Horizons 2|96|R|{1}{B}|Sorcery|||Return target nonlegendary creature card from your graveyard to the battlefield with a -1/-1 counter on it.| Profane Tutor|Modern Horizons 2|97|R||Sorcery|||Suspend 2—{1}{B}$Search your library for a card, put that card into your hand, then shuffle.| Radiant Epicure|Modern Horizons 2|98|U|{4}{B}|Creature - Vampire Wizard|5|5|Converge — When Radiant Epicure enters the battlefield, each opponent loses X life and you gain X life, where X is the number of colors of mana spent to cast this spell.| Sinister Starfish|Modern Horizons 2|99|C|{1}{B}|Creature - Starfish|0|3|{T}: Surveil 1.| Sudden Edict|Modern Horizons 2|100|U|{1}{B}|Instant|||Split second$Target player sacrifices a creature.| +Tizerus Charger|Modern Horizons 2|101|C|{2}{B}|Creature - Pegasus|3|2|Escape—{4}{B}, Exile five other cards from your graveyard.$Tizerus Charger escapes with your choice of a +1/+1 counter or a flying counter on it.| Tourach, Dread Cantor|Modern Horizons 2|102|M|{1}{B}|Legendary Creature - Human Cleric|2|1|Kicker {B}{B}$Protection from white$Whenever an opponent discards a card, put a +1/+1 counter on Tourach, Dread Cantor.$When Tourach enters the battelfield, if it was kicked, target opponent discards two cards at random.| Tourach's Canticle|Modern Horizons 2|103|C|{3}{B}|Sorcery|||Target opponent reveals their hand. You choose a card from it. That player discards that card, then discards a card at random.| +Tragic Fall|Modern Horizons 2|104|C|{1}{B}|Instant|||Target creature gets -3/-3 until end of turn.$Hellbent — That creature gets -13/-13 until end of turn instead if you have no cards in hand.| Underworld Hermit|Modern Horizons 2|105|U|{4}{B}{B}|Creature - Human Peasant|3|3|When Underworld Hermit enters the battlefield, create a number of 1/1 green Squirrel creature tokens equal to your devotion to black.| Unmarked Grave|Modern Horizons 2|106|R|{1}{B}|Sorcery|||Search your library for a nonlegendary card, put that card into your graveyard, then shuffle.| +Vermin Gorger|Modern Horizons 2|107|C|{1}{B}|Creature - Vampire|2|2|{T}, Sacrifice another creature: Each opponent loses 2 life and you gain 2 life.| +Vile Entomber|Modern Horizons 2|108|U|{2}{B}{B}|Creature - Zombie Warlock|2|2|Deathtouch$When Vile Entomber enters the battlefield, search your library for a card, put that card into your graveyard, then shuffle.| World-Weary|Modern Horizons 2|109|C|{3}{B}{B}|Enchantment - Aura|||Enchant creature$Enchanted creature gets -4/-4.$Basic landcycling {1}{B}| Young Necromancer|Modern Horizons 2|110|U|{4}{B}|Creature - Human Warlock|2|3|When Young Necromancer enters the battlefield, you may exile two cards from your graveyard. When you do, return target creature card from your graveyard to the battlefield.| Arcbound Slasher|Modern Horizons 2|111|C|{4}{R}|Artifact Creature - Cat|0|0|Modular 4$Riot| +Arcbound Tracker|Modern Horizons 2|112|C|{2}{R}|Artifact Creature - Dog|0|0|Menace$Modular 2$Whenever you cast a spell other than your first spell each turn, put a +1/+1 counter on Arcbound Tracker.| Arcbound Whelp|Modern Horizons 2|113|U|{3}{R}|Artifact Creature - Dragon|0|0|Flying${R}: Arcbound Whelp gets +1/+0 until end of turn.$Modular 2| Battle Plan|Modern Horizons 2|114|C|{3}{R}|Enchantment|||At the beginning of combat on your turn, target creature you control gets +2/+0 until end of turn.$Basic landcycling {1}{R}| Blazing Rootwalla|Modern Horizons 2|115|U|{R}|Creature - Lizard|1|1|{R}: Blazing Rootwalla gets +2/+0 until end of turn. Activate only once each turn.$Madness {0}| @@ -41431,35 +41458,51 @@ Flame Blitz|Modern Horizons 2|124|U|{R}|Enchantment|||At the beginning of your e Flametongue Yearling|Modern Horizons 2|125|U|{R}{R}|Creature - Kavu|2|1|Multikicker {2}$Flametongue Yearling enters the battlefield with a +1/+1 counter on it for each time it was kicked.$When Flametongue Yearling enters the battlefield, it deals damage equal to its power to target creature.| Fury|Modern Horizons 2|126|M|{3}{R}{R}|Creature - Elemental Incarnation|3|3|Double strike$When Fury enters the battlefield, it deals 4 damage divided as you choose among any number of target creatures and/or planeswalkers.$Evoke—Exile a red card from your hand.| Galvanic Relay|Modern Horizons 2|127|C|{2}{R}|Sorcery|||Exile the top card of your library. During your next turn, you may play that card.$Storm| +Gargadon|Modern Horizons 2|128|C|{5}{R}{R}|Creature - Beast|7|5|Trample$Suspend 4—{1}{R}| Glimpse of Tomorrow|Modern Horizons 2|129|R||Sorcery|||Suspend 3—{R}{R}$Shuffle all permanents you own into your library, then reveal that many cards from the top of your library. Put all non-Aura permanent cards revealed this way onto the battlefield, then do the same for Aura cards, then put the rest on the bottom of your library in a random order.| +Gouged Zealot|Modern Horizons 2|131|C|{3}{R}|Creature - Cyclops Berserker|4|3|Reach$Delirium — Whenever Gouged Zealot attacks, if there are four or more card types among cards in your graveyard, Gouged Zealot deals 1 damage to each creature defending player controls.| Harmonic Prodigy|Modern Horizons 2|132|R|{1}{R}|Creature - Human Wizard|1|3|Prowess$If an ability of a Shaman or another Wizard you control triggers, that ability triggers an additional time.| Kaleidoscorch|Modern Horizons 2|133|U|{1}{R}|Sorcery|||Converge — Kaleidoscorch deals X damage to any target, where X is the number of colors of mana spent to cast this spell.$Flashback {4}{R}| +Lightning Spear|Modern Horizons 2|134|C|{1}{R}|Artifact - Equipment|||Equipped creature gets +1/+0 and has trample.${2}{R}, Sacrifice Lightning Spear: It deals 3 damage to any target.$Equip {1}| +Mine Collapse|Modern Horizons 2|135|C|{3}{R}|Instant|||If it's your turn, you may sacrifice a Mountain rater than pay this spell's mana cost.$Mine Collapse deals 5 damage to target creature or planeswalker.| +Mount Velus Manticore|Modern Horizons 2|136|C|{2}{R}{R}|Enchantment Creature - Manticore|3|4|At the beginning of combat on your turn, you may discard a card. When you do, Mount Velus Manticore deals X damage to any target, where X is the number of card types the discarded card has.| Obsidian Charmaw|Modern Horizons 2|137|R|{3}{R}{R}|Creature - Dragon|4|4|This spell costs {1} less to cast for each land your opponents control that could produce {C}.$Flying$When Obsidian Charmaw enters the battlefield, destroy target nonbasic land an opponent controls.| Ragavan, Nimble Pilferer|Modern Horizons 2|138|M|{R}|Legendary Creature - Monkey Pirate|2|1|Whenever Ragavan, Nimble Pilferer deals combat damage to a player, create a Treasure token and exile the top card of that player's library. Until end of turn, you may cast that card.$Dash {1}{R}| +Revolutionist|Modern Horizons 2|139|C|{5}{R}|Creature - Human Wizard|3|3|When Revolutionist enters the battlefield, return target instant or sorcery card from your graveyard to your hand.$Madness {3}{R}| Skophos Reaver|Modern Horizons 2|140|C|{2}{R}|Creature - Minotaur Warrior|2|3|As long as it's your turn, Skophos Reaver gets +2/+0.$Madness {1}{R}| Slag Strider|Modern Horizons 2|141|U|{5}{R}{R}|Creature - Elemental|3|3|Affinity for artifacts${1}, Sacrifice an artifact: Slag Strider deals 1 damage to any target.| Spreading Insurrection|Modern Horizons 2|142|U|{4}{R}|Sorcery|||Gain control of target creature you don't control until end of turn. Untap that creature. It gains haste until end of turn.$Storm| Strike It Rich|Modern Horizons 2|143|U|{R}|Sorcery|||Create a Treasure token.$Flashback {2}{R}| Tavern Scoundrel|Modern Horizons 2|144|C|{1}{R}|Creature - Human Rogue|1|3|Whenever you win a coin flip, create two Treasure tokens.${1}, {T}, Sacrifice another permanent: Flip a coin.| +Unholy Heat|Modern Horizons 2|145|C|{R}|Instant|||Unholy Heat deals 2 damage to target creature or planeswalker.$Delirium — Unholy Heat deals 6 damage instead if there are four or more card types among cards in your graveyard.| +Viashino Lashclaw|Modern Horizons 2|146|C|{1}{R}|Creature - Viashino Warrior|2|2|{T}, Discard a card: Creatures you control gain haste until end of turn.| Abundant Harvest|Modern Horizons 2|147|C|{G}|Sorcery|||Choose land or nonland. Reveal cards from the top of your library until you reveal a card of the chosen kind. Put that card into your hand and the rest on the bottom of your library in a random order.| -Aeve, Progenitor Ooze|Modern Horizons 2|148|R|{2}{G}{G}{G}|Legendary Creature - Ooze|2|2|Storm$Aeve, Progenitor Ooze isn't legendary as long as it's a token.$Aeve enters the battlefield with a +1/+1 counter on it for each Ooze you control.| +Aeve, Progenitor Ooze|Modern Horizons 2|148|R|{2}{G}{G}{G}|Legendary Creature - Ooze|2|2|Storm$Aeve, Progenitor Ooze isn't legendary as long as it's a token.$Aeve enters the battlefield with a +1/+1 counter on it for each other Ooze you control.| +Bannerhide Krushok|Modern Horizons 2|149|C|{3}{G}|Creature - Beast|4|4|Trample$Reinforce 2—{1}{G}$Scavenge {5}{G}{G}| +Blessed Respite|Modern Horizons 2|150|U|{1}{G}|Instant|||Target player shuffles their graveyard into their library. Prevent all combat damage that would be dealt this turn.| Chatterfang, Squirrel General|Modern Horizons 2|151|M|{2}{G}|Legendary Creature - Squirrel Warrior|3|3|Forestwalk$If one or more tokens would be created under your control, those tokens plus that many 1/1 green Squirrel creature tokens are created instead.${B}, Sacrifice X Squirrels: Target creature gets +X/-X until end of turn.| Chatterstorm|Modern Horizons 2|152|C|{1}{G}|Sorcery|||Create a 1/1 green Squirrel creature token.$Storm| Chitterspitter|Modern Horizons 2|153|R|{2}{G}|Artifact|||At the beginning of your upkeep, you may sacrifice a token. If you do, put an acorn counter on Chitterspitter.$Squirrels you control get +1/+1 for each acorn counter on Chitterspitter.${G}, {T}: Create a 1/1 green Squirrel creature token.| +Crack Open|Modern Horizons 2|154|C|{2}{G}|Sorcery|||Destroy target artifact or enchantment. Create a Treasure token.| +Deepwood Denizen|Modern Horizons 2|155|C|{2}{G}|Creature - Elf Warrior|3|2|Vigilance${5}{G}, {T}: Draw a card. This ability costs {1} less to activate for each +1/+1 counter on creatures you control.| +Duskshell Crawler|Modern Horizons 2|156|C|{1}{G}|Creature - Insect|0|3|When Duskshell Crawler enters the battlefield, put a +1/+1 counter on target creature.$Each creature you control with a +1/+1 counter on it has trample.| Endurance|Modern Horizons 2|157|M|{1}{G}{G}|Creature - Elemental Incarnation|3|4|Flash$Reach$When Endurance enters the battlefield, up to one target player puts all the cards from their graveyard on the bottom of their library in a random order.$Evoke—Exile a green card from your hand.| Fae Offering|Modern Horizons 2|158|U|{2}{G}|Enchantment|||At the beginning of each end step, if you've cast both a creature spell and a noncreature spell this turn, create a Clue token, a Food token, and a Treasure token.| +Flourishing Strike|Modern Horizons 2|159|C|{1}{G}|Instant|||Choose one —$• Flourishing Strike deals 5 damage to target creature with flying.$• Target creature gets +3/+3 until end of turn.$Entwine {2}{G}| Foundation Breaker|Modern Horizons 2|160|U|{3}{G}|Creature - Elemental|2|2|When Foundation Breaker enters the battlefield, you may destroy target artifact or enchantment.$Evoke {1}{G}| Funnel-Web Recluse|Modern Horizons 2|161|C|{4}{G}|Creature - Spider|3|5|Reach$Morbid — When Funnel-Web Recluse enters the battlefield, if a creature died this turn, investigate.| Gaea's Will|Modern Horizons 2|162|R||Sorcery|||Suspend 4—{G}$Until end of turn, you may play lands and cast spells from your graveyard.$If a card would be put into your graveyard from anywhere this turn, exile that card instead.| -Wren's Run Hydra|Modern Horizons 2|163|U|{X}{G}|Creature - Hydra|0|0|Reach$Wren's Run Hydra enters the battlefield with X +1/+1 counters on it.$Reinforce X—{X}{G}{G}| +Glimmer Bairn|Modern Horizons 2|163|C|{G}|Creature - Ouphe|1|2|Sacrifice a token: Glimmer Bairn gets +2/+2 until end of turn.| Glinting Creeper|Modern Horizons 2|164|U|{4}{G}|Creature - Plant|0|0|Converge — Glinting Creeper enters the battlefield with two +1/+1 counters on it for each color of mana spent to cast it.$Glinting Creeper can't be blocked by creatures with power 2 or less.| Herd Baloth|Modern Horizons 2|165|U|{3}{G}{G}|Creature - Beast|4|4|Whenever one or more +1/+1 counters are put on Herd Baloth, you may create a 4/4 green Beast creature token.| Ignoble Hierarch|Modern Horizons 2|166|R|{G}|Creature - Goblin Shaman|0|1|Exalted${T}: Add {B}, {R}, or {G}.| Jade Avenger|Modern Horizons 2|167|C|{1}{G}|Creature - Frog Samurai|2|2|Bushido 2| +Jewel-Eyed Cobra|Modern Horizons 2|168|C|{2}{G}|Creature - Snake|3|1|Deathtouch$When Jewel-Eyed Cobra dies, create a Treasure token.| Orchard Strider|Modern Horizons 2|169|C|{4}{G}{G}|Creature - Treefolk|6|4|When Orchard Strider enters the battlefield, create two Food tokens.$Basic landcycling {1}{G}| Rift Sower|Modern Horizons 2|170|C|{2}{G}|Creature - Elf Druid|1|3|{T}: Add one mana of any color.$Suspend 2—{G}| Sanctum Weaver|Modern Horizons 2|171|R|{1}{G}|Enchantment Creature - Dryad|0|2|{T}: Add X mana of any one color, where X is the number of enchantments you control.| Scurry Oak|Modern Horizons 2|172|U|{2}{G}|Creature - Treefolk|1|2|Evolve$Whenever one or more +1/+1 counters are put on Scurry Oak, you may create a 1/1 green Squirrel creature token.| +Smell Fear|Modern Horizons 2|173|C|{1}{G}|Sorcery|||Proliferate.$Target creature you control fights up to one target creature you don't control.| Squirrel Sanctuary|Modern Horizons 2|174|U|{G}|Enchantment|||When Squirrel Sanctuary enters the battlefield, create a 1/1 green Squirrel creature token.$Whenever a nontoken creature you control dies, you may pay {1}. If you do, return Squirrel Sanctuary to its owner's hand.| Squirrel Sovereign|Modern Horizons 2|175|U|{1}{G}|Creature - Squirrel Noble|2|2|Other Squirrels you control get +1/+1.| Sylvan Anthem|Modern Horizons 2|176|R|{G}{G}|Enchantment|||Green creatures you control get +1/+1.$Whenever a green creature enters the battlefield under your control, scry 1.| @@ -41469,6 +41512,7 @@ Timeless Witness|Modern Horizons 2|179|U|{2}{G}{G}|Creature - Human Shaman|2|1|W Tireless Provisioner|Modern Horizons 2|180|U|{2}{G}|Creature - Elf Scout|3|2|Landfall — Whenever a land enters the battelfield under your control, create a Food token or a Treasure token.| Urban Daggertooth|Modern Horizons 2|181|C|{2}{G}{G}|Creature - Dinosaur|4|3|Vigilance$Enrage — Whenever Urban Daggertooth is dealt damage, proliferate.| Verdant Command|Modern Horizons 2|182|R|{1}{G}|Instant|||Choose two —$• Target player creates two tapped 1/1 green Squirrel creature tokens.$• Counter target loyalty ability of a planeswalker.$• Exile target card from a graveyard.$• Target player gains 3 life.| +Wren's Run Hydra|Modern Horizons 2|183|U|{X}{G}|Creature - Hydra|0|0|Reach$Wren's Run Hydra enters the battlefield with X +1/+1 counters on it.$Reinforce X—{X}{G}{G}| Arcbound Shikari|Modern Horizons 2|184|U|{1}{R}{W}|Artifact Creature - Cat Soldier|0|0|First strike$When Arcbound Shikari enters the battlefield, put a +1/+1 counter on each other artifact creature you control.$Modular 2| Arcus Acolyte|Modern Horizons 2|185|U|{G}{W}|Creature - Human Cleric Archer|2|2|Reach, lifelink$Outlast {G/W}$Each other creature you control without a +1/+1 counter on it has outlast {G/W}.| Asmoranomardicadaistinaculdacar|Modern Horizons 2|186|R||Legendary Creature - Human Wizard|3|3|As long as you've discarded a card this turn, you may pay {B/R} to cast this spell.$When Asmoranomardicadaistinaculdacar enters the battlefield, you may search your library for a card named The Underworld Cookbook, reveal it, put it into your hand, then shuffle.$Sacrifice two Foods: Target creature deals 6 damage to itself.| @@ -41478,8 +41522,10 @@ Carth the Lion|Modern Horizons 2|189|R|{2}{B}{G}|Legendary Creature - Human Warr Chrome Courier|Modern Horizons 2|190|C|{1}{W}{U}|Artifact Creature - Thopter|1|1|Flying$When Chrome Courier enters the battlefield, reveal the top two cards of your library. Put one of them into your hand and the other into your graveyard. If you put an artifact card into your hand this way, you gain 3 life.| Combine Chrysalis|Modern Horizons 2|191|U|{G}{U}|Artifact|||Creature tokens you control have flying.${2}{G}{U}, {T}, Sacrifice a token: Create a 4/4 green Beast creature token. Activate only as a sorcery.| Dakkon, Shadow Slayer|Modern Horizons 2|192|M|{W}{U}{B}|Legendary Planeswalker - Dakkon|0|Dakkon, Shadow Slayer enters the battlefield with a number of loyalty counters on him equal to the number of lands you control.$+1: Surveil 2.$−3: Exile target creature.$−6: You may put an artifact card from your hand or graveyard onto the battlefield.| +Dihada's Ploy|Modern Horizons 2|193|C|{1}{U}{B}|Instant|||Draw two cards, then discard a card. You gain life equal to the number of cards you've discarded this turn.$Jump-start| Drey Keeper|Modern Horizons 2|194|C|{3}{B}{G}|Creature - Elf Druid|2|2|When Drey Keeper enters the battlefield, create two 1/1 green Squirrel creature tokens.${3}{B}: Squirrels you control get +1/+0 and gain menace until end of turn.| Ethersworn Sphinx|Modern Horizons 2|195|U|{7}{W}{U}|Artifact Creature - Sphinx|4|4|Affinity for artifacts$Flying$Cascade| +Foundry Helix|Modern Horizons 2|196|C|{1}{R}{W}|Instant|||As an additional cost to cast this spell, sacrifice a permanent.$Foundry Helix deals 4 damage to any target. If the sacrificed permanent was an artifact, you gain 4 life.| Garth One-Eye|Modern Horizons 2|197|M|{W}{U}{B}{R}{G}|Legendary Creature - Human Wizard|5|5|{T}: Choose a card name that hasn't been chosen from among Disenchant, Braingeyser, Terror, Shivan Dragon, Regrowth, and Black Lotus. Create a copy of the card with the chosen name. You may cast the copy.| General Ferrous Rokiric|Modern Horizons 2|198|R|{1}{R}{W}|Legendary Creature - Human Soldier|3|1|Hexproof from monocolored$Whenever you cast a multicolored spell, create a 4/4 red and white Golem artifact creature token.| Geyadrone Dihada|Modern Horizons 2|199|M|{1}{U}{B}{R}|Legendary Planeswalker - Dihada|4|Protection from permanents with corruption counters on them$+1: Each opponent loses 2 life and you gain 2 life. Put a corruption counter on up to one other target creature or planeswalker.$−3: Gain control of target creature or planeswalker until end of tun. Untap it and put a corruption counter on it. It gains haste until end of turn.$−7: Gain control of each permanent with a corruption counter on it.| @@ -41496,8 +41542,11 @@ Prophetic Titan|Modern Horizons 2|209|U|{4}{U}{R}|Creature - Giant Wizard|4|4|De Rakdos Headliner|Modern Horizons 2|210|U|{B}{R}|Creature - Devil|3|3|Haste$Echo—Discard a card.| Ravenous Squirrel|Modern Horizons 2|211|U|{B/G}|Creature - Squirrel|1|1|Whenever you sacrifice an artifact or creature, put a +1/+1 counter on Ravenous Squirrel.${1}{B}{G}, Sacrifice an artifact or creature: You gain 1 life and draw a card.| Road // Ruin|Modern Horizons 2|212|U|{2}{G}|Instant|||Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.$Ruin${1}{R}{R}$Sorcery$Aftermath$Ruin deals damage to target creature equal to the number of lands you control.| +Storm God's Oracle|Modern Horizons 2|213|C|{1}{U}{R}|Enchantment Creature - Human Shaman|1|3|{1}: Storm God's Oracle gets +1/-1 until end of turn.$When Storm God's Oracle dies, it deals 3 damage to any target.| Sythis, Harvest's Hand|Modern Horizons 2|214|R|{G}{W}|Legendary Enchantment Creature - Nymph|1|2|Whenever you cast an enchantment spell, you gain 1 life and draw a card.| +Terminal Agony|Modern Horizons 2|215|C|{2}{B}{R}|Sorcery|||Destroy target creature.$Madness {B}{R}| Territorial Kavu|Modern Horizons 2|216|R|{R}{G}|Creature - Kavu|*|*|Domain — Territorial Kavu's power and toughness are each equal to the number of basic land types among lands you control.$Whenever Territorial Kavu attacks, choose one —$• Discard a card. If you do, draw a card.$• Exile up to one target card from a graveyard.| +Wavesifter|Modern Horizons 2|217|C|{3}{G}{U}|Creature - Elemental|3|2|Flying$When Wavesifter enters the battlefield, investigate twice.$Evoke {G}{U}| Yusri, Fortune's Flame|Modern Horizons 2|218|R|{1}{U}{R}|Legendary Creature - Efreet|2|3|Flying$Whenever Yusri, Fortune's Flame attacks, choose a number between 1 and 5. Flip that many coins. For each flip you win, draw a card. For each flip you lose, Yursi deals 2 damage to you. If you won five flips this way, you may cast spells from your hand this turn without paying their mana costs.| Academy Manufactor|Modern Horizons 2|219|R|{3}|Artifact Creature - Assembly-Worker|1|3|If you would create a Clue, Food, or Treasure token, instead create one of each.| Altar of the Goyf|Modern Horizons 2|220|U|{5}|Tribal Artifact - Lhurgoyf|||Whenever a creature you control attacks alone, it gets +X/+X until end of turn, where X is the number of card types among cards in all graveyard.$Lhurgoyf creatures you control have trample.| @@ -41506,13 +41555,16 @@ Bottle Golems|Modern Horizons 2|222|C|{4}|Artifact Creature - Golem|3|3|Trample$ Brainstone|Modern Horizons 2|223|U|{1}|Artifact|||{2},{T}, Sacrifice Brainstone: Draw three cards, then put two cards from your hand on top of your library in any order.| Dermotaxi|Modern Horizons 2|224|R|{2}|Artifact - Vehicle|0|0|Imprint — As Dermotaxi enters the battlefield, exile a creature card from a graveyard.$Tap two untapped creatures you control: Until end of turn, Dermotaxi becomes a copy of the imprinted card, except it's a Vehicle artifact in addition to its other types.| Diamond Lion|Modern Horizons 2|225|R|{2}|Artifact Creature - Cat|2|2|{T}, Discard your hand, Sacrifice Diamond Lion: Add three mana of any one color. Activate only as an instant.| +Fodder Tosser|Modern Horizons 2|226|C|{3}|Artifact|||{T}, Discard a card: Fodder Tosser deals 2 damage to target player or planeswalker.| Kaldra Compleat|Modern Horizons 2|227|M|{7}|Legendary Artifact - Equipment|||Living weapon$Indestructible$Equipped creature gets +5/+5 and has first strike, trample, indestructible, haste, and "Whenever this creature deals combat damage to a creature, exile that creature."$Equip {7}| Liquimetal Torque|Modern Horizons 2|228|U|{2}|Artifact|||{T}: Add {C}.${T}: Target nonland permanent becomes an artifact in addition to its other types until end of turn.| Monoskelion|Modern Horizons 2|229|U|{2}|Artifact Creature - Construct|1|1|Monoskelion enters the battlefield with a +1/+1 counter on it.${1}, Remove a +1/+1 counter from Monoskelion: Monoskelion deals 1 damage to any target.| +Myr Scrapling|Modern Horizons 2|230|C|{1}|Artifact Creature - Myr|1|1|Sacrifice Myr Scrapling: Put a +1/+1 counter on target creature.| Nettlecyst|Modern Horizons 2|231|R|{3}|Artifact - Equipment|||Living weapon$Equipped creature gets +1/+1 for each artifact and/or enchantment you control.$Equip {2}| Ornithopter of Paradise|Modern Horizons 2|232|C|{2}|Artifact Creature - Thopter|0|2|Flying${T}: Add one mana of any color.| Sanctuary Raptor|Modern Horizons 2|233|U|{3}|Artifact Creature - Bird|2|1|Flying$Whenever Sanctuary Raptor attacks, if you control three or more tokens, Sanctuary Raptor gets +2/+0 and gains first strike until end of turn.| Scion of Draco|Modern Horizons 2|234|M|{12}|Artifact Creature - Dragon|4|4|Domain — This spell costs {2} less to cast for each basic land type among lands you control.$Flying$Each creature you control has vigilance if it's white, hexproof if it's blue, lifelink if it's black, first strike if it's red, and trample if it's green.| +Sojourner's Companion|Modern Horizons 2|235|C|{7}|Artifact Creature - Salamander|4|4|Affinity for artifacts$Artifact landcycling {2}| Sol Talisman|Modern Horizons 2|236|R||Artifact|||Suspend 3—{1}${T}: Add {C}{C}.| Steel Dromedary|Modern Horizons 2|237|U|{3}|Artifact Creature - Camel|2|2|Steel Dromedary enters the battlefield tapped with two +1/+1 counters on it.$Steel Dromedary doesn't untap during your untap step if it has a +1/+1 counter on it.$At the beginning of combat on your turn, you may move a +1/+1 counter from Steel Dromedary onto target creature.| Sword of Hearth and Home|Modern Horizons 2|238|M|{3}|Artifact - Equipment|||Equipped creature gets +2/+2 and has protection from green and from white.$Whenever equipped creature deals combat damage to a player, exile up to one target creature you own, then search your library for a basic land card. Put both cards onto the battlefield under your control, then shuffle.$Equip {2}| @@ -41538,7 +41590,7 @@ Thornglint Bridge|Modern Horizons 2|258|C||Artifact Land|||Thornglint Bridge ent Urza's Saga|Modern Horizons 2|259|R||Enchantment Land - Urza’s Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I — Urza's Saga gains "{T}: Add {C}."$II — Urza's Saga gains "{2}, {T}: Create a 0/0 colorless Construct artifact creature token with 'This creature gets +1/+1 for each artifact you control.'"$III — Search your library for an artifact card with mana cost {0} or {1}, put it onto the battlefield, then shuffle.| Verdant Catacombs|Modern Horizons 2|260|R||Land|||{T}, Pay 1 life, Sacrifice Verdant Catacombs: Search your library for a Swamp or Forest card, put it onto the battlefield, then shuffle.| Yavimaya, Cradle of Growth|Modern Horizons 2|261|R||Legendary Land|||Each land is a Forest in addition to its other land types.| -Angelic Curator|Modern Horizons 2|262|C|{1}{W}|Creature - Angel Spirit|1|1|Flying, protection from artifacts| +Angelic Curator|Modern Horizons 2|262|U|{1}{W}|Creature - Angel Spirit|1|1|Flying, protection from artifacts| Karmic Guide|Modern Horizons 2|263|R|{3}{W}{W}|Creature - Angel Spirit|2|2|Flying, protection from black$Echo {3}{W}{W}$When Karmic Guide enters the battlefield, return target creature card from your graveyard to the battlefield.| Seal of Cleansing|Modern Horizons 2|264|U|{1}{W}|Enchantment|||Sacrifice Seal of Cleansing: Destroy target artifact or enchantment.| Solitary Confinement|Modern Horizons 2|265|R|{2}{W}|Enchantment|||At the beginning of your upkeep, sacrifice Solitary Confinement unless you discard a card.$Skip your draw step.$You have shroud.$Prevent all damage that would be dealt to you.| @@ -41580,8 +41632,6 @@ Zuran Orb|Modern Horizons 2|300|U|{0}|Artifact|||Sacrifice a land: You gain 2 li Cabal Coffers|Modern Horizons 2|301|M||Land|||{2}, {T}: Add {B} for each Swamp you control.| Mishra's Factory|Modern Horizons 2|302|U||Land|||{T}: Add {C}.${1}: Mishra's Factory becomes a 2/2 Assembly-Worker artifact creature until end of turn. It's still a land.${T}: Target Assembly-Worker creature gets +1/+1 until end of turn.| Riptide Laboratory|Modern Horizons 2|303|R||Land|||{T}: Add {C}.${1}{U}, {T}: Return target Wizard you control to its owner's hand.| -Vile Entomber|Modern Horizons 2|403|U|{2}{B}{B}|Creature - Zombie Warlock|2|2|Deathtouch$When Vile Entomber enters the battlefield, search your library for a card, put that card into your graveyard, then shuffle.| -Glimmer Bairn|Modern Horizons 2|413|C|{G}|Creature - Ouphe|1|2|Sacrifice a token: Glimmer Bairn gets +2/+2 until end of turn.| Plains|Modern Horizons 2|481|C||Basic Land - Plains|||({T}: Add {W}.)| Island|Modern Horizons 2|483|C||Basic Land - Island|||({T}: Add {U}.)| Swamp|Modern Horizons 2|485|C||Basic Land - Swamp|||({T}: Add {B}.)| From 4c48a29685c639424899a6bd9cc57857a5f40132 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:04:26 -0400 Subject: [PATCH 089/188] [MH2] Implemented Arcbound Prototype --- .../src/mage/cards/a/ArcboundPrototype.java | 36 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 37 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/ArcboundPrototype.java diff --git a/Mage.Sets/src/mage/cards/a/ArcboundPrototype.java b/Mage.Sets/src/mage/cards/a/ArcboundPrototype.java new file mode 100644 index 00000000000..468ac2b1e00 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArcboundPrototype.java @@ -0,0 +1,36 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.keyword.ModularAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ArcboundPrototype extends CardImpl { + + public ArcboundPrototype(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.ASSEMBLY_WORKER); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // Modular 2 + this.addAbility(new ModularAbility(this, 2)); + } + + private ArcboundPrototype(final ArcboundPrototype card) { + super(card); + } + + @Override + public ArcboundPrototype copy() { + return new ArcboundPrototype(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 726caede758..b9d8d53f95e 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -34,6 +34,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Angelic Curator", 262, Rarity.UNCOMMON, mage.cards.a.AngelicCurator.class)); cards.add(new SetCardInfo("Arcbound Javelineer", 2, Rarity.UNCOMMON, mage.cards.a.ArcboundJavelineer.class)); cards.add(new SetCardInfo("Arcbound Mouser", 3, Rarity.COMMON, mage.cards.a.ArcboundMouser.class)); + cards.add(new SetCardInfo("Arcbound Prototype", 4, Rarity.COMMON, mage.cards.a.ArcboundPrototype.class)); cards.add(new SetCardInfo("Arcbound Shikari", 184, Rarity.UNCOMMON, mage.cards.a.ArcboundShikari.class)); cards.add(new SetCardInfo("Arcbound Slasher", 111, Rarity.COMMON, mage.cards.a.ArcboundSlasher.class)); cards.add(new SetCardInfo("Arcbound Whelp", 113, Rarity.UNCOMMON, mage.cards.a.ArcboundWhelp.class)); From 23fe55f5adbc8097a4109f196315418fefc3d727 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:06:34 -0400 Subject: [PATCH 090/188] [MH2] Implemented Marble Gargoyle --- .../src/mage/cards/m/MarbleGargoyle.java | 45 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 46 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MarbleGargoyle.java diff --git a/Mage.Sets/src/mage/cards/m/MarbleGargoyle.java b/Mage.Sets/src/mage/cards/m/MarbleGargoyle.java new file mode 100644 index 00000000000..3bbc44d2f39 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MarbleGargoyle.java @@ -0,0 +1,45 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MarbleGargoyle extends CardImpl { + + public MarbleGargoyle(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.GARGOYLE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {W}: Marble Gargoyle gets +0/+1 until end of turn. + this.addAbility(new SimpleActivatedAbility( + new BoostSourceEffect(0, 1, Duration.EndOfTurn), new ManaCostsImpl<>("{W}") + )); + } + + private MarbleGargoyle(final MarbleGargoyle card) { + super(card); + } + + @Override + public MarbleGargoyle copy() { + return new MarbleGargoyle(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index b9d8d53f95e..a4ddaa7aa11 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -134,6 +134,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Liquimetal Torque", 228, Rarity.UNCOMMON, mage.cards.l.LiquimetalTorque.class)); cards.add(new SetCardInfo("Lose Focus", 49, Rarity.COMMON, mage.cards.l.LoseFocus.class)); cards.add(new SetCardInfo("Lucid Dreams", 50, Rarity.UNCOMMON, mage.cards.l.LucidDreams.class)); + cards.add(new SetCardInfo("Marble Gargoyle", 21, Rarity.COMMON, mage.cards.m.MarbleGargoyle.class)); cards.add(new SetCardInfo("Marsh Flats", 248, Rarity.RARE, mage.cards.m.MarshFlats.class)); cards.add(new SetCardInfo("Master of Death", 205, Rarity.RARE, mage.cards.m.MasterOfDeath.class)); cards.add(new SetCardInfo("Mental Journey", 51, Rarity.COMMON, mage.cards.m.MentalJourney.class)); From 5f01d00f08ab6216006a0aeb0c74795f69e2f76a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:08:05 -0400 Subject: [PATCH 091/188] [MH2] Implemented Soul of Migration --- .../src/mage/cards/s/SoulOfMigration.java | 46 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SoulOfMigration.java diff --git a/Mage.Sets/src/mage/cards/s/SoulOfMigration.java b/Mage.Sets/src/mage/cards/s/SoulOfMigration.java new file mode 100644 index 00000000000..0ae5a3c590b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoulOfMigration.java @@ -0,0 +1,46 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.EvokeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.BirdToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SoulOfMigration extends CardImpl { + + public SoulOfMigration(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}{W}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Soul of Migration enters the battlefield, create two 1/1 white Bird creature tokens with flying. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new BirdToken(), 2))); + + // Evoke {3}{W} + this.addAbility(new EvokeAbility("{3}{W}")); + } + + private SoulOfMigration(final SoulOfMigration card) { + super(card); + } + + @Override + public SoulOfMigration copy() { + return new SoulOfMigration(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index a4ddaa7aa11..24df47673f4 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -198,6 +198,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Solitary Confinement", 265, Rarity.RARE, mage.cards.s.SolitaryConfinement.class)); cards.add(new SetCardInfo("Solitude", 32, Rarity.MYTHIC, mage.cards.s.Solitude.class)); cards.add(new SetCardInfo("Soul Snare", 266, Rarity.UNCOMMON, mage.cards.s.SoulSnare.class)); + cards.add(new SetCardInfo("Soul of Migration", 33, Rarity.COMMON, mage.cards.s.SoulOfMigration.class)); cards.add(new SetCardInfo("Specimen Collector", 64, Rarity.UNCOMMON, mage.cards.s.SpecimenCollector.class)); cards.add(new SetCardInfo("Spreading Insurrection", 142, Rarity.UNCOMMON, mage.cards.s.SpreadingInsurrection.class)); cards.add(new SetCardInfo("Squirrel Mob", 286, Rarity.RARE, mage.cards.s.SquirrelMob.class)); From f1128a587815957610966422a9478f87a02877a5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:09:09 -0400 Subject: [PATCH 092/188] [MH2] Implemented Parcel Myr --- Mage.Sets/src/mage/cards/p/ParcelMyr.java | 45 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 46 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/ParcelMyr.java diff --git a/Mage.Sets/src/mage/cards/p/ParcelMyr.java b/Mage.Sets/src/mage/cards/p/ParcelMyr.java new file mode 100644 index 00000000000..a52322bf5d0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/ParcelMyr.java @@ -0,0 +1,45 @@ +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ParcelMyr extends CardImpl { + + public ParcelMyr(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.CLUE); + this.subtype.add(SubType.MYR); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // {2}, Sacrifice Parcel Myr: Draw a card + Ability ability = new SimpleActivatedAbility( + new DrawCardSourceControllerEffect(1), new GenericManaCost(2) + ); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); + } + + private ParcelMyr(final ParcelMyr card) { + super(card); + } + + @Override + public ParcelMyr copy() { + return new ParcelMyr(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 24df47673f4..668403f14bb 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -154,6 +154,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Obsidian Charmaw", 137, Rarity.RARE, mage.cards.o.ObsidianCharmaw.class)); cards.add(new SetCardInfo("Orchard Strider", 169, Rarity.COMMON, mage.cards.o.OrchardStrider.class)); cards.add(new SetCardInfo("Ornithopter of Paradise", 232, Rarity.COMMON, mage.cards.o.OrnithopterOfParadise.class)); + cards.add(new SetCardInfo("Parcel Myr", 54, Rarity.COMMON, mage.cards.p.ParcelMyr.class)); cards.add(new SetCardInfo("Patchwork Gnomes", 299, Rarity.COMMON, mage.cards.p.PatchworkGnomes.class)); cards.add(new SetCardInfo("Patriarch's Bidding", 275, Rarity.RARE, mage.cards.p.PatriarchsBidding.class)); cards.add(new SetCardInfo("Phantasmal Dreadmaw", 55, Rarity.COMMON, mage.cards.p.PhantasmalDreadmaw.class)); From 480795ad2d47db550966fa218acbae653af199ed Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:10:25 -0400 Subject: [PATCH 093/188] [MH2] Implemented Hell Mongrel --- Mage.Sets/src/mage/cards/h/HellMongrel.java | 47 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 48 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HellMongrel.java diff --git a/Mage.Sets/src/mage/cards/h/HellMongrel.java b/Mage.Sets/src/mage/cards/h/HellMongrel.java new file mode 100644 index 00000000000..334b84710b5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HellMongrel.java @@ -0,0 +1,47 @@ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.MadnessAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HellMongrel extends CardImpl { + + public HellMongrel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.NIGHTMARE); + this.subtype.add(SubType.DOG); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Discard a card: Hell Mongrel gets +1/+1 until end of turn. + this.addAbility(new SimpleActivatedAbility( + new BoostSourceEffect(1, 1, Duration.EndOfTurn), new DiscardCardCost() + )); + + // Madness {2}{B} + this.addAbility(new MadnessAbility(this, new ManaCostsImpl<>("{2}{B}"))); + } + + private HellMongrel(final HellMongrel card) { + super(card); + } + + @Override + public HellMongrel copy() { + return new HellMongrel(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 668403f14bb..5f8eadc5cf2 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -117,6 +117,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Grief", 87, Rarity.MYTHIC, mage.cards.g.Grief.class)); cards.add(new SetCardInfo("Hard Evidence", 46, Rarity.COMMON, mage.cards.h.HardEvidence.class)); cards.add(new SetCardInfo("Harmonic Prodigy", 132, Rarity.RARE, mage.cards.h.HarmonicProdigy.class)); + cards.add(new SetCardInfo("Hell Mongrel", 88, Rarity.COMMON, mage.cards.h.HellMongrel.class)); cards.add(new SetCardInfo("Herd Baloth", 165, Rarity.UNCOMMON, mage.cards.h.HerdBaloth.class)); cards.add(new SetCardInfo("Hunting Pack", 284, Rarity.UNCOMMON, mage.cards.h.HuntingPack.class)); cards.add(new SetCardInfo("Ignoble Hierarch", 166, Rarity.RARE, mage.cards.i.IgnobleHierarch.class)); From e1cfd427e31dfe5684702c906674b156f2269d1d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:11:58 -0400 Subject: [PATCH 094/188] [MH2] Implemented Bannerhide Krushok --- .../src/mage/cards/b/BannerhideKrushok.java | 45 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 46 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BannerhideKrushok.java diff --git a/Mage.Sets/src/mage/cards/b/BannerhideKrushok.java b/Mage.Sets/src/mage/cards/b/BannerhideKrushok.java new file mode 100644 index 00000000000..4ef5cba1cdb --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BannerhideKrushok.java @@ -0,0 +1,45 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.ReinforceAbility; +import mage.abilities.keyword.ScavengeAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BannerhideKrushok extends CardImpl { + + public BannerhideKrushok(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + + this.subtype.add(SubType.BEAST); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Reinforce 2—{1}{G} + this.addAbility(new ReinforceAbility(2, new ManaCostsImpl<>("{1}{G}"))); + + // Scavenge {5}{G}{G} + this.addAbility(new ScavengeAbility(new ManaCostsImpl<>("{5}{G}{G}"))); + } + + private BannerhideKrushok(final BannerhideKrushok card) { + super(card); + } + + @Override + public BannerhideKrushok copy() { + return new BannerhideKrushok(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 5f8eadc5cf2..ce1304421ca 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -43,6 +43,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Arcus Acolyte", 185, Rarity.UNCOMMON, mage.cards.a.ArcusAcolyte.class)); cards.add(new SetCardInfo("Arid Mesa", 244, Rarity.RARE, mage.cards.a.AridMesa.class)); cards.add(new SetCardInfo("Asmoranomardicadaistinaculdacar", 186, Rarity.RARE, mage.cards.a.Asmoranomardicadaistinaculdacar.class)); + cards.add(new SetCardInfo("Bannerhide Krushok", 149, Rarity.COMMON, mage.cards.b.BannerhideKrushok.class)); cards.add(new SetCardInfo("Barbed Spike", 5, Rarity.UNCOMMON, mage.cards.b.BarbedSpike.class)); cards.add(new SetCardInfo("Batterbone", 221, Rarity.UNCOMMON, mage.cards.b.Batterbone.class)); cards.add(new SetCardInfo("Battle Plan", 114, Rarity.COMMON, mage.cards.b.BattlePlan.class)); From ff9c1ce8dd217300604302903a3dd72acf647684 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:13:46 -0400 Subject: [PATCH 095/188] [MH2] Implemented Viashino Lashclaw --- .../src/mage/cards/v/ViashinoLashclaw.java | 49 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 50 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/ViashinoLashclaw.java diff --git a/Mage.Sets/src/mage/cards/v/ViashinoLashclaw.java b/Mage.Sets/src/mage/cards/v/ViashinoLashclaw.java new file mode 100644 index 00000000000..e4ddb9cacac --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/ViashinoLashclaw.java @@ -0,0 +1,49 @@ +package mage.cards.v; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ViashinoLashclaw extends CardImpl { + + public ViashinoLashclaw(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.VIASHINO); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {T}, Discard a card: Creatures you control gain haste until end of turn. + Ability ability = new SimpleActivatedAbility(new GainAbilityControlledEffect( + HasteAbility.getInstance(), Duration.EndOfTurn, + StaticFilters.FILTER_PERMANENT_CREATURES + ), new TapSourceCost()); + ability.addCost(new DiscardCardCost()); + this.addAbility(ability); + } + + private ViashinoLashclaw(final ViashinoLashclaw card) { + super(card); + } + + @Override + public ViashinoLashclaw copy() { + return new ViashinoLashclaw(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index ce1304421ca..5f2df82b53f 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -243,6 +243,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Vedalken Infiltrator", 73, Rarity.UNCOMMON, mage.cards.v.VedalkenInfiltrator.class)); cards.add(new SetCardInfo("Verdant Catacombs", 260, Rarity.RARE, mage.cards.v.VerdantCatacombs.class)); cards.add(new SetCardInfo("Verdant Command", 182, Rarity.RARE, mage.cards.v.VerdantCommand.class)); + cards.add(new SetCardInfo("Viashino Lashclaw", 146, Rarity.COMMON, mage.cards.v.ViashinoLashclaw.class)); cards.add(new SetCardInfo("Vindicate", 294, Rarity.RARE, mage.cards.v.Vindicate.class)); cards.add(new SetCardInfo("Void Mirror", 242, Rarity.RARE, mage.cards.v.VoidMirror.class)); cards.add(new SetCardInfo("Wonder", 271, Rarity.RARE, mage.cards.w.Wonder.class)); From 752462aa91ef61f53aa383cad2d80c0de42944e2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:15:16 -0400 Subject: [PATCH 096/188] [MH2] Implemented Crack Open --- Mage.Sets/src/mage/cards/c/CrackOpen.java | 36 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 37 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CrackOpen.java diff --git a/Mage.Sets/src/mage/cards/c/CrackOpen.java b/Mage.Sets/src/mage/cards/c/CrackOpen.java new file mode 100644 index 00000000000..fc2afcfb4c6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CrackOpen.java @@ -0,0 +1,36 @@ +package mage.cards.c; + +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.game.permanent.token.TreasureToken; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class CrackOpen extends CardImpl { + + public CrackOpen(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}"); + + // Destroy target artifact or enchantment. Create a Treasure token. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); + this.getSpellAbility().addEffect(new CreateTokenEffect(new TreasureToken())); + } + + private CrackOpen(final CrackOpen card) { + super(card); + } + + @Override + public CrackOpen copy() { + return new CrackOpen(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 5f2df82b53f..b64b76ee782 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -71,6 +71,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Combine Chrysalis", 191, Rarity.UNCOMMON, mage.cards.c.CombineChrysalis.class)); cards.add(new SetCardInfo("Constable of the Realm", 10, Rarity.UNCOMMON, mage.cards.c.ConstableOfTheRealm.class)); cards.add(new SetCardInfo("Counterspell", 267, Rarity.UNCOMMON, mage.cards.c.Counterspell.class)); + cards.add(new SetCardInfo("Crack Open", 154, Rarity.COMMON, mage.cards.c.CrackOpen.class)); cards.add(new SetCardInfo("Cursed Totem", 295, Rarity.RARE, mage.cards.c.CursedTotem.class)); cards.add(new SetCardInfo("Dakkon, Shadow Slayer", 192, Rarity.MYTHIC, mage.cards.d.DakkonShadowSlayer.class)); cards.add(new SetCardInfo("Darkmoss Bridge", 245, Rarity.COMMON, mage.cards.d.DarkmossBridge.class)); From 88d076519b1bdf5128bf74a89b09c2edd5d63e34 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:17:13 -0400 Subject: [PATCH 097/188] [MH2] Implemented Flourishing Strike --- .../src/mage/cards/f/FlourishingStrike.java | 56 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 57 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FlourishingStrike.java diff --git a/Mage.Sets/src/mage/cards/f/FlourishingStrike.java b/Mage.Sets/src/mage/cards/f/FlourishingStrike.java new file mode 100644 index 00000000000..fa4d511a980 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FlourishingStrike.java @@ -0,0 +1,56 @@ +package mage.cards.f; + +import mage.abilities.Mode; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.EntwineAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FlourishingStrike extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with flying"); + + static { + filter.add(new AbilityPredicate(FlyingAbility.class)); + } + + public FlourishingStrike(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); + + + // Choose one — + // • Flourishing Strike deals 5 damage to target creature with flying. + this.getSpellAbility().addEffect(new DamageTargetEffect(5)); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + + // • Target creature gets +3/+3 until end of turn. + Mode mode = new Mode(new BoostTargetEffect(3, 3, Duration.EndOfTurn)); + mode.addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addMode(mode); + + // Entwine {2}{G} + this.addAbility(new EntwineAbility("{2}{G}")); + } + + private FlourishingStrike(final FlourishingStrike card) { + super(card); + } + + @Override + public FlourishingStrike copy() { + return new FlourishingStrike(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index b64b76ee782..1893c3a6699 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -98,6 +98,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Flametongue Yearling", 125, Rarity.UNCOMMON, mage.cards.f.FlametongueYearling.class)); cards.add(new SetCardInfo("Flay Essence", 85, Rarity.UNCOMMON, mage.cards.f.FlayEssence.class)); cards.add(new SetCardInfo("Floodhound", 42, Rarity.COMMON, mage.cards.f.Floodhound.class)); + cards.add(new SetCardInfo("Flourishing Strike", 159, Rarity.COMMON, mage.cards.f.FlourishingStrike.class)); cards.add(new SetCardInfo("Forest", 489, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Foundation Breaker", 160, Rarity.UNCOMMON, mage.cards.f.FoundationBreaker.class)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); From b8c169434423c6d65cec131e77007f5acaac3657 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:17:58 -0400 Subject: [PATCH 098/188] [MH2] Implemented Jewel-Eyed Cobra --- .../src/mage/cards/j/JewelEyedCobra.java | 42 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 43 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/j/JewelEyedCobra.java diff --git a/Mage.Sets/src/mage/cards/j/JewelEyedCobra.java b/Mage.Sets/src/mage/cards/j/JewelEyedCobra.java new file mode 100644 index 00000000000..85546f1285a --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JewelEyedCobra.java @@ -0,0 +1,42 @@ +package mage.cards.j; + +import mage.MageInt; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.TreasureToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class JewelEyedCobra extends CardImpl { + + public JewelEyedCobra(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.SNAKE); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // When Jewel-Eyed Cobra dies, create a Treasure token. + this.addAbility(new DiesSourceTriggeredAbility(new CreateTokenEffect(new TreasureToken()))); + } + + private JewelEyedCobra(final JewelEyedCobra card) { + super(card); + } + + @Override + public JewelEyedCobra copy() { + return new JewelEyedCobra(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 1893c3a6699..e440aebf338 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -127,6 +127,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Imperial Recruiter", 281, Rarity.MYTHIC, mage.cards.i.ImperialRecruiter.class)); cards.add(new SetCardInfo("Island", 483, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jade Avenger", 167, Rarity.COMMON, mage.cards.j.JadeAvenger.class)); + cards.add(new SetCardInfo("Jewel-Eyed Cobra", 168, Rarity.COMMON, mage.cards.j.JewelEyedCobra.class)); cards.add(new SetCardInfo("Junk Winder", 48, Rarity.UNCOMMON, mage.cards.j.JunkWinder.class)); cards.add(new SetCardInfo("Kaleidoscorch", 133, Rarity.UNCOMMON, mage.cards.k.Kaleidoscorch.class)); cards.add(new SetCardInfo("Karmic Guide", 263, Rarity.RARE, mage.cards.k.KarmicGuide.class)); From c09f90f64f5e696588037d890e3a65979977e128 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:18:42 -0400 Subject: [PATCH 099/188] [MH2] Implemented Terminal Agony --- Mage.Sets/src/mage/cards/t/TerminalAgony.java | 37 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TerminalAgony.java diff --git a/Mage.Sets/src/mage/cards/t/TerminalAgony.java b/Mage.Sets/src/mage/cards/t/TerminalAgony.java new file mode 100644 index 00000000000..f4200e43ee9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TerminalAgony.java @@ -0,0 +1,37 @@ +package mage.cards.t; + +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.MadnessAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TerminalAgony extends CardImpl { + + public TerminalAgony(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{R}"); + + // Destroy target creature. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + // Madness {B}{R} + this.addAbility(new MadnessAbility(this, new ManaCostsImpl<>("{B}{R}"))); + } + + private TerminalAgony(final TerminalAgony card) { + super(card); + } + + @Override + public TerminalAgony copy() { + return new TerminalAgony(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index e440aebf338..10b87ee1333 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -223,6 +223,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Sythis, Harvest's Hand", 214, Rarity.RARE, mage.cards.s.SythisHarvestsHand.class)); cards.add(new SetCardInfo("Tanglepool Bridge", 257, Rarity.COMMON, mage.cards.t.TanglepoolBridge.class)); cards.add(new SetCardInfo("Tavern Scoundrel", 144, Rarity.COMMON, mage.cards.t.TavernScoundrel.class)); + cards.add(new SetCardInfo("Terminal Agony", 215, Rarity.COMMON, mage.cards.t.TerminalAgony.class)); cards.add(new SetCardInfo("Terramorph", 177, Rarity.UNCOMMON, mage.cards.t.Terramorph.class)); cards.add(new SetCardInfo("Territorial Kavu", 216, Rarity.RARE, mage.cards.t.TerritorialKavu.class)); cards.add(new SetCardInfo("The Underworld Cookbook", 240, Rarity.UNCOMMON, mage.cards.t.TheUnderworldCookbook.class)); From 0184ccc246a81e11c818a93a2d2b747a7ad99a71 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:19:51 -0400 Subject: [PATCH 100/188] [MH2] Implemented Fodder Tosser --- Mage.Sets/src/mage/cards/f/FodderTosser.java | 38 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 39 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FodderTosser.java diff --git a/Mage.Sets/src/mage/cards/f/FodderTosser.java b/Mage.Sets/src/mage/cards/f/FodderTosser.java new file mode 100644 index 00000000000..074c3c37be2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FodderTosser.java @@ -0,0 +1,38 @@ +package mage.cards.f; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetPlayerOrPlaneswalker; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FodderTosser extends CardImpl { + + public FodderTosser(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + // {T}, Discard a card: Fodder Tosser deals 2 damage to target player or planeswalker. + Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(2), new TapSourceCost()); + ability.addCost(new DiscardCardCost()); + ability.addTarget(new TargetPlayerOrPlaneswalker()); + this.addAbility(ability); + } + + private FodderTosser(final FodderTosser card) { + super(card); + } + + @Override + public FodderTosser copy() { + return new FodderTosser(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 10b87ee1333..45e2d19c4d9 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -99,6 +99,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Flay Essence", 85, Rarity.UNCOMMON, mage.cards.f.FlayEssence.class)); cards.add(new SetCardInfo("Floodhound", 42, Rarity.COMMON, mage.cards.f.Floodhound.class)); cards.add(new SetCardInfo("Flourishing Strike", 159, Rarity.COMMON, mage.cards.f.FlourishingStrike.class)); + cards.add(new SetCardInfo("Fodder Tosser", 226, Rarity.COMMON, mage.cards.f.FodderTosser.class)); cards.add(new SetCardInfo("Forest", 489, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Foundation Breaker", 160, Rarity.UNCOMMON, mage.cards.f.FoundationBreaker.class)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); From b868f0bdae892788a2ed0e21932f345cf6d504b4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:21:42 -0400 Subject: [PATCH 101/188] [MH2] Implemented Storm God's Oracle --- .../src/mage/cards/s/StormGodsOracle.java | 51 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 52 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/StormGodsOracle.java diff --git a/Mage.Sets/src/mage/cards/s/StormGodsOracle.java b/Mage.Sets/src/mage/cards/s/StormGodsOracle.java new file mode 100644 index 00000000000..d3913a0e2a6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StormGodsOracle.java @@ -0,0 +1,51 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class StormGodsOracle extends CardImpl { + + public StormGodsOracle(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{U}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SHAMAN); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // {1}: Storm God's Oracle gets +1/-1 until end of turn. + this.addAbility(new SimpleActivatedAbility( + new BoostSourceEffect(1, -1, Duration.EndOfTurn), new GenericManaCost(1) + )); + + // When Storm God's Oracle dies, it deals 3 damage to any target. + Ability ability = new DiesSourceTriggeredAbility(new DamageTargetEffect(3, "it")); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability); + } + + private StormGodsOracle(final StormGodsOracle card) { + super(card); + } + + @Override + public StormGodsOracle copy() { + return new StormGodsOracle(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 45e2d19c4d9..5339aa5b13b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -214,6 +214,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Steelfin Whale", 65, Rarity.COMMON, mage.cards.s.SteelfinWhale.class)); cards.add(new SetCardInfo("Step Through", 66, Rarity.COMMON, mage.cards.s.StepThrough.class)); cards.add(new SetCardInfo("Sterling Grove", 293, Rarity.RARE, mage.cards.s.SterlingGrove.class)); + cards.add(new SetCardInfo("Storm God's Oracle", 213, Rarity.COMMON, mage.cards.s.StormGodsOracle.class)); cards.add(new SetCardInfo("Strike It Rich", 143, Rarity.UNCOMMON, mage.cards.s.StrikeItRich.class)); cards.add(new SetCardInfo("Subtlety", 67, Rarity.MYTHIC, mage.cards.s.Subtlety.class)); cards.add(new SetCardInfo("Sudden Edict", 100, Rarity.UNCOMMON, mage.cards.s.SuddenEdict.class)); From 9eabb7596df2f23090b21669421b1de723d4ce08 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:24:00 -0400 Subject: [PATCH 102/188] [MH2] Implemented Myr Scrapling --- Mage.Sets/src/mage/cards/m/MyrScrapling.java | 45 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 46 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MyrScrapling.java diff --git a/Mage.Sets/src/mage/cards/m/MyrScrapling.java b/Mage.Sets/src/mage/cards/m/MyrScrapling.java new file mode 100644 index 00000000000..687a6080cff --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MyrScrapling.java @@ -0,0 +1,45 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MyrScrapling extends CardImpl { + + public MyrScrapling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}"); + + this.subtype.add(SubType.MYR); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Sacrifice Myr Scrapling: Put a +1/+1 counter on target creature. + Ability ability = new SimpleActivatedAbility( + new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new SacrificeSourceCost() + ); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + private MyrScrapling(final MyrScrapling card) { + super(card); + } + + @Override + public MyrScrapling copy() { + return new MyrScrapling(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 5339aa5b13b..002f6d5c252 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -153,6 +153,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Mogg Salvage", 282, Rarity.UNCOMMON, mage.cards.m.MoggSalvage.class)); cards.add(new SetCardInfo("Monoskelion", 229, Rarity.UNCOMMON, mage.cards.m.Monoskelion.class)); cards.add(new SetCardInfo("Mountain", 487, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Myr Scrapling", 230, Rarity.COMMON, mage.cards.m.MyrScrapling.class)); cards.add(new SetCardInfo("Mystic Redaction", 53, Rarity.UNCOMMON, mage.cards.m.MysticRedaction.class)); cards.add(new SetCardInfo("Necromancer's Familiar", 94, Rarity.UNCOMMON, mage.cards.n.NecromancersFamiliar.class)); cards.add(new SetCardInfo("Nettlecyst", 231, Rarity.RARE, mage.cards.n.Nettlecyst.class)); From 03910cc99485156cd3ea85d87fabbf39e570be44 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Wed, 2 Jun 2021 19:41:24 -0500 Subject: [PATCH 103/188] [MH2] Implemented Arcbound Tracker --- .../src/mage/cards/a/ArcboundTracker.java | 85 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 86 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/ArcboundTracker.java diff --git a/Mage.Sets/src/mage/cards/a/ArcboundTracker.java b/Mage.Sets/src/mage/cards/a/ArcboundTracker.java new file mode 100644 index 00000000000..bf4ae60c689 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArcboundTracker.java @@ -0,0 +1,85 @@ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.MenaceAbility; +import mage.abilities.keyword.ModularAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.watchers.common.SpellsCastWatcher; + +/** + * + * @author weirddan455 + */ +public final class ArcboundTracker extends CardImpl { + + public ArcboundTracker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.DOG); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // Menace + this.addAbility(new MenaceAbility()); + + // Modular 2 + this.addAbility(new ModularAbility(this, 2)); + + // Whenever you cast a spell other than your first spell each turn, put a +1/+1 counter on Arcbound Tracker. + this.addAbility(new ArcboundTrackerTriggeredAbility(), new SpellsCastWatcher()); + } + + private ArcboundTracker(final ArcboundTracker card) { + super(card); + } + + @Override + public ArcboundTracker copy() { + return new ArcboundTracker(this); + } +} + +class ArcboundTrackerTriggeredAbility extends TriggeredAbilityImpl { + + public ArcboundTrackerTriggeredAbility() { + super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance())); + } + + private ArcboundTrackerTriggeredAbility(final ArcboundTrackerTriggeredAbility ability) { + super(ability); + } + + @Override + public ArcboundTrackerTriggeredAbility copy() { + return new ArcboundTrackerTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getPlayerId().equals(this.getControllerId())) { + SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); + return watcher != null && watcher.getSpellsCastThisTurn(event.getPlayerId()).size() > 1; + } + return false; + } + + @Override + public String getRule() { + return "Whenever you cast a spell other than your first spell each turn, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 002f6d5c252..45c3e84af7f 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -37,6 +37,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Arcbound Prototype", 4, Rarity.COMMON, mage.cards.a.ArcboundPrototype.class)); cards.add(new SetCardInfo("Arcbound Shikari", 184, Rarity.UNCOMMON, mage.cards.a.ArcboundShikari.class)); cards.add(new SetCardInfo("Arcbound Slasher", 111, Rarity.COMMON, mage.cards.a.ArcboundSlasher.class)); + cards.add(new SetCardInfo("Arcbound Tracker", 112, Rarity.COMMON, mage.cards.a.ArcboundTracker.class)); cards.add(new SetCardInfo("Arcbound Whelp", 113, Rarity.UNCOMMON, mage.cards.a.ArcboundWhelp.class)); cards.add(new SetCardInfo("Archfiend of Sorrows", 74, Rarity.UNCOMMON, mage.cards.a.ArchfiendOfSorrows.class)); cards.add(new SetCardInfo("Archon of Cruelty", 75, Rarity.MYTHIC, mage.cards.a.ArchonOfCruelty.class)); From ca01eddae06ea5a00fffb8ed3000fd8b691773b0 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Wed, 2 Jun 2021 20:00:24 -0500 Subject: [PATCH 104/188] [MH2] Implemented Blessed Respite --- .../src/mage/cards/b/BlessedRespite.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BlessedRespite.java diff --git a/Mage.Sets/src/mage/cards/b/BlessedRespite.java b/Mage.Sets/src/mage/cards/b/BlessedRespite.java new file mode 100644 index 00000000000..a34c207eb7b --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BlessedRespite.java @@ -0,0 +1,69 @@ +package mage.cards.b; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PreventAllDamageByAllPermanentsEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; + +/** + * + * @author weirddan455 + */ +public final class BlessedRespite extends CardImpl { + + public BlessedRespite(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); + + // Target player shuffles their graveyard into their library. Prevent all combat damage that would be dealt this turn. + this.getSpellAbility().addEffect(new BlessedRespiteEffect()); + this.getSpellAbility().addEffect(new PreventAllDamageByAllPermanentsEffect(Duration.EndOfTurn, true)); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + private BlessedRespite(final BlessedRespite card) { + super(card); + } + + @Override + public BlessedRespite copy() { + return new BlessedRespite(this); + } +} + +class BlessedRespiteEffect extends OneShotEffect { + + public BlessedRespiteEffect() { + super(Outcome.Detriment); + this.staticText = "Target player shuffles their graveyard into their library"; + } + + private BlessedRespiteEffect(final BlessedRespiteEffect effect) { + super(effect); + } + + @Override + public BlessedRespiteEffect copy() { + return new BlessedRespiteEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (targetPlayer != null) { + targetPlayer.moveCards(targetPlayer.getGraveyard(), Zone.LIBRARY, source, game); + targetPlayer.shuffleLibrary(source, game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 45c3e84af7f..5fc5caa8b60 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -49,6 +49,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Batterbone", 221, Rarity.UNCOMMON, mage.cards.b.Batterbone.class)); cards.add(new SetCardInfo("Battle Plan", 114, Rarity.COMMON, mage.cards.b.BattlePlan.class)); cards.add(new SetCardInfo("Blacksmith's Skill", 6, Rarity.COMMON, mage.cards.b.BlacksmithsSkill.class)); + cards.add(new SetCardInfo("Blessed Respite", 150, Rarity.UNCOMMON, mage.cards.b.BlessedRespite.class)); cards.add(new SetCardInfo("Bloodbraid Marauder", 116, Rarity.RARE, mage.cards.b.BloodbraidMarauder.class)); cards.add(new SetCardInfo("Blossoming Calm", 7, Rarity.UNCOMMON, mage.cards.b.BlossomingCalm.class)); cards.add(new SetCardInfo("Bone Shards", 76, Rarity.COMMON, mage.cards.b.BoneShards.class)); From 42c61047480e696d5ecfbee6dee8c6b1c796f8ce Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Wed, 2 Jun 2021 20:15:47 -0500 Subject: [PATCH 105/188] [MH2] Implemented Burdened Aerialist --- .../src/mage/cards/b/BurdenedAerialist.java | 54 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 55 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BurdenedAerialist.java diff --git a/Mage.Sets/src/mage/cards/b/BurdenedAerialist.java b/Mage.Sets/src/mage/cards/b/BurdenedAerialist.java new file mode 100644 index 00000000000..70d3101c25d --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BurdenedAerialist.java @@ -0,0 +1,54 @@ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SacrificePermanentTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.permanent.token.TreasureToken; + +/** + * + * @author weirddan455 + */ +public final class BurdenedAerialist extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("a token"); + + static { + filter.add(TokenPredicate.instance); + } + + public BurdenedAerialist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // When Burdened Aerialist enters the battlefield, create a Treasure token. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new TreasureToken()))); + + // Whenever you sacrifice a token, Burdened Aerialist gains flying until end of turn. + this.addAbility(new SacrificePermanentTriggeredAbility(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), filter)); + } + + private BurdenedAerialist(final BurdenedAerialist card) { + super(card); + } + + @Override + public BurdenedAerialist copy() { + return new BurdenedAerialist(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 5fc5caa8b60..96ef969417b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -61,6 +61,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Break the Ice", 77, Rarity.UNCOMMON, mage.cards.b.BreakTheIce.class)); cards.add(new SetCardInfo("Breathless Knight", 187, Rarity.COMMON, mage.cards.b.BreathlessKnight.class)); cards.add(new SetCardInfo("Breya's Apprentice", 117, Rarity.RARE, mage.cards.b.BreyasApprentice.class)); + cards.add(new SetCardInfo("Burdened Aerialist", 38, Rarity.COMMON, mage.cards.b.BurdenedAerialist.class)); cards.add(new SetCardInfo("Cabal Coffers", 301, Rarity.MYTHIC, mage.cards.c.CabalCoffers.class)); cards.add(new SetCardInfo("Calibrated Blast", 118, Rarity.RARE, mage.cards.c.CalibratedBlast.class)); cards.add(new SetCardInfo("Captain Ripley Vance", 119, Rarity.UNCOMMON, mage.cards.c.CaptainRipleyVance.class)); From 0191c4a9c1cc2e800ba75ff031f867e9eec63f4c Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Wed, 2 Jun 2021 20:36:44 -0500 Subject: [PATCH 106/188] [MH2] Implemented Cabal Initiate --- Mage.Sets/src/mage/cards/c/CabalInitiate.java | 53 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 54 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CabalInitiate.java diff --git a/Mage.Sets/src/mage/cards/c/CabalInitiate.java b/Mage.Sets/src/mage/cards/c/CabalInitiate.java new file mode 100644 index 00000000000..d227202ae31 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CabalInitiate.java @@ -0,0 +1,53 @@ +package mage.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CardsInControllerGraveyardCondition; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.LifelinkAbility; +import mage.constants.AbilityWord; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author weirddan455 + */ +public final class CabalInitiate extends CardImpl { + + public CabalInitiate(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Discard a card: Cabal Initiate gains lifelink until end of turn. + this.addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn), new DiscardCardCost())); + + // Threshold — Cabal Initiate gets +1/+2 as long as seven or more cards are in your graveyard. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new BoostSourceEffect(1, 2, Duration.WhileOnBattlefield), + new CardsInControllerGraveyardCondition(7), + "{this} gets +1/+2 as long as seven or more cards are in your graveyard" + )).setAbilityWord(AbilityWord.THRESHOLD)); + } + + private CabalInitiate(final CabalInitiate card) { + super(card); + } + + @Override + public CabalInitiate copy() { + return new CabalInitiate(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 96ef969417b..dd52851fc79 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -63,6 +63,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Breya's Apprentice", 117, Rarity.RARE, mage.cards.b.BreyasApprentice.class)); cards.add(new SetCardInfo("Burdened Aerialist", 38, Rarity.COMMON, mage.cards.b.BurdenedAerialist.class)); cards.add(new SetCardInfo("Cabal Coffers", 301, Rarity.MYTHIC, mage.cards.c.CabalCoffers.class)); + cards.add(new SetCardInfo("Cabal Initiate", 78, Rarity.COMMON, mage.cards.c.CabalInitiate.class)); cards.add(new SetCardInfo("Calibrated Blast", 118, Rarity.RARE, mage.cards.c.CalibratedBlast.class)); cards.add(new SetCardInfo("Captain Ripley Vance", 119, Rarity.UNCOMMON, mage.cards.c.CaptainRipleyVance.class)); cards.add(new SetCardInfo("Captured by Lagacs", 188, Rarity.COMMON, mage.cards.c.CapturedByLagacs.class)); From 9fba3be2d51ab82aa016dbb46aa299fdd6a6358c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 18:49:13 -0400 Subject: [PATCH 107/188] [RMH1] added set --- .../dl/sources/ScryfallImageSupportCards.java | 1 + .../mage/sets/ModernHorizons1Timeshifts.java | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/ModernHorizons1Timeshifts.java diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java index 2d3a925d727..0a763757804 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java @@ -500,6 +500,7 @@ public class ScryfallImageSupportCards { add("STA"); // Strixhaven Mystical Archive add("C21"); // Commander 2021 Edition add("MH2"); // Modern Horizons 2 + add("RMH1"); // Modern Horizons 1 Timeshifts add("AFR"); // Adventures in the Forgotten Realms } }; diff --git a/Mage.Sets/src/mage/sets/ModernHorizons1Timeshifts.java b/Mage.Sets/src/mage/sets/ModernHorizons1Timeshifts.java new file mode 100644 index 00000000000..15dc95108f6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/ModernHorizons1Timeshifts.java @@ -0,0 +1,64 @@ +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author TheElk801 + */ +public final class ModernHorizons1Timeshifts extends ExpansionSet { + + private static final ModernHorizons1Timeshifts instance = new ModernHorizons1Timeshifts(); + + public static ModernHorizons1Timeshifts getInstance() { + return instance; + } + + private ModernHorizons1Timeshifts() { + super("Modern Horizons 1 Timeshifts", "RMH1", ExpansionSet.buildDate(2021, 6, 11), SetType.SUPPLEMENTAL); + this.hasBasicLands = false; + this.hasBoosters = false; + + cards.add(new SetCardInfo("Archmage's Charm", 7, Rarity.RARE, mage.cards.a.ArchmagesCharm.class)); + cards.add(new SetCardInfo("Ayula, Queen Among Bears", 19, Rarity.RARE, mage.cards.a.AyulaQueenAmongBears.class)); + cards.add(new SetCardInfo("Changeling Outcast", 12, Rarity.UNCOMMON, mage.cards.c.ChangelingOutcast.class)); + cards.add(new SetCardInfo("Deep Forest Hermit", 20, Rarity.RARE, mage.cards.d.DeepForestHermit.class)); + cards.add(new SetCardInfo("Defile", 13, Rarity.UNCOMMON, mage.cards.d.Defile.class)); + cards.add(new SetCardInfo("Ephemerate", 1, Rarity.UNCOMMON, mage.cards.e.Ephemerate.class)); + cards.add(new SetCardInfo("Etchings of the Chosen", 25, Rarity.UNCOMMON, mage.cards.e.EtchingsOfTheChosen.class)); + cards.add(new SetCardInfo("Faerie Seer", 8, Rarity.UNCOMMON, mage.cards.f.FaerieSeer.class)); + cards.add(new SetCardInfo("Force of Negation", 9, Rarity.RARE, mage.cards.f.ForceOfNegation.class)); + cards.add(new SetCardInfo("Force of Vigor", 21, Rarity.RARE, mage.cards.f.ForceOfVigor.class)); + cards.add(new SetCardInfo("Generous Gift", 2, Rarity.UNCOMMON, mage.cards.g.GenerousGift.class)); + cards.add(new SetCardInfo("Giver of Runes", 3, Rarity.RARE, mage.cards.g.GiverOfRunes.class)); + cards.add(new SetCardInfo("Goblin Engineer", 16, Rarity.RARE, mage.cards.g.GoblinEngineer.class)); + cards.add(new SetCardInfo("Hall of Heliod's Generosity", 39, Rarity.RARE, mage.cards.h.HallOfHeliodsGenerosity.class)); + cards.add(new SetCardInfo("Ice-Fang Coatl", 27, Rarity.RARE, mage.cards.i.IceFangCoatl.class)); + cards.add(new SetCardInfo("Ingenious Infiltrator", 28, Rarity.UNCOMMON, mage.cards.i.IngeniousInfiltrator.class)); + cards.add(new SetCardInfo("King of the Pride", 4, Rarity.UNCOMMON, mage.cards.k.KingOfThePride.class)); + cards.add(new SetCardInfo("Lavabelly Sliver", 29, Rarity.UNCOMMON, mage.cards.l.LavabellySliver.class)); + cards.add(new SetCardInfo("Llanowar Tribe", 22, Rarity.UNCOMMON, mage.cards.l.LlanowarTribe.class)); + cards.add(new SetCardInfo("Magmatic Sinkhole", 17, Rarity.UNCOMMON, mage.cards.m.MagmaticSinkhole.class)); + cards.add(new SetCardInfo("Plague Engineer", 14, Rarity.RARE, mage.cards.p.PlagueEngineer.class)); + cards.add(new SetCardInfo("Prismatic Vista", 40, Rarity.RARE, mage.cards.p.PrismaticVista.class)); + cards.add(new SetCardInfo("Ranger-Captain of Eos", 5, Rarity.MYTHIC, mage.cards.r.RangerCaptainOfEos.class)); + cards.add(new SetCardInfo("Scale Up", 23, Rarity.UNCOMMON, mage.cards.s.ScaleUp.class)); + cards.add(new SetCardInfo("Shenanigans", 18, Rarity.UNCOMMON, mage.cards.s.Shenanigans.class)); + cards.add(new SetCardInfo("Sisay, Weatherlight Captain", 6, Rarity.RARE, mage.cards.s.SisayWeatherlightCaptain.class)); + cards.add(new SetCardInfo("Soulherder", 30, Rarity.UNCOMMON, mage.cards.s.Soulherder.class)); + cards.add(new SetCardInfo("Sword of Sinew and Steel", 31, Rarity.MYTHIC, mage.cards.s.SwordOfSinewAndSteel.class)); + cards.add(new SetCardInfo("Sword of Truth and Justice", 32, Rarity.MYTHIC, mage.cards.s.SwordOfTruthAndJustice.class)); + cards.add(new SetCardInfo("Talisman of Conviction", 33, Rarity.UNCOMMON, mage.cards.t.TalismanOfConviction.class)); + cards.add(new SetCardInfo("Talisman of Creativity", 34, Rarity.UNCOMMON, mage.cards.t.TalismanOfCreativity.class)); + cards.add(new SetCardInfo("Talisman of Curiosity", 35, Rarity.UNCOMMON, mage.cards.t.TalismanOfCuriosity.class)); + cards.add(new SetCardInfo("Talisman of Hierarchy", 36, Rarity.UNCOMMON, mage.cards.t.TalismanOfHierarchy.class)); + cards.add(new SetCardInfo("Talisman of Resilience", 37, Rarity.UNCOMMON, mage.cards.t.TalismanOfResilience.class)); + cards.add(new SetCardInfo("The First Sliver", 26, Rarity.MYTHIC, mage.cards.t.TheFirstSliver.class)); + cards.add(new SetCardInfo("Tribute Mage", 10, Rarity.UNCOMMON, mage.cards.t.TributeMage.class)); + cards.add(new SetCardInfo("Undead Augur", 15, Rarity.UNCOMMON, mage.cards.u.UndeadAugur.class)); + cards.add(new SetCardInfo("Universal Automaton", 38, Rarity.UNCOMMON, mage.cards.u.UniversalAutomaton.class)); + cards.add(new SetCardInfo("Urza, Lord High Artificer", 11, Rarity.MYTHIC, mage.cards.u.UrzaLordHighArtificer.class)); + cards.add(new SetCardInfo("Weather the Storm", 24, Rarity.UNCOMMON, mage.cards.w.WeatherTheStorm.class)); + } +} From 99b1cd86df32d8005e7a907d6b382885e48d9e98 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:14:08 -0400 Subject: [PATCH 108/188] [MH2] Implemented Guardian Kirin --- Mage.Sets/src/mage/cards/g/GuardianKirin.java | 54 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 55 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GuardianKirin.java diff --git a/Mage.Sets/src/mage/cards/g/GuardianKirin.java b/Mage.Sets/src/mage/cards/g/GuardianKirin.java new file mode 100644 index 00000000000..9e911784531 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GuardianKirin.java @@ -0,0 +1,54 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GuardianKirin extends CardImpl { + + private static final FilterPermanent filter + = new FilterControlledCreaturePermanent("another creature you control"); + + static { + filter.add(AnotherPredicate.instance); + } + + public GuardianKirin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.KIRIN); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever another creature you control dies, put a +1/+1 counter on Guardian Kirin. + this.addAbility(new DiesCreatureTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, filter + )); + } + + private GuardianKirin(final GuardianKirin card) { + super(card); + } + + @Override + public GuardianKirin copy() { + return new GuardianKirin(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index dd52851fc79..813677ea24d 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -123,6 +123,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Graceful Restoration", 201, Rarity.UNCOMMON, mage.cards.g.GracefulRestoration.class)); cards.add(new SetCardInfo("Greed", 274, Rarity.UNCOMMON, mage.cards.g.Greed.class)); cards.add(new SetCardInfo("Grief", 87, Rarity.MYTHIC, mage.cards.g.Grief.class)); + cards.add(new SetCardInfo("Guardian Kirin", 15, Rarity.COMMON, mage.cards.g.GuardianKirin.class)); cards.add(new SetCardInfo("Hard Evidence", 46, Rarity.COMMON, mage.cards.h.HardEvidence.class)); cards.add(new SetCardInfo("Harmonic Prodigy", 132, Rarity.RARE, mage.cards.h.HarmonicProdigy.class)); cards.add(new SetCardInfo("Hell Mongrel", 88, Rarity.COMMON, mage.cards.h.HellMongrel.class)); From 3f876a756f6c05aff9cf1d8a96a5327c4dadab08 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:15:45 -0400 Subject: [PATCH 109/188] [MH2] Implemented Lens Flare --- Mage.Sets/src/mage/cards/l/LensFlare.java | 36 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 37 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LensFlare.java diff --git a/Mage.Sets/src/mage/cards/l/LensFlare.java b/Mage.Sets/src/mage/cards/l/LensFlare.java new file mode 100644 index 00000000000..bc87ea67294 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LensFlare.java @@ -0,0 +1,36 @@ +package mage.cards.l; + +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.AffinityForArtifactsAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetAttackingOrBlockingCreature; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LensFlare extends CardImpl { + + public LensFlare(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{W}"); + + // Affinity for artifacts + this.addAbility(new AffinityForArtifactsAbility()); + + // Lens Flare deals 5 damage to target attacking or blocking creature. + this.getSpellAbility().addEffect(new DamageTargetEffect(5)); + this.getSpellAbility().addTarget(new TargetAttackingOrBlockingCreature()); + } + + private LensFlare(final LensFlare card) { + super(card); + } + + @Override + public LensFlare copy() { + return new LensFlare(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 813677ea24d..81d531f3842 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -142,6 +142,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Late to Dinner", 19, Rarity.COMMON, mage.cards.l.LateToDinner.class)); cards.add(new SetCardInfo("Lazotep Chancellor", 203, Rarity.UNCOMMON, mage.cards.l.LazotepChancellor.class)); cards.add(new SetCardInfo("Legion Vanguard", 90, Rarity.UNCOMMON, mage.cards.l.LegionVanguard.class)); + cards.add(new SetCardInfo("Lens Flare", 20, Rarity.COMMON, mage.cards.l.LensFlare.class)); cards.add(new SetCardInfo("Liquimetal Torque", 228, Rarity.UNCOMMON, mage.cards.l.LiquimetalTorque.class)); cards.add(new SetCardInfo("Lose Focus", 49, Rarity.COMMON, mage.cards.l.LoseFocus.class)); cards.add(new SetCardInfo("Lucid Dreams", 50, Rarity.UNCOMMON, mage.cards.l.LucidDreams.class)); From cff89f6bfc03cbb7288f9c17093fd8f45b21fbd3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:18:33 -0400 Subject: [PATCH 110/188] [MH2] Implemented Knighted Myr --- Mage.Sets/src/mage/cards/k/KnightedMyr.java | 46 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KnightedMyr.java diff --git a/Mage.Sets/src/mage/cards/k/KnightedMyr.java b/Mage.Sets/src/mage/cards/k/KnightedMyr.java new file mode 100644 index 00000000000..8e0c5855be3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KnightedMyr.java @@ -0,0 +1,46 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.common.OneOrMoreCountersAddedTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.AdaptAbility; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KnightedMyr extends CardImpl { + + public KnightedMyr(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.MYR); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {2}{W}: Adapt 1. + this.addAbility(new AdaptAbility(1, "{2}{W}")); + + // Whenever one or more +1/+1 counters are put on Knighted Myr, it gains double strike until end of turn. + this.addAbility(new OneOrMoreCountersAddedTriggeredAbility(new GainAbilitySourceEffect( + DoubleStrikeAbility.getInstance(), Duration.EndOfTurn + ).setText("it gains double strike until end of turn"))); + } + + private KnightedMyr(final KnightedMyr card) { + super(card); + } + + @Override + public KnightedMyr copy() { + return new KnightedMyr(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 81d531f3842..fb534f824e9 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -138,6 +138,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Kaleidoscorch", 133, Rarity.UNCOMMON, mage.cards.k.Kaleidoscorch.class)); cards.add(new SetCardInfo("Karmic Guide", 263, Rarity.RARE, mage.cards.k.KarmicGuide.class)); cards.add(new SetCardInfo("Kitchen Imp", 89, Rarity.COMMON, mage.cards.k.KitchenImp.class)); + cards.add(new SetCardInfo("Knighted Myr", 17, Rarity.COMMON, mage.cards.k.KnightedMyr.class)); cards.add(new SetCardInfo("Landscaper Colos", 18, Rarity.COMMON, mage.cards.l.LandscaperColos.class)); cards.add(new SetCardInfo("Late to Dinner", 19, Rarity.COMMON, mage.cards.l.LateToDinner.class)); cards.add(new SetCardInfo("Lazotep Chancellor", 203, Rarity.UNCOMMON, mage.cards.l.LazotepChancellor.class)); From bcd35b9d46d262acef509d5640981bbce11e6e55 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:24:37 -0400 Subject: [PATCH 111/188] [MH2] Implemented Unholy Heat --- Mage.Sets/src/mage/cards/u/UnholyHeat.java | 42 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 43 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/u/UnholyHeat.java diff --git a/Mage.Sets/src/mage/cards/u/UnholyHeat.java b/Mage.Sets/src/mage/cards/u/UnholyHeat.java new file mode 100644 index 00000000000..ae3f1920fd6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UnholyHeat.java @@ -0,0 +1,42 @@ +package mage.cards.u; + +import mage.abilities.condition.common.DeliriumCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.hint.common.CardTypesInGraveyardHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreatureOrPlaneswalker; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class UnholyHeat extends CardImpl { + + public UnholyHeat(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); + + // Unholy Heat deals 2 damage to target creature or planeswalker. + // Delirium — Unholy Heat deals 6 damage instead if there are four or more card types among cards in your graveyard. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new DamageTargetEffect(6), new DamageTargetEffect(2), + DeliriumCondition.instance, "{this} deals 2 damage to target creature " + + "or planeswalker.
Delirium — {this} deals 6 damage instead " + + "if there are four or more card types among cards in your graveyard." + )); + this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker()); + this.getSpellAbility().addHint(CardTypesInGraveyardHint.YOU); + } + + private UnholyHeat(final UnholyHeat card) { + super(card); + } + + @Override + public UnholyHeat copy() { + return new UnholyHeat(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index fb534f824e9..7a6bd5e523a 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -249,6 +249,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Tormod's Cryptkeeper", 239, Rarity.COMMON, mage.cards.t.TormodsCryptkeeper.class)); cards.add(new SetCardInfo("Tourach's Canticle", 103, Rarity.COMMON, mage.cards.t.TourachsCanticle.class)); cards.add(new SetCardInfo("Underworld Hermit", 105, Rarity.UNCOMMON, mage.cards.u.UnderworldHermit.class)); + cards.add(new SetCardInfo("Unholy Heat", 145, Rarity.COMMON, mage.cards.u.UnholyHeat.class)); cards.add(new SetCardInfo("Unmarked Grave", 106, Rarity.RARE, mage.cards.u.UnmarkedGrave.class)); cards.add(new SetCardInfo("Upheaval", 270, Rarity.RARE, mage.cards.u.Upheaval.class)); cards.add(new SetCardInfo("Urban Daggertooth", 181, Rarity.COMMON, mage.cards.u.UrbanDaggertooth.class)); From 266001212293924bdba1e5aff36f728fbb2b46dc Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:26:44 -0400 Subject: [PATCH 112/188] [MH2] Implemented Wavesifter --- Mage.Sets/src/mage/cards/w/Wavesifter.java | 48 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 49 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/Wavesifter.java diff --git a/Mage.Sets/src/mage/cards/w/Wavesifter.java b/Mage.Sets/src/mage/cards/w/Wavesifter.java new file mode 100644 index 00000000000..4a05a057d7a --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/Wavesifter.java @@ -0,0 +1,48 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.InvestigateEffect; +import mage.abilities.keyword.EvokeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Wavesifter extends CardImpl { + + public Wavesifter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{U}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Wavesifter enters the battlefield, investigate twice. + Ability ability = new EntersBattlefieldTriggeredAbility(new InvestigateEffect().setText("investigate")); + ability.addEffect(new InvestigateEffect().setText("twice")); + this.addAbility(ability); + + // Evoke {G}{U} + this.addAbility(new EvokeAbility("{G}{U}")); + } + + private Wavesifter(final Wavesifter card) { + super(card); + } + + @Override + public Wavesifter copy() { + return new Wavesifter(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 7a6bd5e523a..a42a2833438 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -261,6 +261,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Viashino Lashclaw", 146, Rarity.COMMON, mage.cards.v.ViashinoLashclaw.class)); cards.add(new SetCardInfo("Vindicate", 294, Rarity.RARE, mage.cards.v.Vindicate.class)); cards.add(new SetCardInfo("Void Mirror", 242, Rarity.RARE, mage.cards.v.VoidMirror.class)); + cards.add(new SetCardInfo("Wavesifter", 217, Rarity.COMMON, mage.cards.w.Wavesifter.class)); cards.add(new SetCardInfo("Wonder", 271, Rarity.RARE, mage.cards.w.Wonder.class)); cards.add(new SetCardInfo("World-Weary", 109, Rarity.COMMON, mage.cards.w.WorldWeary.class)); cards.add(new SetCardInfo("Wren's Run Hydra", 183, Rarity.UNCOMMON, mage.cards.w.WrensRunHydra.class)); From 636b3c15b8006b47731de057592d9534c5166eb0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:29:38 -0400 Subject: [PATCH 113/188] [MH2] Implemented Vermin Gorger --- Mage.Sets/src/mage/cards/v/VerminGorger.java | 46 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VerminGorger.java diff --git a/Mage.Sets/src/mage/cards/v/VerminGorger.java b/Mage.Sets/src/mage/cards/v/VerminGorger.java new file mode 100644 index 00000000000..bd04209696c --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VerminGorger.java @@ -0,0 +1,46 @@ +package mage.cards.v; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class VerminGorger extends CardImpl { + + public VerminGorger(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add(SubType.VAMPIRE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {T}, Sacrifice another creature: Each opponent loses 2 life and you gain 2 life. + Ability ability = new SimpleActivatedAbility(new LoseLifeOpponentsEffect(2), new TapSourceCost()); + ability.addEffect(new GainLifeEffect(2).concatBy("and")); + ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + this.addAbility(ability); + } + + private VerminGorger(final VerminGorger card) { + super(card); + } + + @Override + public VerminGorger copy() { + return new VerminGorger(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index a42a2833438..f881b167e5a 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -258,6 +258,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Vedalken Infiltrator", 73, Rarity.UNCOMMON, mage.cards.v.VedalkenInfiltrator.class)); cards.add(new SetCardInfo("Verdant Catacombs", 260, Rarity.RARE, mage.cards.v.VerdantCatacombs.class)); cards.add(new SetCardInfo("Verdant Command", 182, Rarity.RARE, mage.cards.v.VerdantCommand.class)); + cards.add(new SetCardInfo("Vermin Gorger", 107, Rarity.COMMON, mage.cards.v.VerminGorger.class)); cards.add(new SetCardInfo("Viashino Lashclaw", 146, Rarity.COMMON, mage.cards.v.ViashinoLashclaw.class)); cards.add(new SetCardInfo("Vindicate", 294, Rarity.RARE, mage.cards.v.Vindicate.class)); cards.add(new SetCardInfo("Void Mirror", 242, Rarity.RARE, mage.cards.v.VoidMirror.class)); From 728ac2af296a148b22fee10e8125012901b3a786 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:33:42 -0400 Subject: [PATCH 114/188] [MH2] Implemented Disciple of the Sun --- .../src/mage/cards/d/DiscipleOfTheSun.java | 56 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 57 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DiscipleOfTheSun.java diff --git a/Mage.Sets/src/mage/cards/d/DiscipleOfTheSun.java b/Mage.Sets/src/mage/cards/d/DiscipleOfTheSun.java new file mode 100644 index 00000000000..9a36d055345 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DiscipleOfTheSun.java @@ -0,0 +1,56 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.common.FilterPermanentCard; +import mage.filter.predicate.mageobject.ManaValuePredicate; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DiscipleOfTheSun extends CardImpl { + + private static final FilterCard filter = new FilterPermanentCard("permanent card with mana value 3 or less"); + + static { + filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 4)); + } + + public DiscipleOfTheSun(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // When Disciple of the Sun enters the battlefield, return target permanent card with mana value 3 or less from your graveyard to your hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect()); + ability.addTarget(new TargetCardInYourGraveyard(filter)); + this.addAbility(ability); + } + + private DiscipleOfTheSun(final DiscipleOfTheSun card) { + super(card); + } + + @Override + public DiscipleOfTheSun copy() { + return new DiscipleOfTheSun(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index f881b167e5a..bc2d7455136 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -81,6 +81,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Darkmoss Bridge", 245, Rarity.COMMON, mage.cards.d.DarkmossBridge.class)); cards.add(new SetCardInfo("Diamond Lion", 225, Rarity.RARE, mage.cards.d.DiamondLion.class)); cards.add(new SetCardInfo("Discerning Taste", 82, Rarity.COMMON, mage.cards.d.DiscerningTaste.class)); + cards.add(new SetCardInfo("Disciple of the Sun", 11, Rarity.COMMON, mage.cards.d.DiscipleOfTheSun.class)); cards.add(new SetCardInfo("Dragon's Rage Channeler", 121, Rarity.UNCOMMON, mage.cards.d.DragonsRageChanneler.class)); cards.add(new SetCardInfo("Dress Down", 39, Rarity.RARE, mage.cards.d.DressDown.class)); cards.add(new SetCardInfo("Drey Keeper", 194, Rarity.COMMON, mage.cards.d.DreyKeeper.class)); From b058370c649db93b5fae62665bcc6974cc418788 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:35:37 -0400 Subject: [PATCH 115/188] [MH2] Implemented Etherium Spinner --- .../src/mage/cards/e/EtheriumSpinner.java | 50 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 51 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EtheriumSpinner.java diff --git a/Mage.Sets/src/mage/cards/e/EtheriumSpinner.java b/Mage.Sets/src/mage/cards/e/EtheriumSpinner.java new file mode 100644 index 00000000000..ab7e8e32652 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EtheriumSpinner.java @@ -0,0 +1,50 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.filter.FilterSpell; +import mage.filter.predicate.mageobject.ManaValuePredicate; +import mage.game.permanent.token.ThopterColorlessToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EtheriumSpinner extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("a spell with mana value 4 or greater"); + + static { + filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 3)); + } + + public EtheriumSpinner(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Whenever you cast a spell with mana value 4 or greater, create a 1/1 colorless Thopter artifact creature token with flying. + this.addAbility(new SpellCastControllerTriggeredAbility( + new CreateTokenEffect(new ThopterColorlessToken()), filter, false + )); + } + + private EtheriumSpinner(final EtheriumSpinner card) { + super(card); + } + + @Override + public EtheriumSpinner copy() { + return new EtheriumSpinner(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index bc2d7455136..faeff7b62d3 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -90,6 +90,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Enchantress's Presence", 283, Rarity.RARE, mage.cards.e.EnchantresssPresence.class)); cards.add(new SetCardInfo("Endurance", 157, Rarity.MYTHIC, mage.cards.e.Endurance.class)); cards.add(new SetCardInfo("Esper Sentinel", 12, Rarity.RARE, mage.cards.e.EsperSentinel.class)); + cards.add(new SetCardInfo("Etherium Spinner", 40, Rarity.COMMON, mage.cards.e.EtheriumSpinner.class)); cards.add(new SetCardInfo("Ethersworn Sphinx", 195, Rarity.UNCOMMON, mage.cards.e.EtherswornSphinx.class)); cards.add(new SetCardInfo("Extruder", 296, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); cards.add(new SetCardInfo("Fae Offering", 158, Rarity.UNCOMMON, mage.cards.f.FaeOffering.class)); From da31fa9cffe38160e739830df31866d6588dae67 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:40:56 -0400 Subject: [PATCH 116/188] [MH2] Implemented Tragic Fall --- Mage.Sets/src/mage/cards/t/TragicFall.java | 41 ++++++++++++++++++++ Mage.Sets/src/mage/cards/t/TragicSlip.java | 2 +- Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/t/TragicFall.java diff --git a/Mage.Sets/src/mage/cards/t/TragicFall.java b/Mage.Sets/src/mage/cards/t/TragicFall.java new file mode 100644 index 00000000000..26063dce5f5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TragicFall.java @@ -0,0 +1,41 @@ +package mage.cards.t; + +import mage.abilities.condition.LockedInCondition; +import mage.abilities.condition.common.MorbidCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TragicFall extends CardImpl { + + public TragicFall(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}"); + + // Target creature gets -3/-3 until end of turn. + // Hellbent — That creature gets -13/-13 until end of turn instead if you have no cards in hand. + this.getSpellAbility().addEffect(new ConditionalContinuousEffect( + new BoostTargetEffect(-13, -13), new BoostTargetEffect(-3, -3), + new LockedInCondition(MorbidCondition.instance), "Target creature gets -1/-1 " + + "until end of turn.
Hellbent — That creature gets -13/-13 " + + "until end of turn instead if you have no cards in hand" + )); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + private TragicFall(final TragicFall card) { + super(card); + } + + @Override + public TragicFall copy() { + return new TragicFall(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TragicSlip.java b/Mage.Sets/src/mage/cards/t/TragicSlip.java index 0146d5aef5f..8916202a87a 100644 --- a/Mage.Sets/src/mage/cards/t/TragicSlip.java +++ b/Mage.Sets/src/mage/cards/t/TragicSlip.java @@ -28,7 +28,7 @@ public final class TragicSlip extends CardImpl { new BoostTargetEffect(-13, -13, Duration.EndOfTurn), new BoostTargetEffect(-1, -1, Duration.EndOfTurn), new LockedInCondition(MorbidCondition.instance), - "Target creature gets -1/-1 until end of turn. Morbid — That creature gets -13/-13 until end of turn instead if a creature died this turn")); + "Target creature gets -1/-1 until end of turn.
Morbid — That creature gets -13/-13 until end of turn instead if a creature died this turn")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index faeff7b62d3..20f0439d4f4 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -250,6 +250,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Titania, Protector of Argoth", 287, Rarity.MYTHIC, mage.cards.t.TitaniaProtectorOfArgoth.class)); cards.add(new SetCardInfo("Tormod's Cryptkeeper", 239, Rarity.COMMON, mage.cards.t.TormodsCryptkeeper.class)); cards.add(new SetCardInfo("Tourach's Canticle", 103, Rarity.COMMON, mage.cards.t.TourachsCanticle.class)); + cards.add(new SetCardInfo("Tragic Fall", 104, Rarity.COMMON, mage.cards.t.TragicFall.class)); cards.add(new SetCardInfo("Underworld Hermit", 105, Rarity.UNCOMMON, mage.cards.u.UnderworldHermit.class)); cards.add(new SetCardInfo("Unholy Heat", 145, Rarity.COMMON, mage.cards.u.UnholyHeat.class)); cards.add(new SetCardInfo("Unmarked Grave", 106, Rarity.RARE, mage.cards.u.UnmarkedGrave.class)); From 722f4d391b4f4b086e1aa23340699159211b2171 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Wed, 2 Jun 2021 20:46:09 -0500 Subject: [PATCH 117/188] [MH2] Implemented Galvanic Relay (#7877) --- Mage.Sets/src/mage/cards/g/GalvanicRelay.java | 126 ++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 127 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GalvanicRelay.java diff --git a/Mage.Sets/src/mage/cards/g/GalvanicRelay.java b/Mage.Sets/src/mage/cards/g/GalvanicRelay.java new file mode 100644 index 00000000000..e2bf3f82e6b --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GalvanicRelay.java @@ -0,0 +1,126 @@ +package mage.cards.g; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.StormAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +/** + * + * @author weirddan455 + */ +public final class GalvanicRelay extends CardImpl { + + public GalvanicRelay(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); + + // Exile the top card of your library. During your next turn, you may play that card. + this.getSpellAbility().addEffect(new GalvanicRelayEffect()); + + // Storm + this.addAbility(new StormAbility()); + } + + private GalvanicRelay(final GalvanicRelay card) { + super(card); + } + + @Override + public GalvanicRelay copy() { + return new GalvanicRelay(this); + } +} + +class GalvanicRelayEffect extends OneShotEffect { + + public GalvanicRelayEffect() { + super(Outcome.Benefit); + this.staticText = "Exile the top card of your library. During your next turn, you may play that card"; + } + + private GalvanicRelayEffect(final GalvanicRelayEffect effect) { + super(effect); + } + + @Override + public GalvanicRelayEffect copy() { + return new GalvanicRelayEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Card topCard = controller.getLibrary().getFromTop(game); + if (topCard != null) { + Card sourceCard = game.getCard(source.getSourceId()); + controller.moveCardsToExile(topCard, source, game, true, CardUtil.getCardExileZoneId(game, source), sourceCard != null ? sourceCard.getIdName() : ""); + ContinuousEffect effect = new GalvanicRelayMayPlayEffect(); + effect.setTargetPointer(new FixedTarget(topCard.getId())); + game.addEffect(effect, source); + return true; + } + } + return false; + } +} + +class GalvanicRelayMayPlayEffect extends AsThoughEffectImpl { + + private int castOnTurn = 0; + + public GalvanicRelayMayPlayEffect() { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit); + this.staticText = "During your next turn, you may play that card"; + } + + private GalvanicRelayMayPlayEffect(final GalvanicRelayMayPlayEffect effect) { + super(effect); + this.castOnTurn = effect.castOnTurn; + } + + @Override + public GalvanicRelayMayPlayEffect copy() { + return new GalvanicRelayMayPlayEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + this.castOnTurn = game.getTurnNum(); + } + + @Override + public boolean isInactive(Ability source, Game game) { + // Keep effect active until cleanup step of the controller's next turn. Turn will be checked again in applies method below. + if (castOnTurn != game.getTurnNum() && game.getPhase().getStep().getType() == PhaseStep.CLEANUP) { + return game.isActivePlayer(source.getControllerId()); + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + UUID mainCardId = CardUtil.getMainCardId(game, sourceId); + return source.isControlledBy(affectedControllerId) + && castOnTurn != game.getTurnNum() + && game.isActivePlayer(affectedControllerId) + && getTargetPointer().getTargets(game, source).contains(mainCardId); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 20f0439d4f4..01cd4e4ab74 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -112,6 +112,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Funnel-Web Recluse", 161, Rarity.COMMON, mage.cards.f.FunnelWebRecluse.class)); cards.add(new SetCardInfo("Fury", 126, Rarity.MYTHIC, mage.cards.f.Fury.class)); cards.add(new SetCardInfo("Gaea's Will", 162, Rarity.RARE, mage.cards.g.GaeasWill.class)); + cards.add(new SetCardInfo("Galvanic Relay", 127, Rarity.COMMON, mage.cards.g.GalvanicRelay.class)); cards.add(new SetCardInfo("General Ferrous Rokiric", 198, Rarity.RARE, mage.cards.g.GeneralFerrousRokiric.class)); cards.add(new SetCardInfo("Geyadrone Dihada", 199, Rarity.MYTHIC, mage.cards.g.GeyadroneDihada.class)); cards.add(new SetCardInfo("Ghost-Lit Drifter", 45, Rarity.UNCOMMON, mage.cards.g.GhostLitDrifter.class)); From 71ea4a51d67ba84e37041e1c6e8cab315c27490d Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Wed, 2 Jun 2021 20:46:51 -0500 Subject: [PATCH 118/188] [MH2] Implemented Academy Manufactor (#7864) * [MH2] Implemented Academy Manufactor * [MH2] Implemented Chatterfang, Squirrel General --- .../src/mage/cards/a/AcademyManufactor.java | 133 ++++++++++ .../cards/c/ChatterfangSquirrelGeneral.java | 116 +++++++++ .../src/mage/cards/d/DivineVisitation.java | 30 ++- .../src/mage/cards/d/DoublingSeason.java | 5 +- .../src/mage/cards/e/EsixFractalBloom.java | 7 +- .../src/mage/cards/g/GatherSpecimens.java | 11 +- Mage.Sets/src/mage/cards/p/PrimalVigor.java | 5 +- Mage.Sets/src/mage/sets/ModernHorizons2.java | 2 + .../replacement/AcademyManufactorTest.java | 71 ++++++ .../ChatterfangSquirrelGeneralTest.java | 54 ++++ .../CreateTwiceThatManyTokensEffect.java | 5 +- .../mage/game/events/CreateTokenEvent.java | 30 ++- .../mage/game/permanent/token/TokenImpl.java | 235 +++++++++--------- 13 files changed, 577 insertions(+), 127 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/AcademyManufactor.java create mode 100644 Mage.Sets/src/mage/cards/c/ChatterfangSquirrelGeneral.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/replacement/AcademyManufactorTest.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/replacement/ChatterfangSquirrelGeneralTest.java diff --git a/Mage.Sets/src/mage/cards/a/AcademyManufactor.java b/Mage.Sets/src/mage/cards/a/AcademyManufactor.java new file mode 100644 index 00000000000..e5ccd23d644 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AcademyManufactor.java @@ -0,0 +1,133 @@ +package mage.cards.a; + +import java.util.Map; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.Game; +import mage.game.events.CreateTokenEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.token.ClueArtifactToken; +import mage.game.permanent.token.FoodToken; +import mage.game.permanent.token.Token; +import mage.game.permanent.token.TreasureToken; + +/** + * + * @author weirddan455 + */ +public final class AcademyManufactor extends CardImpl { + + public AcademyManufactor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); + + this.subtype.add(SubType.ASSEMBLY_WORKER); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // If you would create a Clue, Food, or Treasure token, instead create one of each. + this.addAbility(new SimpleStaticAbility(new AcademyManufactorEffect())); + } + + private AcademyManufactor(final AcademyManufactor card) { + super(card); + } + + @Override + public AcademyManufactor copy() { + return new AcademyManufactor(this); + } +} + +class AcademyManufactorEffect extends ReplacementEffectImpl { + + public AcademyManufactorEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + this.staticText = "If you would create a Clue, Food, or Treasure token, instead create one of each"; + } + + private AcademyManufactorEffect(final AcademyManufactorEffect effect) { + super(effect); + } + + @Override + public AcademyManufactorEffect copy() { + return new AcademyManufactorEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CREATE_TOKEN; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event instanceof CreateTokenEvent && event.getPlayerId().equals(source.getControllerId())) { + CreateTokenEvent tokenEvent = (CreateTokenEvent) event; + for (Token token : tokenEvent.getTokens().keySet()) { + if (token instanceof ClueArtifactToken || token instanceof FoodToken || token instanceof TreasureToken) { + return true; + } + } + } + return false; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + if (event instanceof CreateTokenEvent) { + CreateTokenEvent tokenEvent = (CreateTokenEvent) event; + int clues = 0; + int food = 0; + int treasures = 0; + ClueArtifactToken clueToken = null; + FoodToken foodToken = null; + TreasureToken treasureToken = null; + Map tokens = tokenEvent.getTokens(); + + for (Map.Entry entry : tokens.entrySet()) { + Token token = entry.getKey(); + int amount = entry.getValue(); + if (token instanceof ClueArtifactToken) { + clueToken = (ClueArtifactToken) token; + clues += amount; + } + else if (token instanceof FoodToken) { + foodToken = (FoodToken) token; + food += amount; + } + else if (token instanceof TreasureToken) { + treasureToken = (TreasureToken) token; + treasures += amount; + } + } + + if (clueToken == null) { + clueToken = new ClueArtifactToken(); + } + if (foodToken == null) { + foodToken = new FoodToken(); + } + if (treasureToken == null) { + treasureToken = new TreasureToken(); + } + + int cluesToAdd = food + treasures; + int foodToAdd = clues + treasures; + int treasuresToAdd = clues + food; + + tokens.put(clueToken, tokens.getOrDefault(clueToken, 0) + cluesToAdd); + tokens.put(foodToken, tokens.getOrDefault(foodToken, 0) + foodToAdd); + tokens.put(treasureToken, tokens.getOrDefault(treasureToken, 0) + treasuresToAdd); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/c/ChatterfangSquirrelGeneral.java b/Mage.Sets/src/mage/cards/c/ChatterfangSquirrelGeneral.java new file mode 100644 index 00000000000..519ad331df6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChatterfangSquirrelGeneral.java @@ -0,0 +1,116 @@ +package mage.cards.c; + +import java.util.Map; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.SacrificeXTargetCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.GetXValue; +import mage.abilities.dynamicvalue.common.SignInversionDynamicValue; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.constants.*; +import mage.abilities.keyword.ForestwalkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.game.events.CreateTokenEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.token.SquirrelToken; +import mage.game.permanent.token.Token; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author weirddan455 + */ +public final class ChatterfangSquirrelGeneral extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.SQUIRREL, "Squirrels"); + + public ChatterfangSquirrelGeneral(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.SQUIRREL); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Forestwalk + this.addAbility(new ForestwalkAbility()); + + // If one or more tokens would be created under your control, those tokens plus that many 1/1 green Squirrel creature tokens are created instead. + this.addAbility(new SimpleStaticAbility(new ChatterfangSquirrelGeneralReplacementEffect())); + + // {B}, Sacrifice X Squirrels: Target creature gets +X/-X until end of turn. + Ability ability = new SimpleActivatedAbility(new BoostTargetEffect( + GetXValue.instance, new SignInversionDynamicValue(GetXValue.instance), Duration.EndOfTurn), + new ManaCostsImpl<>("{B}") + ); + ability.addCost(new SacrificeXTargetCost(filter)); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + private ChatterfangSquirrelGeneral(final ChatterfangSquirrelGeneral card) { + super(card); + } + + @Override + public ChatterfangSquirrelGeneral copy() { + return new ChatterfangSquirrelGeneral(this); + } +} + +class ChatterfangSquirrelGeneralReplacementEffect extends ReplacementEffectImpl { + + public ChatterfangSquirrelGeneralReplacementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + this.staticText = "If one or more tokens would be created under your control, those tokens plus that many 1/1 green Squirrel creature tokens are created instead"; + } + + private ChatterfangSquirrelGeneralReplacementEffect(final ChatterfangSquirrelGeneralReplacementEffect effect) { + super(effect); + } + + @Override + public ChatterfangSquirrelGeneralReplacementEffect copy() { + return new ChatterfangSquirrelGeneralReplacementEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CREATE_TOKEN; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + if (event instanceof CreateTokenEvent) { + CreateTokenEvent tokenEvent = (CreateTokenEvent) event; + SquirrelToken squirrelToken = null; + int amount = 0; + Map tokens = tokenEvent.getTokens(); + for (Map.Entry entry : tokens.entrySet()) { + amount += entry.getValue(); + if (entry.getKey() instanceof SquirrelToken) { + squirrelToken = (SquirrelToken) entry.getKey(); + } + } + if (squirrelToken == null) { + squirrelToken = new SquirrelToken(); + } + tokens.put(squirrelToken, tokens.getOrDefault(squirrelToken, 0) + amount); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/d/DivineVisitation.java b/Mage.Sets/src/mage/cards/d/DivineVisitation.java index d1689f614a7..3d35c6366da 100644 --- a/Mage.Sets/src/mage/cards/d/DivineVisitation.java +++ b/Mage.Sets/src/mage/cards/d/DivineVisitation.java @@ -1,5 +1,7 @@ package mage.cards.d; +import java.util.Iterator; +import java.util.Map; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -14,6 +16,7 @@ import mage.game.Game; import mage.game.events.CreateTokenEvent; import mage.game.events.GameEvent; import mage.game.permanent.token.AngelVigilanceToken; +import mage.game.permanent.token.Token; /** * @@ -62,13 +65,34 @@ class DivineVisitationEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getPlayerId().equals(source.getControllerId()) - && ((CreateTokenEvent) event).getToken().isCreature(); + if (event instanceof CreateTokenEvent && event.getPlayerId().equals(source.getControllerId())) { + CreateTokenEvent tokenEvent = (CreateTokenEvent) event; + for (Token token : tokenEvent.getTokens().keySet()) { + if (token.isCreature()) { + return true; + } + } + } + return false; } @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - ((CreateTokenEvent) event).setToken(new AngelVigilanceToken()); + if (event instanceof CreateTokenEvent) { + int amount = 0; + CreateTokenEvent tokenEvent = (CreateTokenEvent) event; + Iterator> it = tokenEvent.getTokens().entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = it.next(); + if (entry.getKey().isCreature()) { + amount += entry.getValue(); + it.remove(); + } + } + if (amount > 0) { + tokenEvent.getTokens().put(new AngelVigilanceToken(), amount); + } + } return false; } diff --git a/Mage.Sets/src/mage/cards/d/DoublingSeason.java b/Mage.Sets/src/mage/cards/d/DoublingSeason.java index 471950ef73e..432ea08502d 100644 --- a/Mage.Sets/src/mage/cards/d/DoublingSeason.java +++ b/Mage.Sets/src/mage/cards/d/DoublingSeason.java @@ -9,6 +9,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.game.Game; +import mage.game.events.CreateTokenEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -69,7 +70,9 @@ class DoublingSeasonTokenEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() * 2); + if (event instanceof CreateTokenEvent) { + ((CreateTokenEvent) event).doubleTokens(); + } return false; } diff --git a/Mage.Sets/src/mage/cards/e/EsixFractalBloom.java b/Mage.Sets/src/mage/cards/e/EsixFractalBloom.java index 6f332535606..ccfacd565e1 100644 --- a/Mage.Sets/src/mage/cards/e/EsixFractalBloom.java +++ b/Mage.Sets/src/mage/cards/e/EsixFractalBloom.java @@ -107,7 +107,12 @@ class EsixFractalBloomEffect extends ReplacementEffectImpl { if (permanent == null) { return false; } - ((CreateTokenEvent) event).setToken(copyPermanentToToken(permanent, game, source)); + if (event instanceof CreateTokenEvent) { + CreateTokenEvent tokenEvent = (CreateTokenEvent) event; + int amount = tokenEvent.getAmount(); + tokenEvent.getTokens().clear(); + tokenEvent.getTokens().put(copyPermanentToToken(permanent, game, source), amount); + } return false; } diff --git a/Mage.Sets/src/mage/cards/g/GatherSpecimens.java b/Mage.Sets/src/mage/cards/g/GatherSpecimens.java index 20eeab20d88..0c0ae278dc3 100644 --- a/Mage.Sets/src/mage/cards/g/GatherSpecimens.java +++ b/Mage.Sets/src/mage/cards/g/GatherSpecimens.java @@ -13,6 +13,7 @@ import mage.game.Game; import mage.game.events.CreateTokenEvent; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.token.Token; import mage.players.Player; import java.util.UUID; @@ -77,9 +78,15 @@ class GatherSpecimensReplacementEffect extends ReplacementEffectImpl { } } } - if (event.getType() == GameEvent.EventType.CREATE_TOKEN && ((CreateTokenEvent) event).getToken().isCreature()) { + if (event.getType() == GameEvent.EventType.CREATE_TOKEN) { Player controller = game.getPlayer(source.getControllerId()); - return controller != null && controller.hasOpponent(event.getPlayerId(), game); + if (controller != null && controller.hasOpponent(event.getPlayerId(), game)) { + for (Token token : ((CreateTokenEvent) event).getTokens().keySet()) { + if (token.isCreature()) { + return true; + } + } + } } return false; } diff --git a/Mage.Sets/src/mage/cards/p/PrimalVigor.java b/Mage.Sets/src/mage/cards/p/PrimalVigor.java index 547ce9b03e5..377f203e933 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalVigor.java +++ b/Mage.Sets/src/mage/cards/p/PrimalVigor.java @@ -10,6 +10,7 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.CreateTokenEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -73,7 +74,9 @@ class PrimalVigorTokenEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() * 2); + if (event instanceof CreateTokenEvent) { + ((CreateTokenEvent) event).doubleTokens(); + } return false; } diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 01cd4e4ab74..ddba7ff6017 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -29,6 +29,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Abiding Grace", 1, Rarity.UNCOMMON, mage.cards.a.AbidingGrace.class)); cards.add(new SetCardInfo("Abundant Harvest", 147, Rarity.COMMON, mage.cards.a.AbundantHarvest.class)); + cards.add(new SetCardInfo("Academy Manufactor", 219, Rarity.RARE, mage.cards.a.AcademyManufactor.class)); cards.add(new SetCardInfo("Aeromoeba", 37, Rarity.COMMON, mage.cards.a.Aeromoeba.class)); cards.add(new SetCardInfo("Aeve, Progenitor Ooze", 148, Rarity.RARE, mage.cards.a.AeveProgenitorOoze.class)); cards.add(new SetCardInfo("Angelic Curator", 262, Rarity.UNCOMMON, mage.cards.a.AngelicCurator.class)); @@ -69,6 +70,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Captured by Lagacs", 188, Rarity.COMMON, mage.cards.c.CapturedByLagacs.class)); cards.add(new SetCardInfo("Chainer, Nightmare Adept", 289, Rarity.RARE, mage.cards.c.ChainerNightmareAdept.class)); cards.add(new SetCardInfo("Chance Encounter", 277, Rarity.RARE, mage.cards.c.ChanceEncounter.class)); + cards.add(new SetCardInfo("Chatterfang, Squirrel General", 151, Rarity.MYTHIC, mage.cards.c.ChatterfangSquirrelGeneral.class)); cards.add(new SetCardInfo("Chatterstorm", 152, Rarity.COMMON, mage.cards.c.Chatterstorm.class)); cards.add(new SetCardInfo("Chitterspitter", 153, Rarity.RARE, mage.cards.c.Chitterspitter.class)); cards.add(new SetCardInfo("Chrome Courier", 190, Rarity.COMMON, mage.cards.c.ChromeCourier.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/AcademyManufactorTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/AcademyManufactorTest.java new file mode 100644 index 00000000000..068f70edab9 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/AcademyManufactorTest.java @@ -0,0 +1,71 @@ +package org.mage.test.cards.replacement; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class AcademyManufactorTest extends CardTestPlayerBase { + + @Test + public void testAcademyManufactor() { + addCard(Zone.BATTLEFIELD, playerA, "Academy Manufactor"); + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.HAND, playerA, "Thraben Inspector"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Thraben Inspector"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertAllCommandsUsed(); + assertPermanentCount(playerA, "Plains", 1); + assertPermanentCount(playerA, "Academy Manufactor", 1); + assertPermanentCount(playerA, "Thraben Inspector", 1); + assertPermanentCount(playerA, "Clue", 1); + assertPermanentCount(playerA, "Food", 1); + assertPermanentCount(playerA, "Treasure", 1); + } + + @Test + public void testMultipleReplacementEffect() { + addCard(Zone.BATTLEFIELD, playerA, "Academy Manufactor", 2); + addCard(Zone.BATTLEFIELD, playerA, "Anointed Procession"); + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.HAND, playerA, "Thraben Inspector"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Thraben Inspector"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertAllCommandsUsed(); + assertPermanentCount(playerA, "Plains", 1); + assertPermanentCount(playerA, "Academy Manufactor", 2); + assertPermanentCount(playerA, "Anointed Procession", 1); + assertPermanentCount(playerA, "Thraben Inspector", 1); + assertPermanentCount(playerA, "Clue", 6); + assertPermanentCount(playerA, "Food", 6); + assertPermanentCount(playerA, "Treasure", 6); + } + + @Test + public void testTokenLimit() { + addCard(Zone.BATTLEFIELD, playerA, "Academy Manufactor", 6); + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.HAND, playerA, "Thraben Inspector"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Thraben Inspector"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertAllCommandsUsed(); + assertPermanentCount(playerA, "Plains", 1); + assertPermanentCount(playerA, "Academy Manufactor", 6); + assertPermanentCount(playerA, "Thraben Inspector", 1); + + // 8 permanents above + 500 token limit + assertPermanentCount(playerA, 508); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ChatterfangSquirrelGeneralTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ChatterfangSquirrelGeneralTest.java new file mode 100644 index 00000000000..f9912ba60eb --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ChatterfangSquirrelGeneralTest.java @@ -0,0 +1,54 @@ +package org.mage.test.cards.replacement; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class ChatterfangSquirrelGeneralTest extends CardTestPlayerBase { + + private static final String chatterfang = "Chatterfang, Squirrel General"; + + @Test + public void testChatterfang() { + addCard(Zone.BATTLEFIELD, playerA, chatterfang); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + addCard(Zone.HAND, playerA, "Raise the Alarm"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raise the Alarm"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertAllCommandsUsed(); + assertPermanentCount(playerA, "Plains", 2); + assertPermanentCount(playerA, chatterfang, 1); + assertPermanentCount(playerA, "Soldier", 2); + assertPermanentCount(playerA, "Squirrel", 2); + } + + @Test + public void testChatterfangPlusAcademyManufactor() { + addCard(Zone.BATTLEFIELD, playerA, chatterfang); + addCard(Zone.BATTLEFIELD, playerA, "Academy Manufactor"); + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.HAND, playerA, "Thraben Inspector"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Thraben Inspector"); + // Order Academy Manufactor replacement effect first + setChoice(playerA, "Academy Manufactor"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertAllCommandsUsed(); + assertPermanentCount(playerA, "Plains", 1); + assertPermanentCount(playerA, chatterfang, 1); + assertPermanentCount(playerA, "Academy Manufactor", 1); + assertPermanentCount(playerA, "Clue", 1); + assertPermanentCount(playerA, "Food", 1); + assertPermanentCount(playerA, "Treasure" ,1); + assertPermanentCount(playerA, "Squirrel", 3); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/replacement/CreateTwiceThatManyTokensEffect.java b/Mage/src/main/java/mage/abilities/effects/common/replacement/CreateTwiceThatManyTokensEffect.java index d9942302275..ef77c25eec4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/replacement/CreateTwiceThatManyTokensEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/replacement/CreateTwiceThatManyTokensEffect.java @@ -5,6 +5,7 @@ import mage.abilities.effects.ReplacementEffectImpl; import mage.constants.Duration; import mage.constants.Outcome; import mage.game.Game; +import mage.game.events.CreateTokenEvent; import mage.game.events.GameEvent; /** @@ -39,7 +40,9 @@ public class CreateTwiceThatManyTokensEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() * 2); + if (event instanceof CreateTokenEvent) { + ((CreateTokenEvent) event).doubleTokens(); + } return false; } diff --git a/Mage/src/main/java/mage/game/events/CreateTokenEvent.java b/Mage/src/main/java/mage/game/events/CreateTokenEvent.java index 9c73da08565..5b87a3d4778 100644 --- a/Mage/src/main/java/mage/game/events/CreateTokenEvent.java +++ b/Mage/src/main/java/mage/game/events/CreateTokenEvent.java @@ -3,22 +3,40 @@ package mage.game.events; import mage.abilities.Ability; import mage.game.permanent.token.Token; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; public class CreateTokenEvent extends GameEvent { - private Token token; + private final Map tokens = new HashMap<>(); public CreateTokenEvent(Ability source, UUID controllerId, int amount, Token token) { super(GameEvent.EventType.CREATE_TOKEN, null, source, controllerId, amount, false); - this.token = token; + tokens.put(token, amount); } - public Token getToken() { - return token; + public Map getTokens() { + return tokens; } - public void setToken(Token token) { - this.token = token; + public void doubleTokens() { + for (Map.Entry entry : tokens.entrySet()) { + entry.setValue(entry.getValue() * 2); + } + } + + @Override + public int getAmount() { + int amount = 0; + for (Integer num : tokens.values()) { + amount += num; + } + return amount; + } + + @Override + public void setAmount(int amount) { + throw new UnsupportedOperationException("Do not use event.setAmount for tokens. Amount must be set individually in event.getTokens"); } } diff --git a/Mage/src/main/java/mage/game/permanent/token/TokenImpl.java b/Mage/src/main/java/mage/game/permanent/token/TokenImpl.java index e2a9d18e990..fd73338f47b 100644 --- a/Mage/src/main/java/mage/game/permanent/token/TokenImpl.java +++ b/Mage/src/main/java/mage/game/permanent/token/TokenImpl.java @@ -14,10 +14,8 @@ import mage.game.permanent.PermanentToken; import mage.players.Player; import mage.util.RandomUtil; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.UUID; +import java.util.*; + import mage.abilities.SpellAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; @@ -184,13 +182,24 @@ public abstract class TokenImpl extends MageObjectImpl implements Token { if (!created || !game.replaceEvent(event)) { int currentTokens = game.getBattlefield().countTokens(event.getPlayerId()); int tokenSlots = Math.max(MAX_TOKENS_PER_GAME - currentTokens, 0); - if (event.getAmount() > tokenSlots) { + int amountToRemove = event.getAmount() - tokenSlots; + if (amountToRemove > 0) { game.informPlayers( "The token limit per player is " + MAX_TOKENS_PER_GAME + ", " + controller.getName() + " will only create " + tokenSlots + " tokens." ); + Iterator> it = event.getTokens().entrySet().iterator(); + while (it.hasNext() && amountToRemove > 0) { + Map.Entry entry = it.next(); + int newValue = entry.getValue() - amountToRemove; + if (newValue > 0) { + entry.setValue(newValue); + break; + } + amountToRemove -= entry.getValue(); + it.remove(); + } } - event.setAmount(Math.min(event.getAmount(), tokenSlots)); putOntoBattlefieldHelper(event, game, source, tapped, attacking, attackedPlayer, created); return true; } @@ -203,129 +212,131 @@ public abstract class TokenImpl extends MageObjectImpl implements Token { return; } - Token token = event.getToken(); - int amount = event.getAmount(); - String setCode = token instanceof TokenImpl ? ((TokenImpl) token).getSetCode(game, event.getSourceId()) : null; + for (Map.Entry entry : event.getTokens().entrySet()) { + Token token = entry.getKey(); + int amount = entry.getValue(); + String setCode = token instanceof TokenImpl ? ((TokenImpl) token).getSetCode(game, event.getSourceId()) : null; - List needTokens = new ArrayList<>(); - List allowedTokens = new ArrayList<>(); + List needTokens = new ArrayList<>(); + List allowedTokens = new ArrayList<>(); - // prepare tokens to enter - for (int i = 0; i < amount; i++) { - // use event.getPlayerId() as controller cause it can be replaced by replacement effect - PermanentToken newPermanent = new PermanentToken(token, event.getPlayerId(), setCode, game); - game.getState().addCard(newPermanent); - needTokens.add(newPermanent); - game.getPermanentsEntering().put(newPermanent.getId(), newPermanent); - newPermanent.setTapped(tapped); + // prepare tokens to enter + for (int i = 0; i < amount; i++) { + // use event.getPlayerId() as controller cause it can be replaced by replacement effect + PermanentToken newPermanent = new PermanentToken(token, event.getPlayerId(), setCode, game); + game.getState().addCard(newPermanent); + needTokens.add(newPermanent); + game.getPermanentsEntering().put(newPermanent.getId(), newPermanent); + newPermanent.setTapped(tapped); - ZoneChangeEvent emptyEvent = new ZoneChangeEvent(newPermanent, newPermanent.getControllerId(), Zone.OUTSIDE, Zone.BATTLEFIELD); - // tokens zcc must simulate card's zcc too keep copied card/spell settings - // (example: etb's kicker ability of copied creature spell, see tests with Deathforge Shaman) - newPermanent.updateZoneChangeCounter(game, emptyEvent); - } + ZoneChangeEvent emptyEvent = new ZoneChangeEvent(newPermanent, newPermanent.getControllerId(), Zone.OUTSIDE, Zone.BATTLEFIELD); + // tokens zcc must simulate card's zcc too keep copied card/spell settings + // (example: etb's kicker ability of copied creature spell, see tests with Deathforge Shaman) + newPermanent.updateZoneChangeCounter(game, emptyEvent); + } - // check ETB effects - game.setScopeRelevant(true); - for (Permanent permanent : needTokens) { - if (permanent.entersBattlefield(source, game, Zone.OUTSIDE, true)) { - allowedTokens.add(permanent); - } else { + // check ETB effects + game.setScopeRelevant(true); + for (Permanent permanent : needTokens) { + if (permanent.entersBattlefield(source, game, Zone.OUTSIDE, true)) { + allowedTokens.add(permanent); + } else { + game.getPermanentsEntering().remove(permanent.getId()); + } + } + game.setScopeRelevant(false); + + // put allowed tokens to play + int createOrder = game.getState().getNextPermanentOrderNumber(); + for (Permanent permanent : allowedTokens) { + game.addPermanent(permanent, createOrder); + permanent.setZone(Zone.BATTLEFIELD, game); game.getPermanentsEntering().remove(permanent.getId()); - } - } - game.setScopeRelevant(false); - // put allowed tokens to play - int createOrder = game.getState().getNextPermanentOrderNumber(); - for (Permanent permanent : allowedTokens) { - game.addPermanent(permanent, createOrder); - permanent.setZone(Zone.BATTLEFIELD, game); - game.getPermanentsEntering().remove(permanent.getId()); - - // keep tokens ids - if (token instanceof TokenImpl) { - ((TokenImpl) token).lastAddedTokenIds.add(permanent.getId()); - ((TokenImpl) token).lastAddedTokenId = permanent.getId(); - } - - // created token events - ZoneChangeEvent zccEvent = new ZoneChangeEvent(permanent, permanent.getControllerId(), Zone.OUTSIDE, Zone.BATTLEFIELD); - game.addSimultaneousEvent(zccEvent); - if (permanent instanceof PermanentToken && created) { - game.addSimultaneousEvent(new CreatedTokenEvent(source, (PermanentToken) permanent)); - } - - // handle auras coming into the battlefield - // code refactored from CopyPermanentEffect - if (permanent.getSubtype().contains(SubType.AURA)) { - Outcome auraOutcome = Outcome.BoostCreature; - Target auraTarget = null; - - // attach - search effect in spell ability (example: cast Utopia Sprawl, cast Estrid's Invocation on it) - for (Ability ability : permanent.getAbilities()) { - if (!(ability instanceof SpellAbility)) { - continue; - } - auraOutcome = ability.getEffects().getOutcome(ability); - for (Effect effect : ability.getEffects()) { - if (!(effect instanceof AttachEffect)) { - continue; - } - if (permanent.getSpellAbility().getTargets().size() > 0) { - auraTarget = permanent.getSpellAbility().getTargets().get(0); - } - } + // keep tokens ids + if (token instanceof TokenImpl) { + ((TokenImpl) token).lastAddedTokenIds.add(permanent.getId()); + ((TokenImpl) token).lastAddedTokenId = permanent.getId(); } - // enchant - search in all abilities (example: cast Estrid's Invocation on enchanted creature by Estrid, the Masked second ability, cast Estrid's Invocation on it) - if (auraTarget == null) { + // created token events + ZoneChangeEvent zccEvent = new ZoneChangeEvent(permanent, permanent.getControllerId(), Zone.OUTSIDE, Zone.BATTLEFIELD); + game.addSimultaneousEvent(zccEvent); + if (permanent instanceof PermanentToken && created) { + game.addSimultaneousEvent(new CreatedTokenEvent(source, (PermanentToken) permanent)); + } + + // handle auras coming into the battlefield + // code refactored from CopyPermanentEffect + if (permanent.getSubtype().contains(SubType.AURA)) { + Outcome auraOutcome = Outcome.BoostCreature; + Target auraTarget = null; + + // attach - search effect in spell ability (example: cast Utopia Sprawl, cast Estrid's Invocation on it) for (Ability ability : permanent.getAbilities()) { - if (!(ability instanceof EnchantAbility)) { + if (!(ability instanceof SpellAbility)) { continue; } auraOutcome = ability.getEffects().getOutcome(ability); - if (ability.getTargets().size() > 0) { // Animate Dead don't have targets - auraTarget = ability.getTargets().get(0); + for (Effect effect : ability.getEffects()) { + if (!(effect instanceof AttachEffect)) { + continue; + } + if (permanent.getSpellAbility().getTargets().size() > 0) { + auraTarget = permanent.getSpellAbility().getTargets().get(0); + } } } + + // enchant - search in all abilities (example: cast Estrid's Invocation on enchanted creature by Estrid, the Masked second ability, cast Estrid's Invocation on it) + if (auraTarget == null) { + for (Ability ability : permanent.getAbilities()) { + if (!(ability instanceof EnchantAbility)) { + continue; + } + auraOutcome = ability.getEffects().getOutcome(ability); + if (ability.getTargets().size() > 0) { // Animate Dead don't have targets + auraTarget = ability.getTargets().get(0); + } + } + } + + // if this is a copy of a copy, the copy's target has been copied and needs to be cleared + if (auraTarget == null) { + break; + } + // clear selected target + if (auraTarget.getFirstTarget() != null) { + auraTarget.remove(auraTarget.getFirstTarget()); + } + + // select new target + auraTarget.setNotTarget(true); + if (!controller.choose(auraOutcome, auraTarget, source.getSourceId(), game)) { + break; + } + UUID targetId = auraTarget.getFirstTarget(); + Permanent targetPermanent = game.getPermanent(targetId); + Player targetPlayer = game.getPlayer(targetId); + if (targetPermanent != null) { + targetPermanent.addAttachment(permanent.getId(), source, game); + } else if (targetPlayer != null) { + targetPlayer.addAttachment(permanent.getId(), source, game); + } + } + // end of aura code : just remove this line if everything works out well + + // must attack + if (attacking && game.getCombat() != null && game.getActivePlayerId().equals(permanent.getControllerId())) { + game.getCombat().addAttackingCreature(permanent.getId(), game, attackedPlayer); } - // if this is a copy of a copy, the copy's target has been copied and needs to be cleared - if (auraTarget == null) { - break; + // game logs + if (created) { + game.informPlayers(controller.getLogName() + " creates a " + permanent.getLogName() + " token"); + } else { + game.informPlayers(permanent.getLogName() + " enters the battlefield as a token under " + controller.getLogName() + "'s control'"); } - // clear selected target - if (auraTarget.getFirstTarget() != null) { - auraTarget.remove(auraTarget.getFirstTarget()); - } - - // select new target - auraTarget.setNotTarget(true); - if (!controller.choose(auraOutcome, auraTarget, source.getSourceId(), game)) { - break; - } - UUID targetId = auraTarget.getFirstTarget(); - Permanent targetPermanent = game.getPermanent(targetId); - Player targetPlayer = game.getPlayer(targetId); - if (targetPermanent != null) { - targetPermanent.addAttachment(permanent.getId(), source, game); - } else if (targetPlayer != null) { - targetPlayer.addAttachment(permanent.getId(), source, game); - } - } - // end of aura code : just remove this line if everything works out well - - // must attack - if (attacking && game.getCombat() != null && game.getActivePlayerId().equals(permanent.getControllerId())) { - game.getCombat().addAttackingCreature(permanent.getId(), game, attackedPlayer); - } - - // game logs - if (created) { - game.informPlayers(controller.getLogName() + " creates a " + permanent.getLogName() + " token"); - } else { - game.informPlayers(permanent.getLogName() + " enters the battlefield as a token under " + controller.getLogName() + "'s control'"); } } game.getState().applyEffects(game); // Needed to do it here without LKIReset i.e. do get SwordOfTheMeekTest running correctly. From 71ea01227c56edb6415f3797da1e5c7d14488493 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:49:19 -0400 Subject: [PATCH 119/188] [MH2] Implemented Gargodon --- Mage.Sets/src/mage/cards/g/Gargadon.java | 41 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 42 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/Gargadon.java diff --git a/Mage.Sets/src/mage/cards/g/Gargadon.java b/Mage.Sets/src/mage/cards/g/Gargadon.java new file mode 100644 index 00000000000..5c7c82d720e --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/Gargadon.java @@ -0,0 +1,41 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.SuspendAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Gargadon extends CardImpl { + + public Gargadon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{R}"); + + this.subtype.add(SubType.BEAST); + this.power = new MageInt(7); + this.toughness = new MageInt(5); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Suspend 4—{1}{R} + this.addAbility(new SuspendAbility(4, new ManaCostsImpl<>("{1}{R}"), this)); + } + + private Gargadon(final Gargadon card) { + super(card); + } + + @Override + public Gargadon copy() { + return new Gargadon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index ddba7ff6017..f8857149081 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -115,6 +115,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Fury", 126, Rarity.MYTHIC, mage.cards.f.Fury.class)); cards.add(new SetCardInfo("Gaea's Will", 162, Rarity.RARE, mage.cards.g.GaeasWill.class)); cards.add(new SetCardInfo("Galvanic Relay", 127, Rarity.COMMON, mage.cards.g.GalvanicRelay.class)); + cards.add(new SetCardInfo("Gargadon", 128, Rarity.COMMON, mage.cards.g.Gargadon.class)); cards.add(new SetCardInfo("General Ferrous Rokiric", 198, Rarity.RARE, mage.cards.g.GeneralFerrousRokiric.class)); cards.add(new SetCardInfo("Geyadrone Dihada", 199, Rarity.MYTHIC, mage.cards.g.GeyadroneDihada.class)); cards.add(new SetCardInfo("Ghost-Lit Drifter", 45, Rarity.UNCOMMON, mage.cards.g.GhostLitDrifter.class)); From ca59ae5c56d89b5c0e36025b458f4ce78d169c9d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:49:55 -0400 Subject: [PATCH 120/188] [MH2] updated spoiler --- Utils/mtg-cards-data.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 0f84eba9fed..2aefba99082 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -41348,6 +41348,7 @@ Esper Sentinel|Modern Horizons 2|12|R|{W}|Artifact Creature - Human Soldier|1|1| Fairgrounds Patrol|Modern Horizons 2|13|C|{1}{W}|Creature - Human Soldier|2|1|{1}{W}, Exile Fairgrounds Patrol from your graveyard: Create a 1/1 colorless Thopter creature token with flying. Activate only as a sorcery.| Glorious Enforcer|Modern Horizons 2|14|U|{5}{W}{W}|Creature - Angel|5|5|Flying, lifelink$At the beginning of each combat, if you have more life than an opponent, Glorious Enforcer gains double strike until end of turn.| Guardian Kirin|Modern Horizons 2|15|C|{3}{W}|Creature - Kirin|2|3|Flying$Whenever another creature you control dies, put a +1/+1 counter on Guardian Kirin.| +Healer's Flock|Modern Horizons 2|16|U|{W}{W}{W}|Creature - Bird|3|3|Flying, lifelink| Knighted Myr|Modern Horizons 2|17|C|{2}{W}|Artifact Creature - Myr Knight|2|2|{2}{W}: Adapt 1.$Whenever one or more +1/+1 counters are put on Knighted Myr, it gains double strike until end of turn.| Landscaper Colos|Modern Horizons 2|18|C|{5}{W}|Creature - Goat Beast|4|6|When Landscaper Colos enters the battlefield, put target card from an opponent's graveyard on the bottom of their library.$Basic landcycling {1}{W}| Late to Dinner|Modern Horizons 2|19|C|{3}{W}|Sorcery|||Return target creature card from your graveyard to the battlefield. Create a Food token.| @@ -41391,6 +41392,7 @@ Raving Visionary|Modern Horizons 2|56|U|{1}{U}|Creature - Merfolk Wizard|1|1|{U} Recalibrate|Modern Horizons 2|57|C|{1}{U}|Instant|||Return target creature to its owner's hand. If you've discarded a card this turn, draw a card.| Rise and Shine|Modern Horizons 2|58|R|{1}{U}|Sorcery|||Target noncreature artifact you control becomes a 0/0 artifact creature. Put four +1/+1 counters on each artifact that became a creature this way.$Overload {4}{U}{U}| Rishadan Dockhand|Modern Horizons 2|59|R|{U}|Creature - Merfolk|1|2|Islandwalk${1}, {T}: Tap target land.| +Said // Done|Modern Horizons 2|60|U|{2}{U}|Sorcery|||Return target instant or sorcery card from your graveyard to your hand.$Done${3}{U}$Instant$Tap up to two target creatures. They don't untap during their controllers' next untap step.| Scuttletide|Modern Horizons 2|61|U|{1}{U}|Enchantment|||{1}, Discard a card: Create a 0/3 blue Crab creature token.$Delirium — Crabs you control get +1/+1 as long as there are four or more card types among cards in your graveyard.| Shattered Ego|Modern Horizons 2|62|C|{U}|Enchantment - Aura|||Enchant creature$Enchanted creature gets -3/-0.${3}{U}{U}: Put enchanted creature into its owner's library third from the top.| So Shiny|Modern Horizons 2|63|C|{2}{U}|Enchantment - Aura|||Enchant creature$When So Shiny enters the battlefield, if you control a token, tap enchanted creature, then scry 2.$Enchanted creature doesn't untap during its controller's untap step.| @@ -41460,6 +41462,7 @@ Fury|Modern Horizons 2|126|M|{3}{R}{R}|Creature - Elemental Incarnation|3|3|Doub Galvanic Relay|Modern Horizons 2|127|C|{2}{R}|Sorcery|||Exile the top card of your library. During your next turn, you may play that card.$Storm| Gargadon|Modern Horizons 2|128|C|{5}{R}{R}|Creature - Beast|7|5|Trample$Suspend 4—{1}{R}| Glimpse of Tomorrow|Modern Horizons 2|129|R||Sorcery|||Suspend 3—{R}{R}$Shuffle all permanents you own into your library, then reveal that many cards from the top of your library. Put all non-Aura permanent cards revealed this way onto the battlefield, then do the same for Aura cards, then put the rest on the bottom of your library in a random order.| +Goblin Traprunner|Modern Horizons 2|130|U|{3}{R}|Creature - Goblin|4|2|Whenever Goblin Traprunner attacks, flip three coins. For each flip you win, create a 1/1 red Goblin creature token that's tapped and attacking.| Gouged Zealot|Modern Horizons 2|131|C|{3}{R}|Creature - Cyclops Berserker|4|3|Reach$Delirium — Whenever Gouged Zealot attacks, if there are four or more card types among cards in your graveyard, Gouged Zealot deals 1 damage to each creature defending player controls.| Harmonic Prodigy|Modern Horizons 2|132|R|{1}{R}|Creature - Human Wizard|1|3|Prowess$If an ability of a Shaman or another Wizard you control triggers, that ability triggers an additional time.| Kaleidoscorch|Modern Horizons 2|133|U|{1}{R}|Sorcery|||Converge — Kaleidoscorch deals X damage to any target, where X is the number of colors of mana spent to cast this spell.$Flashback {4}{R}| @@ -41580,6 +41583,7 @@ Goldmire Bridge|Modern Horizons 2|247|C||Artifact Land|||Goldmire Bridge enters Marsh Flats|Modern Horizons 2|248|R||Land|||{T}, Pay 1 life, Sacrifice Marsh Flats: Search your library for a Plains or Swamp card, put it onto the battlefield, then shuffle.| Mistvault Bridge|Modern Horizons 2|249|C||Artifact Land|||Mistvault Bridge enters the battlefield tapped.$Indestructible${T}: Add {U} or {B}.| Misty Rainforest|Modern Horizons 2|250|R||Land|||{T}, Pay 1 life, Sacrifice Misty Rainforest: Search your library for a Forest or Island card, put it onto the battlefield, then shuffle.| +Power Depot|Modern Horizons 2|251|U||Artifact Land|||Power Depot enters the battlefield tapped.${T}: Add {C}.${T}: Add one mana of any color. Spend this mana only to cast artifact spells or activate abilities of artifacts.$Modular 1| Razortide Bridge|Modern Horizons 2|252|C||Artifact Land|||Razortide Bridge enters the battlefield tapped.$Indestructible${T}: Add {W} or {U}.| Rustvale Bridge|Modern Horizons 2|253|C||Artifact Land|||Rustvale Bridge enters the battlefield tapped.$Indestructible${T}: Add {R} or {W}.| Scalding Tarn|Modern Horizons 2|254|R||Land|||{T}, Pay 1 life, Sacrifice Scalding Tarn: Search your library for an Island or Mountain card, put it onto the battlefield, then shuffle.| From f40da1e537e794fe31b0fb2911c421db3e6f907c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:50:31 -0400 Subject: [PATCH 121/188] [MH2] Implemented Healer's Flock --- Mage.Sets/src/mage/cards/h/HealersFlock.java | 40 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 41 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HealersFlock.java diff --git a/Mage.Sets/src/mage/cards/h/HealersFlock.java b/Mage.Sets/src/mage/cards/h/HealersFlock.java new file mode 100644 index 00000000000..2e3c13a5d51 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HealersFlock.java @@ -0,0 +1,40 @@ +package mage.cards.h; + +import mage.MageInt; +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 java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HealersFlock extends CardImpl { + + public HealersFlock(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{W}{W}"); + + this.subtype.add(SubType.BIRD); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + } + + private HealersFlock(final HealersFlock card) { + super(card); + } + + @Override + public HealersFlock copy() { + return new HealersFlock(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index f8857149081..4e7df907c3c 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -132,6 +132,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Guardian Kirin", 15, Rarity.COMMON, mage.cards.g.GuardianKirin.class)); cards.add(new SetCardInfo("Hard Evidence", 46, Rarity.COMMON, mage.cards.h.HardEvidence.class)); cards.add(new SetCardInfo("Harmonic Prodigy", 132, Rarity.RARE, mage.cards.h.HarmonicProdigy.class)); + cards.add(new SetCardInfo("Healer's Flock", 16, Rarity.UNCOMMON, mage.cards.h.HealersFlock.class)); cards.add(new SetCardInfo("Hell Mongrel", 88, Rarity.COMMON, mage.cards.h.HellMongrel.class)); cards.add(new SetCardInfo("Herd Baloth", 165, Rarity.UNCOMMON, mage.cards.h.HerdBaloth.class)); cards.add(new SetCardInfo("Hunting Pack", 284, Rarity.UNCOMMON, mage.cards.h.HuntingPack.class)); From b53ecd827a1c55e8431cc5b570f6009e23093240 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:53:45 -0400 Subject: [PATCH 122/188] [MH2] Implemented Fairgrounds Patrol --- .../src/mage/cards/f/FairgroundsPatrol.java | 47 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 48 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FairgroundsPatrol.java diff --git a/Mage.Sets/src/mage/cards/f/FairgroundsPatrol.java b/Mage.Sets/src/mage/cards/f/FairgroundsPatrol.java new file mode 100644 index 00000000000..78e01ef20ae --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FairgroundsPatrol.java @@ -0,0 +1,47 @@ +package mage.cards.f; + +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.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.permanent.token.ThopterColorlessToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FairgroundsPatrol extends CardImpl { + + public FairgroundsPatrol(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // {1}{W}, Exile Fairgrounds Patrol from your graveyard: Create a 1/1 colorless Thopter creature token with flying. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + Zone.GRAVEYARD, new CreateTokenEffect(new ThopterColorlessToken()), new ManaCostsImpl<>("{1}{W}") + ); + ability.addCost(new ExileSourceFromGraveCost()); + this.addAbility(ability); + } + + private FairgroundsPatrol(final FairgroundsPatrol card) { + super(card); + } + + @Override + public FairgroundsPatrol copy() { + return new FairgroundsPatrol(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 4e7df907c3c..3d1f1dd9b2c 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -96,6 +96,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Ethersworn Sphinx", 195, Rarity.UNCOMMON, mage.cards.e.EtherswornSphinx.class)); cards.add(new SetCardInfo("Extruder", 296, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); cards.add(new SetCardInfo("Fae Offering", 158, Rarity.UNCOMMON, mage.cards.f.FaeOffering.class)); + cards.add(new SetCardInfo("Fairgrounds Patrol", 13, Rarity.COMMON, mage.cards.f.FairgroundsPatrol.class)); cards.add(new SetCardInfo("Faithless Salvaging", 122, Rarity.COMMON, mage.cards.f.FaithlessSalvaging.class)); cards.add(new SetCardInfo("Fast // Furious", 123, Rarity.UNCOMMON, mage.cards.f.FastFurious.class)); cards.add(new SetCardInfo("Feast of Sanity", 84, Rarity.UNCOMMON, mage.cards.f.FeastOfSanity.class)); From df477ca56ad8aac7ae2a252e7dd100e5aeb28e79 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:57:41 -0400 Subject: [PATCH 123/188] [MH2] Implemented Foul Watcher --- Mage.Sets/src/mage/cards/f/FoulWatcher.java | 55 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 56 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FoulWatcher.java diff --git a/Mage.Sets/src/mage/cards/f/FoulWatcher.java b/Mage.Sets/src/mage/cards/f/FoulWatcher.java new file mode 100644 index 00000000000..51959963cc3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FoulWatcher.java @@ -0,0 +1,55 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.DeliriumCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.keyword.SurveilEffect; +import mage.abilities.hint.common.CardTypesInGraveyardHint; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FoulWatcher extends CardImpl { + + public FoulWatcher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.NIGHTMARE); + this.subtype.add(SubType.BIRD); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Foul Watcher enters the battlefield, surveil 1. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SurveilEffect(1))); + + // Delirium — Foul Watcher gets +1/+0 as long as there are four more card types among cards in your graveyard. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new BoostSourceEffect(1, 0, Duration.WhileOnBattlefield), DeliriumCondition.instance, + "{this} gets +1/+0 as long as there are four more card types among cards in your graveyard" + )).setAbilityWord(AbilityWord.DELIRIUM).addHint(CardTypesInGraveyardHint.YOU)); + } + + private FoulWatcher(final FoulWatcher card) { + super(card); + } + + @Override + public FoulWatcher copy() { + return new FoulWatcher(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 3d1f1dd9b2c..f3160adb968 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -110,6 +110,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Flourishing Strike", 159, Rarity.COMMON, mage.cards.f.FlourishingStrike.class)); cards.add(new SetCardInfo("Fodder Tosser", 226, Rarity.COMMON, mage.cards.f.FodderTosser.class)); cards.add(new SetCardInfo("Forest", 489, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Foul Watcher", 43, Rarity.COMMON, mage.cards.f.FoulWatcher.class)); cards.add(new SetCardInfo("Foundation Breaker", 160, Rarity.UNCOMMON, mage.cards.f.FoundationBreaker.class)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); cards.add(new SetCardInfo("Funnel-Web Recluse", 161, Rarity.COMMON, mage.cards.f.FunnelWebRecluse.class)); From 5f61112a45da9321f04ce05d2bdeca4a2ed7f7c1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 21:59:57 -0400 Subject: [PATCH 124/188] [MH2] Implemented Revolutionist --- Mage.Sets/src/mage/cards/a/Archaeomancer.java | 19 +++----- Mage.Sets/src/mage/cards/r/Revolutionist.java | 48 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 3 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/r/Revolutionist.java diff --git a/Mage.Sets/src/mage/cards/a/Archaeomancer.java b/Mage.Sets/src/mage/cards/a/Archaeomancer.java index e94afc39c54..7fa14cb6798 100644 --- a/Mage.Sets/src/mage/cards/a/Archaeomancer.java +++ b/Mage.Sets/src/mage/cards/a/Archaeomancer.java @@ -1,25 +1,23 @@ package mage.cards.a; -import java.util.UUID; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.filter.common.FilterInstantOrSorceryCard; -import mage.target.Target; +import mage.filter.StaticFilters; import mage.target.common.TargetCardInYourGraveyard; +import java.util.UUID; + /** - * * @author North */ public final class Archaeomancer extends CardImpl { - private static final FilterInstantOrSorceryCard filter = new FilterInstantOrSorceryCard("instant or sorcery card from your graveyard"); - public Archaeomancer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); this.subtype.add(SubType.HUMAN); @@ -29,11 +27,8 @@ public final class Archaeomancer extends CardImpl { this.toughness = new MageInt(2); // When Archaeomancer enters the battlefield, return target instant or sorcery card from your graveyard to your hand. - EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility( - new ReturnToHandTargetEffect() - .setText("return target instant or sorcery card from your graveyard to your hand"), false); - Target target = new TargetCardInYourGraveyard(filter); - ability.addTarget(target); + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect()); + ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/Revolutionist.java b/Mage.Sets/src/mage/cards/r/Revolutionist.java new file mode 100644 index 00000000000..9fb5d4e2a0d --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/Revolutionist.java @@ -0,0 +1,48 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.abilities.keyword.MadnessAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Revolutionist extends CardImpl { + + public Revolutionist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Revolutionist enters the battlefield, return target instant or sorcery card from your graveyard to your hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect()); + ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD)); + this.addAbility(ability); + + // Madness {3}{R} + this.addAbility(new MadnessAbility(this, new ManaCostsImpl<>("{3}{R}"))); + } + + private Revolutionist(final Revolutionist card) { + super(card); + } + + @Override + public Revolutionist copy() { + return new Revolutionist(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index f3160adb968..2db559761c7 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -193,6 +193,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Ravenous Squirrel", 211, Rarity.UNCOMMON, mage.cards.r.RavenousSquirrel.class)); cards.add(new SetCardInfo("Raving Visionary", 56, Rarity.UNCOMMON, mage.cards.r.RavingVisionary.class)); cards.add(new SetCardInfo("Razortide Bridge", 252, Rarity.COMMON, mage.cards.r.RazortideBridge.class)); + cards.add(new SetCardInfo("Revolutionist", 139, Rarity.COMMON, mage.cards.r.Revolutionist.class)); cards.add(new SetCardInfo("Rift Sower", 170, Rarity.COMMON, mage.cards.r.RiftSower.class)); cards.add(new SetCardInfo("Riptide Laboratory", 303, Rarity.RARE, mage.cards.r.RiptideLaboratory.class)); cards.add(new SetCardInfo("Rishadan Dockhand", 59, Rarity.RARE, mage.cards.r.RishadanDockhand.class)); From 2bcb06775b154537c89c04306778b5f85ab9f7c0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 2 Jun 2021 22:03:17 -0400 Subject: [PATCH 125/188] [MH2] Implemented Lightning Spear --- .../src/mage/cards/l/LightningSpear.java | 59 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 60 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LightningSpear.java diff --git a/Mage.Sets/src/mage/cards/l/LightningSpear.java b/Mage.Sets/src/mage/cards/l/LightningSpear.java new file mode 100644 index 00000000000..a9523063d60 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LightningSpear.java @@ -0,0 +1,59 @@ +package mage.cards.l; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LightningSpear extends CardImpl { + + public LightningSpear(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{R}"); + + this.subtype.add(SubType.EQUIPMENT); + + // Equipped creature gets +1/+0 and has trample. + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 0)); + ability.addEffect(new GainAbilityAttachedEffect( + TrampleAbility.getInstance(), AttachmentType.EQUIPMENT + ).setText("and has trample")); + this.addAbility(ability); + + // {2}{R}, Sacrifice Lightning Spear: It deals 3 damage to any target. + ability = new SimpleActivatedAbility( + new DamageTargetEffect(3, "it"), new ManaCostsImpl<>("{2}{R}") + ); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability); + + // Equip {1} + this.addAbility(new EquipAbility(1)); + } + + private LightningSpear(final LightningSpear card) { + super(card); + } + + @Override + public LightningSpear copy() { + return new LightningSpear(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 2db559761c7..5446efb0a71 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -153,6 +153,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Lazotep Chancellor", 203, Rarity.UNCOMMON, mage.cards.l.LazotepChancellor.class)); cards.add(new SetCardInfo("Legion Vanguard", 90, Rarity.UNCOMMON, mage.cards.l.LegionVanguard.class)); cards.add(new SetCardInfo("Lens Flare", 20, Rarity.COMMON, mage.cards.l.LensFlare.class)); + cards.add(new SetCardInfo("Lightning Spear", 134, Rarity.COMMON, mage.cards.l.LightningSpear.class)); cards.add(new SetCardInfo("Liquimetal Torque", 228, Rarity.UNCOMMON, mage.cards.l.LiquimetalTorque.class)); cards.add(new SetCardInfo("Lose Focus", 49, Rarity.COMMON, mage.cards.l.LoseFocus.class)); cards.add(new SetCardInfo("Lucid Dreams", 50, Rarity.UNCOMMON, mage.cards.l.LucidDreams.class)); From acb8070d6b1343e5dd3a1205d72f267eee390814 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 07:48:38 -0400 Subject: [PATCH 126/188] [MH2] Implemented Recalibrate --- .../a/Asmoranomardicadaistinaculdacar.java | 54 ++++--------------- Mage.Sets/src/mage/cards/r/Recalibrate.java | 44 +++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../ControllerDiscardedThisTurnCondition.java | 18 +++++++ .../hint/common/ControllerDiscardedHint.java | 28 ++++++++++ .../watchers/common/DiscardedCardWatcher.java | 40 ++++++++++++++ 6 files changed, 140 insertions(+), 45 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/r/Recalibrate.java create mode 100644 Mage/src/main/java/mage/abilities/condition/common/ControllerDiscardedThisTurnCondition.java create mode 100644 Mage/src/main/java/mage/abilities/hint/common/ControllerDiscardedHint.java create mode 100644 Mage/src/main/java/mage/watchers/common/DiscardedCardWatcher.java diff --git a/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java b/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java index 633d44dec74..def750d9b3c 100644 --- a/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java +++ b/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java @@ -4,28 +4,29 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.ControllerDiscardedThisTurnCondition; import mage.abilities.costs.AlternativeCostSourceAbility; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.hint.common.ControllerDiscardedHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.filter.FilterCard; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.NamePredicate; import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; -import mage.watchers.Watcher; +import mage.watchers.common.DiscardedCardWatcher; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** @@ -53,9 +54,9 @@ public final class Asmoranomardicadaistinaculdacar extends CardImpl { // As long as you've discarded a card this turn, you may pay {B/R} to cast this spell. this.addAbility(new AlternativeCostSourceAbility( - new ManaCostsImpl<>("{B/R}"), AsmoranomardicadaistinaculdacarCondition.instance, + new ManaCostsImpl<>("{B/R}"), ControllerDiscardedThisTurnCondition.instance, "as long as you've discarded a card this turn, you may pay {B/R} to cast this spell" - ), new AsmoranomardicadaistinaculdacarWatcher()); + ).addHint(ControllerDiscardedHint.instance), new DiscardedCardWatcher()); // When Asmoranomardicadaistinaculdacar enters the battlefield, you may search your library for a card named The Underworld Cookbook, reveal it, put it into your hand, then shuffle. this.addAbility(new EntersBattlefieldTriggeredAbility( @@ -81,15 +82,6 @@ public final class Asmoranomardicadaistinaculdacar extends CardImpl { } } -enum AsmoranomardicadaistinaculdacarCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - return AsmoranomardicadaistinaculdacarWatcher.checkPlayer(source.getControllerId(), game); - } -} - class AsmoranomardicadaistinaculdacarEffect extends OneShotEffect { AsmoranomardicadaistinaculdacarEffect() { @@ -115,32 +107,4 @@ class AsmoranomardicadaistinaculdacarEffect extends OneShotEffect { return permanent.damage(6, permanent.getId(), source, game) > 0; } } - -class AsmoranomardicadaistinaculdacarWatcher extends Watcher { - - private final Set playerSet = new HashSet<>(); - - AsmoranomardicadaistinaculdacarWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.DISCARDED_CARD) { - playerSet.add(event.getPlayerId()); - } - } - - @Override - public void reset() { - playerSet.clear(); - super.reset(); - } - - static boolean checkPlayer(UUID playerId, Game game) { - AsmoranomardicadaistinaculdacarWatcher watcher - = game.getState().getWatcher(AsmoranomardicadaistinaculdacarWatcher.class); - return watcher != null && watcher.playerSet.contains(playerId); - } -} // it's easier to pronounce if you break it into separate words: asmorano mardica daistina culdacar diff --git a/Mage.Sets/src/mage/cards/r/Recalibrate.java b/Mage.Sets/src/mage/cards/r/Recalibrate.java new file mode 100644 index 00000000000..3455a5c6858 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/Recalibrate.java @@ -0,0 +1,44 @@ +package mage.cards.r; + +import mage.abilities.condition.common.ControllerDiscardedThisTurnCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.hint.common.ControllerDiscardedHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; +import mage.watchers.common.DiscardedCardWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Recalibrate extends CardImpl { + + public Recalibrate(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + // Return target creature to its owner's hand. If you've discarded a card this turn, draw a card. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new DrawCardSourceControllerEffect(1), + ControllerDiscardedThisTurnCondition.instance, + "If you've discarded a card this turn, draw a card" + )); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addHint(ControllerDiscardedHint.instance); + this.getSpellAbility().addWatcher(new DiscardedCardWatcher()); + } + + private Recalibrate(final Recalibrate card) { + super(card); + } + + @Override + public Recalibrate copy() { + return new Recalibrate(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 5446efb0a71..bd77a77f271 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -194,6 +194,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Ravenous Squirrel", 211, Rarity.UNCOMMON, mage.cards.r.RavenousSquirrel.class)); cards.add(new SetCardInfo("Raving Visionary", 56, Rarity.UNCOMMON, mage.cards.r.RavingVisionary.class)); cards.add(new SetCardInfo("Razortide Bridge", 252, Rarity.COMMON, mage.cards.r.RazortideBridge.class)); + cards.add(new SetCardInfo("Recalibrate", 57, Rarity.COMMON, mage.cards.r.Recalibrate.class)); cards.add(new SetCardInfo("Revolutionist", 139, Rarity.COMMON, mage.cards.r.Revolutionist.class)); cards.add(new SetCardInfo("Rift Sower", 170, Rarity.COMMON, mage.cards.r.RiftSower.class)); cards.add(new SetCardInfo("Riptide Laboratory", 303, Rarity.RARE, mage.cards.r.RiptideLaboratory.class)); diff --git a/Mage/src/main/java/mage/abilities/condition/common/ControllerDiscardedThisTurnCondition.java b/Mage/src/main/java/mage/abilities/condition/common/ControllerDiscardedThisTurnCondition.java new file mode 100644 index 00000000000..8cdea17eb8d --- /dev/null +++ b/Mage/src/main/java/mage/abilities/condition/common/ControllerDiscardedThisTurnCondition.java @@ -0,0 +1,18 @@ +package mage.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.game.Game; +import mage.watchers.common.DiscardedCardWatcher; + +/** + * @author TheElk801 + */ +public enum ControllerDiscardedThisTurnCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return DiscardedCardWatcher.checkPlayerDiscarded(source.getControllerId(), game); + } +} diff --git a/Mage/src/main/java/mage/abilities/hint/common/ControllerDiscardedHint.java b/Mage/src/main/java/mage/abilities/hint/common/ControllerDiscardedHint.java new file mode 100644 index 00000000000..213fb416184 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/hint/common/ControllerDiscardedHint.java @@ -0,0 +1,28 @@ +package mage.abilities.hint.common; + +import mage.abilities.Ability; +import mage.abilities.condition.common.ControllerDiscardedThisTurnCondition; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.game.Game; + +/** + * @author TheElk801 + */ +public enum ControllerDiscardedHint implements Hint { + instance; + + private static final Hint hint = new ConditionHint( + ControllerDiscardedThisTurnCondition.instance, "You discarded a card this turn" + ); + + @Override + public String getText(Game game, Ability ability) { + return hint.getText(game, ability); + } + + @Override + public ControllerDiscardedHint copy() { + return instance; + } +} diff --git a/Mage/src/main/java/mage/watchers/common/DiscardedCardWatcher.java b/Mage/src/main/java/mage/watchers/common/DiscardedCardWatcher.java new file mode 100644 index 00000000000..5237835f378 --- /dev/null +++ b/Mage/src/main/java/mage/watchers/common/DiscardedCardWatcher.java @@ -0,0 +1,40 @@ +package mage.watchers.common; + +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.watchers.Watcher; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class DiscardedCardWatcher extends Watcher { + + private final Map playerMap = new HashMap<>(); + + public DiscardedCardWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DISCARDED_CARD) { + playerMap.compute(event.getPlayerId(), (u, i) -> i == null ? 1 : Integer.sum(i, 1)); + } + } + + @Override + public void reset() { + playerMap.clear(); + super.reset(); + } + + public static boolean checkPlayerDiscarded(UUID playerId, Game game) { + DiscardedCardWatcher watcher = game.getState().getWatcher(DiscardedCardWatcher.class); + return watcher != null && watcher.playerMap.getOrDefault(playerId, 0) > 0; + } +} From d3be492f8c5cc6e0987fff736f9dccce6a80d999 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 07:53:10 -0400 Subject: [PATCH 127/188] [MH2] Implemented Gilt-Blade Prowler --- .../src/mage/cards/g/GiltBladeProwler.java | 52 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../ControllerDiscardedThisTurnCondition.java | 5 ++ 3 files changed, 58 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GiltBladeProwler.java diff --git a/Mage.Sets/src/mage/cards/g/GiltBladeProwler.java b/Mage.Sets/src/mage/cards/g/GiltBladeProwler.java new file mode 100644 index 00000000000..d6e26165c25 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GiltBladeProwler.java @@ -0,0 +1,52 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.condition.common.ControllerDiscardedThisTurnCondition; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.hint.common.ControllerDiscardedHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.watchers.common.DiscardedCardWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GiltBladeProwler extends CardImpl { + + public GiltBladeProwler(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // {1}, {T}, Pay 1 life: Draw a card. Activate only if you've discarded a card this turn. + Ability ability = new ActivateIfConditionActivatedAbility( + Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), + new GenericManaCost(1), ControllerDiscardedThisTurnCondition.instance + ); + ability.addCost(new TapSourceCost()); + ability.addCost(new PayLifeCost(1)); + this.addAbility(ability.addHint(ControllerDiscardedHint.instance), new DiscardedCardWatcher()); + } + + private GiltBladeProwler(final GiltBladeProwler card) { + super(card); + } + + @Override + public GiltBladeProwler copy() { + return new GiltBladeProwler(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index bd77a77f271..259b5fd966b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -121,6 +121,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("General Ferrous Rokiric", 198, Rarity.RARE, mage.cards.g.GeneralFerrousRokiric.class)); cards.add(new SetCardInfo("Geyadrone Dihada", 199, Rarity.MYTHIC, mage.cards.g.GeyadroneDihada.class)); cards.add(new SetCardInfo("Ghost-Lit Drifter", 45, Rarity.UNCOMMON, mage.cards.g.GhostLitDrifter.class)); + cards.add(new SetCardInfo("Gilt-Blade Prowler", 86, Rarity.COMMON, mage.cards.g.GiltBladeProwler.class)); cards.add(new SetCardInfo("Glimmer Bairn", 163, Rarity.COMMON, mage.cards.g.GlimmerBairn.class)); cards.add(new SetCardInfo("Glinting Creeper", 164, Rarity.UNCOMMON, mage.cards.g.GlintingCreeper.class)); cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); diff --git a/Mage/src/main/java/mage/abilities/condition/common/ControllerDiscardedThisTurnCondition.java b/Mage/src/main/java/mage/abilities/condition/common/ControllerDiscardedThisTurnCondition.java index 8cdea17eb8d..fad174e8ad0 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/ControllerDiscardedThisTurnCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/ControllerDiscardedThisTurnCondition.java @@ -15,4 +15,9 @@ public enum ControllerDiscardedThisTurnCondition implements Condition { public boolean apply(Game game, Ability source) { return DiscardedCardWatcher.checkPlayerDiscarded(source.getControllerId(), game); } + + @Override + public String toString() { + return "you've discarded a card this turn"; + } } From c26ef0774fdf4cc98000cdafd70c2d61b9e50bea Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 08:05:07 -0400 Subject: [PATCH 128/188] [MH2] Implemented Goblin Traprunner --- .../src/mage/cards/g/GoblinTraprunner.java | 75 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 76 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GoblinTraprunner.java diff --git a/Mage.Sets/src/mage/cards/g/GoblinTraprunner.java b/Mage.Sets/src/mage/cards/g/GoblinTraprunner.java new file mode 100644 index 00000000000..dceeef319b6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoblinTraprunner.java @@ -0,0 +1,75 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.permanent.token.GoblinToken; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GoblinTraprunner extends CardImpl { + + public GoblinTraprunner(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + // Whenever Goblin Traprunner attacks, flip three coins. For each flip you win, create a 1/1 red Goblin creature token that's tapped and attacking. + this.addAbility(new AttacksTriggeredAbility(new CreateTokenEffect( + new GoblinToken(), GoblinTraprunnerValue.instance, true, true + ).setText("flip three coins. For each flip you win, " + + "create a 1/1 red Goblin creature token that's tapped and attacking"), false)); + } + + private GoblinTraprunner(final GoblinTraprunner card) { + super(card); + } + + @Override + public GoblinTraprunner copy() { + return new GoblinTraprunner(this); + } +} + +enum GoblinTraprunnerValue implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + Player player = game.getPlayer(sourceAbility.getControllerId()); + if (player == null) { + return 0; + } + int count = 0; + for (int i = 0; i < 3; i++) { + if (player.flipCoin(sourceAbility, game, true)) { + count++; + } + } + return count; + } + + @Override + public GoblinTraprunnerValue copy() { + return instance; + } + + @Override + public String getMessage() { + return ""; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 259b5fd966b..820e86ec529 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -127,6 +127,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); cards.add(new SetCardInfo("Goblin Anarchomancer", 200, Rarity.COMMON, mage.cards.g.GoblinAnarchomancer.class)); cards.add(new SetCardInfo("Goblin Bombardment", 279, Rarity.RARE, mage.cards.g.GoblinBombardment.class)); + cards.add(new SetCardInfo("Goblin Traprunner", 130, Rarity.UNCOMMON, mage.cards.g.GoblinTraprunner.class)); cards.add(new SetCardInfo("Goldmire Bridge", 247, Rarity.COMMON, mage.cards.g.GoldmireBridge.class)); cards.add(new SetCardInfo("Gorilla Shaman", 280, Rarity.UNCOMMON, mage.cards.g.GorillaShaman.class)); cards.add(new SetCardInfo("Graceful Restoration", 201, Rarity.UNCOMMON, mage.cards.g.GracefulRestoration.class)); From 28033c7c17521544f0ac6648e88f60d52b27ee11 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 08:23:53 -0400 Subject: [PATCH 129/188] [MH2] Implemented Inevitable Betrayal --- .../src/mage/cards/i/InevitableBetrayal.java | 78 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + Utils/gen-card.pl | 6 +- Utils/keywords.txt | 1 + 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/i/InevitableBetrayal.java diff --git a/Mage.Sets/src/mage/cards/i/InevitableBetrayal.java b/Mage.Sets/src/mage/cards/i/InevitableBetrayal.java new file mode 100644 index 00000000000..fd07c43ce44 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InevitableBetrayal.java @@ -0,0 +1,78 @@ +package mage.cards.i; + +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.SuspendAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetOpponent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class InevitableBetrayal extends CardImpl { + + public InevitableBetrayal(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, ""); + + // Suspend 3—{1}{U}{U} + this.addAbility(new SuspendAbility(3, new ManaCostsImpl<>("{1}{U}{U}"), this)); + + // Search target opponent's library for a creature card and put that card onto the battlefield under your control. Then that player shuffles. + this.getSpellAbility().addEffect(new InevitableBetrayalEffect()); + this.getSpellAbility().addTarget(new TargetOpponent()); + } + + private InevitableBetrayal(final InevitableBetrayal card) { + super(card); + } + + @Override + public InevitableBetrayal copy() { + return new InevitableBetrayal(this); + } +} + +class InevitableBetrayalEffect extends OneShotEffect { + + InevitableBetrayalEffect() { + super(Outcome.Benefit); + staticText = "search target opponent's library for a creature card and put that card " + + "onto the battlefield under your control. Then that player shuffles"; + } + + private InevitableBetrayalEffect(final InevitableBetrayalEffect effect) { + super(effect); + } + + @Override + public InevitableBetrayalEffect copy() { + return new InevitableBetrayalEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player player = game.getPlayer(source.getFirstTarget()); + if (controller == null || player == null) { + return false; + } + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE); + controller.searchLibrary(target, source, game, player.getId()); + Card card = player.getLibrary().getCard(target.getFirstTarget(), game); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + player.shuffleLibrary(source, game); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 820e86ec529..f971c203264 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -142,6 +142,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Hunting Pack", 284, Rarity.UNCOMMON, mage.cards.h.HuntingPack.class)); cards.add(new SetCardInfo("Ignoble Hierarch", 166, Rarity.RARE, mage.cards.i.IgnobleHierarch.class)); cards.add(new SetCardInfo("Imperial Recruiter", 281, Rarity.MYTHIC, mage.cards.i.ImperialRecruiter.class)); + cards.add(new SetCardInfo("Inevitable Betrayal", 47, Rarity.RARE, mage.cards.i.InevitableBetrayal.class)); cards.add(new SetCardInfo("Island", 483, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jade Avenger", 167, Rarity.COMMON, mage.cards.j.JadeAvenger.class)); cards.add(new SetCardInfo("Jewel-Eyed Cobra", 168, Rarity.COMMON, mage.cards.j.JewelEyedCobra.class)); diff --git a/Utils/gen-card.pl b/Utils/gen-card.pl index eaa8bca4fc1..4a16b843837 100755 --- a/Utils/gen-card.pl +++ b/Utils/gen-card.pl @@ -263,7 +263,11 @@ foreach my $ability (@abilities) { $ability =~ m/({.*})/g; $vars{'abilities'} .= "\n this.addAbility(new " . $kw . 'Ability(this, new ManaCostsImpl<>("' . fixCost($1) . '")));'; $vars{'abilitiesImports'} .= "\nimport mage.abilities.costs.mana.ManaCostsImpl;"; - } elsif ($keywords{$kw} eq 'cost, card') { + } elsif ($keywords{$kw} eq 'number, cost, card') { + $ability =~ m/({.*})/g; + $vars{'abilities'} .= "\n this.addAbility(new " . $kw . 'Ability(_, new ManaCostsImpl<>("' . fixCost($1) . '"), this));'; + $vars{'abilitiesImports'} .= "\nimport mage.abilities.costs.mana.ManaCostsImpl;"; + } elsif ($keywords{$kw} eq 'cost, card') { $ability =~ m/({.*})/g; $vars{'abilities'} .= "\n this.addAbility(new " . $kw . 'Ability(new ManaCostsImpl<>("' . fixCost($1) . '"), this));'; $vars{'abilitiesImports'} .= "\nimport mage.abilities.costs.mana.ManaCostsImpl;"; diff --git a/Utils/keywords.txt b/Utils/keywords.txt index 78a41c48734..d40f5a9e688 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -95,6 +95,7 @@ Skulk|new| Spectacle|card, cost| Storm|new| Sunburst|new| +Suspend|number, cost, card| Swampcycling|cost| Swampwalk|new| Totem armor|new| From a999738807611a1195945d54c0b52d2723d542d1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 08:33:47 -0400 Subject: [PATCH 130/188] [MH2] Implemented So Shiny --- Mage.Sets/src/mage/cards/s/SoShiny.java | 76 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 77 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SoShiny.java diff --git a/Mage.Sets/src/mage/cards/s/SoShiny.java b/Mage.Sets/src/mage/cards/s/SoShiny.java new file mode 100644 index 00000000000..535474ff5c7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoShiny.java @@ -0,0 +1,76 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect; +import mage.abilities.effects.common.TapEnchantedEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SoShiny extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent(); + + static { + filter.add(TokenPredicate.instance); + } + + private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter); + private static final Hint hint = new ConditionHint(condition, "You control a token"); + + public SoShiny(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When So Shiny enters the battlefield, if you control a token, tap enchanted creature, then scry 2. + ability = new ConditionalInterveningIfTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect()), + condition, "When {this} enters the battlefield, " + + "if you control a token, tap enchanted creature, then scry 2." + ); + ability.addEffect(new ScryEffect(2)); + this.addAbility(ability.addHint(hint)); + + // Enchanted creature doesn't untap during its controller's untap step. + this.addAbility(new SimpleStaticAbility(new DontUntapInControllersUntapStepEnchantedEffect())); + } + + private SoShiny(final SoShiny card) { + super(card); + } + + @Override + public SoShiny copy() { + return new SoShiny(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index f971c203264..3bcd9492763 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -224,6 +224,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Skophos Reaver", 140, Rarity.COMMON, mage.cards.s.SkophosReaver.class)); cards.add(new SetCardInfo("Slag Strider", 141, Rarity.UNCOMMON, mage.cards.s.SlagStrider.class)); cards.add(new SetCardInfo("Slagwoods Bridge", 256, Rarity.COMMON, mage.cards.s.SlagwoodsBridge.class)); + cards.add(new SetCardInfo("So Shiny", 63, Rarity.COMMON, mage.cards.s.SoShiny.class)); cards.add(new SetCardInfo("Sol Talisman", 236, Rarity.RARE, mage.cards.s.SolTalisman.class)); cards.add(new SetCardInfo("Solitary Confinement", 265, Rarity.RARE, mage.cards.s.SolitaryConfinement.class)); cards.add(new SetCardInfo("Solitude", 32, Rarity.MYTHIC, mage.cards.s.Solitude.class)); From d4eb9f5c9239ac1e5141de992ca7bbba4a4aa347 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 08:36:17 -0400 Subject: [PATCH 131/188] [MH2] Implemented Unbounded Potential --- .../src/mage/cards/u/UnboundedPotential.java | 44 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 45 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/u/UnboundedPotential.java diff --git a/Mage.Sets/src/mage/cards/u/UnboundedPotential.java b/Mage.Sets/src/mage/cards/u/UnboundedPotential.java new file mode 100644 index 00000000000..06bc2a58918 --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UnboundedPotential.java @@ -0,0 +1,44 @@ +package mage.cards.u; + +import mage.abilities.Mode; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.effects.common.counter.ProliferateEffect; +import mage.abilities.keyword.EntwineAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class UnboundedPotential extends CardImpl { + + public UnboundedPotential(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); + + // Choose one — + // • Put a +1/+1 counter on each of up to two target creatures. + this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance()) + .setText("put a +1/+1 counter on each of up to two target creatures")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2)); + + // • Proliferate. + this.getSpellAbility().addMode(new Mode(new ProliferateEffect())); + + // Entwine {3}{W} + this.addAbility(new EntwineAbility("{3}{W}")); + } + + private UnboundedPotential(final UnboundedPotential card) { + super(card); + } + + @Override + public UnboundedPotential copy() { + return new UnboundedPotential(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 3bcd9492763..6294c89de5b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -265,6 +265,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Tormod's Cryptkeeper", 239, Rarity.COMMON, mage.cards.t.TormodsCryptkeeper.class)); cards.add(new SetCardInfo("Tourach's Canticle", 103, Rarity.COMMON, mage.cards.t.TourachsCanticle.class)); cards.add(new SetCardInfo("Tragic Fall", 104, Rarity.COMMON, mage.cards.t.TragicFall.class)); + cards.add(new SetCardInfo("Unbounded Potential", 36, Rarity.COMMON, mage.cards.u.UnboundedPotential.class)); cards.add(new SetCardInfo("Underworld Hermit", 105, Rarity.UNCOMMON, mage.cards.u.UnderworldHermit.class)); cards.add(new SetCardInfo("Unholy Heat", 145, Rarity.COMMON, mage.cards.u.UnholyHeat.class)); cards.add(new SetCardInfo("Unmarked Grave", 106, Rarity.RARE, mage.cards.u.UnmarkedGrave.class)); From 798b57812585b5eb624bed836cfbe57d8c925121 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 08:44:01 -0400 Subject: [PATCH 132/188] [MH2] Implemented Vile Entomber --- Mage.Sets/src/mage/cards/e/Entomb.java | 50 ++----------------- .../src/mage/cards/g/GravebreakerLamia.java | 39 +-------------- Mage.Sets/src/mage/cards/v/VileEntomber.java | 42 ++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../SearchLibraryPutInGraveyardEffect.java | 44 ++++++++++++++++ 5 files changed, 94 insertions(+), 82 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/v/VileEntomber.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInGraveyardEffect.java diff --git a/Mage.Sets/src/mage/cards/e/Entomb.java b/Mage.Sets/src/mage/cards/e/Entomb.java index f7a8bf8f59c..aeff5ad3242 100644 --- a/Mage.Sets/src/mage/cards/e/Entomb.java +++ b/Mage.Sets/src/mage/cards/e/Entomb.java @@ -1,30 +1,22 @@ - package mage.cards.e; -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.effects.SearchEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInGraveyardEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; /** - * * @author Plopman */ public final class Entomb extends CardImpl { public Entomb(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}"); // Search your library for a card and put that card into your graveyard. Then shuffle your library. - this.getSpellAbility().addEffect(new SearchLibraryPutInGraveyard()); + this.getSpellAbility().addEffect(new SearchLibraryPutInGraveyardEffect()); } private Entomb(final Entomb card) { @@ -36,35 +28,3 @@ public final class Entomb extends CardImpl { return new Entomb(this); } } - - -class SearchLibraryPutInGraveyard extends SearchEffect { - - public SearchLibraryPutInGraveyard() { - super(new TargetCardInLibrary(new FilterCard()), Outcome.Neutral); - staticText = "search your library for a card, put that card into your graveyard, then shuffle"; - } - - public SearchLibraryPutInGraveyard(final SearchLibraryPutInGraveyard effect) { - super(effect); - } - - @Override - public SearchLibraryPutInGraveyard copy() { - return new SearchLibraryPutInGraveyard(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - if (controller.searchLibrary(target, source, game)) { - controller.moveCards(game.getCard(target.getFirstTarget()), Zone.GRAVEYARD, source, game); - } - controller.shuffleLibrary(source, game); - return true; - } - -} diff --git a/Mage.Sets/src/mage/cards/g/GravebreakerLamia.java b/Mage.Sets/src/mage/cards/g/GravebreakerLamia.java index 3e4e1350852..f000c0d51eb 100644 --- a/Mage.Sets/src/mage/cards/g/GravebreakerLamia.java +++ b/Mage.Sets/src/mage/cards/g/GravebreakerLamia.java @@ -1,23 +1,18 @@ package mage.cards.g; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.SearchEffect; import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInGraveyardEffect; import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.card.CastFromZonePredicate; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetCardInLibrary; import java.util.UUID; @@ -45,7 +40,7 @@ public final class GravebreakerLamia extends CardImpl { this.addAbility(LifelinkAbility.getInstance()); // When Gravebreaker Lamia enters the battlefield, search your library for a card, put it into your graveyard, then shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new GravebreakerLamiaSearchEffect(), false)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInGraveyardEffect(), false)); // Spells you cast from your graveyard cost {1} less to cast. this.addAbility(new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 1) @@ -61,33 +56,3 @@ public final class GravebreakerLamia extends CardImpl { return new GravebreakerLamia(this); } } - -class GravebreakerLamiaSearchEffect extends SearchEffect { - - GravebreakerLamiaSearchEffect() { - super(new TargetCardInLibrary(), Outcome.Neutral); - staticText = "search your library for a card, put it into your graveyard, then shuffle"; - } - - private GravebreakerLamiaSearchEffect(final GravebreakerLamiaSearchEffect effect) { - super(effect); - } - - @Override - public GravebreakerLamiaSearchEffect copy() { - return new GravebreakerLamiaSearchEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - if (controller.searchLibrary(target, source, game)) { - controller.moveCards(game.getCard(target.getFirstTarget()), Zone.GRAVEYARD, source, game); - } - controller.shuffleLibrary(source, game); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/v/VileEntomber.java b/Mage.Sets/src/mage/cards/v/VileEntomber.java new file mode 100644 index 00000000000..144ad9a5c6c --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VileEntomber.java @@ -0,0 +1,42 @@ +package mage.cards.v; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryPutInGraveyardEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class VileEntomber extends CardImpl { + + public VileEntomber(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + + this.subtype.add(SubType.ZOMBIE); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // When Vile Entomber enters the battlefield, search your library for a card, put that card into your graveyard, then shuffle. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInGraveyardEffect())); + } + + private VileEntomber(final VileEntomber card) { + super(card); + } + + @Override + public VileEntomber copy() { + return new VileEntomber(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 6294c89de5b..4e7710d5b71 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -278,6 +278,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Verdant Command", 182, Rarity.RARE, mage.cards.v.VerdantCommand.class)); cards.add(new SetCardInfo("Vermin Gorger", 107, Rarity.COMMON, mage.cards.v.VerminGorger.class)); cards.add(new SetCardInfo("Viashino Lashclaw", 146, Rarity.COMMON, mage.cards.v.ViashinoLashclaw.class)); + cards.add(new SetCardInfo("Vile Entomber", 108, Rarity.UNCOMMON, mage.cards.v.VileEntomber.class)); cards.add(new SetCardInfo("Vindicate", 294, Rarity.RARE, mage.cards.v.Vindicate.class)); cards.add(new SetCardInfo("Void Mirror", 242, Rarity.RARE, mage.cards.v.VoidMirror.class)); cards.add(new SetCardInfo("Wavesifter", 217, Rarity.COMMON, mage.cards.w.Wavesifter.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInGraveyardEffect.java b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInGraveyardEffect.java new file mode 100644 index 00000000000..090a7366b57 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInGraveyardEffect.java @@ -0,0 +1,44 @@ +package mage.abilities.effects.common.search; + +import mage.abilities.Ability; +import mage.abilities.effects.SearchEffect; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; + +/** + * @author TheElk801 + */ +public class SearchLibraryPutInGraveyardEffect extends SearchEffect { + + public SearchLibraryPutInGraveyardEffect() { + super(new TargetCardInLibrary(StaticFilters.FILTER_CARD), Outcome.Neutral); + staticText = "search your library for a card, put that card into your graveyard, then shuffle"; + } + + public SearchLibraryPutInGraveyardEffect(final SearchLibraryPutInGraveyardEffect effect) { + super(effect); + } + + @Override + public SearchLibraryPutInGraveyardEffect copy() { + return new SearchLibraryPutInGraveyardEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + if (controller.searchLibrary(target, source, game)) { + controller.moveCards(game.getCard(target.getFirstTarget()), Zone.GRAVEYARD, source, game); + } + controller.shuffleLibrary(source, game); + return true; + } + +} \ No newline at end of file From 5ac00083692dc75f7df3d85058d91c84f566edad Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 08:49:03 -0400 Subject: [PATCH 133/188] [MH2] Implemented Resurgent Belief --- .../src/mage/cards/r/ResurgentBelief.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/ResurgentBelief.java diff --git a/Mage.Sets/src/mage/cards/r/ResurgentBelief.java b/Mage.Sets/src/mage/cards/r/ResurgentBelief.java new file mode 100644 index 00000000000..ee8941fccb2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/ResurgentBelief.java @@ -0,0 +1,69 @@ +package mage.cards.r; + +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.SuspendAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterEnchantmentCard; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ResurgentBelief extends CardImpl { + + public ResurgentBelief(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, ""); + + // Suspend 2—{1}{W} + this.addAbility(new SuspendAbility(2, new ManaCostsImpl<>("{1}{W}"), this)); + + // Return all enchantment cards from your graveyard to the battlefield. + this.getSpellAbility().addEffect(new ResurgentBeliefEffect()); + } + + private ResurgentBelief(final ResurgentBelief card) { + super(card); + } + + @Override + public ResurgentBelief copy() { + return new ResurgentBelief(this); + } +} + +class ResurgentBeliefEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterEnchantmentCard(); + + ResurgentBeliefEffect() { + super(Outcome.Benefit); + staticText = "return all enchantment cards from your graveyard to the battlefield"; + } + + private ResurgentBeliefEffect(final ResurgentBeliefEffect effect) { + super(effect); + } + + @Override + public ResurgentBeliefEffect copy() { + return new ResurgentBeliefEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + return player != null && player.moveCards( + player.getGraveyard().getCards(filter, game), Zone.BATTLEFIELD, source, game + ); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 4e7710d5b71..81eee3a2fee 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -198,6 +198,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Raving Visionary", 56, Rarity.UNCOMMON, mage.cards.r.RavingVisionary.class)); cards.add(new SetCardInfo("Razortide Bridge", 252, Rarity.COMMON, mage.cards.r.RazortideBridge.class)); cards.add(new SetCardInfo("Recalibrate", 57, Rarity.COMMON, mage.cards.r.Recalibrate.class)); + cards.add(new SetCardInfo("Resurgent Belief", 26, Rarity.RARE, mage.cards.r.ResurgentBelief.class)); cards.add(new SetCardInfo("Revolutionist", 139, Rarity.COMMON, mage.cards.r.Revolutionist.class)); cards.add(new SetCardInfo("Rift Sower", 170, Rarity.COMMON, mage.cards.r.RiftSower.class)); cards.add(new SetCardInfo("Riptide Laboratory", 303, Rarity.RARE, mage.cards.r.RiptideLaboratory.class)); From 54e521422787d57037e83f52d866c32274a55fce Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 08:54:12 -0400 Subject: [PATCH 134/188] [MH2] Implemented Loathsome Curator --- .../src/mage/cards/l/LoathsomeCurator.java | 63 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LoathsomeCurator.java diff --git a/Mage.Sets/src/mage/cards/l/LoathsomeCurator.java b/Mage.Sets/src/mage/cards/l/LoathsomeCurator.java new file mode 100644 index 00000000000..a8c5485f967 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LoathsomeCurator.java @@ -0,0 +1,63 @@ +package mage.cards.l; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ExploitCreatureTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.ExploitAbility; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ManaValuePredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LoathsomeCurator extends CardImpl { + + private static final FilterPermanent filter + = new FilterCreaturePermanent("creature you don't control with mana value 3 or less"); + + static { + filter.add(TargetController.NOT_YOU.getControllerPredicate()); + filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 4)); + } + + public LoathsomeCurator(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + + this.subtype.add(SubType.GORGON); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Exploit + this.addAbility(new ExploitAbility()); + + // Menace + this.addAbility(new MenaceAbility()); + + // When Loathsome Curator exploits a creature, destroy target creature you don't control with mana value 3 or less. + Ability ability = new ExploitCreatureTriggeredAbility(new DestroyTargetEffect(), false); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + private LoathsomeCurator(final LoathsomeCurator card) { + super(card); + } + + @Override + public LoathsomeCurator copy() { + return new LoathsomeCurator(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 81eee3a2fee..e06705b9900 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -158,6 +158,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Lens Flare", 20, Rarity.COMMON, mage.cards.l.LensFlare.class)); cards.add(new SetCardInfo("Lightning Spear", 134, Rarity.COMMON, mage.cards.l.LightningSpear.class)); cards.add(new SetCardInfo("Liquimetal Torque", 228, Rarity.UNCOMMON, mage.cards.l.LiquimetalTorque.class)); + cards.add(new SetCardInfo("Loathsome Curator", 91, Rarity.COMMON, mage.cards.l.LoathsomeCurator.class)); cards.add(new SetCardInfo("Lose Focus", 49, Rarity.COMMON, mage.cards.l.LoseFocus.class)); cards.add(new SetCardInfo("Lucid Dreams", 50, Rarity.UNCOMMON, mage.cards.l.LucidDreams.class)); cards.add(new SetCardInfo("Marble Gargoyle", 21, Rarity.COMMON, mage.cards.m.MarbleGargoyle.class)); From 390075efd45cca47123e2cc55082a15c1a807e6e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 09:05:07 -0400 Subject: [PATCH 135/188] [MH2] Implemented Dihada's Ploy --- Mage.Sets/src/mage/cards/d/DihadasPloy.java | 71 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../watchers/common/DiscardedCardWatcher.java | 5 ++ 3 files changed, 77 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DihadasPloy.java diff --git a/Mage.Sets/src/mage/cards/d/DihadasPloy.java b/Mage.Sets/src/mage/cards/d/DihadasPloy.java new file mode 100644 index 00000000000..8c680cad0ea --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DihadasPloy.java @@ -0,0 +1,71 @@ +package mage.cards.d; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.JumpStartAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.Game; +import mage.watchers.common.DiscardedCardWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DihadasPloy extends CardImpl { + + private static final Hint hint = new ValueHint("Cards you've discarded this turn", DihadasPloyValue.instance); + + public DihadasPloy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}{B}"); + + // Draw two cards, then discard a card. You gain life equal to the number of cards you've discarded this turn. + this.getSpellAbility().addEffect(new DrawDiscardControllerEffect(2, 1)); + this.getSpellAbility().addEffect(new GainLifeEffect(DihadasPloyValue.instance)); + this.getSpellAbility().addHint(hint); + this.getSpellAbility().addWatcher(new DiscardedCardWatcher()); + + // Jump-start + this.addAbility(new JumpStartAbility(this)); + } + + private DihadasPloy(final DihadasPloy card) { + super(card); + } + + @Override + public DihadasPloy copy() { + return new DihadasPloy(this); + } +} + +enum DihadasPloyValue implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return DiscardedCardWatcher.getDiscarded(sourceAbility.getControllerId(), game); + } + + @Override + public DihadasPloyValue copy() { + return instance; + } + + @Override + public String getMessage() { + return "1"; + } + + @Override + public String toString() { + return "cards you've discarded this turn"; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index e06705b9900..98d28f9a677 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -82,6 +82,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Dakkon, Shadow Slayer", 192, Rarity.MYTHIC, mage.cards.d.DakkonShadowSlayer.class)); cards.add(new SetCardInfo("Darkmoss Bridge", 245, Rarity.COMMON, mage.cards.d.DarkmossBridge.class)); cards.add(new SetCardInfo("Diamond Lion", 225, Rarity.RARE, mage.cards.d.DiamondLion.class)); + cards.add(new SetCardInfo("Dihada's Ploy", 193, Rarity.COMMON, mage.cards.d.DihadasPloy.class)); cards.add(new SetCardInfo("Discerning Taste", 82, Rarity.COMMON, mage.cards.d.DiscerningTaste.class)); cards.add(new SetCardInfo("Disciple of the Sun", 11, Rarity.COMMON, mage.cards.d.DiscipleOfTheSun.class)); cards.add(new SetCardInfo("Dragon's Rage Channeler", 121, Rarity.UNCOMMON, mage.cards.d.DragonsRageChanneler.class)); diff --git a/Mage/src/main/java/mage/watchers/common/DiscardedCardWatcher.java b/Mage/src/main/java/mage/watchers/common/DiscardedCardWatcher.java index 5237835f378..a6483f67819 100644 --- a/Mage/src/main/java/mage/watchers/common/DiscardedCardWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/DiscardedCardWatcher.java @@ -37,4 +37,9 @@ public class DiscardedCardWatcher extends Watcher { DiscardedCardWatcher watcher = game.getState().getWatcher(DiscardedCardWatcher.class); return watcher != null && watcher.playerMap.getOrDefault(playerId, 0) > 0; } + + public static int getDiscarded(UUID playerId, Game game) { + DiscardedCardWatcher watcher = game.getState().getWatcher(DiscardedCardWatcher.class); + return watcher == null ? 0 : watcher.playerMap.getOrDefault(playerId, 0); + } } From bff38a195d5186c21861b24dafa363de1b83fe91 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Thu, 3 Jun 2021 18:49:02 -0500 Subject: [PATCH 136/188] [MH2] Implemented Gouged Zealot (#7882) --- Mage.Sets/src/mage/cards/g/GougedZealot.java | 81 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GougedZealot.java diff --git a/Mage.Sets/src/mage/cards/g/GougedZealot.java b/Mage.Sets/src/mage/cards/g/GougedZealot.java new file mode 100644 index 00000000000..c0e129a4087 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GougedZealot.java @@ -0,0 +1,81 @@ +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.condition.common.DeliriumCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.hint.common.CardTypesInGraveyardHint; +import mage.constants.*; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author weirddan455 + */ +public final class GougedZealot extends CardImpl { + + public GougedZealot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.CYCLOPS); + this.subtype.add(SubType.BERSERKER); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // Delirium — Whenever Gouged Zealot attacks, if there are four or more card types among cards in your graveyard, Gouged Zealot deals 1 damage to each creature defending player controls. + this.addAbility(new ConditionalInterveningIfTriggeredAbility( + new AttacksTriggeredAbility(new GougedZealotEffect(), false, null, SetTargetPointer.PLAYER), + DeliriumCondition.instance, + "Delirium — Whenever {this} attacks, if there are four or more card types among cards in your graveyard, {this} deals 1 damage to each creature defending player controls." + ).addHint(CardTypesInGraveyardHint.YOU)); + } + + private GougedZealot(final GougedZealot card) { + super(card); + } + + @Override + public GougedZealot copy() { + return new GougedZealot(this); + } +} + +class GougedZealotEffect extends OneShotEffect { + + public GougedZealotEffect() { + super(Outcome.Damage); + this.staticText = "{this} deals 1 damage to each creature defending player controls"; + } + + private GougedZealotEffect(final GougedZealotEffect effect) { + super(effect); + } + + @Override + public GougedZealotEffect copy() { + return new GougedZealotEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + UUID defendingPlayerId = getTargetPointer().getFirst(game, source); + if (defendingPlayerId != null) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, defendingPlayerId, game)) { + permanent.damage(1, source.getSourceId(), source, game); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 98d28f9a677..41336bd2248 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -131,6 +131,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Goblin Traprunner", 130, Rarity.UNCOMMON, mage.cards.g.GoblinTraprunner.class)); cards.add(new SetCardInfo("Goldmire Bridge", 247, Rarity.COMMON, mage.cards.g.GoldmireBridge.class)); cards.add(new SetCardInfo("Gorilla Shaman", 280, Rarity.UNCOMMON, mage.cards.g.GorillaShaman.class)); + cards.add(new SetCardInfo("Gouged Zealot", 131, Rarity.COMMON, mage.cards.g.GougedZealot.class)); cards.add(new SetCardInfo("Graceful Restoration", 201, Rarity.UNCOMMON, mage.cards.g.GracefulRestoration.class)); cards.add(new SetCardInfo("Greed", 274, Rarity.UNCOMMON, mage.cards.g.Greed.class)); cards.add(new SetCardInfo("Grief", 87, Rarity.MYTHIC, mage.cards.g.Grief.class)); From 11a19a8fc1db4bf3da0288cc3d9b4ccdb204239c Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Thu, 3 Jun 2021 18:49:53 -0500 Subject: [PATCH 137/188] [MH2] Implemented Foundry Helix (#7881) --- Mage.Sets/src/mage/cards/f/FoundryHelix.java | 69 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FoundryHelix.java diff --git a/Mage.Sets/src/mage/cards/f/FoundryHelix.java b/Mage.Sets/src/mage/cards/f/FoundryHelix.java new file mode 100644 index 00000000000..6460d9aadfa --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FoundryHelix.java @@ -0,0 +1,69 @@ +package mage.cards.f; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetAnyTarget; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author weirddan455 + */ +public final class FoundryHelix extends CardImpl { + + public FoundryHelix(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}{W}"); + + // As an additional cost to cast this spell, sacrifice a permanent. + this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent())); + + // Foundry Helix deals 4 damage to any target. If the sacrificed permanent was an artifact, you gain 4 life. + this.getSpellAbility().addEffect(new DamageTargetEffect(4)); + this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new GainLifeEffect(4), FoundryHelixCondition.instance)); + this.getSpellAbility().addTarget(new TargetAnyTarget()); + } + + private FoundryHelix(final FoundryHelix card) { + super(card); + } + + @Override + public FoundryHelix copy() { + return new FoundryHelix(this); + } +} + +enum FoundryHelixCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + for (Cost cost : source.getCosts()) { + if (cost instanceof SacrificeTargetCost) { + for (Permanent permanent : ((SacrificeTargetCost) cost).getPermanents()) { + if (permanent.isArtifact()) { + return true; + } + } + } + } + return false; + } + + @Override + public String toString() { + return "the sacrificed permanent was an artifact"; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 41336bd2248..0b77e819c04 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -113,6 +113,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Forest", 489, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Foul Watcher", 43, Rarity.COMMON, mage.cards.f.FoulWatcher.class)); cards.add(new SetCardInfo("Foundation Breaker", 160, Rarity.UNCOMMON, mage.cards.f.FoundationBreaker.class)); + cards.add(new SetCardInfo("Foundry Helix", 196, Rarity.COMMON, mage.cards.f.FoundryHelix.class)); cards.add(new SetCardInfo("Fractured Sanity", 44, Rarity.RARE, mage.cards.f.FracturedSanity.class)); cards.add(new SetCardInfo("Funnel-Web Recluse", 161, Rarity.COMMON, mage.cards.f.FunnelWebRecluse.class)); cards.add(new SetCardInfo("Fury", 126, Rarity.MYTHIC, mage.cards.f.Fury.class)); From e5ccca1563c7a114b382a65fb1815a3dd909199f Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Thu, 3 Jun 2021 18:52:32 -0500 Subject: [PATCH 138/188] [MH2] Implemented Deepwood Denizen (#7878) --- .../src/mage/cards/d/DeepwoodDenizen.java | 98 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 99 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DeepwoodDenizen.java diff --git a/Mage.Sets/src/mage/cards/d/DeepwoodDenizen.java b/Mage.Sets/src/mage/cards/d/DeepwoodDenizen.java new file mode 100644 index 00000000000..bf94d9fe8d8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeepwoodDenizen.java @@ -0,0 +1,98 @@ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.CostAdjuster; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.hint.ValueHint; +import mage.constants.SubType; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; + +/** + * + * @author weirddan455 + */ +public final class DeepwoodDenizen extends CardImpl { + + public DeepwoodDenizen(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // {5}{G}, {T}: Draw a card. This ability costs {1} less to activate for each +1/+1 counter on creatures you control. + Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{5}{G}")); + ability.addCost(new TapSourceCost()); + ability.addEffect(new InfoEffect("This ability costs {1} less to activate for each +1/+1 counter on creatures you control")); + ability.setCostAdjuster(DeepwoodDenizenAdjuster.instance); + ability.addHint(new ValueHint("+1/+1 counters on creatures you control", DeepwoodDenizenValue.instance)); + this.addAbility(ability); + } + + private DeepwoodDenizen(final DeepwoodDenizen card) { + super(card); + } + + @Override + public DeepwoodDenizen copy() { + return new DeepwoodDenizen(this); + } +} + +enum DeepwoodDenizenAdjuster implements CostAdjuster { + instance; + + @Override + public void adjustCosts(Ability ability, Game game) { + CardUtil.reduceCost(ability, DeepwoodDenizenValue.instance.calculate(game, ability, null)); + } +} + +enum DeepwoodDenizenValue implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + int counters = 0; + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(sourceAbility.getControllerId())) { + if (permanent.isCreature()) { + counters += permanent.getCounters(game).getCount(CounterType.P1P1); + } + } + return counters; + } + + @Override + public DynamicValue copy() { + return instance; + } + + @Override + public String getMessage() { + return "+1/+1 counter on creatures you control"; + } + + @Override + public String toString() { + return "X"; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 0b77e819c04..83f8ec7f6ba 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -81,6 +81,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Cursed Totem", 295, Rarity.RARE, mage.cards.c.CursedTotem.class)); cards.add(new SetCardInfo("Dakkon, Shadow Slayer", 192, Rarity.MYTHIC, mage.cards.d.DakkonShadowSlayer.class)); cards.add(new SetCardInfo("Darkmoss Bridge", 245, Rarity.COMMON, mage.cards.d.DarkmossBridge.class)); + cards.add(new SetCardInfo("Deepwood Denizen", 155, Rarity.COMMON, mage.cards.d.DeepwoodDenizen.class)); cards.add(new SetCardInfo("Diamond Lion", 225, Rarity.RARE, mage.cards.d.DiamondLion.class)); cards.add(new SetCardInfo("Dihada's Ploy", 193, Rarity.COMMON, mage.cards.d.DihadasPloy.class)); cards.add(new SetCardInfo("Discerning Taste", 82, Rarity.COMMON, mage.cards.d.DiscerningTaste.class)); From 06a15f9e832a230fa9b671607b4e0a03ac786b2b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 09:58:37 -0400 Subject: [PATCH 139/188] [MH2] Implemented Glimpse of Tomorrow --- .../src/mage/cards/g/GlimpseOfTomorrow.java | 99 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 100 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GlimpseOfTomorrow.java diff --git a/Mage.Sets/src/mage/cards/g/GlimpseOfTomorrow.java b/Mage.Sets/src/mage/cards/g/GlimpseOfTomorrow.java new file mode 100644 index 00000000000..f182948eac5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GlimpseOfTomorrow.java @@ -0,0 +1,99 @@ +package mage.cards.g; + +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.SuspendAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +import java.util.List; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GlimpseOfTomorrow extends CardImpl { + + public GlimpseOfTomorrow(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, ""); + + // Suspend 3—{R}{R} + this.addAbility(new SuspendAbility(3, new ManaCostsImpl<>("{R}{R}"), this)); + + // Shuffle all permanents you own into your library, then reveal that many cards from the top of your library. Put all non-Aura permanent cards revealed this way onto the battlefield, then do the same for Aura cards, then put the rest on the bottom of your library in a random order. + this.getSpellAbility().addEffect(new GlimpseOfTomorrowEffect()); + } + + private GlimpseOfTomorrow(final GlimpseOfTomorrow card) { + super(card); + } + + @Override + public GlimpseOfTomorrow copy() { + return new GlimpseOfTomorrow(this); + } +} + +class GlimpseOfTomorrowEffect extends OneShotEffect { + + private static final FilterPermanent filter = new FilterPermanent(); + + static { + filter.add(TargetController.YOU.getOwnerPredicate()); + } + + GlimpseOfTomorrowEffect() { + super(Outcome.Benefit); + staticText = "shuffle all permanents you own into your library, then reveal " + + "that many cards from the top of your library. Put all non-Aura permanent cards " + + "revealed this way onto the battlefield, then do the same for Aura cards, " + + "then put the rest on the bottom of your library in a random order"; + } + + private GlimpseOfTomorrowEffect(final GlimpseOfTomorrowEffect effect) { + super(effect); + } + + @Override + public GlimpseOfTomorrowEffect copy() { + return new GlimpseOfTomorrowEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + List permanents = game.getBattlefield().getActivePermanents( + filter, source.getControllerId(), source.getSourceId(), game + ); + int count = permanents.size(); + player.shuffleCardsToLibrary(new CardsImpl(permanents), game, source); + + Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, count)); + player.revealCards(source, cards, game); + + Cards toBattlefield = new CardsImpl(cards.getCards(StaticFilters.FILTER_CARD_PERMANENT, game)); + toBattlefield.removeIf(uuid -> game.getCard(uuid).hasSubtype(SubType.AURA, game)); + player.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game); + toBattlefield.clear(); + cards.retainZone(Zone.LIBRARY, game); + + toBattlefield.addAll(cards.getCards(StaticFilters.FILTER_CARD_PERMANENT, game)); + toBattlefield.removeIf(uuid -> !game.getCard(uuid).hasSubtype(SubType.AURA, game)); + player.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game); + cards.retainZone(Zone.LIBRARY, game); + player.putCardsOnBottomOfLibrary(cards, game, source, false); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 83f8ec7f6ba..eca6f2a809e 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -126,6 +126,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Ghost-Lit Drifter", 45, Rarity.UNCOMMON, mage.cards.g.GhostLitDrifter.class)); cards.add(new SetCardInfo("Gilt-Blade Prowler", 86, Rarity.COMMON, mage.cards.g.GiltBladeProwler.class)); cards.add(new SetCardInfo("Glimmer Bairn", 163, Rarity.COMMON, mage.cards.g.GlimmerBairn.class)); + cards.add(new SetCardInfo("Glimpse of Tomorrow", 129, Rarity.RARE, mage.cards.g.GlimpseOfTomorrow.class)); cards.add(new SetCardInfo("Glinting Creeper", 164, Rarity.UNCOMMON, mage.cards.g.GlintingCreeper.class)); cards.add(new SetCardInfo("Glorious Enforcer", 14, Rarity.UNCOMMON, mage.cards.g.GloriousEnforcer.class)); cards.add(new SetCardInfo("Goblin Anarchomancer", 200, Rarity.COMMON, mage.cards.g.GoblinAnarchomancer.class)); From 5d15eca51424c06a7b25f6bbeda7be7ec0ed87f0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 20:04:45 -0400 Subject: [PATCH 140/188] [MH2] Implemented Mount Velus Manticore --- .../src/mage/cards/m/MountVelusManticore.java | 85 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 86 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MountVelusManticore.java diff --git a/Mage.Sets/src/mage/cards/m/MountVelusManticore.java b/Mage.Sets/src/mage/cards/m/MountVelusManticore.java new file mode 100644 index 00000000000..7e89c53c291 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MountVelusManticore.java @@ -0,0 +1,85 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MountVelusManticore extends CardImpl { + + public MountVelusManticore(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{2}{R}{R}"); + + this.subtype.add(SubType.MANTICORE); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // At the beginning of combat on your turn, you may discard a card. When you do, Mount Velus Manticore deals X damage to any target, where X is the number of card types the discarded card has. + this.addAbility(new BeginningOfCombatTriggeredAbility( + new MountVelusManticoreEffect(), TargetController.YOU, false + )); + } + + private MountVelusManticore(final MountVelusManticore card) { + super(card); + } + + @Override + public MountVelusManticore copy() { + return new MountVelusManticore(this); + } +} + +class MountVelusManticoreEffect extends OneShotEffect { + + MountVelusManticoreEffect() { + super(Outcome.Benefit); + staticText = "you may discard a card. When you do, {this} deals X damage to any target, " + + "where X is the number of card types the discarded card has"; + } + + private MountVelusManticoreEffect(final MountVelusManticoreEffect effect) { + super(effect); + } + + @Override + public MountVelusManticoreEffect copy() { + return new MountVelusManticoreEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Card card = player.discard(0, 1, false, source, game).getRandom(game); + if (card == null) { + return false; + } + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( + new DamageTargetEffect(card.getCardType().size()), false, "{this} deals X damage " + + "to any target, where X is the number of card types the discarded card has" + ); + ability.addTarget(new TargetAnyTarget()); + game.fireReflexiveTriggeredAbility(ability, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index eca6f2a809e..a2cd7a23696 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -178,6 +178,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Moderation", 206, Rarity.RARE, mage.cards.m.Moderation.class)); cards.add(new SetCardInfo("Mogg Salvage", 282, Rarity.UNCOMMON, mage.cards.m.MoggSalvage.class)); cards.add(new SetCardInfo("Monoskelion", 229, Rarity.UNCOMMON, mage.cards.m.Monoskelion.class)); + cards.add(new SetCardInfo("Mount Velus Manticore", 136, Rarity.COMMON, mage.cards.m.MountVelusManticore.class)); cards.add(new SetCardInfo("Mountain", 487, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Myr Scrapling", 230, Rarity.COMMON, mage.cards.m.MyrScrapling.class)); cards.add(new SetCardInfo("Mystic Redaction", 53, Rarity.UNCOMMON, mage.cards.m.MysticRedaction.class)); From 1c6f8ae0350c4dcc9f09cfa38bc40b5888656813 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jun 2021 20:10:38 -0400 Subject: [PATCH 141/188] [MH2] Implemented Sojourner's Companion --- .../src/mage/cards/s/SojournersCompanion.java | 41 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../keyword/ArtifactLandcyclingAbility.java | 30 ++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SojournersCompanion.java create mode 100644 Mage/src/main/java/mage/abilities/keyword/ArtifactLandcyclingAbility.java diff --git a/Mage.Sets/src/mage/cards/s/SojournersCompanion.java b/Mage.Sets/src/mage/cards/s/SojournersCompanion.java new file mode 100644 index 00000000000..4213dbe9848 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SojournersCompanion.java @@ -0,0 +1,41 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.keyword.AffinityForArtifactsAbility; +import mage.abilities.keyword.ArtifactLandcyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SojournersCompanion extends CardImpl { + + public SojournersCompanion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}"); + + this.subtype.add(SubType.SALAMANDER); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Affinity for artifacts + this.addAbility(new AffinityForArtifactsAbility()); + + // Artifact landcycling {2} + this.addAbility(new ArtifactLandcyclingAbility(new GenericManaCost(2))); + } + + private SojournersCompanion(final SojournersCompanion card) { + super(card); + } + + @Override + public SojournersCompanion copy() { + return new SojournersCompanion(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index a2cd7a23696..553522b71f0 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -233,6 +233,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Slag Strider", 141, Rarity.UNCOMMON, mage.cards.s.SlagStrider.class)); cards.add(new SetCardInfo("Slagwoods Bridge", 256, Rarity.COMMON, mage.cards.s.SlagwoodsBridge.class)); cards.add(new SetCardInfo("So Shiny", 63, Rarity.COMMON, mage.cards.s.SoShiny.class)); + cards.add(new SetCardInfo("Sojourner's Companion", 235, Rarity.COMMON, mage.cards.s.SojournersCompanion.class)); cards.add(new SetCardInfo("Sol Talisman", 236, Rarity.RARE, mage.cards.s.SolTalisman.class)); cards.add(new SetCardInfo("Solitary Confinement", 265, Rarity.RARE, mage.cards.s.SolitaryConfinement.class)); cards.add(new SetCardInfo("Solitude", 32, Rarity.MYTHIC, mage.cards.s.Solitude.class)); diff --git a/Mage/src/main/java/mage/abilities/keyword/ArtifactLandcyclingAbility.java b/Mage/src/main/java/mage/abilities/keyword/ArtifactLandcyclingAbility.java new file mode 100644 index 00000000000..2687b3c7a45 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/ArtifactLandcyclingAbility.java @@ -0,0 +1,30 @@ +package mage.abilities.keyword; + +import mage.abilities.costs.Cost; +import mage.constants.CardType; +import mage.filter.common.FilterLandCard; + +/** + * @author TheElk801 + */ +public class ArtifactLandcyclingAbility extends CyclingAbility { + + private static final FilterLandCard filter = new FilterLandCard("artifact land card"); + + static { + filter.add(CardType.ARTIFACT.getPredicate()); + } + + public ArtifactLandcyclingAbility(Cost cost) { + super(cost, filter, "Artifact landcycling"); + } + + private ArtifactLandcyclingAbility(final ArtifactLandcyclingAbility ability) { + super(ability); + } + + @Override + public ArtifactLandcyclingAbility copy() { + return new ArtifactLandcyclingAbility(this); + } +} From cdca453738a1afa3cb2b97acb4746c44779cd043 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Thu, 3 Jun 2021 19:12:48 -0500 Subject: [PATCH 142/188] [MH2] Implemented Duskshell Crawler (#7879) * [MH2] Implemented Duskshell Crawler * [MH2] Duskshell Crawler - Fixed predicate --- .../src/mage/cards/d/DuskshellCrawler.java | 59 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 60 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DuskshellCrawler.java diff --git a/Mage.Sets/src/mage/cards/d/DuskshellCrawler.java b/Mage.Sets/src/mage/cards/d/DuskshellCrawler.java new file mode 100644 index 00000000000..25a79751481 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DuskshellCrawler.java @@ -0,0 +1,59 @@ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author weirddan455 + */ +public final class DuskshellCrawler extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(CounterType.P1P1.getPredicate()); + } + + public DuskshellCrawler(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.INSECT); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // When Duskshell Crawler enters the battlefield, put a +1/+1 counter on target creature. + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + // Each creature you control with a +1/+1 counter on it has trample. + this.addAbility(new SimpleStaticAbility( + new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield, filter) + .setText("Each creature you control with a +1/+1 counter on it has trample") + )); + } + + private DuskshellCrawler(final DuskshellCrawler card) { + super(card); + } + + @Override + public DuskshellCrawler copy() { + return new DuskshellCrawler(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 553522b71f0..3439694b891 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -90,6 +90,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Dress Down", 39, Rarity.RARE, mage.cards.d.DressDown.class)); cards.add(new SetCardInfo("Drey Keeper", 194, Rarity.COMMON, mage.cards.d.DreyKeeper.class)); cards.add(new SetCardInfo("Drossforge Bridge", 246, Rarity.COMMON, mage.cards.d.DrossforgeBridge.class)); + cards.add(new SetCardInfo("Duskshell Crawler", 156, Rarity.COMMON, mage.cards.d.DuskshellCrawler.class)); cards.add(new SetCardInfo("Echoing Return", 83, Rarity.COMMON, mage.cards.e.EchoingReturn.class)); cards.add(new SetCardInfo("Enchantress's Presence", 283, Rarity.RARE, mage.cards.e.EnchantresssPresence.class)); cards.add(new SetCardInfo("Endurance", 157, Rarity.MYTHIC, mage.cards.e.Endurance.class)); From 9581fe16e32b0a636491b99255ab8da3c273e3d8 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Thu, 3 Jun 2021 19:55:29 -0500 Subject: [PATCH 143/188] Fixed verify error --- Mage.Sets/src/mage/cards/g/GlimpseOfTomorrow.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mage.Sets/src/mage/cards/g/GlimpseOfTomorrow.java b/Mage.Sets/src/mage/cards/g/GlimpseOfTomorrow.java index f182948eac5..aafcd2a15ea 100644 --- a/Mage.Sets/src/mage/cards/g/GlimpseOfTomorrow.java +++ b/Mage.Sets/src/mage/cards/g/GlimpseOfTomorrow.java @@ -26,6 +26,8 @@ public final class GlimpseOfTomorrow extends CardImpl { public GlimpseOfTomorrow(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, ""); + this.color.setRed(true); + // Suspend 3—{R}{R} this.addAbility(new SuspendAbility(3, new ManaCostsImpl<>("{R}{R}"), this)); From 90f09dd816c2eb912c949e4e879543884b3c755e Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Thu, 3 Jun 2021 20:50:34 -0500 Subject: [PATCH 144/188] [MH2] Implemented Kaldra Compleat (#7883) --- .../src/mage/cards/k/KaldraCompleat.java | 87 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + ...ealsDamageToACreatureTriggeredAbility.java | 1 + 3 files changed, 89 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KaldraCompleat.java diff --git a/Mage.Sets/src/mage/cards/k/KaldraCompleat.java b/Mage.Sets/src/mage/cards/k/KaldraCompleat.java new file mode 100644 index 00000000000..d336cf27470 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KaldraCompleat.java @@ -0,0 +1,87 @@ +package mage.cards.k; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToACreatureTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.*; +import mage.constants.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.filter.StaticFilters; + +/** + * + * @author weirddan455 + */ +public final class KaldraCompleat extends CardImpl { + + public KaldraCompleat(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{7}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.EQUIPMENT); + + // Living weapon + this.addAbility(new LivingWeaponAbility()); + + // Indestructible + this.addAbility(IndestructibleAbility.getInstance()); + + // Equipped creature gets +5/+5 and has first strike, trample, indestructible, haste, and "Whenever this creature deals combat damage to a creature, exile that creature." + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(5, 5)); + ability.addEffect(new GainAbilityAttachedEffect( + FirstStrikeAbility.getInstance(), + AttachmentType.EQUIPMENT, + Duration.WhileOnBattlefield, + "and has first strike" + )); + ability.addEffect(new GainAbilityAttachedEffect( + TrampleAbility.getInstance(), + AttachmentType.EQUIPMENT, + Duration.WhileOnBattlefield, + ", trample" + )); + ability.addEffect(new GainAbilityAttachedEffect( + IndestructibleAbility.getInstance(), + AttachmentType.EQUIPMENT, + Duration.WhileOnBattlefield, + ", indestructible" + )); + ability.addEffect(new GainAbilityAttachedEffect( + HasteAbility.getInstance(), + AttachmentType.EQUIPMENT, + Duration.WhileOnBattlefield, + ", haste" + )); + ability.addEffect(new GainAbilityAttachedEffect( + new DealsDamageToACreatureTriggeredAbility( + new ExileTargetEffect("exile that creature"), + true, + false, + true, + StaticFilters.FILTER_PERMANENT_CREATURE_A + ), + AttachmentType.EQUIPMENT, + Duration.WhileOnBattlefield, + ", and \"Whenever this creature deals combat damage to a creature, exile that creature.\"" + )); + this.addAbility(ability); + + // Equip {7} + this.addAbility(new EquipAbility(7)); + } + + private KaldraCompleat(final KaldraCompleat card) { + super(card); + } + + @Override + public KaldraCompleat copy() { + return new KaldraCompleat(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 3439694b891..e4df579954c 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -153,6 +153,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Jade Avenger", 167, Rarity.COMMON, mage.cards.j.JadeAvenger.class)); cards.add(new SetCardInfo("Jewel-Eyed Cobra", 168, Rarity.COMMON, mage.cards.j.JewelEyedCobra.class)); cards.add(new SetCardInfo("Junk Winder", 48, Rarity.UNCOMMON, mage.cards.j.JunkWinder.class)); + cards.add(new SetCardInfo("Kaldra Compleat", 227, Rarity.MYTHIC, mage.cards.k.KaldraCompleat.class)); cards.add(new SetCardInfo("Kaleidoscorch", 133, Rarity.UNCOMMON, mage.cards.k.Kaleidoscorch.class)); cards.add(new SetCardInfo("Karmic Guide", 263, Rarity.RARE, mage.cards.k.KarmicGuide.class)); cards.add(new SetCardInfo("Kitchen Imp", 89, Rarity.COMMON, mage.cards.k.KitchenImp.class)); diff --git a/Mage/src/main/java/mage/abilities/common/DealsDamageToACreatureTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DealsDamageToACreatureTriggeredAbility.java index 5de73a3a578..8f780f2883b 100644 --- a/Mage/src/main/java/mage/abilities/common/DealsDamageToACreatureTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DealsDamageToACreatureTriggeredAbility.java @@ -81,6 +81,7 @@ public class DealsDamageToACreatureTriggeredAbility extends TriggeredAbilityImpl sb.append("a creature, "); } else { sb.append(filter.getMessage()); + sb.append(", "); } sb.append(super.getRule()); return sb.toString(); From 1722541fe32b76cc33747ceb4755551e8adb42cc Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Fri, 4 Jun 2021 06:30:43 -0500 Subject: [PATCH 145/188] [MH2] Implemented Lonis, Cryptozoologist (#7884) --- .../mage/cards/l/LonisCryptozoologist.java | 118 ++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 119 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LonisCryptozoologist.java diff --git a/Mage.Sets/src/mage/cards/l/LonisCryptozoologist.java b/Mage.Sets/src/mage/cards/l/LonisCryptozoologist.java new file mode 100644 index 00000000000..32a8d29f7e9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LonisCryptozoologist.java @@ -0,0 +1,118 @@ +package mage.cards.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeXTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.common.GetXValue; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.keyword.InvestigateEffect; +import mage.cards.*; +import mage.constants.*; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.common.FilterPermanentCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.mageobject.ManaValuePredicate; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; + +/** + * + * @author weirddan455 + */ +public final class LonisCryptozoologist extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another nontoken creature"); + private static final FilterControlledPermanent filter2 = new FilterControlledPermanent(SubType.CLUE, "Clues"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(Predicates.not(TokenPredicate.instance)); + } + + public LonisCryptozoologist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.SNAKE); + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Whenever another nontoken creature enters the battlefield under your control, investigate. + this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new InvestigateEffect(), filter, false, null, true)); + + // {T}, Sacrifice X Clues: Target opponent reveals the top X cards of their library. + // You may put a nonland permanent card with mana value X or less from among them onto the battlefield under your control. + // That player puts the rest on the bottom of their library in a random order. + Ability ability = new SimpleActivatedAbility(new LonisCryptozoologistEffect(), new TapSourceCost()); + ability.addCost(new SacrificeXTargetCost(filter2)); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + private LonisCryptozoologist(final LonisCryptozoologist card) { + super(card); + } + + @Override + public LonisCryptozoologist copy() { + return new LonisCryptozoologist(this); + } +} + +class LonisCryptozoologistEffect extends OneShotEffect { + + public LonisCryptozoologistEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "Target opponent reveals the top X cards of their library." + + " You may put a nonland permanent card with mana value X or less from among them onto the battlefield under your control." + + " That player puts the rest on the bottom of their library in a random order"; + } + + private LonisCryptozoologistEffect(final LonisCryptozoologistEffect effect) { + super(effect); + } + + @Override + public LonisCryptozoologistEffect copy() { + return new LonisCryptozoologistEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (controller != null && opponent != null) { + int xValue = GetXValue.instance.calculate(game, source, this); + Cards cards = new CardsImpl(opponent.getLibrary().getTopCards(game, xValue)); + opponent.revealCards(source, cards, game); + if (controller.chooseUse(outcome, "Put a nonland permanent card with mana value " + xValue + + " or less from among revealed cards onto the battlefield under your control?", source, game)) { + FilterPermanentCard filter = new FilterPermanentCard("nonland permanent card with mana value " + xValue + " or less"); + filter.add(Predicates.not(CardType.LAND.getPredicate())); + filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, xValue + 1)); + TargetCard target = new TargetCard(Zone.LIBRARY, filter); + if (controller.choose(outcome, cards, target, game)) { + Card selectedCard = game.getCard(target.getFirstTarget()); + if (selectedCard != null) { + cards.remove(selectedCard); + controller.moveCards(selectedCard, Zone.BATTLEFIELD, source, game); + } + } + } + opponent.putCardsOnBottomOfLibrary(cards, game, source, false); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index e4df579954c..5c317171309 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -166,6 +166,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Lightning Spear", 134, Rarity.COMMON, mage.cards.l.LightningSpear.class)); cards.add(new SetCardInfo("Liquimetal Torque", 228, Rarity.UNCOMMON, mage.cards.l.LiquimetalTorque.class)); cards.add(new SetCardInfo("Loathsome Curator", 91, Rarity.COMMON, mage.cards.l.LoathsomeCurator.class)); + cards.add(new SetCardInfo("Lonis, Cryptozoologist", 204, Rarity.RARE, mage.cards.l.LonisCryptozoologist.class)); cards.add(new SetCardInfo("Lose Focus", 49, Rarity.COMMON, mage.cards.l.LoseFocus.class)); cards.add(new SetCardInfo("Lucid Dreams", 50, Rarity.UNCOMMON, mage.cards.l.LucidDreams.class)); cards.add(new SetCardInfo("Marble Gargoyle", 21, Rarity.COMMON, mage.cards.m.MarbleGargoyle.class)); From 9fda9563acf47f667c738df61984b5f2d0985561 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jun 2021 08:11:46 -0400 Subject: [PATCH 146/188] [MH2] Implemented Nested Shambler --- .../src/mage/cards/n/NestedShambler.java | 44 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 45 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/n/NestedShambler.java diff --git a/Mage.Sets/src/mage/cards/n/NestedShambler.java b/Mage.Sets/src/mage/cards/n/NestedShambler.java new file mode 100644 index 00000000000..6a19ea125d4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NestedShambler.java @@ -0,0 +1,44 @@ +package mage.cards.n; + +import mage.MageInt; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.SquirrelToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class NestedShambler extends CardImpl { + + private static final DynamicValue xValue = new SourcePermanentPowerCount(false); + + public NestedShambler(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); + + this.subtype.add(SubType.ZOMBIE); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // When Nested Shambler dies, create X tapped 1/1 green Squirrel creature tokens, where X is Nested Shambler's power. + this.addAbility(new DiesSourceTriggeredAbility(new CreateTokenEffect( + new SquirrelToken(), xValue, true, false + ))); + } + + private NestedShambler(final NestedShambler card) { + super(card); + } + + @Override + public NestedShambler copy() { + return new NestedShambler(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 5c317171309..2e98314928b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -186,6 +186,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Myr Scrapling", 230, Rarity.COMMON, mage.cards.m.MyrScrapling.class)); cards.add(new SetCardInfo("Mystic Redaction", 53, Rarity.UNCOMMON, mage.cards.m.MysticRedaction.class)); cards.add(new SetCardInfo("Necromancer's Familiar", 94, Rarity.UNCOMMON, mage.cards.n.NecromancersFamiliar.class)); + cards.add(new SetCardInfo("Nested Shambler", 95, Rarity.COMMON, mage.cards.n.NestedShambler.class)); cards.add(new SetCardInfo("Nettlecyst", 231, Rarity.RARE, mage.cards.n.Nettlecyst.class)); cards.add(new SetCardInfo("Nevinyrral's Disk", 298, Rarity.RARE, mage.cards.n.NevinyrralsDisk.class)); cards.add(new SetCardInfo("Obsidian Charmaw", 137, Rarity.RARE, mage.cards.o.ObsidianCharmaw.class)); From f6cdbd6b4d9c6e31123e5e1f4ca124e5aad7c5a5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jun 2021 08:22:40 -0400 Subject: [PATCH 147/188] [MH2] Implemented Necrogoyf --- Mage.Sets/src/mage/cards/n/Necrogoyf.java | 56 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../common/CardsInAllGraveyardsCount.java | 9 +-- 3 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/n/Necrogoyf.java diff --git a/Mage.Sets/src/mage/cards/n/Necrogoyf.java b/Mage.Sets/src/mage/cards/n/Necrogoyf.java new file mode 100644 index 00000000000..7201dab97dd --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/Necrogoyf.java @@ -0,0 +1,56 @@ +package mage.cards.n; + +import mage.MageInt; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CardsInAllGraveyardsCount; +import mage.abilities.effects.common.continuous.SetPowerSourceEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.abilities.keyword.MadnessAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Necrogoyf extends CardImpl { + + private static final DynamicValue xValue = new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURES); + + public Necrogoyf(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + + this.subtype.add(SubType.LHURGOYF); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // Necrogoyf's power is equal to the number of creature cards in all graveyards. + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new SetPowerSourceEffect(xValue, Duration.EndOfGame) + )); + + // At the beginning of each player's upkeep, that player discards a card. + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + Zone.BATTLEFIELD, new DiscardTargetEffect(1), + TargetController.EACH_PLAYER, false, true + )); + + // Madness {1}{B}{B} + this.addAbility(new MadnessAbility(this, new ManaCostsImpl<>("{1}{B}{B}"))); + } + + private Necrogoyf(final Necrogoyf card) { + super(card); + } + + @Override + public Necrogoyf copy() { + return new Necrogoyf(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 2e98314928b..7f2d74a057c 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -185,6 +185,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 487, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Myr Scrapling", 230, Rarity.COMMON, mage.cards.m.MyrScrapling.class)); cards.add(new SetCardInfo("Mystic Redaction", 53, Rarity.UNCOMMON, mage.cards.m.MysticRedaction.class)); + cards.add(new SetCardInfo("Necrogoyf", 93, Rarity.RARE, mage.cards.n.Necrogoyf.class)); cards.add(new SetCardInfo("Necromancer's Familiar", 94, Rarity.UNCOMMON, mage.cards.n.NecromancersFamiliar.class)); cards.add(new SetCardInfo("Nested Shambler", 95, Rarity.COMMON, mage.cards.n.NestedShambler.class)); cards.add(new SetCardInfo("Nettlecyst", 231, Rarity.RARE, mage.cards.n.Nettlecyst.class)); diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInAllGraveyardsCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInAllGraveyardsCount.java index 72cd99216cb..4976affce1a 100644 --- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInAllGraveyardsCount.java +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInAllGraveyardsCount.java @@ -1,23 +1,24 @@ package mage.abilities.dynamicvalue.common; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** - * * @author North */ public class CardsInAllGraveyardsCount implements DynamicValue { - private FilterCard filter; + private final FilterCard filter; public CardsInAllGraveyardsCount() { - this(new FilterCard()); + this(StaticFilters.FILTER_CARD); } public CardsInAllGraveyardsCount(FilterCard filter) { From 7bedbf6e55197501bfaffa838e0f0cbb1a8306aa Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jun 2021 08:30:48 -0400 Subject: [PATCH 148/188] [MH2] Implemented Piercing Rays --- Mage.Sets/src/mage/cards/p/PiercingRays.java | 52 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 53 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PiercingRays.java diff --git a/Mage.Sets/src/mage/cards/p/PiercingRays.java b/Mage.Sets/src/mage/cards/p/PiercingRays.java new file mode 100644 index 00000000000..5a9f7670e44 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PiercingRays.java @@ -0,0 +1,52 @@ +package mage.cards.p; + +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.keyword.ForecastAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PiercingRays extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("tapped creature"); + private static final FilterPermanent filter2 = new FilterCreaturePermanent("untapped creature"); + + static { + filter.add(TappedPredicate.TAPPED); + filter2.add(TappedPredicate.UNTAPPED); + } + + public PiercingRays(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{W}"); + + // Exile target tapped creature. + this.getSpellAbility().addEffect(new ExileTargetEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + + // Forecast—{2}{W}, Reveal Piercing Rays from your hand: Tap target untapped creature. + Ability ability = new ForecastAbility(new TapTargetEffect(), new ManaCostsImpl<>("{2}{W}")); + ability.addTarget(new TargetPermanent(filter2)); + this.addAbility(ability); + } + + private PiercingRays(final PiercingRays card) { + super(card); + } + + @Override + public PiercingRays copy() { + return new PiercingRays(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 7f2d74a057c..92b4824a62d 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -197,6 +197,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Patchwork Gnomes", 299, Rarity.COMMON, mage.cards.p.PatchworkGnomes.class)); cards.add(new SetCardInfo("Patriarch's Bidding", 275, Rarity.RARE, mage.cards.p.PatriarchsBidding.class)); cards.add(new SetCardInfo("Phantasmal Dreadmaw", 55, Rarity.COMMON, mage.cards.p.PhantasmalDreadmaw.class)); + cards.add(new SetCardInfo("Piercing Rays", 24, Rarity.COMMON, mage.cards.p.PiercingRays.class)); cards.add(new SetCardInfo("Piru, the Volatile", 207, Rarity.RARE, mage.cards.p.PiruTheVolatile.class)); cards.add(new SetCardInfo("Plains", 481, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Priest of Fell Rites", 208, Rarity.RARE, mage.cards.p.PriestOfFellRites.class)); From b8c7fd2e12312b748bc4d0e18d5d691ae6b86f3b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jun 2021 08:38:52 -0400 Subject: [PATCH 149/188] [MH2] Implemented Smell Fear --- Mage.Sets/src/mage/cards/s/SmellFear.java | 40 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 41 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SmellFear.java diff --git a/Mage.Sets/src/mage/cards/s/SmellFear.java b/Mage.Sets/src/mage/cards/s/SmellFear.java new file mode 100644 index 00000000000..601caa4aeed --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SmellFear.java @@ -0,0 +1,40 @@ +package mage.cards.s; + +import mage.abilities.effects.common.FightTargetsEffect; +import mage.abilities.effects.common.counter.ProliferateEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SmellFear extends CardImpl { + + public SmellFear(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}"); + + // Proliferate. + this.getSpellAbility().addEffect(new ProliferateEffect()); + + // Target creature you control fights up to one target creature you don't control. + this.getSpellAbility().addEffect(new FightTargetsEffect( + "
Target creature you control fights up to one target creature you don't control" + )); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent()); + } + + private SmellFear(final SmellFear card) { + super(card); + } + + @Override + public SmellFear copy() { + return new SmellFear(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 92b4824a62d..849dde9ef44 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -238,6 +238,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Skophos Reaver", 140, Rarity.COMMON, mage.cards.s.SkophosReaver.class)); cards.add(new SetCardInfo("Slag Strider", 141, Rarity.UNCOMMON, mage.cards.s.SlagStrider.class)); cards.add(new SetCardInfo("Slagwoods Bridge", 256, Rarity.COMMON, mage.cards.s.SlagwoodsBridge.class)); + cards.add(new SetCardInfo("Smell Fear", 173, Rarity.COMMON, mage.cards.s.SmellFear.class)); cards.add(new SetCardInfo("So Shiny", 63, Rarity.COMMON, mage.cards.s.SoShiny.class)); cards.add(new SetCardInfo("Sojourner's Companion", 235, Rarity.COMMON, mage.cards.s.SojournersCompanion.class)); cards.add(new SetCardInfo("Sol Talisman", 236, Rarity.RARE, mage.cards.s.SolTalisman.class)); From 836bc9500755d0126e2719e460b1cc1eff61b9fa Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jun 2021 09:17:43 -0400 Subject: [PATCH 150/188] [MH2] Implemented Sword of Hearth and Home --- .../src/mage/cards/s/SwordOfBodyAndMind.java | 32 ++--- .../mage/cards/s/SwordOfFeastAndFamine.java | 25 ++-- .../src/mage/cards/s/SwordOfFireAndIce.java | 69 +++-------- .../mage/cards/s/SwordOfHearthAndHome.java | 109 ++++++++++++++++++ .../mage/cards/s/SwordOfLightAndShadow.java | 107 +++++------------ .../mage/cards/s/SwordOfSinewAndSteel.java | 6 +- .../mage/cards/s/SwordOfTruthAndJustice.java | 6 +- .../src/mage/cards/s/SwordOfWarAndPeace.java | 10 +- Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 9 files changed, 190 insertions(+), 175 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/SwordOfHearthAndHome.java diff --git a/Mage.Sets/src/mage/cards/s/SwordOfBodyAndMind.java b/Mage.Sets/src/mage/cards/s/SwordOfBodyAndMind.java index a7be5dabb61..d7125ec8ffd 100644 --- a/Mage.Sets/src/mage/cards/s/SwordOfBodyAndMind.java +++ b/Mage.Sets/src/mage/cards/s/SwordOfBodyAndMind.java @@ -1,14 +1,10 @@ - - package mage.cards.s; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; @@ -17,34 +13,30 @@ import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.ProtectionAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.game.permanent.token.WolfToken; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author Loki */ public final class SwordOfBodyAndMind extends CardImpl { public SwordOfBodyAndMind(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); this.subtype.add(SubType.EQUIPMENT); // Equipped creature gets +2/+2 and has protection from green and from blue. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2)); - Effect effect = new GainAbilityAttachedEffect(ProtectionAbility.from(ObjectColor.GREEN, ObjectColor.BLUE), AttachmentType.EQUIPMENT); - effect.setText("and has protection from green and from blue"); - ability.addEffect(effect); + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2)); + ability.addEffect(new GainAbilityAttachedEffect( + ProtectionAbility.from(ObjectColor.GREEN, ObjectColor.BLUE), AttachmentType.EQUIPMENT + ).setText("and has protection from green and from blue")); this.addAbility(ability); // Whenever equipped creature deals combat damage to a player, you create a 2/2 green Wolf creature token and that player puts the top ten cards of their library into their graveyard. @@ -87,12 +79,10 @@ class SwordOfBodyAndMindAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event; + DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; Permanent p = game.getPermanent(event.getSourceId()); if (damageEvent.isCombatDamage() && p != null && p.getAttachments().contains(this.getSourceId())) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getPlayerId())); - } + this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId())); return true; } return false; @@ -102,4 +92,4 @@ class SwordOfBodyAndMindAbility extends TriggeredAbilityImpl { public String getRule() { return "Whenever equipped creature deals combat damage to a player, you create a 2/2 green Wolf creature token and that player mills ten cards."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/SwordOfFeastAndFamine.java b/Mage.Sets/src/mage/cards/s/SwordOfFeastAndFamine.java index 1fde6eb4249..2726d3e9a05 100644 --- a/Mage.Sets/src/mage/cards/s/SwordOfFeastAndFamine.java +++ b/Mage.Sets/src/mage/cards/s/SwordOfFeastAndFamine.java @@ -1,10 +1,10 @@ package mage.cards.s; import mage.ObjectColor; +import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.UntapAllLandsControllerEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; @@ -17,7 +17,6 @@ import mage.constants.*; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; @@ -32,15 +31,18 @@ public final class SwordOfFeastAndFamine extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); this.subtype.add(SubType.EQUIPMENT); - // Equip {2} - this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); - // Equipped creature gets +2/+2 and has protection from black and from green. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ProtectionAbility.from(ObjectColor.GREEN, ObjectColor.BLACK), AttachmentType.EQUIPMENT))); + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2)); + ability.addEffect(new GainAbilityAttachedEffect( + ProtectionAbility.from(ObjectColor.BLACK, ObjectColor.GREEN), AttachmentType.EQUIPMENT + ).setText("and has protection from black and from green")); + this.addAbility(ability); // Whenever equipped creature deals combat damage to a player, that player discards a card and you untap all lands you control. this.addAbility(new SwordOfFeastAndFamineAbility()); + + // Equip {2} + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); } private SwordOfFeastAndFamine(final SwordOfFeastAndFamine card) { @@ -79,9 +81,7 @@ class SwordOfFeastAndFamineAbility extends TriggeredAbilityImpl { DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; Permanent p = game.getPermanent(event.getSourceId()); if (damageEvent.isCombatDamage() && p != null && p.getAttachments().contains(this.getSourceId())) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getPlayerId())); - } + this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId())); return true; } return false; @@ -89,6 +89,7 @@ class SwordOfFeastAndFamineAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever equipped creature deals combat damage to a player, that player discards a card and you untap all lands you control."; + return "Whenever equipped creature deals combat damage to a player, " + + "that player discards a card and you untap all lands you control."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/SwordOfFireAndIce.java b/Mage.Sets/src/mage/cards/s/SwordOfFireAndIce.java index dce0293fc3e..2f169cfbddd 100644 --- a/Mage.Sets/src/mage/cards/s/SwordOfFireAndIce.java +++ b/Mage.Sets/src/mage/cards/s/SwordOfFireAndIce.java @@ -1,8 +1,8 @@ package mage.cards.s; -import java.util.UUID; import mage.ObjectColor; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.DamageTargetEffect; @@ -15,16 +15,12 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AttachmentType; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; +import mage.constants.SubType; import mage.target.common.TargetAnyTarget; +import java.util.UUID; + /** * @author Loki */ @@ -35,12 +31,21 @@ public final class SwordOfFireAndIce extends CardImpl { this.subtype.add(SubType.EQUIPMENT); // Equipped creature gets +2/+2 and has protection from red and from blue. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect( - ProtectionAbility.from(ObjectColor.RED, ObjectColor.BLUE), AttachmentType.EQUIPMENT))); + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2)); + ability.addEffect(new GainAbilityAttachedEffect( + ProtectionAbility.from(ObjectColor.RED, ObjectColor.BLUE), AttachmentType.EQUIPMENT + ).setText("and has protection from red and from blue")); + this.addAbility(ability); + // Whenever equipped creature deals combat damage to a player, Sword of Fire // and Ice deals 2 damage to any target and you draw a card. - this.addAbility(new SwordOfFireAndIceAbility()); + ability = new DealsDamageToAPlayerAttachedTriggeredAbility( + new DamageTargetEffect(2), "equipped", false + ); + ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and")); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability); + // Equip {2} this.addAbility(new EquipAbility(Outcome.Benefit, new GenericManaCost(2))); } @@ -55,41 +60,3 @@ public final class SwordOfFireAndIce extends CardImpl { } } - -class SwordOfFireAndIceAbility extends TriggeredAbilityImpl { - - public SwordOfFireAndIceAbility() { - super(Zone.BATTLEFIELD, new DamageTargetEffect(2)); - this.addEffect(new DrawCardSourceControllerEffect(1)); - this.addTarget(new TargetAnyTarget()); - } - - public SwordOfFireAndIceAbility(final SwordOfFireAndIceAbility ability) { - super(ability); - } - - @Override - public SwordOfFireAndIceAbility copy() { - return new SwordOfFireAndIceAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - Permanent p = game.getPermanent(event.getSourceId()); - return damageEvent.isCombatDamage() - && p != null - && p.getAttachments().contains(this.getSourceId()); - } - - @Override - public String getRule() { - return "Whenever equipped creature deals combat damage to a player, " - + "{this} deals 2 damage to any target and you draw a card."; - } -} diff --git a/Mage.Sets/src/mage/cards/s/SwordOfHearthAndHome.java b/Mage.Sets/src/mage/cards/s/SwordOfHearthAndHome.java new file mode 100644 index 00000000000..f43d18eb7d5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SwordOfHearthAndHome.java @@ -0,0 +1,109 @@ +package mage.cards.s; + +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SwordOfHearthAndHome extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("creature you own"); + + static { + filter.add(TargetController.YOU.getOwnerPredicate()); + } + + public SwordOfHearthAndHome(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + this.subtype.add(SubType.EQUIPMENT); + + // Equipped creature gets +2/+2 and has protection from green and from white. + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2)); + ability.addEffect(new GainAbilityAttachedEffect( + ProtectionAbility.from(ObjectColor.GREEN, ObjectColor.WHITE), AttachmentType.EQUIPMENT + ).setText("and has protection from green and from white")); + this.addAbility(ability); + + // Whenever equipped creature deals combat damage to a player, exile up to one target creature you own, then search your library for a basic land card. Put both cards onto the battlefield under your control, then shuffle. + ability = new DealsDamageToAPlayerAttachedTriggeredAbility( + new SwordOfHearthAndHomeEffect(), "equipped", false + ); + ability.addTarget(new TargetPermanent(0, 1, filter)); + this.addAbility(ability); + + // Equip {2} + this.addAbility(new EquipAbility(Outcome.Benefit, new GenericManaCost(2))); + } + + private SwordOfHearthAndHome(final SwordOfHearthAndHome card) { + super(card); + } + + @Override + public SwordOfHearthAndHome copy() { + return new SwordOfHearthAndHome(this); + } +} + +class SwordOfHearthAndHomeEffect extends OneShotEffect { + + SwordOfHearthAndHomeEffect() { + super(Outcome.Benefit); + staticText = "exile up to one target creature you own, then search your library for a basic land card. " + + "Put both cards onto the battlefield under your control, then shuffle"; + } + + private SwordOfHearthAndHomeEffect(final SwordOfHearthAndHomeEffect effect) { + super(effect); + } + + @Override + public SwordOfHearthAndHomeEffect copy() { + return new SwordOfHearthAndHomeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cards cards = new CardsImpl(); + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent != null) { + player.moveCards(permanent, Zone.EXILED, source, game); + cards.add(permanent); + } + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); + player.searchLibrary(target, source, game); + cards.add(player.getLibrary().getCard(target.getFirstTarget(), game)); + player.moveCards(cards, Zone.BATTLEFIELD, source, game); + player.shuffleLibrary(source, game); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SwordOfLightAndShadow.java b/Mage.Sets/src/mage/cards/s/SwordOfLightAndShadow.java index 61a10a06634..9a27b5cd093 100644 --- a/Mage.Sets/src/mage/cards/s/SwordOfLightAndShadow.java +++ b/Mage.Sets/src/mage/cards/s/SwordOfLightAndShadow.java @@ -1,10 +1,8 @@ - package mage.cards.s; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; @@ -16,20 +14,14 @@ import mage.abilities.keyword.ProtectionAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; +import java.util.UUID; + /** * @author Loki */ @@ -40,12 +32,22 @@ public final class SwordOfLightAndShadow extends CardImpl { this.subtype.add(SubType.EQUIPMENT); // Equipped creature gets +2/+2 and has protection from white and from black. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ProtectionAbility.from(ObjectColor.WHITE, ObjectColor.BLACK), AttachmentType.EQUIPMENT))); - // Whenever equipped creature deals combat damage to a player, you gain 3 life and you may return up to one target creature card from your graveyard to your hand. - Ability ability = new SwordOfLightAndShadowAbility(); - ability.addTarget(new TargetCardInYourGraveyard(0, 1, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2)); + ability.addEffect(new GainAbilityAttachedEffect( + ProtectionAbility.from(ObjectColor.WHITE, ObjectColor.BLACK), AttachmentType.EQUIPMENT + ).setText("and has protection from white and from black")); this.addAbility(ability); + + // Whenever equipped creature deals combat damage to a player, you gain 3 life and you may return up to one target creature card from your graveyard to your hand. + ability = new DealsDamageToAPlayerAttachedTriggeredAbility( + new GainLifeEffect(3), "equipped", false + ); + ability.addEffect(new SwordOfLightAndShadowEffect()); + ability.addTarget(new TargetCardInYourGraveyard( + 0, 1, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD + )); + this.addAbility(ability); + // Equip {2} this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); } @@ -60,81 +62,28 @@ public final class SwordOfLightAndShadow extends CardImpl { } } -class SwordOfLightAndShadowAbility extends TriggeredAbilityImpl { +class SwordOfLightAndShadowEffect extends OneShotEffect { - public SwordOfLightAndShadowAbility() { - super(Zone.BATTLEFIELD, new GainLifeEffect(3), false); - this.addEffect(new SwordOfLightAndShadowReturnToHandTargetEffect()); - - } - - public SwordOfLightAndShadowAbility(final SwordOfLightAndShadowAbility ability) { - super(ability); - } - - @Override - public SwordOfLightAndShadowAbility copy() { - return new SwordOfLightAndShadowAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - Permanent p = game.getPermanent(event.getSourceId()); - return damageEvent.isCombatDamage() && p != null && p.getAttachments().contains(this.getSourceId()); - } - - @Override - public String getRule() { - return "Whenever equipped creature deals combat damage to a player, you gain 3 life and you may return up to one target creature card from your graveyard to your hand."; - } -} - -class SwordOfLightAndShadowReturnToHandTargetEffect extends OneShotEffect { - - public SwordOfLightAndShadowReturnToHandTargetEffect() { + public SwordOfLightAndShadowEffect() { super(Outcome.ReturnToHand); staticText = "and you may return up to one target creature card from your graveyard to your hand"; } - public SwordOfLightAndShadowReturnToHandTargetEffect(final SwordOfLightAndShadowReturnToHandTargetEffect effect) { + public SwordOfLightAndShadowEffect(final SwordOfLightAndShadowEffect effect) { super(effect); } @Override - public SwordOfLightAndShadowReturnToHandTargetEffect copy() { - return new SwordOfLightAndShadowReturnToHandTargetEffect(this); + public SwordOfLightAndShadowEffect copy() { + return new SwordOfLightAndShadowEffect(this); } @Override public boolean apply(Game game, Ability source) { - boolean result = true; // in case no target is selected Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - if (!source.getTargets().isEmpty() && targetPointer.getFirst(game, source) != null) { - if (controller.chooseUse(outcome, "Return creature card from graveyard to hand?", source, game)) { - for (UUID targetId : targetPointer.getTargets(game, source)) { - switch (game.getState().getZone(targetId)) { - case GRAVEYARD: - Card card = game.getCard(targetId); - if (card != null) { - controller.moveCards(card, Zone.HAND, source, game); - } else { - result = false; - } - break; - } - } - } - } - return result; + Card card = game.getCard(targetPointer.getFirst(game, source)); + return controller != null && card != null && controller.chooseUse( + outcome, "Return " + card.getName() + " from your graveyard to your hand?", source, game + ) && controller.moveCards(card, Zone.HAND, source, game); } - } diff --git a/Mage.Sets/src/mage/cards/s/SwordOfSinewAndSteel.java b/Mage.Sets/src/mage/cards/s/SwordOfSinewAndSteel.java index 0ca554787de..5fd5c2d1c4c 100644 --- a/Mage.Sets/src/mage/cards/s/SwordOfSinewAndSteel.java +++ b/Mage.Sets/src/mage/cards/s/SwordOfSinewAndSteel.java @@ -33,9 +33,9 @@ public final class SwordOfSinewAndSteel extends CardImpl { // Equipped creature gets +2/+2 and has protection from black and from red. Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2)); - ability.addEffect(new GainAbilityAttachedEffect(ProtectionAbility.from( - ObjectColor.BLACK, ObjectColor.RED - ), AttachmentType.EQUIPMENT).setText("and has protection from black and from red")); + ability.addEffect(new GainAbilityAttachedEffect( + ProtectionAbility.from(ObjectColor.BLACK, ObjectColor.RED), AttachmentType.EQUIPMENT + ).setText("and has protection from black and from red")); this.addAbility(ability); // Whenever equipped creature deals combat damage to a player, destroy up to one target planeswalker and up to one target artifact. diff --git a/Mage.Sets/src/mage/cards/s/SwordOfTruthAndJustice.java b/Mage.Sets/src/mage/cards/s/SwordOfTruthAndJustice.java index c8f902ef4c6..f4bc9dce2d4 100644 --- a/Mage.Sets/src/mage/cards/s/SwordOfTruthAndJustice.java +++ b/Mage.Sets/src/mage/cards/s/SwordOfTruthAndJustice.java @@ -38,9 +38,9 @@ public final class SwordOfTruthAndJustice extends CardImpl { // Equipped creature gets +2/+2 and has protection from white and from blue. Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2)); - ability.addEffect(new GainAbilityAttachedEffect(ProtectionAbility.from( - ObjectColor.WHITE, ObjectColor.BLUE - ), AttachmentType.EQUIPMENT).setText("and has protection from white and from blue")); + ability.addEffect(new GainAbilityAttachedEffect( + ProtectionAbility.from(ObjectColor.WHITE, ObjectColor.BLUE), AttachmentType.EQUIPMENT + ).setText("and has protection from white and from blue")); this.addAbility(ability); // Whenever equipped creature deals combat damage to a player, put a +1/+1 counter on a creature you control, then proliferate. diff --git a/Mage.Sets/src/mage/cards/s/SwordOfWarAndPeace.java b/Mage.Sets/src/mage/cards/s/SwordOfWarAndPeace.java index fbb56c2eca9..4998d591815 100644 --- a/Mage.Sets/src/mage/cards/s/SwordOfWarAndPeace.java +++ b/Mage.Sets/src/mage/cards/s/SwordOfWarAndPeace.java @@ -6,7 +6,6 @@ import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.dynamicvalue.common.CardsInControllerHandCount; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; @@ -19,7 +18,6 @@ import mage.constants.*; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.targetpointer.FixedTarget; @@ -36,10 +34,10 @@ public final class SwordOfWarAndPeace extends CardImpl { this.subtype.add(SubType.EQUIPMENT); // Equipped creature gets +2/+2 and has protection from red and from white. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2)); - Effect effect = new GainAbilityAttachedEffect(ProtectionAbility.from(ObjectColor.RED, ObjectColor.WHITE), AttachmentType.EQUIPMENT); - effect.setText("and has protection from red and from white"); - ability.addEffect(effect); + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2)); + ability.addEffect(new GainAbilityAttachedEffect( + ProtectionAbility.from(ObjectColor.RED, ObjectColor.WHITE), AttachmentType.EQUIPMENT + ).setText("and has protection from red and from white")); this.addAbility(ability); // Whenever equipped creature deals combat damage to a player, Sword of War and Peace deals damage to that player equal to the number of cards in their hand and you gain 1 life for each card in your hand. diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 849dde9ef44..20a8ccb530d 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -261,6 +261,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Svyelun of Sea and Sky", 69, Rarity.MYTHIC, mage.cards.s.SvyelunOfSeaAndSky.class)); cards.add(new SetCardInfo("Swamp", 485, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sweep the Skies", 70, Rarity.UNCOMMON, mage.cards.s.SweepTheSkies.class)); + cards.add(new SetCardInfo("Sword of Hearth and Home", 238, Rarity.MYTHIC, mage.cards.s.SwordOfHearthAndHome.class)); cards.add(new SetCardInfo("Sylvan Anthem", 176, Rarity.RARE, mage.cards.s.SylvanAnthem.class)); cards.add(new SetCardInfo("Sythis, Harvest's Hand", 214, Rarity.RARE, mage.cards.s.SythisHarvestsHand.class)); cards.add(new SetCardInfo("Tanglepool Bridge", 257, Rarity.COMMON, mage.cards.t.TanglepoolBridge.class)); From 4c5c4e4d3f044528953b011cad5f69ca3516d9bb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jun 2021 09:22:09 -0400 Subject: [PATCH 151/188] [MH2] Implemented Said // Done --- Mage.Sets/src/mage/cards/c/CallToMind.java | 12 ++--- Mage.Sets/src/mage/cards/s/SaidDone.java | 50 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 3 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/SaidDone.java diff --git a/Mage.Sets/src/mage/cards/c/CallToMind.java b/Mage.Sets/src/mage/cards/c/CallToMind.java index f253ed5412d..70f254a9447 100644 --- a/Mage.Sets/src/mage/cards/c/CallToMind.java +++ b/Mage.Sets/src/mage/cards/c/CallToMind.java @@ -1,27 +1,25 @@ - - package mage.cards.c; -import java.util.UUID; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.common.FilterInstantOrSorceryCard; +import mage.filter.StaticFilters; import mage.target.common.TargetCardInYourGraveyard; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public final class CallToMind extends CardImpl { public CallToMind(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); // Return target instant or sorcery card from your graveyard to your hand. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterInstantOrSorceryCard("instant or sorcery card from your graveyard"))); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD)); } private CallToMind(final CallToMind card) { diff --git a/Mage.Sets/src/mage/cards/s/SaidDone.java b/Mage.Sets/src/mage/cards/s/SaidDone.java new file mode 100644 index 00000000000..24cb3f31eb6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SaidDone.java @@ -0,0 +1,50 @@ +package mage.cards.s; + +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.cards.CardSetInfo; +import mage.cards.SplitCard; +import mage.constants.CardType; +import mage.constants.SpellAbilityType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInYourGraveyard; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SaidDone extends SplitCard { + + public SaidDone(UUID ownerId, CardSetInfo setInfo) { + super( + ownerId, setInfo, + new CardType[]{CardType.SORCERY}, new CardType[]{CardType.INSTANT}, + "{2}{U}", "{3}{U}", SpellAbilityType.SPLIT + ); + + // Said + // Return target instant or sorcery card from your graveyard to your hand. + this.getLeftHalfCard().getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getLeftHalfCard().getSpellAbility().addTarget(new TargetCardInYourGraveyard( + StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD + )); + + // Done + // Tap up to two target creatures. They don't untap during their controllers' next untap step. + this.getRightHalfCard().getSpellAbility().addEffect(new TapTargetEffect()); + this.getRightHalfCard().getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2)); + this.getRightHalfCard().getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect("They")); + } + + private SaidDone(final SaidDone card) { + super(card); + } + + @Override + public SaidDone copy() { + return new SaidDone(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 20a8ccb530d..bae914db46d 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -218,6 +218,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Rishadan Dockhand", 59, Rarity.RARE, mage.cards.r.RishadanDockhand.class)); cards.add(new SetCardInfo("Road // Ruin", 212, Rarity.UNCOMMON, mage.cards.r.RoadRuin.class)); cards.add(new SetCardInfo("Rustvale Bridge", 253, Rarity.COMMON, mage.cards.r.RustvaleBridge.class)); + cards.add(new SetCardInfo("Said // Done", 60, Rarity.UNCOMMON, mage.cards.s.SaidDone.class)); cards.add(new SetCardInfo("Sanctuary Raptor", 233, Rarity.UNCOMMON, mage.cards.s.SanctuaryRaptor.class)); cards.add(new SetCardInfo("Sanctum Prelate", 491, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class)); cards.add(new SetCardInfo("Sanctum Weaver", 171, Rarity.RARE, mage.cards.s.SanctumWeaver.class)); From 29e85cd4b94ecd3b26d721ba7ebaa35b19897064 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Fri, 4 Jun 2021 10:27:27 -0500 Subject: [PATCH 152/188] [MH2] Implemented Mine Collapse --- Mage.Sets/src/mage/cards/m/MineCollapse.java | 49 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 50 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MineCollapse.java diff --git a/Mage.Sets/src/mage/cards/m/MineCollapse.java b/Mage.Sets/src/mage/cards/m/MineCollapse.java new file mode 100644 index 00000000000..c389fdfd918 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MineCollapse.java @@ -0,0 +1,49 @@ +package mage.cards.m; + +import java.util.UUID; + +import mage.abilities.condition.common.MyTurnCondition; +import mage.abilities.costs.AlternativeCostSourceAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.hint.common.MyTurnHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.common.FilterControlledPermanent; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetCreatureOrPlaneswalker; + +/** + * + * @author weirddan455 + */ +public final class MineCollapse extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.MOUNTAIN, "a Mountain"); + + public MineCollapse(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}"); + + // If it's your turn, you may sacrifice a Mountain rather than pay this spell's mana cost. + this.addAbility(new AlternativeCostSourceAbility( + new SacrificeTargetCost(new TargetControlledPermanent(filter)), + MyTurnCondition.instance, + "If it's your turn, you may sacrifice a Mountain rather than pay this spell's mana cost." + ).addHint(MyTurnHint.instance)); + + // Mine Collapse deals 5 damage to target creature or planeswalker. + this.getSpellAbility().addEffect(new DamageTargetEffect(5)); + this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker()); + } + + private MineCollapse(final MineCollapse card) { + super(card); + } + + @Override + public MineCollapse copy() { + return new MineCollapse(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index bae914db46d..4f57f4f9e19 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -174,6 +174,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Master of Death", 205, Rarity.RARE, mage.cards.m.MasterOfDeath.class)); cards.add(new SetCardInfo("Mental Journey", 51, Rarity.COMMON, mage.cards.m.MentalJourney.class)); cards.add(new SetCardInfo("Millikin", 297, Rarity.UNCOMMON, mage.cards.m.Millikin.class)); + cards.add(new SetCardInfo("Mine Collapse", 135, Rarity.COMMON, mage.cards.m.MineCollapse.class)); cards.add(new SetCardInfo("Mirari's Wake", 291, Rarity.MYTHIC, mage.cards.m.MirarisWake.class)); cards.add(new SetCardInfo("Mishra's Factory", 302, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class)); cards.add(new SetCardInfo("Mistvault Bridge", 249, Rarity.COMMON, mage.cards.m.MistvaultBridge.class)); From 0d84a4a133e50b0dcd5990f78417496393e8e731 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Fri, 4 Jun 2021 18:51:26 -0500 Subject: [PATCH 153/188] [MH2] Fixed missing colors on suspend cards --- Mage.Sets/src/mage/cards/i/InevitableBetrayal.java | 2 ++ Mage.Sets/src/mage/cards/r/ResurgentBelief.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Mage.Sets/src/mage/cards/i/InevitableBetrayal.java b/Mage.Sets/src/mage/cards/i/InevitableBetrayal.java index fd07c43ce44..3afdd73ac37 100644 --- a/Mage.Sets/src/mage/cards/i/InevitableBetrayal.java +++ b/Mage.Sets/src/mage/cards/i/InevitableBetrayal.java @@ -26,6 +26,8 @@ public final class InevitableBetrayal extends CardImpl { public InevitableBetrayal(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, ""); + this.color.setBlue(true); + // Suspend 3—{1}{U}{U} this.addAbility(new SuspendAbility(3, new ManaCostsImpl<>("{1}{U}{U}"), this)); diff --git a/Mage.Sets/src/mage/cards/r/ResurgentBelief.java b/Mage.Sets/src/mage/cards/r/ResurgentBelief.java index ee8941fccb2..d553855a2b5 100644 --- a/Mage.Sets/src/mage/cards/r/ResurgentBelief.java +++ b/Mage.Sets/src/mage/cards/r/ResurgentBelief.java @@ -24,6 +24,8 @@ public final class ResurgentBelief extends CardImpl { public ResurgentBelief(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, ""); + this.color.setWhite(true); + // Suspend 2—{1}{W} this.addAbility(new SuspendAbility(2, new ManaCostsImpl<>("{1}{W}"), this)); From 4bf1ce9c0e4bb83bf4ba672431e61cc97ecde13d Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Fri, 4 Jun 2021 19:01:23 -0500 Subject: [PATCH 154/188] [MH2] Implemented Magus of the Bridge (#7886) --- .../src/mage/cards/m/MagusOfTheBridge.java | 99 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 100 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MagusOfTheBridge.java diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheBridge.java b/Mage.Sets/src/mage/cards/m/MagusOfTheBridge.java new file mode 100644 index 00000000000..d87ec7c5b97 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MagusOfTheBridge.java @@ -0,0 +1,99 @@ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.ExileSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.ZombieToken; +import mage.players.Player; + +/** + * + * @author weirddan455 + */ +public final class MagusOfTheBridge extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a nontoken creature"); + + static { + filter.add(Predicates.not(TokenPredicate.instance)); + } + + public MagusOfTheBridge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Whenever a nontoken creature is put into your graveyard from the battlefield, create a 2/2 black Zombie creature token. + this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility( + new CreateTokenEffect(new ZombieToken()), false, filter, false, true + )); + + // When a creature is put into an opponent's graveyard from the battlefield, exile Magus of the Bridge. + this.addAbility(new MagusOfTheBridgeTriggeredAbility()); + } + + private MagusOfTheBridge(final MagusOfTheBridge card) { + super(card); + } + + @Override + public MagusOfTheBridge copy() { + return new MagusOfTheBridge(this); + } +} + +class MagusOfTheBridgeTriggeredAbility extends TriggeredAbilityImpl { + + public MagusOfTheBridgeTriggeredAbility() { + super(Zone.BATTLEFIELD, new ExileSourceEffect()); + } + + private MagusOfTheBridgeTriggeredAbility(final MagusOfTheBridgeTriggeredAbility ability) { + super(ability); + } + + @Override + public MagusOfTheBridgeTriggeredAbility copy() { + return new MagusOfTheBridgeTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.isDiesEvent()) { + Permanent permanent = zEvent.getTarget(); + Player controller = game.getPlayer(getControllerId()); + return permanent != null && controller != null + && permanent.isCreature() && controller.hasOpponent(permanent.getOwnerId(), game); + } + return false; + } + + @Override + public String getRule() { + return "When a creature is put into an opponent's graveyard from the battlefield, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 4f57f4f9e19..15d49034e0b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -169,6 +169,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Lonis, Cryptozoologist", 204, Rarity.RARE, mage.cards.l.LonisCryptozoologist.class)); cards.add(new SetCardInfo("Lose Focus", 49, Rarity.COMMON, mage.cards.l.LoseFocus.class)); cards.add(new SetCardInfo("Lucid Dreams", 50, Rarity.UNCOMMON, mage.cards.l.LucidDreams.class)); + cards.add(new SetCardInfo("Magus of the Bridge", 92, Rarity.RARE, mage.cards.m.MagusOfTheBridge.class)); cards.add(new SetCardInfo("Marble Gargoyle", 21, Rarity.COMMON, mage.cards.m.MarbleGargoyle.class)); cards.add(new SetCardInfo("Marsh Flats", 248, Rarity.RARE, mage.cards.m.MarshFlats.class)); cards.add(new SetCardInfo("Master of Death", 205, Rarity.RARE, mage.cards.m.MasterOfDeath.class)); From 4a09b2a1ed96c2989c77686f6a1cfa7463f4cd36 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Fri, 4 Jun 2021 19:02:10 -0500 Subject: [PATCH 155/188] [MH2] Implemented Murktide Regent (#7887) --- .../src/mage/cards/m/MurktideRegent.java | 133 ++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 134 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MurktideRegent.java diff --git a/Mage.Sets/src/mage/cards/m/MurktideRegent.java b/Mage.Sets/src/mage/cards/m/MurktideRegent.java new file mode 100644 index 00000000000..b1bc5276390 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MurktideRegent.java @@ -0,0 +1,133 @@ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.Card; +import mage.cards.Cards; +import mage.constants.SubType; +import mage.abilities.keyword.DelveAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.util.CardUtil; + +/** + * + * @author weirddan455 + */ +public final class MurktideRegent extends CardImpl { + + public MurktideRegent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}"); + + this.subtype.add(SubType.DRAGON); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Delve + this.addAbility(new DelveAbility()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Murktide Regent enters the battlefield with a +1/+1 counter on it for each instant and sorcery card exiled with it. + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(), MurktideRegentValue.instance, false), + "with a +1/+1 counter on it for each instant and sorcery card exiled with it" + )); + + // Whenever an instant or sorcery card leaves your graveyard, put a +1/+1 counter on Murktide Regent. + this.addAbility(new MurktideRegentTriggeredAbility()); + } + + private MurktideRegent(final MurktideRegent card) { + super(card); + } + + @Override + public MurktideRegent copy() { + return new MurktideRegent(this); + } +} + +enum MurktideRegentValue implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + int amount = 0; + Cards delvedCards = (Cards) game.getState().getValue(CardUtil.getCardZoneString("delvedCards", sourceAbility.getSourceId(), game)); + if (delvedCards != null) { + for (UUID cardId : delvedCards) { + Card card = game.getCard(cardId); + if (card != null && card.isInstantOrSorcery()) { + amount++; + } + } + } + return amount; + } + + @Override + public MurktideRegentValue copy() { + return instance; + } + + @Override + public String toString() { + return "X"; + } + + @Override + public String getMessage() { + return "instant and sorcery card exiled with it"; + } +} + +class MurktideRegentTriggeredAbility extends TriggeredAbilityImpl { + + public MurktideRegentTriggeredAbility() { + super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance())); + } + + private MurktideRegentTriggeredAbility(final MurktideRegentTriggeredAbility ability) { + super(ability); + } + + @Override + public MurktideRegentTriggeredAbility copy() { + return new MurktideRegentTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() == Zone.GRAVEYARD) { + Card card = game.getCard(zEvent.getTargetId()); + return card != null && card.isInstantOrSorcery() && card.getOwnerId().equals(getControllerId()); + } + return false; + } + + @Override + public String getRule() { + return "Whenever an instant or sorcery card leaves your graveyard, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 15d49034e0b..41cc862d913 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -185,6 +185,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Monoskelion", 229, Rarity.UNCOMMON, mage.cards.m.Monoskelion.class)); cards.add(new SetCardInfo("Mount Velus Manticore", 136, Rarity.COMMON, mage.cards.m.MountVelusManticore.class)); cards.add(new SetCardInfo("Mountain", 487, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Murktide Regent", 52, Rarity.MYTHIC, mage.cards.m.MurktideRegent.class)); cards.add(new SetCardInfo("Myr Scrapling", 230, Rarity.COMMON, mage.cards.m.MyrScrapling.class)); cards.add(new SetCardInfo("Mystic Redaction", 53, Rarity.UNCOMMON, mage.cards.m.MysticRedaction.class)); cards.add(new SetCardInfo("Necrogoyf", 93, Rarity.RARE, mage.cards.n.Necrogoyf.class)); From 4fee736a1f833acfab4a0a7572ecf93cc0570e08 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jun 2021 21:05:36 -0400 Subject: [PATCH 156/188] [MH2] reworked Academy Manufactor to match ruling --- .../src/mage/cards/a/AcademyManufactor.java | 84 +++++++------------ .../replacement/AcademyManufactorTest.java | 24 ++++++ 2 files changed, 53 insertions(+), 55 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AcademyManufactor.java b/Mage.Sets/src/mage/cards/a/AcademyManufactor.java index e5ccd23d644..94d885eb6f6 100644 --- a/Mage.Sets/src/mage/cards/a/AcademyManufactor.java +++ b/Mage.Sets/src/mage/cards/a/AcademyManufactor.java @@ -1,17 +1,15 @@ package mage.cards.a; -import java.util.Map; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.game.events.CreateTokenEvent; import mage.game.events.GameEvent; @@ -20,8 +18,11 @@ import mage.game.permanent.token.FoodToken; import mage.game.permanent.token.Token; import mage.game.permanent.token.TreasureToken; +import java.util.Iterator; +import java.util.Map; +import java.util.UUID; + /** - * * @author weirddan455 */ public final class AcademyManufactor extends CardImpl { @@ -70,12 +71,14 @@ class AcademyManufactorEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (event instanceof CreateTokenEvent && event.getPlayerId().equals(source.getControllerId())) { - CreateTokenEvent tokenEvent = (CreateTokenEvent) event; - for (Token token : tokenEvent.getTokens().keySet()) { - if (token instanceof ClueArtifactToken || token instanceof FoodToken || token instanceof TreasureToken) { - return true; - } + if (!(event instanceof CreateTokenEvent) || !event.getPlayerId().equals(source.getControllerId())) { + return false; + } + for (Token token : ((CreateTokenEvent) event).getTokens().keySet()) { + if (token.hasSubtype(SubType.CLUE, game) + || token.hasSubtype(SubType.FOOD, game) + || token.hasSubtype(SubType.TREASURE, game)) { + return true; } } return false; @@ -83,51 +86,22 @@ class AcademyManufactorEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - if (event instanceof CreateTokenEvent) { - CreateTokenEvent tokenEvent = (CreateTokenEvent) event; - int clues = 0; - int food = 0; - int treasures = 0; - ClueArtifactToken clueToken = null; - FoodToken foodToken = null; - TreasureToken treasureToken = null; - Map tokens = tokenEvent.getTokens(); - - for (Map.Entry entry : tokens.entrySet()) { - Token token = entry.getKey(); - int amount = entry.getValue(); - if (token instanceof ClueArtifactToken) { - clueToken = (ClueArtifactToken) token; - clues += amount; - } - else if (token instanceof FoodToken) { - foodToken = (FoodToken) token; - food += amount; - } - else if (token instanceof TreasureToken) { - treasureToken = (TreasureToken) token; - treasures += amount; - } + int amount = 0; + Map tokens = ((CreateTokenEvent) event).getTokens(); + for (Iterator> iter = tokens.entrySet().iterator(); iter.hasNext(); ) { + Map.Entry entry = iter.next(); + Token token = entry.getKey(); + if (token.hasSubtype(SubType.CLUE, game) + || token.hasSubtype(SubType.FOOD, game) + || token.hasSubtype(SubType.TREASURE, game)) { + amount += entry.getValue(); + iter.remove(); } - - if (clueToken == null) { - clueToken = new ClueArtifactToken(); - } - if (foodToken == null) { - foodToken = new FoodToken(); - } - if (treasureToken == null) { - treasureToken = new TreasureToken(); - } - - int cluesToAdd = food + treasures; - int foodToAdd = clues + treasures; - int treasuresToAdd = clues + food; - - tokens.put(clueToken, tokens.getOrDefault(clueToken, 0) + cluesToAdd); - tokens.put(foodToken, tokens.getOrDefault(foodToken, 0) + foodToAdd); - tokens.put(treasureToken, tokens.getOrDefault(treasureToken, 0) + treasuresToAdd); } + + tokens.put(new ClueArtifactToken(), amount); + tokens.put(new FoodToken(), amount); + tokens.put(new TreasureToken(), amount); return false; } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/AcademyManufactorTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/AcademyManufactorTest.java index 068f70edab9..25af4cffbaa 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/AcademyManufactorTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/AcademyManufactorTest.java @@ -68,4 +68,28 @@ public class AcademyManufactorTest extends CardTestPlayerBase { // 8 permanents above + 500 token limit assertPermanentCount(playerA, 508); } + + @Test + public void testGingerbruteToken() { + addCard(Zone.BATTLEFIELD, playerA, "Academy Manufactor", 2); + addCard(Zone.BATTLEFIELD, playerA, "Tundra", 5); + addCard(Zone.HAND, playerA, "Fractured Identity"); + + addCard(Zone.BATTLEFIELD, playerB, "Gingerbrute"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fractured Identity", "Gingerbrute"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertAllCommandsUsed(); + assertPermanentCount(playerA, "Tundra", 5); + assertPermanentCount(playerA, "Academy Manufactor", 2); + // Gingerbrute token copy becomes a regular Food + assertPermanentCount(playerA, "Gingerbrute", 0); + assertPermanentCount(playerB, "Gingerbrute", 0); + assertPermanentCount(playerA, "Clue", 3); + assertPermanentCount(playerA, "Food", 3); + assertPermanentCount(playerA, "Treasure", 3); + } } From b5b4dec694007afab3242e68fa31b1db3ada599e Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Fri, 4 Jun 2021 20:08:01 -0500 Subject: [PATCH 157/188] [MH2] Implemented Nykthos Paragon (#7888) * [MH2] Implemented Nykthos Paragon * [MH2] Nykthos Paragon - Added check to checkTrigger --- .../src/mage/cards/n/NykthosParagon.java | 140 ++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 141 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/n/NykthosParagon.java diff --git a/Mage.Sets/src/mage/cards/n/NykthosParagon.java b/Mage.Sets/src/mage/cards/n/NykthosParagon.java new file mode 100644 index 00000000000..40ffbb9a8b0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NykthosParagon.java @@ -0,0 +1,140 @@ +package mage.cards.n; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author weirddan455 + */ +public final class NykthosParagon extends CardImpl { + + public NykthosParagon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{4}{W}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(4); + this.toughness = new MageInt(6); + + // Whenever you gain life, you may put that many +1/+1 counters on each creature you control. Do this only once each turn. + this.addAbility(new NykthosParagonTriggeredAbility()); + } + + private NykthosParagon(final NykthosParagon card) { + super(card); + } + + @Override + public NykthosParagon copy() { + return new NykthosParagon(this); + } +} + +class NykthosParagonTriggeredAbility extends TriggeredAbilityImpl { + + public NykthosParagonTriggeredAbility() { + super(Zone.BATTLEFIELD, new NykthosParagonEffect(), true); + } + + private NykthosParagonTriggeredAbility(final NykthosParagonTriggeredAbility ability) { + super(ability); + } + + @Override + public NykthosParagonTriggeredAbility copy() { + return new NykthosParagonTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.GAINED_LIFE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (abilityAvailableThisTurn(game) && event.getPlayerId().equals(this.getControllerId())) { + for (Effect effect : this.getEffects()) { + effect.setValue("gainedLife", event.getAmount()); + } + return true; + } + return false; + } + + @Override + public boolean resolve(Game game) { + if (abilityAvailableThisTurn(game) && super.resolve(game)) { + game.getState().setValue(CardUtil.getCardZoneString( + "lastTurnResolved" + originalId, sourceId, game + ), game.getTurnNum()); + return true; + } + return false; + } + + private boolean abilityAvailableThisTurn(Game game) { + Integer lastTurnResolved = (Integer) game.getState().getValue( + CardUtil.getCardZoneString("lastTurnResolved" + originalId, sourceId, game) + ); + return lastTurnResolved == null || lastTurnResolved != game.getTurnNum(); + } + + @Override + public String getRule() { + return "Whenever you gain life, you may put that many +1/+1 counters on each creature you control. Do this only once each turn."; + } +} + +class NykthosParagonEffect extends OneShotEffect { + + public NykthosParagonEffect() { + super(Outcome.BoostCreature); + } + + private NykthosParagonEffect(final NykthosParagonEffect effect) { + super(effect); + } + + @Override + public NykthosParagonEffect copy() { + return new NykthosParagonEffect(this); + } + + @Override + public boolean apply (Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + Integer life = (Integer) this.getValue("gainedLife"); + if (controller != null && sourceObject != null && life != null) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(source.getControllerId())) { + if (permanent != null && permanent.isCreature()) { + permanent.addCounters(CounterType.P1P1.createInstance(life), source.getControllerId(), source, game); + if (!game.isSimulation()) { + game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " puts " + life + + " +1/+1 counters on " + permanent.getLogName()); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 41cc862d913..310b9f95d48 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -193,6 +193,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Nested Shambler", 95, Rarity.COMMON, mage.cards.n.NestedShambler.class)); cards.add(new SetCardInfo("Nettlecyst", 231, Rarity.RARE, mage.cards.n.Nettlecyst.class)); cards.add(new SetCardInfo("Nevinyrral's Disk", 298, Rarity.RARE, mage.cards.n.NevinyrralsDisk.class)); + cards.add(new SetCardInfo("Nykthos Paragon", 22, Rarity.RARE, mage.cards.n.NykthosParagon.class)); cards.add(new SetCardInfo("Obsidian Charmaw", 137, Rarity.RARE, mage.cards.o.ObsidianCharmaw.class)); cards.add(new SetCardInfo("Orchard Strider", 169, Rarity.COMMON, mage.cards.o.OrchardStrider.class)); cards.add(new SetCardInfo("Ornithopter of Paradise", 232, Rarity.COMMON, mage.cards.o.OrnithopterOfParadise.class)); From 59678389df10885c46a5ec0b275a8ef542e1fbb3 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Sat, 5 Jun 2021 07:03:04 -0500 Subject: [PATCH 158/188] [MH2] Implemented Persist (#7889) --- .../src/mage/cards/g/GracefulRestoration.java | 51 +------- Mage.Sets/src/mage/cards/p/Persist.java | 43 +++++++ .../src/mage/cards/u/UnbreakableBond.java | 57 +-------- Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + ...dToBattlefieldWithCounterTargetEffect.java | 113 ++++++++++++++++++ 5 files changed, 161 insertions(+), 104 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/p/Persist.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardToBattlefieldWithCounterTargetEffect.java diff --git a/Mage.Sets/src/mage/cards/g/GracefulRestoration.java b/Mage.Sets/src/mage/cards/g/GracefulRestoration.java index 565b523f0e7..fed8e25db2f 100644 --- a/Mage.Sets/src/mage/cards/g/GracefulRestoration.java +++ b/Mage.Sets/src/mage/cards/g/GracefulRestoration.java @@ -2,25 +2,17 @@ package mage.cards.g; import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.Mode; -import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldWithCounterTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ComparisonType; -import mage.constants.Duration; -import mage.constants.Outcome; import mage.counters.CounterType; import mage.filter.StaticFilters; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.mageobject.PowerPredicate; -import mage.game.Game; -import mage.game.events.EntersTheBattlefieldEvent; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.target.common.TargetCardInYourGraveyard; /** @@ -40,9 +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 GracefulRestorationReplacementEffect()); - this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); - this.getSpellAbility().addEffect(new InfoEffect("with an additional +1/+1 counter on it")); + this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(CounterType.P1P1.createInstance(), true)); 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. @@ -60,40 +50,3 @@ public final class GracefulRestoration extends CardImpl { return new GracefulRestoration(this); } } - -class GracefulRestorationReplacementEffect extends ReplacementEffectImpl { - - public GracefulRestorationReplacementEffect() { - super(Duration.EndOfStep, Outcome.BoostCreature); - } - - private GracefulRestorationReplacementEffect(final GracefulRestorationReplacementEffect effect) { - super(effect); - } - - @Override - public GracefulRestorationReplacementEffect copy() { - return new GracefulRestorationReplacementEffect(this); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - return event.getTargetId().equals(getTargetPointer().getFirst(game, source)); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); - if (creature == null) { - return false; - } - creature.addCounters(CounterType.P1P1.createInstance(), source.getControllerId(), source, game, event.getAppliedEffects()); - discard(); - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/p/Persist.java b/Mage.Sets/src/mage/cards/p/Persist.java new file mode 100644 index 00000000000..87fd0feffcd --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/Persist.java @@ -0,0 +1,43 @@ +package mage.cards.p; + +import java.util.UUID; + +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldWithCounterTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SuperType; +import mage.counters.CounterType; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.Predicates; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author weirddan455 + */ +public final class Persist extends CardImpl { + + private static final FilterCreatureCard filter = new FilterCreatureCard("nonlegendary creature card from your graveyard"); + + static { + filter.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); + } + + public Persist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); + + // Return target nonlegendary creature card from your graveyard to the battlefield with a -1/-1 counter on it. + this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(CounterType.M1M1.createInstance())); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filter)); + } + + private Persist(final Persist card) { + super(card); + } + + @Override + public Persist copy() { + return new Persist(this); + } +} diff --git a/Mage.Sets/src/mage/cards/u/UnbreakableBond.java b/Mage.Sets/src/mage/cards/u/UnbreakableBond.java index e67158554cc..5c665708341 100644 --- a/Mage.Sets/src/mage/cards/u/UnbreakableBond.java +++ b/Mage.Sets/src/mage/cards/u/UnbreakableBond.java @@ -1,20 +1,11 @@ package mage.cards.u; -import mage.abilities.Ability; -import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.effects.common.InfoEffect; -import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldWithCounterTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; import mage.counters.CounterType; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.events.EntersTheBattlefieldEvent; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; @@ -28,9 +19,7 @@ public final class UnbreakableBond extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}"); // Return target creature card from your graveyard to the battlefield with a lifelink counter on it. - this.getSpellAbility().addEffect(new UnbreakableBondReplacementEffect()); - this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); - this.getSpellAbility().addEffect(new InfoEffect("with a lifelink counter on it")); + this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(CounterType.LIFELINK.createInstance())); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); } @@ -43,45 +32,3 @@ public final class UnbreakableBond extends CardImpl { return new UnbreakableBond(this); } } - -class UnbreakableBondReplacementEffect extends ReplacementEffectImpl { - - UnbreakableBondReplacementEffect() { - super(Duration.EndOfStep, Outcome.BoostCreature); - } - - private UnbreakableBondReplacementEffect(UnbreakableBondReplacementEffect effect) { - super(effect); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - return event.getTargetId().equals(getTargetPointer().getFirst(game, source)); - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); - if (creature == null) { - return false; - } - creature.addCounters(CounterType.LIFELINK.createInstance(), source.getControllerId(), source, game, event.getAppliedEffects()); - discard(); - return false; - } - - @Override - public UnbreakableBondReplacementEffect copy() { - return new UnbreakableBondReplacementEffect(this); - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 310b9f95d48..55e49898f9e 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -200,6 +200,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Parcel Myr", 54, Rarity.COMMON, mage.cards.p.ParcelMyr.class)); cards.add(new SetCardInfo("Patchwork Gnomes", 299, Rarity.COMMON, mage.cards.p.PatchworkGnomes.class)); cards.add(new SetCardInfo("Patriarch's Bidding", 275, Rarity.RARE, mage.cards.p.PatriarchsBidding.class)); + cards.add(new SetCardInfo("Persist", 96, Rarity.RARE, mage.cards.p.Persist.class)); cards.add(new SetCardInfo("Phantasmal Dreadmaw", 55, Rarity.COMMON, mage.cards.p.PhantasmalDreadmaw.class)); cards.add(new SetCardInfo("Piercing Rays", 24, Rarity.COMMON, mage.cards.p.PiercingRays.class)); cards.add(new SetCardInfo("Piru, the Volatile", 207, Rarity.RARE, mage.cards.p.PiruTheVolatile.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 new file mode 100644 index 00000000000..05afdc49e84 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardToBattlefieldWithCounterTargetEffect.java @@ -0,0 +1,113 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.counters.Counter; +import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +public class ReturnFromGraveyardToBattlefieldWithCounterTargetEffect extends ReturnFromGraveyardToBattlefieldTargetEffect { + + private final Counter counter; + private final boolean additional; + + public ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(Counter counter) { + this(counter, false); + } + + public ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(Counter counter, boolean additional) { + super(); + this.counter = counter; + this.additional = additional; + } + + private ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(final ReturnFromGraveyardToBattlefieldWithCounterTargetEffect effect) { + super(effect); + this.counter = effect.counter; + this.additional = effect.additional; + } + + @Override + public ReturnFromGraveyardToBattlefieldWithCounterTargetEffect copy() { + return new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + AddCounterReplacementEffect counterEffect = new AddCounterReplacementEffect(counter); + game.addEffect(counterEffect, source); + return super.apply(game, source); + } + + @Override + public String getText(Mode mode) { + StringBuilder sb = new StringBuilder(super.getText(mode)); + sb.append(" with "); + if (additional) { + if (counter.getCount() == 1) { + sb.append("an"); + } else { + sb.append(counter.getCount()); + } + sb.append(" additional"); + } else if (counter.getCount() == 1) { + sb.append("a"); + } else { + sb.append(counter.getCount()); + } + sb.append(' '); + sb.append(counter.getName()); + sb.append(" counter"); + if (counter.getCount() != 1) { + sb.append('s'); + } + sb.append(" on it"); + return sb.toString(); + } +} + +class AddCounterReplacementEffect extends ReplacementEffectImpl { + + private final Counter counter; + + public AddCounterReplacementEffect(Counter counter) { + super(Duration.EndOfStep, Outcome.BoostCreature); + this.counter = counter; + } + + private AddCounterReplacementEffect(final AddCounterReplacementEffect effect) { + super(effect); + this.counter = effect.counter; + } + + @Override + public AddCounterReplacementEffect copy() { + return new AddCounterReplacementEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return event.getTargetId().equals(getTargetPointer().getFirst(game, source)); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); + if (creature == null) { + return false; + } + creature.addCounters(counter.copy(), source.getControllerId(), source, game, event.getAppliedEffects()); + discard(); + return false; + } +} From 31220b17ca79c751f22a0b3ba8663a2bae945576 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 5 Jun 2021 08:12:08 -0400 Subject: [PATCH 159/188] [MH2] Implemented Power Depot --- Mage.Sets/src/mage/cards/p/PowerDepot.java | 80 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 81 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PowerDepot.java diff --git a/Mage.Sets/src/mage/cards/p/PowerDepot.java b/Mage.Sets/src/mage/cards/p/PowerDepot.java new file mode 100644 index 00000000000..2d379362e11 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PowerDepot.java @@ -0,0 +1,80 @@ +package mage.cards.p; + +import mage.ConditionalMana; +import mage.MageObject; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.keyword.ModularAbility; +import mage.abilities.mana.ColorlessManaAbility; +import mage.abilities.mana.ConditionalAnyColorManaAbility; +import mage.abilities.mana.builder.ConditionalManaBuilder; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.Game; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PowerDepot extends CardImpl { + + public PowerDepot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.LAND}, ""); + + // Power Depot enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // {T}: Add {C}. + this.addAbility(new ColorlessManaAbility()); + + // {T}: Add one mana of any color. Spend this mana only to cast artifact spells or activate abilities of artifacts. + this.addAbility(new ConditionalAnyColorManaAbility(1, new PowerDepotManaBuilder())); + + // Modular 1 + this.addAbility(new ModularAbility(this, 1)); + } + + private PowerDepot(final PowerDepot card) { + super(card); + } + + @Override + public PowerDepot copy() { + return new PowerDepot(this); + } +} + +class PowerDepotManaBuilder extends ConditionalManaBuilder { + + @Override + public ConditionalMana build(Object... options) { + return new PowerDepotConditionalMana(this.mana); + } + + @Override + public String getRule() { + return "Spend this mana only to cast artifact spells or activate abilities of artifacts"; + } +} + +class PowerDepotConditionalMana extends ConditionalMana { + + PowerDepotConditionalMana(Mana mana) { + super(mana); + this.addCondition(PowerDepotCondition.instance); + } +} + +enum PowerDepotCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + MageObject object = game.getObject(source.getSourceId()); + return object != null && object.isArtifact(); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 55e49898f9e..5839e4dfa8c 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -205,6 +205,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Piercing Rays", 24, Rarity.COMMON, mage.cards.p.PiercingRays.class)); cards.add(new SetCardInfo("Piru, the Volatile", 207, Rarity.RARE, mage.cards.p.PiruTheVolatile.class)); cards.add(new SetCardInfo("Plains", 481, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Power Depot", 251, Rarity.UNCOMMON, mage.cards.p.PowerDepot.class)); cards.add(new SetCardInfo("Priest of Fell Rites", 208, Rarity.RARE, mage.cards.p.PriestOfFellRites.class)); cards.add(new SetCardInfo("Prismatic Ending", 25, Rarity.UNCOMMON, mage.cards.p.PrismaticEnding.class)); cards.add(new SetCardInfo("Profane Tutor", 97, Rarity.RARE, mage.cards.p.ProfaneTutor.class)); From f41ff7177e02d10bce386c7828cc2a0af87dbc68 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 5 Jun 2021 08:29:03 -0400 Subject: [PATCH 160/188] [MH2] Implemented Steel Dromedary --- .../src/mage/cards/s/SteelDromedary.java | 98 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 99 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SteelDromedary.java diff --git a/Mage.Sets/src/mage/cards/s/SteelDromedary.java b/Mage.Sets/src/mage/cards/s/SteelDromedary.java new file mode 100644 index 00000000000..ec19ff467c9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SteelDromedary.java @@ -0,0 +1,98 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.SourceHasCounterCondition; +import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SteelDromedary extends CardImpl { + + private static final Condition condition = new SourceHasCounterCondition(CounterType.P1P1); + + public SteelDromedary(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); + + this.subtype.add(SubType.CAMEL); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Steel Dromedary enters the battlefield tapped with two +1/+1 counters on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect( + CounterType.P1P1.createInstance(2) + ), "with two +1/+1 counters on it")); + + // Steel Dromedary doesn't untap during your untap step if it has a +1/+1 counter on it. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousRuleModifyingEffect( + new DontUntapInControllersUntapStepSourceEffect(), condition + ).setText("{this} doesn't untap during your untap step if it has a +1/+1 counter on it"))); + + // At the beginning of combat on your turn, you may move a +1/+1 counter from Steel Dromedary onto target creature. + Ability ability = new BeginningOfCombatTriggeredAbility( + new SteelDromedaryEffect(), TargetController.YOU, true + ); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + private SteelDromedary(final SteelDromedary card) { + super(card); + } + + @Override + public SteelDromedary copy() { + return new SteelDromedary(this); + } +} + +class SteelDromedaryEffect extends OneShotEffect { + + SteelDromedaryEffect() { + super(Outcome.Benefit); + staticText = "move a +1/+1 counter from {this} onto target creature"; + } + + private SteelDromedaryEffect(final SteelDromedaryEffect effect) { + super(effect); + } + + @Override + public SteelDromedaryEffect copy() { + return new SteelDromedaryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + Permanent creature = game.getPermanent(source.getFirstTarget()); + if (permanent != null + && creature != null + && permanent.getCounters(game).getCount(CounterType.P1P1) > 0 + && creature.addCounters(CounterType.P1P1.createInstance(), source.getControllerId(), source, game)) { + permanent.removeCounters(CounterType.P1P1.createInstance(), source, game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 5839e4dfa8c..7aa159a9dec 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -258,6 +258,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Squirrel Mob", 286, Rarity.RARE, mage.cards.s.SquirrelMob.class)); cards.add(new SetCardInfo("Squirrel Sanctuary", 174, Rarity.UNCOMMON, mage.cards.s.SquirrelSanctuary.class)); cards.add(new SetCardInfo("Squirrel Sovereign", 175, Rarity.UNCOMMON, mage.cards.s.SquirrelSovereign.class)); + cards.add(new SetCardInfo("Steel Dromedary", 237, Rarity.UNCOMMON, mage.cards.s.SteelDromedary.class)); cards.add(new SetCardInfo("Steelfin Whale", 65, Rarity.COMMON, mage.cards.s.SteelfinWhale.class)); cards.add(new SetCardInfo("Step Through", 66, Rarity.COMMON, mage.cards.s.StepThrough.class)); cards.add(new SetCardInfo("Sterling Grove", 293, Rarity.RARE, mage.cards.s.SterlingGrove.class)); From ac04c27133f78949865c5ac8cbae54e9a415a61a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 5 Jun 2021 09:02:04 -0400 Subject: [PATCH 161/188] [MH2] Implemented Yavimaya, Cradle of Growth --- .../mage/cards/u/UrborgTombOfYawgmoth.java | 88 ++---------------- .../mage/cards/y/YavimayaCradleOfGrowth.java | 35 ++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../AddBasicLandTypeAllLandsEffect.java | 89 +++++++++++++++++++ 4 files changed, 130 insertions(+), 83 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/y/YavimayaCradleOfGrowth.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/continuous/AddBasicLandTypeAllLandsEffect.java diff --git a/Mage.Sets/src/mage/cards/u/UrborgTombOfYawgmoth.java b/Mage.Sets/src/mage/cards/u/UrborgTombOfYawgmoth.java index 61e5f9558d2..87e57628444 100644 --- a/Mage.Sets/src/mage/cards/u/UrborgTombOfYawgmoth.java +++ b/Mage.Sets/src/mage/cards/u/UrborgTombOfYawgmoth.java @@ -1,32 +1,14 @@ package mage.cards.u; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.Effect; -import mage.abilities.mana.BlackManaAbility; +import mage.abilities.effects.common.continuous.AddBasicLandTypeAllLandsEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.DependencyType; -import mage.constants.Duration; -import mage.constants.Layer; -import static mage.constants.Layer.TypeChangingEffects_4; -import mage.constants.Outcome; -import mage.constants.SubLayer; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.filter.common.FilterLandPermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.constants.*; + +import java.util.UUID; /** - * * @author Plopman */ public final class UrborgTombOfYawgmoth extends CardImpl { @@ -36,9 +18,7 @@ public final class UrborgTombOfYawgmoth extends CardImpl { addSuperType(SuperType.LEGENDARY); // Each land is a Swamp in addition to its other land types. - Ability ability = new SimpleStaticAbility(new UrborgTombOfYawgmothEffect()); - this.addAbility(ability); - + this.addAbility(new SimpleStaticAbility(new AddBasicLandTypeAllLandsEffect(SubType.SWAMP))); } private UrborgTombOfYawgmoth(final UrborgTombOfYawgmoth card) { @@ -49,62 +29,4 @@ public final class UrborgTombOfYawgmoth extends CardImpl { public UrborgTombOfYawgmoth copy() { return new UrborgTombOfYawgmoth(this); } - - class UrborgTombOfYawgmothEffect extends ContinuousEffectImpl { - - UrborgTombOfYawgmothEffect() { - super(Duration.WhileOnBattlefield, Outcome.AIDontUseIt); - this.staticText = "Each land is a Swamp in addition to its other land types"; - this.dependencyTypes.add(DependencyType.BecomeSwamp); - } - - UrborgTombOfYawgmothEffect(final UrborgTombOfYawgmothEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public UrborgTombOfYawgmothEffect copy() { - return new UrborgTombOfYawgmothEffect(this); - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - for (Permanent land : game.getBattlefield().getActivePermanents(new FilterLandPermanent(), source.getControllerId(), game)) { - switch (layer) { - case TypeChangingEffects_4: - // 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects - // So the ability removing has to be done before Layer 6 - // Lands have their mana ability intrinsically, so that is added in layer 4 - if (!land.hasSubtype(SubType.SWAMP, game)) { - land.addSubType(game, SubType.SWAMP); - } - if (!land.getAbilities().containsRule(new BlackManaAbility())) { - land.addAbility(new BlackManaAbility(), source.getSourceId(), game); - } - break; - } - } - return true; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.TypeChangingEffects_4; - } - - @Override - public Set isDependentTo(List allEffectsInLayer) { - // the dependent classes needs to be an enclosed class for dependent check of continuous effects - return allEffectsInLayer.stream() - .filter(effect -> mage.cards.b.BloodMoon.class.equals(effect.getClass().getEnclosingClass())) - .map(Effect::getId) - .collect(Collectors.toSet()); // Blood Moon affects non-basic land like Urborg - - } - } } diff --git a/Mage.Sets/src/mage/cards/y/YavimayaCradleOfGrowth.java b/Mage.Sets/src/mage/cards/y/YavimayaCradleOfGrowth.java new file mode 100644 index 00000000000..19966050032 --- /dev/null +++ b/Mage.Sets/src/mage/cards/y/YavimayaCradleOfGrowth.java @@ -0,0 +1,35 @@ +package mage.cards.y; + +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.AddBasicLandTypeAllLandsEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class YavimayaCradleOfGrowth extends CardImpl { + + public YavimayaCradleOfGrowth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.addSuperType(SuperType.LEGENDARY); + + // Each land is a Forest in addition to its other land types. + this.addAbility(new SimpleStaticAbility(new AddBasicLandTypeAllLandsEffect(SubType.FOREST))); + } + + private YavimayaCradleOfGrowth(final YavimayaCradleOfGrowth card) { + super(card); + } + + @Override + public YavimayaCradleOfGrowth copy() { + return new YavimayaCradleOfGrowth(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 7aa159a9dec..b84528f32d5 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -311,6 +311,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("World-Weary", 109, Rarity.COMMON, mage.cards.w.WorldWeary.class)); cards.add(new SetCardInfo("Wren's Run Hydra", 183, Rarity.UNCOMMON, mage.cards.w.WrensRunHydra.class)); cards.add(new SetCardInfo("Yavimaya Elder", 288, Rarity.UNCOMMON, mage.cards.y.YavimayaElder.class)); + cards.add(new SetCardInfo("Yavimaya, Cradle of Growth", 261, Rarity.RARE, mage.cards.y.YavimayaCradleOfGrowth.class)); cards.add(new SetCardInfo("Young Necromancer", 110, Rarity.UNCOMMON, mage.cards.y.YoungNecromancer.class)); cards.add(new SetCardInfo("Yusri, Fortune's Flame", 218, Rarity.RARE, mage.cards.y.YusriFortunesFlame.class)); cards.add(new SetCardInfo("Zuran Orb", 300, Rarity.UNCOMMON, mage.cards.z.ZuranOrb.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddBasicLandTypeAllLandsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddBasicLandTypeAllLandsEffect.java new file mode 100644 index 00000000000..49addb7b243 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddBasicLandTypeAllLandsEffect.java @@ -0,0 +1,89 @@ +package mage.abilities.effects.common.continuous; + +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.mana.*; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import org.junit.Assert; + +/** + * @author Plopman, TheElk801 + */ +public class AddBasicLandTypeAllLandsEffect extends ContinuousEffectImpl { + + private final SubType subType; + + public AddBasicLandTypeAllLandsEffect(SubType subType) { + super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.AIDontUseIt); + this.subType = subType; + this.staticText = "Each land is " + subType.getIndefiniteArticle() + " " + + subType.getDescription() + " in addition to its other land types"; + Assert.assertSame("Subtype should be a basic land type", subType.getSubTypeSet(), SubTypeSet.BasicLandType); + switch (subType) { + case PLAINS: + this.dependencyTypes.add(DependencyType.BecomePlains); + break; + case ISLAND: + this.dependencyTypes.add(DependencyType.BecomeIsland); + break; + case SWAMP: + this.dependencyTypes.add(DependencyType.BecomeSwamp); + break; + case MOUNTAIN: + this.dependencyTypes.add(DependencyType.BecomeMountain); + break; + case FOREST: + this.dependencyTypes.add(DependencyType.BecomeForest); + break; + } + } + + private AddBasicLandTypeAllLandsEffect(final AddBasicLandTypeAllLandsEffect effect) { + super(effect); + this.subType = effect.subType; + } + + @Override + public AddBasicLandTypeAllLandsEffect copy() { + return new AddBasicLandTypeAllLandsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Ability ability; + switch (subType) { + case PLAINS: + ability = new WhiteManaAbility(); + break; + case ISLAND: + ability = new BlueManaAbility(); + break; + case SWAMP: + ability = new BlackManaAbility(); + break; + case MOUNTAIN: + ability = new RedManaAbility(); + break; + case FOREST: + ability = new GreenManaAbility(); + break; + default: + ability = null; + } + for (Permanent land : game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_LAND, source.getControllerId(), game + )) { + // 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects + // So the ability removing has to be done before Layer 6 + // Lands have their mana ability intrinsically, so that is added in layer 4 + land.addSubType(game, subType); + if (ability != null && !land.getAbilities().containsRule(ability)) { + land.addAbility(ability, source.getSourceId(), game); + } + } + return true; + } +} From 3cd434e8148e24b2e5500be1419437bb62a262f4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 5 Jun 2021 09:09:09 -0400 Subject: [PATCH 162/188] [MH2] Implemented Tourach, Dread Cantor --- .../src/mage/cards/t/TourachDreadCantor.java | 67 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 68 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TourachDreadCantor.java diff --git a/Mage.Sets/src/mage/cards/t/TourachDreadCantor.java b/Mage.Sets/src/mage/cards/t/TourachDreadCantor.java new file mode 100644 index 00000000000..b35566390ab --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TourachDreadCantor.java @@ -0,0 +1,67 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.DiscardsACardOpponentTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.abilities.keyword.KickerAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.counters.CounterType; +import mage.target.common.TargetOpponent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TourachDreadCantor extends CardImpl { + + public TourachDreadCantor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Kicker {B}{B} + this.addAbility(new KickerAbility("{B}{B}")); + + // Protection from white + this.addAbility(ProtectionAbility.from(ObjectColor.WHITE)); + + // Whenever an opponent discards a card, put a +1/+1 counter on Tourach, Dread Cantor. + this.addAbility(new DiscardsACardOpponentTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false + )); + + // When Tourach enters the battelfield, if it was kicked, target opponent discards two cards at random. + Ability ability = new ConditionalInterveningIfTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new DiscardTargetEffect(2, true)), + KickedCondition.instance, "When {this} enters the battlefield, if it was kicked, " + + "target opponent discards two cards at random." + ); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + private TourachDreadCantor(final TourachDreadCantor card) { + super(card); + } + + @Override + public TourachDreadCantor copy() { + return new TourachDreadCantor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index b84528f32d5..afd4e12d608 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -289,6 +289,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Titania, Protector of Argoth", 287, Rarity.MYTHIC, mage.cards.t.TitaniaProtectorOfArgoth.class)); cards.add(new SetCardInfo("Tormod's Cryptkeeper", 239, Rarity.COMMON, mage.cards.t.TormodsCryptkeeper.class)); cards.add(new SetCardInfo("Tourach's Canticle", 103, Rarity.COMMON, mage.cards.t.TourachsCanticle.class)); + cards.add(new SetCardInfo("Tourach, Dread Cantor", 102, Rarity.MYTHIC, mage.cards.t.TourachDreadCantor.class)); cards.add(new SetCardInfo("Tragic Fall", 104, Rarity.COMMON, mage.cards.t.TragicFall.class)); cards.add(new SetCardInfo("Unbounded Potential", 36, Rarity.COMMON, mage.cards.u.UnboundedPotential.class)); cards.add(new SetCardInfo("Underworld Hermit", 105, Rarity.UNCOMMON, mage.cards.u.UnderworldHermit.class)); From ffd681a0ecd589db8053f4ac1343cc3411a157f4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 5 Jun 2021 11:58:07 -0400 Subject: [PATCH 163/188] [MH2] Implemented Dauthi Voidwalker --- .../src/mage/cards/d/DauthiVoidwalker.java | 148 ++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../main/java/mage/counters/CounterType.java | 1 + 3 files changed, 150 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DauthiVoidwalker.java diff --git a/Mage.Sets/src/mage/cards/d/DauthiVoidwalker.java b/Mage.Sets/src/mage/cards/d/DauthiVoidwalker.java new file mode 100644 index 00000000000..22e5531ab44 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DauthiVoidwalker.java @@ -0,0 +1,148 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; +import mage.abilities.keyword.ShadowAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.players.Player; +import mage.target.common.TargetCardInExile; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DauthiVoidwalker extends CardImpl { + + public DauthiVoidwalker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}"); + + this.subtype.add(SubType.DAUTHI); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Shadow + this.addAbility(ShadowAbility.getInstance()); + + // If a card would be put into an opponent's graveyard from anywhere, instead exile it with a void counter on it. + this.addAbility(new SimpleStaticAbility(new DauthiVoidwalkerReplacementEffect())); + + // {T}, Sacrifice Dauthi Voidwalker: Choose an exiled card an opponent owns with a void counter on it. You may play it this turn without paying its mana cost. + Ability ability = new SimpleActivatedAbility(new DauthiVoidwalkerPlayEffect(), new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); + } + + private DauthiVoidwalker(final DauthiVoidwalker card) { + super(card); + } + + @Override + public DauthiVoidwalker copy() { + return new DauthiVoidwalker(this); + } +} + +class DauthiVoidwalkerReplacementEffect extends ReplacementEffectImpl { + + DauthiVoidwalkerReplacementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Exile); + staticText = "if a card would be put into an opponent's graveyard from anywhere, " + + "instead exile it with a void counter on it"; + } + + private DauthiVoidwalkerReplacementEffect(final DauthiVoidwalkerReplacementEffect effect) { + super(effect); + } + + @Override + public DauthiVoidwalkerReplacementEffect copy() { + return new DauthiVoidwalkerReplacementEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player player = game.getPlayer(source.getControllerId()); + Card card = game.getCard(event.getTargetId()); + if (player == null || card == null) { + return false; + } + player.moveCards(card, Zone.EXILED, source, game); + card.addCounters(CounterType.VOID.createInstance(), source.getControllerId(), source, game); + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return ((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD + && game.getOpponents(source.getControllerId()).contains(game.getOwnerId(event.getTargetId())); + } +} + +class DauthiVoidwalkerPlayEffect extends OneShotEffect { + + private static final FilterCard filter + = new FilterCard("exiled card an opponent owns with a void counter on it"); + + static { + filter.add(CounterType.VOID.getPredicate()); + filter.add(TargetController.OPPONENT.getOwnerPredicate()); + } + + DauthiVoidwalkerPlayEffect() { + super(Outcome.Benefit); + staticText = "choose an exiled card an opponent owns with a void counter on it. " + + "You may play it this turn without paying its mana cost"; + } + + private DauthiVoidwalkerPlayEffect(final DauthiVoidwalkerPlayEffect effect) { + super(effect); + } + + @Override + public DauthiVoidwalkerPlayEffect copy() { + return new DauthiVoidwalkerPlayEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + TargetCardInExile target = new TargetCardInExile( + 0, 1, filter, null, true + ); + player.choose(outcome, target, source.getSourceId(), game); + Card card = game.getCard(target.getFirstTarget()); + if (card == null) { + return false; + } + game.addEffect(new PlayFromNotOwnHandZoneTargetEffect( + Zone.EXILED, TargetController.YOU, Duration.EndOfTurn, true, false + ).setTargetPointer(new FixedTarget(card, game)), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index afd4e12d608..db7573d0d35 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -81,6 +81,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Cursed Totem", 295, Rarity.RARE, mage.cards.c.CursedTotem.class)); cards.add(new SetCardInfo("Dakkon, Shadow Slayer", 192, Rarity.MYTHIC, mage.cards.d.DakkonShadowSlayer.class)); cards.add(new SetCardInfo("Darkmoss Bridge", 245, Rarity.COMMON, mage.cards.d.DarkmossBridge.class)); + cards.add(new SetCardInfo("Dauthi Voidwalker", 81, Rarity.RARE, mage.cards.d.DauthiVoidwalker.class)); cards.add(new SetCardInfo("Deepwood Denizen", 155, Rarity.COMMON, mage.cards.d.DeepwoodDenizen.class)); cards.add(new SetCardInfo("Diamond Lion", 225, Rarity.RARE, mage.cards.d.DiamondLion.class)); cards.add(new SetCardInfo("Dihada's Ploy", 193, Rarity.COMMON, mage.cards.d.DihadasPloy.class)); diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index f84c7895b75..3ae3ff8377a 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -168,6 +168,7 @@ public enum CounterType { VERSE("verse"), VIGILANCE("vigilance"), VITALITY("vitality"), + VOID("void"), VORTEX("vortex"), VOW("vow"), VOYAGE("voyage"), From 395faf811537e41f4330dd131e2082dfdb5edea5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 5 Jun 2021 12:57:31 -0400 Subject: [PATCH 164/188] [MH2] Implemented Ragavan, Nimble Pilferer --- .../mage/cards/r/RagavanNimblePilferer.java | 86 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 87 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RagavanNimblePilferer.java diff --git a/Mage.Sets/src/mage/cards/r/RagavanNimblePilferer.java b/Mage.Sets/src/mage/cards/r/RagavanNimblePilferer.java new file mode 100644 index 00000000000..a1e75b1cfdb --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RagavanNimblePilferer.java @@ -0,0 +1,86 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; +import mage.abilities.keyword.DashAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.token.TreasureToken; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RagavanNimblePilferer extends CardImpl { + + public RagavanNimblePilferer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.MONKEY); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Whenever Ragavan, Nimble Pilferer deals combat damage to a player, create a Treasure token and exile the top card of that player's library. Until end of turn, you may cast that card. + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility( + new CreateTokenEffect(new TreasureToken()), false, true + ); + ability.addEffect(new RagavanNimblePilfererEffect()); + this.addAbility(ability); + + // Dash {1}{R} + this.addAbility(new DashAbility(this, "{1}{R}")); + } + + private RagavanNimblePilferer(final RagavanNimblePilferer card) { + super(card); + } + + @Override + public RagavanNimblePilferer copy() { + return new RagavanNimblePilferer(this); + } +} + +class RagavanNimblePilfererEffect extends OneShotEffect { + + RagavanNimblePilfererEffect() { + super(Outcome.Benefit); + staticText = "and exile the top card of that player's library. Until end of turn, you may cast that card"; + } + + private RagavanNimblePilfererEffect(final RagavanNimblePilfererEffect effect) { + super(effect); + } + + @Override + public RagavanNimblePilfererEffect copy() { + return new RagavanNimblePilfererEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (controller == null || player == null) { + return false; + } + Card card = player.getLibrary().getFromTop(game); + if (card == null) { + return false; + } + return PlayFromNotOwnHandZoneTargetEffect.exileAndPlayFromExile( + game, source, card, TargetController.YOU, Duration.EndOfTurn, false, true + ); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index db7573d0d35..49566776061 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -213,6 +213,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Prophetic Titan", 209, Rarity.UNCOMMON, mage.cards.p.PropheticTitan.class)); cards.add(new SetCardInfo("Quirion Ranger", 285, Rarity.UNCOMMON, mage.cards.q.QuirionRanger.class)); cards.add(new SetCardInfo("Radiant Epicure", 98, Rarity.UNCOMMON, mage.cards.r.RadiantEpicure.class)); + cards.add(new SetCardInfo("Ragavan, Nimble Pilferer", 138, Rarity.MYTHIC, mage.cards.r.RagavanNimblePilferer.class)); cards.add(new SetCardInfo("Rakdos Headliner", 210, Rarity.UNCOMMON, mage.cards.r.RakdosHeadliner.class)); cards.add(new SetCardInfo("Ravenous Squirrel", 211, Rarity.UNCOMMON, mage.cards.r.RavenousSquirrel.class)); cards.add(new SetCardInfo("Raving Visionary", 56, Rarity.UNCOMMON, mage.cards.r.RavingVisionary.class)); From 0bbc904de0802b7628a06610a318cc545822224e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 6 Jun 2021 11:18:43 -0400 Subject: [PATCH 165/188] changed subtype assertion implementation (fixes #7892) --- .../common/continuous/AddBasicLandTypeAllLandsEffect.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddBasicLandTypeAllLandsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddBasicLandTypeAllLandsEffect.java index 49addb7b243..fb92836067d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddBasicLandTypeAllLandsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddBasicLandTypeAllLandsEffect.java @@ -7,7 +7,6 @@ import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; -import org.junit.Assert; /** * @author Plopman, TheElk801 @@ -21,7 +20,6 @@ public class AddBasicLandTypeAllLandsEffect extends ContinuousEffectImpl { this.subType = subType; this.staticText = "Each land is " + subType.getIndefiniteArticle() + " " + subType.getDescription() + " in addition to its other land types"; - Assert.assertSame("Subtype should be a basic land type", subType.getSubTypeSet(), SubTypeSet.BasicLandType); switch (subType) { case PLAINS: this.dependencyTypes.add(DependencyType.BecomePlains); @@ -38,6 +36,8 @@ public class AddBasicLandTypeAllLandsEffect extends ContinuousEffectImpl { case FOREST: this.dependencyTypes.add(DependencyType.BecomeForest); break; + default: + throw new UnsupportedOperationException("Subtype should be a basic land type"); } } From 917b63cc00e77aefa82f873a7f2c0a1ec2c05c79 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 6 Jun 2021 11:35:04 -0400 Subject: [PATCH 166/188] [MH2] fixed Urza's Saga not being able to select cards in library (fixes #7894) --- Mage.Sets/src/mage/cards/u/UrzasSaga.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/u/UrzasSaga.java b/Mage.Sets/src/mage/cards/u/UrzasSaga.java index 983c62a1aa7..473d00d0727 100644 --- a/Mage.Sets/src/mage/cards/u/UrzasSaga.java +++ b/Mage.Sets/src/mage/cards/u/UrzasSaga.java @@ -93,6 +93,6 @@ enum UrzasSagaPredicate implements Predicate { @Override public boolean apply(Card input, Game game) { - return costs.contains(input.getManaCostSymbols().stream().reduce(String::join)); + return costs.contains(String.join("", input.getManaCostSymbols())); } } From 69235e4721fc6feb1f9b482653010eda76e4ea74 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 6 Jun 2021 11:52:47 -0400 Subject: [PATCH 167/188] [MH2] Implemented Serra's Emissary --- .../src/mage/cards/s/SerrasEmissary.java | 90 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 91 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SerrasEmissary.java diff --git a/Mage.Sets/src/mage/cards/s/SerrasEmissary.java b/Mage.Sets/src/mage/cards/s/SerrasEmissary.java new file mode 100644 index 00000000000..77ae01d933d --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SerrasEmissary.java @@ -0,0 +1,90 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.ChooseCardTypeEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SerrasEmissary extends CardImpl { + + public SerrasEmissary(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}{W}"); + + this.subtype.add(SubType.ANGEL); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // As Serra's Emissary enters the battlefield, choose a card type. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCardTypeEffect(Outcome.Benefit))); + + // You and creatures you control have protection from the chosen card type. + this.addAbility(new SimpleStaticAbility(new SerrasEmissaryEffect())); + } + + private SerrasEmissary(final SerrasEmissary card) { + super(card); + } + + @Override + public SerrasEmissary copy() { + return new SerrasEmissary(this); + } +} + +class SerrasEmissaryEffect extends ContinuousEffectImpl { + + SerrasEmissaryEffect() { + super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); + staticText = "you and creatures you control have protection from the chosen card type"; + } + + private SerrasEmissaryEffect(final SerrasEmissaryEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Object savedType = game.getState().getValue(source.getSourceId() + "_type"); + if (controller == null || !(savedType instanceof CardType)) { + return false; + } + CardType cardType = ((CardType) savedType); + FilterCard filter = new FilterCard(cardType + "s"); + filter.add(cardType.getPredicate()); + Ability ability = new ProtectionAbility(filter); + controller.addAbility(ability); + for (Permanent permanent : game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_CONTROLLED_CREATURE, + source.getControllerId(), source.getSourceId(), game + )) { + permanent.addAbility(ability, source.getSourceId(), game); + } + return true; + } + + @Override + public SerrasEmissaryEffect copy() { + return new SerrasEmissaryEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 49566776061..70ebdbed2e8 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -239,6 +239,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Seal of Cleansing", 264, Rarity.UNCOMMON, mage.cards.s.SealOfCleansing.class)); cards.add(new SetCardInfo("Seal of Removal", 269, Rarity.UNCOMMON, mage.cards.s.SealOfRemoval.class)); cards.add(new SetCardInfo("Search the Premises", 29, Rarity.RARE, mage.cards.s.SearchThePremises.class)); + cards.add(new SetCardInfo("Serra's Emissary", 30, Rarity.MYTHIC, mage.cards.s.SerrasEmissary.class)); cards.add(new SetCardInfo("Shardless Agent", 292, Rarity.RARE, mage.cards.s.ShardlessAgent.class)); cards.add(new SetCardInfo("Shattered Ego", 62, Rarity.COMMON, mage.cards.s.ShatteredEgo.class)); cards.add(new SetCardInfo("Silverbluff Bridge", 255, Rarity.COMMON, mage.cards.s.SilverbluffBridge.class)); From 7057d1eb5ffed335aef7dd4231dffc9f3a289aa5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 6 Jun 2021 12:03:14 -0400 Subject: [PATCH 168/188] [MH2] Implemented Rise and Shine --- Mage.Sets/src/mage/cards/r/RiseAndShine.java | 102 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 103 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RiseAndShine.java diff --git a/Mage.Sets/src/mage/cards/r/RiseAndShine.java b/Mage.Sets/src/mage/cards/r/RiseAndShine.java new file mode 100644 index 00000000000..dddb5f8df10 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RiseAndShine.java @@ -0,0 +1,102 @@ +package mage.cards.r; + +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect; +import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.OverloadAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledArtifactPermanent; +import mage.filter.predicate.Predicates; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.targetpointer.FixedTargets; + +import java.util.List; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RiseAndShine extends CardImpl { + + static final FilterPermanent filter + = new FilterControlledArtifactPermanent("noncreature artifact you control"); + + static { + filter.add(Predicates.not(CardType.CREATURE.getPredicate())); + } + + public RiseAndShine(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}"); + + // Target noncreature artifact you control becomes a 0/0 artifact creature. Put four +1/+1 counters on each artifact that became a creature this way. + this.getSpellAbility().addEffect(new AddCardTypeTargetEffect( + Duration.EndOfGame, CardType.ARTIFACT, CardType.CREATURE + ).setText("Target noncreature artifact you control becomes")); + this.getSpellAbility().addEffect(new SetPowerToughnessTargetEffect( + 0, 0, Duration.EndOfGame + ).setText("a 0/0 artifact creature")); + this.getSpellAbility().addEffect(new AddCountersTargetEffect( + CounterType.P1P1.createInstance(4) + ).setText("Put four +1/+1 counters on each artifact that became a creature this way")); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + + // Overload {4}{U}{U} + this.addAbility(new OverloadAbility(this, new RiseAndShineEffect(), new ManaCostsImpl<>("{4}{U}{U}"))); + } + + private RiseAndShine(final RiseAndShine card) { + super(card); + } + + @Override + public RiseAndShine copy() { + return new RiseAndShine(this); + } +} + +class RiseAndShineEffect extends OneShotEffect { + + RiseAndShineEffect() { + super(Outcome.Benefit); + } + + private RiseAndShineEffect(final RiseAndShineEffect effect) { + super(effect); + } + + @Override + public RiseAndShineEffect copy() { + return new RiseAndShineEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + List permanents = game.getBattlefield().getActivePermanents( + RiseAndShine.filter, source.getControllerId(), source.getSourceId(), game + ); + if (permanents.isEmpty()) { + return false; + } + game.addEffect(new AddCardTypeTargetEffect( + Duration.EndOfGame, CardType.ARTIFACT, CardType.CREATURE + ).setTargetPointer(new FixedTargets(permanents, game)), source); + game.addEffect(new SetPowerToughnessTargetEffect( + 0, 0, Duration.EndOfGame + ).setTargetPointer(new FixedTargets(permanents, game)), source); + for (Permanent permanent : permanents) { + permanent.addCounters(CounterType.P1P1.createInstance(4), source.getControllerId(), source, game); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 70ebdbed2e8..876bccd514e 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -223,6 +223,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Revolutionist", 139, Rarity.COMMON, mage.cards.r.Revolutionist.class)); cards.add(new SetCardInfo("Rift Sower", 170, Rarity.COMMON, mage.cards.r.RiftSower.class)); cards.add(new SetCardInfo("Riptide Laboratory", 303, Rarity.RARE, mage.cards.r.RiptideLaboratory.class)); + cards.add(new SetCardInfo("Rise and Shine", 58, Rarity.RARE, mage.cards.r.RiseAndShine.class)); cards.add(new SetCardInfo("Rishadan Dockhand", 59, Rarity.RARE, mage.cards.r.RishadanDockhand.class)); cards.add(new SetCardInfo("Road // Ruin", 212, Rarity.UNCOMMON, mage.cards.r.RoadRuin.class)); cards.add(new SetCardInfo("Rustvale Bridge", 253, Rarity.COMMON, mage.cards.r.RustvaleBridge.class)); From 2a4419b7b112d56ddc675d0358dcc0d6b50e9d54 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 6 Jun 2021 16:53:50 -0400 Subject: [PATCH 169/188] [MH2] Implemented Skyblade's Boon --- Mage.Sets/src/mage/cards/s/SkybladesBoon.java | 79 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 80 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SkybladesBoon.java diff --git a/Mage.Sets/src/mage/cards/s/SkybladesBoon.java b/Mage.Sets/src/mage/cards/s/SkybladesBoon.java new file mode 100644 index 00000000000..d356f4620a5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SkybladesBoon.java @@ -0,0 +1,79 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SkybladesBoon extends CardImpl { + + public SkybladesBoon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets +1/+1 and has flying. + ability = new SimpleStaticAbility(new BoostEnchantedEffect(1, 1)); + ability.addEffect(new GainAbilityAttachedEffect( + FlyingAbility.getInstance(), AttachmentType.AURA + ).setText("and has flying")); + this.addAbility(ability); + + // {2}{W}: Return Skyblade's Boon to its owner's hand. Activate only if Skyblade's Boon is on the battlefield or in your graveyard. + this.addAbility(new ActivateIfConditionActivatedAbility( + Zone.ALL, new ReturnToHandSourceEffect(), + new ManaCostsImpl<>("{2}{W}"), SkybladesBoonCondition.instance + )); + } + + private SkybladesBoon(final SkybladesBoon card) { + super(card); + } + + @Override + public SkybladesBoon copy() { + return new SkybladesBoon(this); + } +} + +enum SkybladesBoonCondition implements Condition { + instance; + private static final List zones = Arrays.asList(Zone.BATTLEFIELD, Zone.GRAVEYARD); + + @Override + public boolean apply(Game game, Ability source) { + return zones.contains(game.getState().getZone(source.getSourceId())); + } + + @Override + public String toString() { + return "{this} is on the battlefield or in your graveyard"; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 876bccd514e..8f9bb2f6c7b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -247,6 +247,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Sinister Starfish", 99, Rarity.COMMON, mage.cards.s.SinisterStarfish.class)); cards.add(new SetCardInfo("Skirge Familiar", 276, Rarity.UNCOMMON, mage.cards.s.SkirgeFamiliar.class)); cards.add(new SetCardInfo("Skophos Reaver", 140, Rarity.COMMON, mage.cards.s.SkophosReaver.class)); + cards.add(new SetCardInfo("Skyblade's Boon", 31, Rarity.UNCOMMON, mage.cards.s.SkybladesBoon.class)); cards.add(new SetCardInfo("Slag Strider", 141, Rarity.UNCOMMON, mage.cards.s.SlagStrider.class)); cards.add(new SetCardInfo("Slagwoods Bridge", 256, Rarity.COMMON, mage.cards.s.SlagwoodsBridge.class)); cards.add(new SetCardInfo("Smell Fear", 173, Rarity.COMMON, mage.cards.s.SmellFear.class)); From 9a3daa683f5fce293e4f35448cacc478857dbffc Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 6 Jun 2021 17:08:25 -0400 Subject: [PATCH 170/188] [MH2] Implemented Tizerus Charger --- .../src/mage/cards/t/TizerusCharger.java | 97 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 98 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TizerusCharger.java diff --git a/Mage.Sets/src/mage/cards/t/TizerusCharger.java b/Mage.Sets/src/mage/cards/t/TizerusCharger.java new file mode 100644 index 00000000000..856ca85927f --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TizerusCharger.java @@ -0,0 +1,97 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.EscapeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityType; +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.players.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TizerusCharger extends CardImpl { + + public TizerusCharger(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.PEGASUS); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Escape—{4}{B}, Exile five other cards from your graveyard. + this.addAbility(new EscapeAbility(this, "{4}{B}", 5)); + + // Tizerus Charger escapes with your choice of a +1/+1 counter or a flying counter on it. + this.addAbility(new EntersBattlefieldAbility( + new TizerusChargerEffect(), null, "{this} escapes " + + "with your choice of a +1/+1 counter or a flying counter on it", "" + )); + } + + private TizerusCharger(final TizerusCharger card) { + super(card); + } + + @Override + public TizerusCharger copy() { + return new TizerusCharger(this); + } +} + +class TizerusChargerEffect extends OneShotEffect { + + TizerusChargerEffect() { + super(Outcome.Benefit); + } + + private TizerusChargerEffect(final TizerusChargerEffect effect) { + super(effect); + } + + @Override + public TizerusChargerEffect copy() { + return new TizerusChargerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null && source.getAbilityType() == AbilityType.STATIC) { + permanent = game.getPermanentEntering(source.getSourceId()); + } + Player player = game.getPlayer(source.getControllerId()); + if (permanent == null || player == null) { + return false; + } + SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); + if (!(spellAbility instanceof EscapeAbility) + || !spellAbility.getSourceId().equals(source.getSourceId()) + || permanent.getZoneChangeCounter(game) != spellAbility.getSourceObjectZoneChangeCounter() + || !spellAbility.getSourceId().equals(source.getSourceId())) { + return false; + } + List appliedEffects = (ArrayList) this.getValue("appliedEffects"); + CounterType counterType = player.chooseUse( + outcome, "Choose +1/+1 or flying", null, + "+1/+1", "Flying", source, game + ) ? CounterType.P1P1 : CounterType.FLYING; + permanent.addCounters(counterType.createInstance(), source.getControllerId(), source, game, appliedEffects); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 8f9bb2f6c7b..2e20254087f 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -292,6 +292,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Timeless Witness", 179, Rarity.UNCOMMON, mage.cards.t.TimelessWitness.class)); cards.add(new SetCardInfo("Tireless Provisioner", 180, Rarity.UNCOMMON, mage.cards.t.TirelessProvisioner.class)); cards.add(new SetCardInfo("Titania, Protector of Argoth", 287, Rarity.MYTHIC, mage.cards.t.TitaniaProtectorOfArgoth.class)); + cards.add(new SetCardInfo("Tizerus Charger", 101, Rarity.COMMON, mage.cards.t.TizerusCharger.class)); cards.add(new SetCardInfo("Tormod's Cryptkeeper", 239, Rarity.COMMON, mage.cards.t.TormodsCryptkeeper.class)); cards.add(new SetCardInfo("Tourach's Canticle", 103, Rarity.COMMON, mage.cards.t.TourachsCanticle.class)); cards.add(new SetCardInfo("Tourach, Dread Cantor", 102, Rarity.MYTHIC, mage.cards.t.TourachDreadCantor.class)); From 0410cb53433752aaa15c5c6e7eafdce3564f09d1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 6 Jun 2021 18:32:19 -0400 Subject: [PATCH 171/188] [MH2] Implemented Suspend --- Mage.Sets/src/mage/cards/s/Suspend.java | 88 ++++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 89 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/Suspend.java diff --git a/Mage.Sets/src/mage/cards/s/Suspend.java b/Mage.Sets/src/mage/cards/s/Suspend.java new file mode 100644 index 00000000000..2c25424c704 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Suspend.java @@ -0,0 +1,88 @@ +package mage.cards.s; + +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainSuspendEffect; +import mage.abilities.keyword.SuspendAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Suspend extends CardImpl { + + public Suspend(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); + + // Exile target creature and put two time counters on it. If it doesn't have suspend, it gains suspend. + this.getSpellAbility().addEffect(new SuspendEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + private Suspend(final Suspend card) { + super(card); + } + + @Override + public Suspend copy() { + return new Suspend(this); + } +} + +class SuspendEffect extends OneShotEffect { + + SuspendEffect() { + super(Outcome.Benefit); + staticText = "exile target creature and put two time counters on it. " + + "If it doesn't have suspend, it gains suspend"; + } + + private SuspendEffect(final SuspendEffect effect) { + super(effect); + } + + @Override + public SuspendEffect copy() { + return new SuspendEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (controller == null || permanent == null) { + return false; + } + Card card = permanent.getMainCard(); + if (!controller.moveCards(permanent, Zone.EXILED, source, game) + || game.getState().getZone(card.getId()) != Zone.EXILED) { + return true; + } + UUID exileId = SuspendAbility.getSuspendExileId(controller.getId(), game); + if (!controller.moveCardToExileWithInfo( + card, exileId, "Suspended cards of " + controller.getLogName(), + source, game, Zone.HAND, true + )) { + return true; + } + card.addCounters(CounterType.TIME.createInstance(2), source.getControllerId(), source, game); + if (!card.getAbilities(game).containsClass(SuspendAbility.class)) { + game.addEffect(new GainSuspendEffect(new MageObjectReference(card, game)), source); + } + game.informPlayers(controller.getLogName() + " suspends 2 - " + card.getName()); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 2e20254087f..bc856ebcf68 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -271,6 +271,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Strike It Rich", 143, Rarity.UNCOMMON, mage.cards.s.StrikeItRich.class)); cards.add(new SetCardInfo("Subtlety", 67, Rarity.MYTHIC, mage.cards.s.Subtlety.class)); cards.add(new SetCardInfo("Sudden Edict", 100, Rarity.UNCOMMON, mage.cards.s.SuddenEdict.class)); + cards.add(new SetCardInfo("Suspend", 68, Rarity.RARE, mage.cards.s.Suspend.class)); cards.add(new SetCardInfo("Svyelun of Sea and Sky", 69, Rarity.MYTHIC, mage.cards.s.SvyelunOfSeaAndSky.class)); cards.add(new SetCardInfo("Swamp", 485, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sweep the Skies", 70, Rarity.UNCOMMON, mage.cards.s.SweepTheSkies.class)); From 568bfad74336a7121d0c4644e26954de84ef0eb6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 6 Jun 2021 18:34:20 -0400 Subject: [PATCH 172/188] [STX] fixed Willowdusk, Essence Seer adding counters when no life has been gained or lost (fixes #7875) --- Mage.Sets/src/mage/cards/w/WillowduskEssenceSeer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/w/WillowduskEssenceSeer.java b/Mage.Sets/src/mage/cards/w/WillowduskEssenceSeer.java index c6cc1294e71..837a5ef0e59 100644 --- a/Mage.Sets/src/mage/cards/w/WillowduskEssenceSeer.java +++ b/Mage.Sets/src/mage/cards/w/WillowduskEssenceSeer.java @@ -48,7 +48,7 @@ public final class WillowduskEssenceSeer extends CardImpl { // {1}, {T}: Choose another target creature. Put a number of +1/+1 counters on it equal to the amount of life you gained this turn or the amount of life you lost this turn, whichever is greater. Activate only as a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(new AddCountersTargetEffect( - CounterType.P1P1.createInstance(), WillowduskEssenceSeerValue.instance + CounterType.P1P1.createInstance(0), WillowduskEssenceSeerValue.instance ).setText("choose another target creature. Put a number of +1/+1 counters on it " + "equal to the amount of life you gained this turn or the amount of " + "life you lost this turn, whichever is greater"), new GenericManaCost(1)); From df5bf2fa25dc2f6af2c9d5dd79c07ba1f8228b44 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Sun, 6 Jun 2021 17:38:48 -0500 Subject: [PATCH 173/188] [MH2] Implemented Sanctifier en-Vec (#7893) * [MH2] Implemented Sanctifier en-Vec * [MH2] Sanctifier en-Vec - Remove unused filter --- .../src/mage/cards/s/SanctifierEnVec.java | 106 +++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../replacement/SanctifierEnVecTest.java | 142 ++++++++++++++++++ .../ExileGraveyardAllPlayersEffect.java | 2 +- 4 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/s/SanctifierEnVec.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/replacement/SanctifierEnVecTest.java diff --git a/Mage.Sets/src/mage/cards/s/SanctifierEnVec.java b/Mage.Sets/src/mage/cards/s/SanctifierEnVec.java new file mode 100644 index 00000000000..1556accec8c --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SanctifierEnVec.java @@ -0,0 +1,106 @@ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.ExileGraveyardAllPlayersEffect; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.Card; +import mage.constants.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author weirddan455 + */ +public final class SanctifierEnVec extends CardImpl { + + private static final FilterCard filter = new FilterCard("cards that are black or red"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.BLACK), new ColorPredicate(ObjectColor.RED))); + } + + public SanctifierEnVec(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Protection from black and from red + this.addAbility(ProtectionAbility.from(ObjectColor.BLACK, ObjectColor.RED)); + + // When Sanctifier en-Vec enters the battlefield, exile all cards that are black or red from all graveyards. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExileGraveyardAllPlayersEffect(filter))); + + // If a black or red permanent, spell, or card not on the battlefield would be put into a graveyard, exile it instead. + this.addAbility(new SimpleStaticAbility(new SanctifierEnVecEffect())); + } + + private SanctifierEnVec(final SanctifierEnVec card) { + super(card); + } + + @Override + public SanctifierEnVec copy() { + return new SanctifierEnVec(this); + } +} + +class SanctifierEnVecEffect extends ReplacementEffectImpl { + + public SanctifierEnVecEffect() { + super(Duration.WhileOnBattlefield, Outcome.Exile); + this.staticText = "If a black or red permanent, spell, or card not on the battlefield would be put into a graveyard, exile it instead"; + } + + private SanctifierEnVecEffect(final SanctifierEnVecEffect effect) { + super(effect); + } + + @Override + public SanctifierEnVecEffect copy() { + return new SanctifierEnVecEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getToZone() == Zone.GRAVEYARD) { + Permanent permanent = zEvent.getTarget(); + if (permanent != null) { + return permanent.getColor(game).contains(ObjectColor.BLACK) || permanent.getColor(game).contains(ObjectColor.RED); + } + Card card = game.getCard(zEvent.getTargetId()); + if (card != null) { + return card.getColor(game).contains(ObjectColor.BLACK) || card.getColor(game).contains(ObjectColor.RED); + } + } + return false; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + ((ZoneChangeEvent) event).setToZone(Zone.EXILED); + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index bc856ebcf68..461cd70fb2f 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -228,6 +228,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Road // Ruin", 212, Rarity.UNCOMMON, mage.cards.r.RoadRuin.class)); cards.add(new SetCardInfo("Rustvale Bridge", 253, Rarity.COMMON, mage.cards.r.RustvaleBridge.class)); cards.add(new SetCardInfo("Said // Done", 60, Rarity.UNCOMMON, mage.cards.s.SaidDone.class)); + cards.add(new SetCardInfo("Sanctifier en-Vec", 27, Rarity.RARE, mage.cards.s.SanctifierEnVec.class)); cards.add(new SetCardInfo("Sanctuary Raptor", 233, Rarity.UNCOMMON, mage.cards.s.SanctuaryRaptor.class)); cards.add(new SetCardInfo("Sanctum Prelate", 491, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class)); cards.add(new SetCardInfo("Sanctum Weaver", 171, Rarity.RARE, mage.cards.s.SanctumWeaver.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/SanctifierEnVecTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/SanctifierEnVecTest.java new file mode 100644 index 00000000000..40375e3fa98 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/SanctifierEnVecTest.java @@ -0,0 +1,142 @@ +package org.mage.test.cards.replacement; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class SanctifierEnVecTest extends CardTestPlayerBase { + + private static final String sanctifier = "Sanctifier en-Vec"; + private static final String painter = "Painter's Servant"; + private static final String jace = "Jace, the Mind Sculptor"; + + @Test + public void testEntersBattlefieldAbility() { + addCard(Zone.GRAVEYARD, playerA, "Divination"); + addCard(Zone.GRAVEYARD, playerA, "Lightning Bolt"); + addCard(Zone.GRAVEYARD, playerB, "Fatal Push"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + addCard(Zone.HAND, playerA, sanctifier); + setStrictChooseMode(true); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sanctifier); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertAllCommandsUsed(); + assertPermanentCount(playerA, sanctifier, 1); + assertGraveyardCount(playerA, "Divination", 1); + assertExileCount(playerA, "Lightning Bolt", 1); + assertExileCount(playerB, "Fatal Push", 1); + } + + @Test + public void testReplacementEffect() { + addCard(Zone.HAND, playerA, "Lightning Bolt", 2); + addCard(Zone.HAND, playerA, "Divination"); + addCard(Zone.HAND, playerB, jace); + addCard(Zone.HAND, playerB, "Fatal Push"); + addCard(Zone.HAND, playerB, "One with Nothing"); + addCard(Zone.BATTLEFIELD, playerA, sanctifier); + addCard(Zone.BATTLEFIELD, playerB, "Midnight Reaper"); + addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1); + setStrictChooseMode(true); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Midnight Reaper"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Grizzly Bears"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Divination"); + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "One with Nothing"); + setStopAt(2, PhaseStep.END_TURN); + execute(); + + assertAllCommandsUsed(); + // Test that Midnight Reaper did not trigger + assertLife(playerA, 20); + assertLife(playerB, 20); + + assertPermanentCount(playerA, sanctifier, 1); + assertGraveyardCount(playerA, "Divination", 1); + assertGraveyardCount(playerB, "Grizzly Bears", 1); + assertExileCount(playerA, "Lightning Bolt", 2); + assertExileCount(playerB, "Midnight Reaper", 1); + + assertExileCount(playerB, "One with Nothing", 1); + assertGraveyardCount(playerB, jace, 1); + assertExileCount(playerB, "Fatal Push", 1); + } + + @Test + public void testEtbWithPaintersServant() { + addCard(Zone.GRAVEYARD, playerA, "Divination"); + addCard(Zone.GRAVEYARD, playerA, "Lightning Bolt"); + addCard(Zone.GRAVEYARD, playerB, "Fatal Push"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.HAND, playerA, sanctifier); + addCard(Zone.HAND, playerA, painter); + setStrictChooseMode(true); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, painter); + setChoice(playerA, "Black"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sanctifier); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertAllCommandsUsed(); + assertPermanentCount(playerA, painter, 1); + assertPermanentCount(playerA, sanctifier, 1); + assertExileCount(playerA, "Divination", 1); + assertExileCount(playerA, "Lightning Bolt", 1); + assertExileCount(playerB, "Fatal Push", 1); + } + + @Test + public void testReplacementWithPaintersServant() { + addCard(Zone.HAND, playerA, "Lightning Bolt", 2); + addCard(Zone.HAND, playerA, "Divination"); + addCard(Zone.HAND, playerA, painter); + addCard(Zone.HAND, playerB, jace); + addCard(Zone.HAND, playerB, "Fatal Push"); + addCard(Zone.HAND, playerB, "One with Nothing"); + addCard(Zone.BATTLEFIELD, playerA, sanctifier); + addCard(Zone.BATTLEFIELD, playerB, "Midnight Reaper"); + addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2); + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1); + setStrictChooseMode(true); + + // Tap correctly for painter + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {C}",2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, painter); + setChoice(playerA, "Red"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Midnight Reaper"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Grizzly Bears"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Divination"); + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "One with Nothing"); + setStopAt(2, PhaseStep.END_TURN); + execute(); + + assertAllCommandsUsed(); + // Test that Midnight Reaper did not trigger + assertLife(playerA, 20); + assertLife(playerB, 20); + + assertPermanentCount(playerA, painter, 1); + assertPermanentCount(playerA, sanctifier, 1); + assertExileCount(playerB, jace, 1); + assertExileCount(playerA, "Divination", 1); + assertExileCount(playerB, "Grizzly Bears", 1); + assertExileCount(playerA, "Lightning Bolt", 2); + assertExileCount(playerB, "Midnight Reaper", 1); + + assertExileCount(playerB, "One with Nothing", 1); + assertExileCount(playerB, jace, 1); + assertExileCount(playerB, "Fatal Push", 1); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileGraveyardAllPlayersEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileGraveyardAllPlayersEffect.java index b3d65f87753..0af1d8339bc 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileGraveyardAllPlayersEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileGraveyardAllPlayersEffect.java @@ -64,7 +64,7 @@ public class ExileGraveyardAllPlayersEffect extends OneShotEffect { } Player player = game.getPlayer(playerId); if (player != null) { - toExile.addAll(player.getGraveyard()); + toExile.addAll(player.getGraveyard().getCards(filter, source.getSourceId(), source.getControllerId(), game)); } } controller.moveCards(toExile, Zone.EXILED, source, game); From 4232b1e7898a169046f6b01dbe3a07e380ac5085 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 7 Jun 2021 09:42:34 -0400 Subject: [PATCH 174/188] [MH2] Implemented Zabaz, the Glimmerwasp --- .../src/mage/cards/z/ZabazTheGlimmerwasp.java | 116 ++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + .../single/mh2/ZabazTheGlimmerwaspTest.java | 57 +++++++++ 3 files changed, 174 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/z/ZabazTheGlimmerwasp.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/mh2/ZabazTheGlimmerwaspTest.java diff --git a/Mage.Sets/src/mage/cards/z/ZabazTheGlimmerwasp.java b/Mage.Sets/src/mage/cards/z/ZabazTheGlimmerwasp.java new file mode 100644 index 00000000000..90caaec27d0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZabazTheGlimmerwasp.java @@ -0,0 +1,116 @@ +package mage.cards.z; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ModularAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.game.stack.StackObject; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ZabazTheGlimmerwasp extends CardImpl { + + public ZabazTheGlimmerwasp(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.INSECT); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // Modular 1 + this.addAbility(new ModularAbility(this, 1)); + + // If a modular triggered ability would put one or more +1/+1 counters on a creature you control, that many plus one +1/+1 counters are put on it instead. + this.addAbility(new SimpleStaticAbility(new ZabazTheGlimmerwaspEffect())); + + // {R}: Destroy target artifact you control. + Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new ManaCostsImpl<>("{R}")); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT)); + this.addAbility(ability); + + // {W}: Zabaz, the Glimmerwasp gains flying until end of turn. + this.addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect( + FlyingAbility.getInstance(), Duration.EndOfTurn + ), new ManaCostsImpl<>("{W}"))); + } + + private ZabazTheGlimmerwasp(final ZabazTheGlimmerwasp card) { + super(card); + } + + @Override + public ZabazTheGlimmerwasp copy() { + return new ZabazTheGlimmerwasp(this); + } +} + +class ZabazTheGlimmerwaspEffect extends ReplacementEffectImpl { + + ZabazTheGlimmerwaspEffect() { + super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false); + staticText = "if a modular triggered ability would put one or more +1/+1 counters on a creature you control, " + + "that many plus one +1/+1 counters are put on it instead"; + } + + ZabazTheGlimmerwaspEffect(final ZabazTheGlimmerwaspEffect effect) { + super(effect); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setAmountForCounters(event.getAmount() + 1, true); + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ADD_COUNTERS; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (!event.getData().equals(CounterType.P1P1.getName()) || event.getAmount() < 1) { + return false; + } + StackObject stackAbility = game.getStack().getStackObject(event.getSourceId()); + if (stackAbility == null || !(stackAbility.getStackAbility() instanceof ModularAbility)) { + return false; + } + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent == null) { + permanent = game.getPermanentEntering(event.getTargetId()); + } + return permanent != null + && permanent.isControlledBy(source.getControllerId()) + && permanent.isCreature(); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public ZabazTheGlimmerwaspEffect copy() { + return new ZabazTheGlimmerwaspEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 461cd70fb2f..5d587261b15 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -323,6 +323,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Yavimaya, Cradle of Growth", 261, Rarity.RARE, mage.cards.y.YavimayaCradleOfGrowth.class)); cards.add(new SetCardInfo("Young Necromancer", 110, Rarity.UNCOMMON, mage.cards.y.YoungNecromancer.class)); cards.add(new SetCardInfo("Yusri, Fortune's Flame", 218, Rarity.RARE, mage.cards.y.YusriFortunesFlame.class)); + cards.add(new SetCardInfo("Zabaz, the Glimmerwasp", 243, Rarity.RARE, mage.cards.z.ZabazTheGlimmerwasp.class)); cards.add(new SetCardInfo("Zuran Orb", 300, Rarity.UNCOMMON, mage.cards.z.ZuranOrb.class)); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mh2/ZabazTheGlimmerwaspTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mh2/ZabazTheGlimmerwaspTest.java new file mode 100644 index 00000000000..e9804cf25f0 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mh2/ZabazTheGlimmerwaspTest.java @@ -0,0 +1,57 @@ +package org.mage.test.cards.single.mh2; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author TheElk801 + */ +public class ZabazTheGlimmerwaspTest extends CardTestPlayerBase { + + private static final String zabaz = "Zabaz, the Glimmerwasp"; + private static final String worker = "Arcbound Worker"; + private static final String atog = "Atog"; + + @Test + public void testModularETB() { + addCard(Zone.BATTLEFIELD, playerA, "Island"); + addCard(Zone.BATTLEFIELD, playerA, zabaz); + addCard(Zone.HAND, playerA, worker); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, worker); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPowerToughness(playerA, worker, 1, 1); + assertPowerToughness(playerA, zabaz, 1, 1); + } + + @Test + public void testModularDies() { + addCard(Zone.BATTLEFIELD, playerA, "Island"); + addCard(Zone.BATTLEFIELD, playerA, zabaz); + addCard(Zone.BATTLEFIELD, playerA, atog); + addCard(Zone.HAND, playerA, worker); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, worker); + + setChoice(playerA, worker); + addTarget(playerA, zabaz); + setChoice(playerA, "Yes"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Sacrifice"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertGraveyardCount(playerA, worker, 1); + assertPowerToughness(playerA, zabaz, 1 + 1 + 1, 1 + 1 + 1); + assertPowerToughness(playerA, atog, 1 + 2, 2 + 2); + } +} From 91df970a8719f21c85c6ff85996cafdec8303616 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Tue, 8 Jun 2021 15:49:32 -0500 Subject: [PATCH 175/188] ReturnToHandAttachedEffect - Fixed incorrect zcc check (Fixes #7885 #7890) --- .../abilities/effects/common/ReturnToHandAttachedEffect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandAttachedEffect.java index 423fa44b68c..73c77b3e930 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandAttachedEffect.java @@ -36,7 +36,7 @@ public class ReturnToHandAttachedEffect extends OneShotEffect { return false; } Card card = permanent.getMainCard(); - if (permanent.getZoneChangeCounter(game) != card.getZoneChangeCounter(game) + 1) { + if (permanent.getZoneChangeCounter(game) + 1 != card.getZoneChangeCounter(game)) { return false; } return player.moveCards(card, Zone.HAND, source, game); From 4a855506765299f9cacc35f9a1c32aa3341a7346 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Wed, 9 Jun 2021 20:09:45 -0500 Subject: [PATCH 176/188] [MH2] Implemented Out of Time (#7898) --- Mage.Sets/src/mage/cards/o/OutOfTime.java | 194 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 195 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OutOfTime.java diff --git a/Mage.Sets/src/mage/cards/o/OutOfTime.java b/Mage.Sets/src/mage/cards/o/OutOfTime.java new file mode 100644 index 00000000000..02a4c1188ca --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OutOfTime.java @@ -0,0 +1,194 @@ +package mage.cards.o; + +import java.util.*; + +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.PhaseOutAllEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.VanishingSacrificeAbility; +import mage.abilities.keyword.VanishingUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; + +/** + * + * @author weirddan455 + */ +public final class OutOfTime extends CardImpl { + + public OutOfTime(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{W}"); + + // When Out of Time enters the battlefield, untap all creatures, then phase them out until Out of Time leaves the battlefield. + // Put a time counter on Out of Time for each creature phased out this way. + this.addAbility(new EntersBattlefieldTriggeredAbility(new OutOfTimePhaseOutEffect())); + + // Vanishing + this.addAbility(new VanishingUpkeepAbility(0, "enchantment")); + this.addAbility(new VanishingSacrificeAbility()); + } + + private OutOfTime(final OutOfTime card) { + super(card); + } + + @Override + public OutOfTime copy() { + return new OutOfTime(this); + } +} + +class OutOfTimePhaseOutEffect extends OneShotEffect { + + public OutOfTimePhaseOutEffect() { + super(Outcome.Detriment); + this.staticText = "untap all creatures, then phase them out until {this} leaves the battlefield. " + + "Put a time counter on {this} for each creature phased out this way"; + } + + private OutOfTimePhaseOutEffect(final OutOfTimePhaseOutEffect effect) { + super(effect); + } + + @Override + public OutOfTimePhaseOutEffect copy() { + return new OutOfTimePhaseOutEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + List creatures = game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game); + int numCreatures = creatures.size(); + if (numCreatures > 0) { + Set creatureIds = new HashSet<>(numCreatures); + for (Permanent creature : creatures) { + creature.untap(game); + creatureIds.add(creature.getId()); + } + // https://magic.wizards.com/en/articles/archive/feature/modern-horizons-2-release-notes-2021-06-04 + // If Out of Time leaves the battlefield before its enter the battlefield trigger resolves, creatures will untap, but they won't phase out. + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + new PhaseOutAllEffect(new ArrayList<>(creatureIds)).apply(game, source); + new AddCountersSourceEffect(CounterType.TIME.createInstance(numCreatures)).apply(game, source); + game.getState().setValue(CardUtil.getCardZoneString("phasedOutCreatures", source.getSourceId(), game), creatureIds); + game.addDelayedTriggeredAbility(new OutOfTimeDelayedTriggeredAbility(), source); + game.addEffect(new OutOfTimeReplcementEffect(), source); + } + } + return true; + } +} + +class OutOfTimeDelayedTriggeredAbility extends DelayedTriggeredAbility { + + public OutOfTimeDelayedTriggeredAbility() { + super(new OutOfTimeLeavesBattlefieldEffect(), Duration.OneUse); + this.usesStack = false; + this.setRuleVisible(false); + } + + private OutOfTimeDelayedTriggeredAbility(final OutOfTimeDelayedTriggeredAbility ability) { + super(ability); + } + + @Override + public OutOfTimeDelayedTriggeredAbility copy() { + return new OutOfTimeDelayedTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getTargetId().equals(this.getSourceId())) { + return ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD; + } + return false; + } +} + +class OutOfTimeLeavesBattlefieldEffect extends OneShotEffect { + + public OutOfTimeLeavesBattlefieldEffect() { + super(Outcome.Benefit); + } + + private OutOfTimeLeavesBattlefieldEffect(final OutOfTimeLeavesBattlefieldEffect effect) { + super(effect); + } + + @Override + public OutOfTimeLeavesBattlefieldEffect copy() { + return new OutOfTimeLeavesBattlefieldEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Set creatureIds = (Set) game.getState().getValue(CardUtil.getCardZoneString( + "phasedOutCreatures", source.getSourceId(), game, true)); + if (creatureIds != null) { + for (UUID creatureId : creatureIds) { + Permanent creature = game.getPermanent(creatureId); + if (creature != null && !creature.isPhasedIn()) { + creature.phaseIn(game); + } + } + return true; + } + return false; + } +} + +// Stops creatures from phasing back in on their controller's next turn +class OutOfTimeReplcementEffect extends ReplacementEffectImpl { + + public OutOfTimeReplcementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + } + + private OutOfTimeReplcementEffect(final OutOfTimeReplcementEffect effect) { + super(effect); + } + + @Override + public OutOfTimeReplcementEffect copy() { + return new OutOfTimeReplcementEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.PHASE_IN; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Set creatureIds = (Set) game.getState().getValue(CardUtil.getCardZoneString( + "phasedOutCreatures", source.getSourceId(), game)); + return creatureIds != null && creatureIds.contains(event.getTargetId()); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 5d587261b15..ec2bbe453ec 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -198,6 +198,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Obsidian Charmaw", 137, Rarity.RARE, mage.cards.o.ObsidianCharmaw.class)); cards.add(new SetCardInfo("Orchard Strider", 169, Rarity.COMMON, mage.cards.o.OrchardStrider.class)); cards.add(new SetCardInfo("Ornithopter of Paradise", 232, Rarity.COMMON, mage.cards.o.OrnithopterOfParadise.class)); + cards.add(new SetCardInfo("Out of Time", 23, Rarity.RARE, mage.cards.o.OutOfTime.class)); cards.add(new SetCardInfo("Parcel Myr", 54, Rarity.COMMON, mage.cards.p.ParcelMyr.class)); cards.add(new SetCardInfo("Patchwork Gnomes", 299, Rarity.COMMON, mage.cards.p.PatchworkGnomes.class)); cards.add(new SetCardInfo("Patriarch's Bidding", 275, Rarity.RARE, mage.cards.p.PatriarchsBidding.class)); From a0e1a14e96a5eaf0b95a49928601e3f0bc9e4c3e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 9 Jun 2021 21:10:12 -0400 Subject: [PATCH 177/188] [MH2] Implemented Garth One-Eye --- Mage.Sets/src/mage/cards/g/GarthOneEye.java | 159 +++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons2.java | 1 + 2 files changed, 160 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GarthOneEye.java diff --git a/Mage.Sets/src/mage/cards/g/GarthOneEye.java b/Mage.Sets/src/mage/cards/g/GarthOneEye.java new file mode 100644 index 00000000000..e1b0a90a7a8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GarthOneEye.java @@ -0,0 +1,159 @@ +package mage.cards.g; + +import mage.ApprovingObject; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.hint.Hint; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.repository.CardCriteria; +import mage.cards.repository.CardInfo; +import mage.cards.repository.CardRepository; +import mage.choices.Choice; +import mage.choices.ChoiceImpl; +import mage.constants.*; +import mage.game.Game; +import mage.players.Player; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class GarthOneEye extends CardImpl { + + public GarthOneEye(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}{B}{R}{G}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // {T}: Choose a card name that hasn't been chosen from among Disenchant, Braingeyser, Terror, Shivan Dragon, Regrowth, and Black Lotus. Create a copy of the card with the chosen name. You may cast the copy. + this.addAbility(new SimpleActivatedAbility( + new GarthOneEyeEffect(), new TapSourceCost() + ).addHint(GarthOneEyeHint.instance)); + } + + private GarthOneEye(final GarthOneEye card) { + super(card); + } + + @Override + public GarthOneEye copy() { + return new GarthOneEye(this); + } +} + +class GarthOneEyeEffect extends OneShotEffect { + + private static final List names = Arrays.asList( + "Disenchant", "Braingeyser", "Terror", "Shivan Dragon", "Regrowth", "Black Lotus" + ); + private static final Map cardMap + = CardRepository + .instance + .findCards(new CardCriteria().setCodes("LEA")) + .stream() + .filter(cardInfo -> names.contains(cardInfo.getName())) + .collect(Collectors.toMap(CardInfo::getName, CardInfo::getCard)); + + GarthOneEyeEffect() { + super(Outcome.Benefit); + staticText = "choose a card name that hasn't been chosen from among " + + "Disenchant, Braingeyser, Terror, Shivan Dragon, Regrowth, and Black Lotus. " + + "Create a copy of the card with the chosen name. You may cast the copy"; + } + + private GarthOneEyeEffect(final GarthOneEyeEffect effect) { + super(effect); + } + + @Override + public GarthOneEyeEffect copy() { + return new GarthOneEyeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Set alreadyChosen = getAlreadyChosen(game, source); + Set choices = new HashSet<>(names); + choices.removeAll(alreadyChosen); + String chosen; + switch (choices.size()) { + case 0: + return false; + case 1: + chosen = choices.stream().findAny().orElse(null); + break; + default: + Choice choice = new ChoiceImpl(true); + choice.setChoices(choices); + player.choose(outcome, choice, game); + chosen = choice.getChoice(); + } + alreadyChosen.add(chosen); + Card card = cardMap.get(chosen); + if (card == null || !player.chooseUse(outcome, "Cast " + card.getName() + '?', source, game)) { + return false; + } + Card copiedCard = game.copyCard(card, source, source.getControllerId()); + copiedCard.setZone(Zone.OUTSIDE, game); + game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE); + player.cast( + player.chooseAbilityForCast(copiedCard, game, false), + game, false, new ApprovingObject(source, game) + ); + game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null); + return true; + } + + private static final Set getAlreadyChosen(Game game, Ability source) { + String key = getKey(source); + Object value = game.getState().getValue(key); + if (value instanceof Set) { + return (Set) value; + } + Set alreadyChosen = new HashSet<>(); + game.getState().setValue(key, alreadyChosen); + return alreadyChosen; + } + + static final String getKey(Ability source) { + return source.getSourceId() + "_" + + source.getSourceObjectZoneChangeCounter() + "_" + + source.getOriginalId() + "_garth"; + } +} + +enum GarthOneEyeHint implements Hint { + instance; + + @Override + public String getText(Game game, Ability ability) { + if (ability.getSourcePermanentIfItStillExists(game) == null) { + return null; + } + Set chosen = (Set) game.getState().getValue(GarthOneEyeEffect.getKey(ability)); + if (chosen == null || chosen.isEmpty()) { + return "Chosen names: None"; + } + return "Chosen names: " + String.join(", ", chosen); + } + + @Override + public GarthOneEyeHint copy() { + return instance; + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index ec2bbe453ec..e1ceb487691 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -123,6 +123,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Gaea's Will", 162, Rarity.RARE, mage.cards.g.GaeasWill.class)); cards.add(new SetCardInfo("Galvanic Relay", 127, Rarity.COMMON, mage.cards.g.GalvanicRelay.class)); cards.add(new SetCardInfo("Gargadon", 128, Rarity.COMMON, mage.cards.g.Gargadon.class)); + cards.add(new SetCardInfo("Garth One-Eye", 197, Rarity.MYTHIC, mage.cards.g.GarthOneEye.class)); cards.add(new SetCardInfo("General Ferrous Rokiric", 198, Rarity.RARE, mage.cards.g.GeneralFerrousRokiric.class)); cards.add(new SetCardInfo("Geyadrone Dihada", 199, Rarity.MYTHIC, mage.cards.g.GeyadroneDihada.class)); cards.add(new SetCardInfo("Ghost-Lit Drifter", 45, Rarity.UNCOMMON, mage.cards.g.GhostLitDrifter.class)); From fd495299db98919dc34da877cf858a3e405158c9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 9 Jun 2021 21:25:50 -0400 Subject: [PATCH 178/188] added ranger creature type errata --- Mage.Sets/src/mage/cards/q/QuirionRanger.java | 1 + Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java | 1 + Mage/src/main/java/mage/constants/SubType.java | 1 + 3 files changed, 3 insertions(+) diff --git a/Mage.Sets/src/mage/cards/q/QuirionRanger.java b/Mage.Sets/src/mage/cards/q/QuirionRanger.java index 6410827af1e..ea1cec61a3c 100644 --- a/Mage.Sets/src/mage/cards/q/QuirionRanger.java +++ b/Mage.Sets/src/mage/cards/q/QuirionRanger.java @@ -32,6 +32,7 @@ public final class QuirionRanger extends CardImpl { public QuirionRanger(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); this.subtype.add(SubType.ELF); + this.subtype.add(SubType.RANGER); this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java b/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java index 60736bcc15c..c9044fbd5a7 100644 --- a/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java +++ b/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java @@ -39,6 +39,7 @@ public final class RangerCaptainOfEos extends CardImpl { this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); + this.subtype.add(SubType.RANGER); this.power = new MageInt(3); this.toughness = new MageInt(3); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 9bc5596f8bf..bced59b4181 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -287,6 +287,7 @@ public enum SubType { // R RABBIT("Rabbit", SubTypeSet.CreatureType), RAIDER("Raider", SubTypeSet.CreatureType, true), // Star Wars + RANGER("Ranger", SubTypeSet.CreatureType), RAT("Rat", SubTypeSet.CreatureType), REBEL("Rebel", SubTypeSet.CreatureType), REFLECTION("Reflection", SubTypeSet.CreatureType), From c8154bf018b86de163b38c5fc9e02c9be3023e59 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 10 Jun 2021 18:40:56 -0400 Subject: [PATCH 179/188] [MH2] added test for Garth One-Eye --- Mage.Sets/src/mage/cards/g/GarthOneEye.java | 21 ++- .../cards/single/mh2/GarthOneEyeTest.java | 151 ++++++++++++++++++ 2 files changed, 165 insertions(+), 7 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/mh2/GarthOneEyeTest.java diff --git a/Mage.Sets/src/mage/cards/g/GarthOneEye.java b/Mage.Sets/src/mage/cards/g/GarthOneEye.java index e1b0a90a7a8..9fe9dd77c81 100644 --- a/Mage.Sets/src/mage/cards/g/GarthOneEye.java +++ b/Mage.Sets/src/mage/cards/g/GarthOneEye.java @@ -57,13 +57,19 @@ class GarthOneEyeEffect extends OneShotEffect { private static final List names = Arrays.asList( "Disenchant", "Braingeyser", "Terror", "Shivan Dragon", "Regrowth", "Black Lotus" ); - private static final Map cardMap - = CardRepository - .instance - .findCards(new CardCriteria().setCodes("LEA")) - .stream() - .filter(cardInfo -> names.contains(cardInfo.getName())) - .collect(Collectors.toMap(CardInfo::getName, CardInfo::getCard)); + private static final Map cardMap = new HashMap<>(); + + private static final void initMap() { + if (!cardMap.isEmpty()) { + return; + } + cardMap.putAll(CardRepository + .instance + .findCards(new CardCriteria().setCodes("LEA")) + .stream() + .filter(cardInfo -> names.contains(cardInfo.getName())) + .collect(Collectors.toMap(CardInfo::getName, CardInfo::getCard))); + } GarthOneEyeEffect() { super(Outcome.Benefit); @@ -83,6 +89,7 @@ class GarthOneEyeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { + initMap(); Player player = game.getPlayer(source.getControllerId()); if (player == null) { return false; diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mh2/GarthOneEyeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mh2/GarthOneEyeTest.java new file mode 100644 index 00000000000..e78adbea829 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mh2/GarthOneEyeTest.java @@ -0,0 +1,151 @@ +package org.mage.test.cards.single.mh2; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.game.permanent.Permanent; +import mage.game.permanent.PermanentToken; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author TheElk801 + */ +public class GarthOneEyeTest extends CardTestPlayerBase { + + private static final String garth = "Garth One-Eye"; + private static final String disenchant = "Disenchant"; + private static final String braingeyser = "Braingeyser"; + private static final String terror = "Terror"; + private static final String dragon = "Shivan Dragon"; + private static final String regrowth = "Regrowth"; + private static final String lotus = "Black Lotus"; + private static final String courser = "Nyxborn Courser"; + + @Test + public void testDisenchant() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + addCard(Zone.BATTLEFIELD, playerA, garth); + addCard(Zone.BATTLEFIELD, playerA, courser); + + setChoice(playerA, disenchant); + setChoice(playerA, "Yes"); + addTarget(playerA, courser); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Choose"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertTapped(garth, true); + assertTapped("Plains", true); + assertPermanentCount(playerA, courser, 0); + assertGraveyardCount(playerA, disenchant, 0); + assertGraveyardCount(playerA, courser, 1); + } + + @Test + public void testBraingeyser() { + addCard(Zone.BATTLEFIELD, playerA, "Island", 5); + addCard(Zone.BATTLEFIELD, playerA, garth); + + setChoice(playerA, braingeyser); + setChoice(playerA, "Yes"); + setChoice(playerA, "X=3"); + addTarget(playerA, playerA); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Choose"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertTapped(garth, true); + assertTapped("Island", true); + assertGraveyardCount(playerA, braingeyser, 0); + assertHandCount(playerA, 3); + } + + @Test + public void testTerror() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + addCard(Zone.BATTLEFIELD, playerA, garth); + addCard(Zone.BATTLEFIELD, playerA, courser); + + setChoice(playerA, terror); + setChoice(playerA, "Yes"); + addTarget(playerA, courser); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Choose"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertTapped(garth, true); + assertTapped("Swamp", true); + assertPermanentCount(playerA, courser, 0); + assertGraveyardCount(playerA, terror, 0); + assertGraveyardCount(playerA, courser, 1); + } + + @Test + public void testShivanDragon() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6); + addCard(Zone.BATTLEFIELD, playerA, garth); + + setChoice(playerA, dragon); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Choose"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertTapped(garth, true); + assertTapped("Mountain", true); + Permanent permanent = getPermanent(dragon); + Assert.assertNotNull(dragon + " should be on the battlefield", permanent); + Assert.assertTrue(dragon + " should be a token", permanent instanceof PermanentToken); + } + + @Test + public void testRegrowth() { + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + addCard(Zone.BATTLEFIELD, playerA, garth); + addCard(Zone.GRAVEYARD, playerA, courser); + + setChoice(playerA, regrowth); + setChoice(playerA, "Yes"); + addTarget(playerA, courser); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Choose"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertTapped(garth, true); + assertTapped("Forest", true); + assertHandCount(playerA, courser, 1); + assertGraveyardCount(playerA, regrowth, 0); + assertGraveyardCount(playerA, courser, 0); + } + + @Test + public void testBlackLotus() { + addCard(Zone.BATTLEFIELD, playerA, garth); + + setChoice(playerA, lotus); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Choose"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertTapped(garth, true); + Permanent permanent = getPermanent(lotus); + Assert.assertNotNull(lotus + " should be on the battlefield", permanent); + Assert.assertTrue(lotus + " should be a token", permanent instanceof PermanentToken); + } +} From bd92ced539c34e158f5bbfdbd23a75f4051b5781 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 10 Jun 2021 18:42:02 -0400 Subject: [PATCH 180/188] [MH2] fixed Garth One-Eye permanent spells not becoming tokens --- Mage/src/main/java/mage/game/stack/Spell.java | 15 +++++++++------ Mage/src/main/java/mage/players/PlayerImpl.java | 3 +++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java index 3d9287d60b0..1dc9de3119e 100644 --- a/Mage/src/main/java/mage/game/stack/Spell.java +++ b/Mage/src/main/java/mage/game/stack/Spell.java @@ -257,19 +257,22 @@ public class Spell extends StackObjectImpl implements Card { card.addSubType(game, SubType.AURA); } } - UUID permId = null; - boolean flag = false; - if (!isCopy()) { - permId = card.getId(); - flag = controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null); - } else { + UUID permId; + boolean flag; + if (isCopy()) { EmptyToken token = new EmptyToken(); CardUtil.copyTo(token).from(card, game, this); // The token that a resolving copy of a spell becomes isn’t said to have been “created.” (2020-09-25) if (token.putOntoBattlefield(1, game, ability, getControllerId(), false, false, null, false)) { permId = token.getLastAddedToken(); flag = true; + } else { + permId = null; + flag = false; } + } else { + permId = card.getId(); + flag = controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null); } if (flag) { if (bestow) { diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 1767a9962ec..389b9d9c2e7 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -1177,6 +1177,9 @@ public abstract class PlayerImpl implements Player, Serializable { logger.error("Got no spell from stack. ability: " + ability.getRule()); return false; } + if (card.isCopy()) { + spell.setCopy(true, null); + } // Update the zcc to the stack ability.setSourceObjectZoneChangeCounter(game.getState().getZoneChangeCounter(ability.getSourceId())); From 7d07c220b0d17ba29ea7aea08608a7d8a749d50a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 10 Jun 2021 18:42:47 -0400 Subject: [PATCH 181/188] fixed while on stack effects of copied spells not discarding when copy has left stack --- Mage.Sets/src/mage/cards/m/MeddlingMage.java | 1 - .../cards/continuous/SplitSecondTest.java | 51 +++++++++++++++++++ Mage/src/main/java/mage/game/GameImpl.java | 9 ++-- 3 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/continuous/SplitSecondTest.java diff --git a/Mage.Sets/src/mage/cards/m/MeddlingMage.java b/Mage.Sets/src/mage/cards/m/MeddlingMage.java index 049fd87c83a..fbe56650a40 100644 --- a/Mage.Sets/src/mage/cards/m/MeddlingMage.java +++ b/Mage.Sets/src/mage/cards/m/MeddlingMage.java @@ -87,7 +87,6 @@ class MeddlingMageReplacementEffect extends ContinuousRuleModifyingEffectImpl { MageObject object = game.getObject(event.getSourceId()); String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); return object != null - && !object.isCopy() && CardUtil.haveSameNames(object, cardName, game); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SplitSecondTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SplitSecondTest.java new file mode 100644 index 00000000000..203cc9a6211 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SplitSecondTest.java @@ -0,0 +1,51 @@ +package org.mage.test.cards.continuous; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author TheElk801 + */ +public class SplitSecondTest extends CardTestPlayerBase { + + @Test + public void testCounterSpell() { + addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 4); + addCard(Zone.HAND, playerA, "Sudden Shock"); + addCard(Zone.HAND, playerA, "Counterspell"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sudden Shock", playerB); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Counterspell", "Sudden Shock"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertHandCount(playerA, "Counterspell", 1); + assertGraveyardCount(playerA, "Sudden Shock", 1); + assertLife(playerB, 20 - 2); + } + + @Test + public void testCopiedSpell() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); + addCard(Zone.HAND, playerA, "Doublecast"); + addCard(Zone.HAND, playerA, "Sudden Shock"); + addCard(Zone.HAND, playerA, "Raging Goblin"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Doublecast"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sudden Shock", playerB); + + // No split second spells are on the stack, effect should not apply anymore + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Raging Goblin"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertLife(playerB, 20 - 2 - 2); + assertPermanentCount(playerA, "Raging Goblin", 1); + } +} diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index c12d8fba34c..8e22f67d90d 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -1965,11 +1965,14 @@ public abstract class GameImpl implements Game, Serializable { // (Isochron Scepter) 12/1/2004: If you don't want to cast the copy, you can choose not to; the copy ceases // to exist the next time state-based actions are checked. Zone zone = state.getZone(copiedCard.getMainCard().getId()); - if (zone == Zone.BATTLEFIELD || zone == Zone.STACK) { - continue; - } // TODO: remember LKI of copied cards here after LKI rework switch (zone) { + case BATTLEFIELD: + continue; + case STACK: + if (getStack().getStackObject(copiedCard.getId()) != null) { + continue; + } case GRAVEYARD: for (Player player : getPlayers().values()) { if (player.getGraveyard().contains(copiedCard.getId())) { From cd99beed6e2f739d5878a15f8b344369dfd29de1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 10 Jun 2021 20:01:27 -0400 Subject: [PATCH 182/188] added phyrexian subtype to applicable creatures --- Mage.Sets/src/mage/cards/a/AscendantEvincar.java | 1 + Mage.Sets/src/mage/cards/a/AtraxaPraetorsVoice.java | 1 + Mage.Sets/src/mage/cards/b/BelbeCorruptedObserver.java | 1 + Mage.Sets/src/mage/cards/b/BlackcleaveGoblin.java | 2 +- Mage.Sets/src/mage/cards/b/BladeSplicer.java | 2 +- Mage.Sets/src/mage/cards/b/BlightMamba.java | 1 + Mage.Sets/src/mage/cards/b/BlightedAgent.java | 2 +- Mage.Sets/src/mage/cards/b/BlightsteelColossus.java | 1 + Mage.Sets/src/mage/cards/b/Blightwidow.java | 1 + Mage.Sets/src/mage/cards/b/BlindZealot.java | 2 +- Mage.Sets/src/mage/cards/b/BlindingSouleater.java | 1 + Mage.Sets/src/mage/cards/b/Blistergrub.java | 1 + Mage.Sets/src/mage/cards/b/BodySnatcher.java | 1 + Mage.Sets/src/mage/cards/b/BoneShredder.java | 1 + Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java | 1 + Mage.Sets/src/mage/cards/b/BrutalizerExarch.java | 1 + Mage.Sets/src/mage/cards/c/CarnifexDemon.java | 1 + Mage.Sets/src/mage/cards/c/CathedralMembrane.java | 1 + Mage.Sets/src/mage/cards/c/CausticHound.java | 1 + Mage.Sets/src/mage/cards/c/ChainedThroatseeker.java | 1 + Mage.Sets/src/mage/cards/c/ChancellorOfTheAnnex.java | 1 + Mage.Sets/src/mage/cards/c/ChancellorOfTheDross.java | 1 + Mage.Sets/src/mage/cards/c/ChancellorOfTheForge.java | 1 + Mage.Sets/src/mage/cards/c/ChancellorOfTheSpires.java | 1 + Mage.Sets/src/mage/cards/c/ChancellorOfTheTangle.java | 1 + Mage.Sets/src/mage/cards/c/CommanderGrevenIlVec.java | 1 + Mage.Sets/src/mage/cards/c/ContagiousNim.java | 1 + Mage.Sets/src/mage/cards/c/CoreProwler.java | 1 + Mage.Sets/src/mage/cards/c/CorpseCur.java | 1 + Mage.Sets/src/mage/cards/c/CorruptedHarvester.java | 1 + Mage.Sets/src/mage/cards/c/CrazedSkirge.java | 1 + Mage.Sets/src/mage/cards/c/Cystbearer.java | 1 + Mage.Sets/src/mage/cards/d/DarkslickDrake.java | 1 + Mage.Sets/src/mage/cards/d/DeathHoodCobra.java | 1 + Mage.Sets/src/mage/cards/d/DeceiverExarch.java | 1 + Mage.Sets/src/mage/cards/d/DementiaBat.java | 1 + Mage.Sets/src/mage/cards/d/DevouringStrossus.java | 1 + Mage.Sets/src/mage/cards/d/DrossHopper.java | 1 + Mage.Sets/src/mage/cards/d/DrossRipper.java | 1 + Mage.Sets/src/mage/cards/e/EasternPaladin.java | 1 + Mage.Sets/src/mage/cards/e/EleshNornGrandCenobite.java | 1 + Mage.Sets/src/mage/cards/e/EntomberExarch.java | 1 + Mage.Sets/src/mage/cards/e/ErtaiTheCorrupted.java | 1 + Mage.Sets/src/mage/cards/e/EtchedMonstrosity.java | 1 + Mage.Sets/src/mage/cards/e/Eviscerator.java | 1 + Mage.Sets/src/mage/cards/e/EzuriClawOfProgress.java | 1 + Mage.Sets/src/mage/cards/f/FallenFerromancer.java | 1 + Mage.Sets/src/mage/cards/f/FirstSphereGargantua.java | 1 + Mage.Sets/src/mage/cards/f/FlamebornViron.java | 1 + Mage.Sets/src/mage/cards/f/Flensermite.java | 1 + Mage.Sets/src/mage/cards/f/FleshEaterImp.java | 1 + Mage.Sets/src/mage/cards/f/FleshReaver.java | 1 + Mage.Sets/src/mage/cards/f/FumeSpitter.java | 1 + Mage.Sets/src/mage/cards/f/FurnaceScamp.java | 1 + Mage.Sets/src/mage/cards/g/Gallowbraid.java | 1 + Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java | 1 + Mage.Sets/src/mage/cards/g/GlissaTheTraitor.java | 1 + Mage.Sets/src/mage/cards/g/GlissasCourier.java | 1 + Mage.Sets/src/mage/cards/g/GlistenerElf.java | 1 + Mage.Sets/src/mage/cards/g/GoreVassal.java | 1 + Mage.Sets/src/mage/cards/g/GrevenPredatorCaptain.java | 1 + Mage.Sets/src/mage/cards/h/HandOfThePraetors.java | 1 + Mage.Sets/src/mage/cards/h/HexParasite.java | 1 + Mage.Sets/src/mage/cards/h/HollowDogs.java | 1 + Mage.Sets/src/mage/cards/i/IchTekikSalvageSplicer.java | 1 + Mage.Sets/src/mage/cards/i/IchorRats.java | 1 + Mage.Sets/src/mage/cards/i/IchorclawMyr.java | 1 + Mage.Sets/src/mage/cards/i/ImmolatingSouleater.java | 1 + Mage.Sets/src/mage/cards/i/ImpalerShrike.java | 1 + Mage.Sets/src/mage/cards/i/InquisitorExarch.java | 1 + Mage.Sets/src/mage/cards/i/InsatiableSouleater.java | 1 + Mage.Sets/src/mage/cards/i/InvaderParasite.java | 1 + Mage.Sets/src/mage/cards/j/JinGitaxiasCoreAugur.java | 1 + Mage.Sets/src/mage/cards/k/KeskitTheFleshSculptor.java | 1 + Mage.Sets/src/mage/cards/k/KilnWalker.java | 1 + Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java | 1 + Mage.Sets/src/mage/cards/l/LostLeonin.java | 1 + Mage.Sets/src/mage/cards/l/LoxodonConvert.java | 1 + Mage.Sets/src/mage/cards/m/MaraudingKnight.java | 1 + Mage.Sets/src/mage/cards/m/MassacreWurm.java | 1 + Mage.Sets/src/mage/cards/m/MasterSplicer.java | 1 + Mage.Sets/src/mage/cards/m/MaulSplicer.java | 1 + Mage.Sets/src/mage/cards/m/MoltensteelDragon.java | 1 + Mage.Sets/src/mage/cards/m/Morinfen.java | 1 + Mage.Sets/src/mage/cards/m/MortisDogs.java | 1 + Mage.Sets/src/mage/cards/m/MycosynthFiend.java | 1 + Mage.Sets/src/mage/cards/m/MyrSire.java | 1 + Mage.Sets/src/mage/cards/n/NecrogenScudder.java | 1 + Mage.Sets/src/mage/cards/n/Necropede.java | 1 + Mage.Sets/src/mage/cards/n/NestedGhoul.java | 1 + Mage.Sets/src/mage/cards/o/Oculus.java | 1 + Mage.Sets/src/mage/cards/o/OgreMenial.java | 1 + Mage.Sets/src/mage/cards/o/OrderOfYawgmoth.java | 1 + Mage.Sets/src/mage/cards/p/PerilousMyr.java | 1 + Mage.Sets/src/mage/cards/p/PestilentSouleater.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianBattleflies.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianBloodstock.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianBroodlings.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianColossus.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianCrusader.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianDebaser.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianDefiler.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianDelver.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianDenouncer.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianDevourer.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianDigester.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianDreadnought.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianDriver.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianGargantua.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianGhoul.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianGremlins.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianHulk.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianHydra.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianInfiltrator.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianIngester.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianIronfoot.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianJuggernaut.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianMarauder.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianMonitor.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianNegator.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianObliterator.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianPlaguelord.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianProwler.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianRager.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianReaper.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianRevoker.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianScuta.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianSlayer.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianSnowcrusher.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianSoulgorger.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianSwarmlord.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianTriniform.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianVatmother.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianWalker.java | 1 + Mage.Sets/src/mage/cards/p/PhyrexianWarBeast.java | 1 + Mage.Sets/src/mage/cards/p/PierceStrider.java | 1 + Mage.Sets/src/mage/cards/p/PithDriller.java | 1 + Mage.Sets/src/mage/cards/p/PlagueDogs.java | 1 + Mage.Sets/src/mage/cards/p/PlagueMyr.java | 1 + Mage.Sets/src/mage/cards/p/PlagueSpitter.java | 1 + Mage.Sets/src/mage/cards/p/PlagueStinger.java | 1 + Mage.Sets/src/mage/cards/p/PlaguemawBeast.java | 1 + Mage.Sets/src/mage/cards/p/PorcelainLegionnaire.java | 1 + Mage.Sets/src/mage/cards/p/PriestOfGix.java | 1 + Mage.Sets/src/mage/cards/p/PriestOfUrabrask.java | 1 + Mage.Sets/src/mage/cards/p/PriestOfYawgmoth.java | 1 + Mage.Sets/src/mage/cards/p/PriestsOfNorn.java | 1 + Mage.Sets/src/mage/cards/p/PsychosisCrawler.java | 1 + Mage.Sets/src/mage/cards/p/Putrefax.java | 1 + Mage.Sets/src/mage/cards/q/QuilledSlagwurm.java | 1 + Mage.Sets/src/mage/cards/r/Rackling.java | 1 + Mage.Sets/src/mage/cards/r/RathiFiend.java | 1 + Mage.Sets/src/mage/cards/r/RathiIntimidator.java | 1 + Mage.Sets/src/mage/cards/r/RavenousSkirge.java | 1 + Mage.Sets/src/mage/cards/r/RazorSwine.java | 1 + Mage.Sets/src/mage/cards/r/ReaperOfSheoldred.java | 1 + Mage.Sets/src/mage/cards/r/RotWolf.java | 1 + Mage.Sets/src/mage/cards/r/RottedHystrix.java | 1 + Mage.Sets/src/mage/cards/r/RustedSlasher.java | 1 + Mage.Sets/src/mage/cards/s/SanguineGuard.java | 1 + Mage.Sets/src/mage/cards/s/SarcomiteMyr.java | 1 + Mage.Sets/src/mage/cards/s/ScourgeServant.java | 1 + Mage.Sets/src/mage/cards/s/SeleniaDarkAngel.java | 1 + Mage.Sets/src/mage/cards/s/SensorSplicer.java | 1 + Mage.Sets/src/mage/cards/s/SepticRats.java | 1 + Mage.Sets/src/mage/cards/s/SerumRaker.java | 1 + Mage.Sets/src/mage/cards/s/ShatteredAngel.java | 1 + Mage.Sets/src/mage/cards/s/ShivanZombie.java | 1 + Mage.Sets/src/mage/cards/s/ShriekRaptor.java | 1 + Mage.Sets/src/mage/cards/s/Skinrender.java | 1 + Mage.Sets/src/mage/cards/s/SkirgeFamiliar.java | 1 + Mage.Sets/src/mage/cards/s/SkithiryxTheBlightDragon.java | 1 + Mage.Sets/src/mage/cards/s/SkitteringHorror.java | 1 + Mage.Sets/src/mage/cards/s/SkitteringSkirge.java | 1 + Mage.Sets/src/mage/cards/s/SlagFiend.java | 1 + Mage.Sets/src/mage/cards/s/SlashPanther.java | 1 + Mage.Sets/src/mage/cards/s/SleeperAgent.java | 1 + Mage.Sets/src/mage/cards/s/SlinkingSkirge.java | 1 + Mage.Sets/src/mage/cards/s/SoulOfNewPhyrexia.java | 1 + Mage.Sets/src/mage/cards/s/Spellskite.java | 1 + Mage.Sets/src/mage/cards/s/Spinebiter.java | 1 + Mage.Sets/src/mage/cards/s/SpinedThopter.java | 1 + Mage.Sets/src/mage/cards/s/SpinelessThug.java | 1 + Mage.Sets/src/mage/cards/s/SpireMonitor.java | 1 + Mage.Sets/src/mage/cards/s/SpitefulBully.java | 1 + Mage.Sets/src/mage/cards/s/StrongholdAssassin.java | 1 + Mage.Sets/src/mage/cards/s/SuturePriest.java | 1 + Mage.Sets/src/mage/cards/t/TangleAngler.java | 1 + Mage.Sets/src/mage/cards/t/TangleHulk.java | 1 + Mage.Sets/src/mage/cards/t/TelJiladFallen.java | 1 + Mage.Sets/src/mage/cards/t/TetheredSkirge.java | 1 + Mage.Sets/src/mage/cards/t/Thrummingbird.java | 1 + Mage.Sets/src/mage/cards/t/ThunderingTanadon.java | 1 + Mage.Sets/src/mage/cards/t/TineShrike.java | 1 + Mage.Sets/src/mage/cards/t/TormentorExarch.java | 1 + Mage.Sets/src/mage/cards/t/ToxicNim.java | 1 + Mage.Sets/src/mage/cards/t/TrespassingSouleater.java | 1 + Mage.Sets/src/mage/cards/t/TsaboTavoc.java | 1 + Mage.Sets/src/mage/cards/t/TsabosAssassin.java | 1 + Mage.Sets/src/mage/cards/u/UnworthyDead.java | 1 + Mage.Sets/src/mage/cards/u/UrabraskTheHidden.java | 1 + Mage.Sets/src/mage/cards/v/VaultSkirge.java | 1 + Mage.Sets/src/mage/cards/v/Vebulid.java | 1 + Mage.Sets/src/mage/cards/v/VectorAsp.java | 1 + Mage.Sets/src/mage/cards/v/VedalkenAnatomist.java | 1 + Mage.Sets/src/mage/cards/v/ViralDrake.java | 1 + Mage.Sets/src/mage/cards/v/ViridianBetrayers.java | 1 + Mage.Sets/src/mage/cards/v/ViridianCorrupter.java | 1 + Mage.Sets/src/mage/cards/v/ViridianEmissary.java | 1 + Mage.Sets/src/mage/cards/v/Viseling.java | 1 + Mage.Sets/src/mage/cards/v/VitalSplicer.java | 1 + Mage.Sets/src/mage/cards/v/VolrathTheFallen.java | 1 + Mage.Sets/src/mage/cards/v/VolrathTheShapestealer.java | 1 + Mage.Sets/src/mage/cards/v/VolrathsShapeshifter.java | 1 + Mage.Sets/src/mage/cards/v/VorinclexVoiceOfHunger.java | 1 + Mage.Sets/src/mage/cards/w/WesternPaladin.java | 1 + Mage.Sets/src/mage/cards/w/WhisperingSpecter.java | 1 + Mage.Sets/src/mage/cards/w/WingSplicer.java | 1 + Mage.Sets/src/mage/cards/w/WurmcoilEngine.java | 1 + Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java | 1 + Mage.Sets/src/mage/cards/y/YawgmothDemon.java | 1 + 221 files changed, 221 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AscendantEvincar.java b/Mage.Sets/src/mage/cards/a/AscendantEvincar.java index 6b96ef15b5b..f46913cde98 100644 --- a/Mage.Sets/src/mage/cards/a/AscendantEvincar.java +++ b/Mage.Sets/src/mage/cards/a/AscendantEvincar.java @@ -31,6 +31,7 @@ public final class AscendantEvincar extends CardImpl { public AscendantEvincar(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{B}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.VAMPIRE); this.subtype.add(SubType.NOBLE); diff --git a/Mage.Sets/src/mage/cards/a/AtraxaPraetorsVoice.java b/Mage.Sets/src/mage/cards/a/AtraxaPraetorsVoice.java index 25630ea70c3..ac56e824285 100644 --- a/Mage.Sets/src/mage/cards/a/AtraxaPraetorsVoice.java +++ b/Mage.Sets/src/mage/cards/a/AtraxaPraetorsVoice.java @@ -26,6 +26,7 @@ public final class AtraxaPraetorsVoice extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{W}{U}{B}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ANGEL); this.subtype.add(SubType.HORROR); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/b/BelbeCorruptedObserver.java b/Mage.Sets/src/mage/cards/b/BelbeCorruptedObserver.java index cc9397a6a84..d64c9f5b040 100644 --- a/Mage.Sets/src/mage/cards/b/BelbeCorruptedObserver.java +++ b/Mage.Sets/src/mage/cards/b/BelbeCorruptedObserver.java @@ -30,6 +30,7 @@ public final class BelbeCorruptedObserver extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{G}"); this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.ELF); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/b/BlackcleaveGoblin.java b/Mage.Sets/src/mage/cards/b/BlackcleaveGoblin.java index 2a082859599..7d14dbaeeb0 100644 --- a/Mage.Sets/src/mage/cards/b/BlackcleaveGoblin.java +++ b/Mage.Sets/src/mage/cards/b/BlackcleaveGoblin.java @@ -19,7 +19,7 @@ public final class BlackcleaveGoblin extends CardImpl { public BlackcleaveGoblin (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); - this.subtype.add(SubType.GOBLIN, SubType.ZOMBIE); + this.subtype.add(SubType.PHYREXIAN, SubType.GOBLIN, SubType.ZOMBIE); this.power = new MageInt(2); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/b/BladeSplicer.java b/Mage.Sets/src/mage/cards/b/BladeSplicer.java index 6f4e3f02bf2..28ce2b57257 100644 --- a/Mage.Sets/src/mage/cards/b/BladeSplicer.java +++ b/Mage.Sets/src/mage/cards/b/BladeSplicer.java @@ -30,7 +30,7 @@ public final class BladeSplicer extends CardImpl { public BladeSplicer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); - this.subtype.add(SubType.HUMAN, SubType.ARTIFICER); + this.subtype.add(SubType.PHYREXIAN, SubType.HUMAN, SubType.ARTIFICER); this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/b/BlightMamba.java b/Mage.Sets/src/mage/cards/b/BlightMamba.java index 964a14c77fa..cf38c80e717 100644 --- a/Mage.Sets/src/mage/cards/b/BlightMamba.java +++ b/Mage.Sets/src/mage/cards/b/BlightMamba.java @@ -22,6 +22,7 @@ public final class BlightMamba extends CardImpl { public BlightMamba (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SNAKE); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/b/BlightedAgent.java b/Mage.Sets/src/mage/cards/b/BlightedAgent.java index 6cd007c0039..5b464c142e6 100644 --- a/Mage.Sets/src/mage/cards/b/BlightedAgent.java +++ b/Mage.Sets/src/mage/cards/b/BlightedAgent.java @@ -18,7 +18,7 @@ public final class BlightedAgent extends CardImpl { public BlightedAgent(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); - this.subtype.add(SubType.HUMAN, SubType.ROGUE); + this.subtype.add(SubType.PHYREXIAN, SubType.HUMAN, SubType.ROGUE); this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/b/BlightsteelColossus.java b/Mage.Sets/src/mage/cards/b/BlightsteelColossus.java index 63116f1032b..b7aa7b2d4b1 100644 --- a/Mage.Sets/src/mage/cards/b/BlightsteelColossus.java +++ b/Mage.Sets/src/mage/cards/b/BlightsteelColossus.java @@ -21,6 +21,7 @@ public final class BlightsteelColossus extends CardImpl { public BlightsteelColossus(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{12}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.GOLEM); this.power = new MageInt(11); this.toughness = new MageInt(11); diff --git a/Mage.Sets/src/mage/cards/b/Blightwidow.java b/Mage.Sets/src/mage/cards/b/Blightwidow.java index c7080e60473..613b4ad8371 100644 --- a/Mage.Sets/src/mage/cards/b/Blightwidow.java +++ b/Mage.Sets/src/mage/cards/b/Blightwidow.java @@ -19,6 +19,7 @@ public final class Blightwidow extends CardImpl { public Blightwidow (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SPIDER); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/b/BlindZealot.java b/Mage.Sets/src/mage/cards/b/BlindZealot.java index 9125da73273..0ea2d5210c5 100644 --- a/Mage.Sets/src/mage/cards/b/BlindZealot.java +++ b/Mage.Sets/src/mage/cards/b/BlindZealot.java @@ -30,7 +30,7 @@ public final class BlindZealot extends CardImpl { public BlindZealot(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); - this.subtype.add(SubType.HUMAN, SubType.CLERIC); + this.subtype.add(SubType.PHYREXIAN, SubType.HUMAN, SubType.CLERIC); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/b/BlindingSouleater.java b/Mage.Sets/src/mage/cards/b/BlindingSouleater.java index 2f3eced177d..b2e51005868 100644 --- a/Mage.Sets/src/mage/cards/b/BlindingSouleater.java +++ b/Mage.Sets/src/mage/cards/b/BlindingSouleater.java @@ -23,6 +23,7 @@ public final class BlindingSouleater extends CardImpl { public BlindingSouleater(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/b/Blistergrub.java b/Mage.Sets/src/mage/cards/b/Blistergrub.java index 198b9e0537a..99b4069cff3 100644 --- a/Mage.Sets/src/mage/cards/b/Blistergrub.java +++ b/Mage.Sets/src/mage/cards/b/Blistergrub.java @@ -20,6 +20,7 @@ public final class Blistergrub extends CardImpl { public Blistergrub (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/b/BodySnatcher.java b/Mage.Sets/src/mage/cards/b/BodySnatcher.java index d1ed5b3402c..d8cbdaa1022 100644 --- a/Mage.Sets/src/mage/cards/b/BodySnatcher.java +++ b/Mage.Sets/src/mage/cards/b/BodySnatcher.java @@ -28,6 +28,7 @@ public final class BodySnatcher extends CardImpl { public BodySnatcher(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MINION); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/b/BoneShredder.java b/Mage.Sets/src/mage/cards/b/BoneShredder.java index c475fcfd148..cbbc3795c26 100644 --- a/Mage.Sets/src/mage/cards/b/BoneShredder.java +++ b/Mage.Sets/src/mage/cards/b/BoneShredder.java @@ -34,6 +34,7 @@ public final class BoneShredder extends CardImpl { public BoneShredder(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MINION); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java b/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java index 1e5f6d5a707..c59c29d4bff 100644 --- a/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java +++ b/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java @@ -38,6 +38,7 @@ public final class BrudicladTelchorEngineer extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}{U}{R}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ARTIFICER); this.power = new MageInt(4); this.toughness = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/b/BrutalizerExarch.java b/Mage.Sets/src/mage/cards/b/BrutalizerExarch.java index 9c35e700144..c5e1ef23a76 100644 --- a/Mage.Sets/src/mage/cards/b/BrutalizerExarch.java +++ b/Mage.Sets/src/mage/cards/b/BrutalizerExarch.java @@ -36,6 +36,7 @@ public final class BrutalizerExarch extends CardImpl { public BrutalizerExarch(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/c/CarnifexDemon.java b/Mage.Sets/src/mage/cards/c/CarnifexDemon.java index 93b6260494c..54c845eb5b1 100644 --- a/Mage.Sets/src/mage/cards/c/CarnifexDemon.java +++ b/Mage.Sets/src/mage/cards/c/CarnifexDemon.java @@ -33,6 +33,7 @@ public final class CarnifexDemon extends CardImpl { public CarnifexDemon(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DEMON); this.power = new MageInt(6); diff --git a/Mage.Sets/src/mage/cards/c/CathedralMembrane.java b/Mage.Sets/src/mage/cards/c/CathedralMembrane.java index 5eefc5d5c80..65c6e374de8 100644 --- a/Mage.Sets/src/mage/cards/c/CathedralMembrane.java +++ b/Mage.Sets/src/mage/cards/c/CathedralMembrane.java @@ -25,6 +25,7 @@ public final class CathedralMembrane extends CardImpl { public CathedralMembrane(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{W/P}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.WALL); this.power = new MageInt(0); diff --git a/Mage.Sets/src/mage/cards/c/CausticHound.java b/Mage.Sets/src/mage/cards/c/CausticHound.java index f01e20fae40..d714aa07df4 100644 --- a/Mage.Sets/src/mage/cards/c/CausticHound.java +++ b/Mage.Sets/src/mage/cards/c/CausticHound.java @@ -19,6 +19,7 @@ public final class CausticHound extends CardImpl { public CausticHound (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DOG); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/c/ChainedThroatseeker.java b/Mage.Sets/src/mage/cards/c/ChainedThroatseeker.java index ded5fb991e6..9b7e2601297 100644 --- a/Mage.Sets/src/mage/cards/c/ChainedThroatseeker.java +++ b/Mage.Sets/src/mage/cards/c/ChainedThroatseeker.java @@ -24,6 +24,7 @@ public final class ChainedThroatseeker extends CardImpl { public ChainedThroatseeker(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/c/ChancellorOfTheAnnex.java b/Mage.Sets/src/mage/cards/c/ChancellorOfTheAnnex.java index 7b73033e2cd..4996e9b3651 100644 --- a/Mage.Sets/src/mage/cards/c/ChancellorOfTheAnnex.java +++ b/Mage.Sets/src/mage/cards/c/ChancellorOfTheAnnex.java @@ -32,6 +32,7 @@ public final class ChancellorOfTheAnnex extends CardImpl { public ChancellorOfTheAnnex(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{W}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ANGEL); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/c/ChancellorOfTheDross.java b/Mage.Sets/src/mage/cards/c/ChancellorOfTheDross.java index bc9632fef5a..b7e0e726090 100644 --- a/Mage.Sets/src/mage/cards/c/ChancellorOfTheDross.java +++ b/Mage.Sets/src/mage/cards/c/ChancellorOfTheDross.java @@ -28,6 +28,7 @@ public final class ChancellorOfTheDross extends CardImpl { public ChancellorOfTheDross(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.VAMPIRE); this.power = new MageInt(6); diff --git a/Mage.Sets/src/mage/cards/c/ChancellorOfTheForge.java b/Mage.Sets/src/mage/cards/c/ChancellorOfTheForge.java index a32905f5ef6..f96678a9873 100644 --- a/Mage.Sets/src/mage/cards/c/ChancellorOfTheForge.java +++ b/Mage.Sets/src/mage/cards/c/ChancellorOfTheForge.java @@ -35,6 +35,7 @@ public final class ChancellorOfTheForge extends CardImpl { public ChancellorOfTheForge(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}{R}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.GIANT); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/c/ChancellorOfTheSpires.java b/Mage.Sets/src/mage/cards/c/ChancellorOfTheSpires.java index 75644b9222e..4dad811921b 100644 --- a/Mage.Sets/src/mage/cards/c/ChancellorOfTheSpires.java +++ b/Mage.Sets/src/mage/cards/c/ChancellorOfTheSpires.java @@ -39,6 +39,7 @@ public final class ChancellorOfTheSpires extends CardImpl { public ChancellorOfTheSpires(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SPHINX); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/c/ChancellorOfTheTangle.java b/Mage.Sets/src/mage/cards/c/ChancellorOfTheTangle.java index f925e067cf7..539cb46c070 100644 --- a/Mage.Sets/src/mage/cards/c/ChancellorOfTheTangle.java +++ b/Mage.Sets/src/mage/cards/c/ChancellorOfTheTangle.java @@ -27,6 +27,7 @@ public final class ChancellorOfTheTangle extends CardImpl { public ChancellorOfTheTangle(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); this.color.setGreen(true); diff --git a/Mage.Sets/src/mage/cards/c/CommanderGrevenIlVec.java b/Mage.Sets/src/mage/cards/c/CommanderGrevenIlVec.java index 029fa0b6ea6..e45b2594b01 100644 --- a/Mage.Sets/src/mage/cards/c/CommanderGrevenIlVec.java +++ b/Mage.Sets/src/mage/cards/c/CommanderGrevenIlVec.java @@ -22,6 +22,7 @@ public final class CommanderGrevenIlVec extends CardImpl { public CommanderGrevenIlVec(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}{B}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WARRIOR); diff --git a/Mage.Sets/src/mage/cards/c/ContagiousNim.java b/Mage.Sets/src/mage/cards/c/ContagiousNim.java index 55aefee4dc3..7a1fd057f74 100644 --- a/Mage.Sets/src/mage/cards/c/ContagiousNim.java +++ b/Mage.Sets/src/mage/cards/c/ContagiousNim.java @@ -18,6 +18,7 @@ public final class ContagiousNim extends CardImpl { public ContagiousNim (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/c/CoreProwler.java b/Mage.Sets/src/mage/cards/c/CoreProwler.java index 86c1e003a9a..cc6dd6d7140 100644 --- a/Mage.Sets/src/mage/cards/c/CoreProwler.java +++ b/Mage.Sets/src/mage/cards/c/CoreProwler.java @@ -18,6 +18,7 @@ public final class CoreProwler extends CardImpl { public CoreProwler(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/c/CorpseCur.java b/Mage.Sets/src/mage/cards/c/CorpseCur.java index 79144ef43c0..b41f588765f 100644 --- a/Mage.Sets/src/mage/cards/c/CorpseCur.java +++ b/Mage.Sets/src/mage/cards/c/CorpseCur.java @@ -30,6 +30,7 @@ public final class CorpseCur extends CardImpl { public CorpseCur (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DOG); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/c/CorruptedHarvester.java b/Mage.Sets/src/mage/cards/c/CorruptedHarvester.java index 6f52b9eb0a0..41051ae17a3 100644 --- a/Mage.Sets/src/mage/cards/c/CorruptedHarvester.java +++ b/Mage.Sets/src/mage/cards/c/CorruptedHarvester.java @@ -24,6 +24,7 @@ public final class CorruptedHarvester extends CardImpl { public CorruptedHarvester(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(6); diff --git a/Mage.Sets/src/mage/cards/c/CrazedSkirge.java b/Mage.Sets/src/mage/cards/c/CrazedSkirge.java index a9e63116d89..fa8d1548690 100644 --- a/Mage.Sets/src/mage/cards/c/CrazedSkirge.java +++ b/Mage.Sets/src/mage/cards/c/CrazedSkirge.java @@ -19,6 +19,7 @@ public final class CrazedSkirge extends CardImpl { public CrazedSkirge (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.IMP); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/c/Cystbearer.java b/Mage.Sets/src/mage/cards/c/Cystbearer.java index 1d3efdd69f7..819613649ca 100644 --- a/Mage.Sets/src/mage/cards/c/Cystbearer.java +++ b/Mage.Sets/src/mage/cards/c/Cystbearer.java @@ -19,6 +19,7 @@ public final class Cystbearer extends CardImpl { public Cystbearer(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/d/DarkslickDrake.java b/Mage.Sets/src/mage/cards/d/DarkslickDrake.java index a47db43bfc6..8330fa63a55 100644 --- a/Mage.Sets/src/mage/cards/d/DarkslickDrake.java +++ b/Mage.Sets/src/mage/cards/d/DarkslickDrake.java @@ -20,6 +20,7 @@ public final class DarkslickDrake extends CardImpl { public DarkslickDrake (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DRAKE); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/d/DeathHoodCobra.java b/Mage.Sets/src/mage/cards/d/DeathHoodCobra.java index fac884a547a..20cb20fc812 100644 --- a/Mage.Sets/src/mage/cards/d/DeathHoodCobra.java +++ b/Mage.Sets/src/mage/cards/d/DeathHoodCobra.java @@ -23,6 +23,7 @@ public final class DeathHoodCobra extends CardImpl { public DeathHoodCobra(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SNAKE); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/d/DeceiverExarch.java b/Mage.Sets/src/mage/cards/d/DeceiverExarch.java index 8df40e2715a..17746f20aa9 100644 --- a/Mage.Sets/src/mage/cards/d/DeceiverExarch.java +++ b/Mage.Sets/src/mage/cards/d/DeceiverExarch.java @@ -32,6 +32,7 @@ public final class DeceiverExarch extends CardImpl { public DeceiverExarch(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/d/DementiaBat.java b/Mage.Sets/src/mage/cards/d/DementiaBat.java index 26868d3de8d..1c5e09a9ff0 100644 --- a/Mage.Sets/src/mage/cards/d/DementiaBat.java +++ b/Mage.Sets/src/mage/cards/d/DementiaBat.java @@ -23,6 +23,7 @@ public final class DementiaBat extends CardImpl { public DementiaBat(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BAT); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/d/DevouringStrossus.java b/Mage.Sets/src/mage/cards/d/DevouringStrossus.java index 48aabae6397..b43ed0486ec 100644 --- a/Mage.Sets/src/mage/cards/d/DevouringStrossus.java +++ b/Mage.Sets/src/mage/cards/d/DevouringStrossus.java @@ -29,6 +29,7 @@ public final class DevouringStrossus extends CardImpl { public DevouringStrossus(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(9); this.toughness = new MageInt(9); diff --git a/Mage.Sets/src/mage/cards/d/DrossHopper.java b/Mage.Sets/src/mage/cards/d/DrossHopper.java index 038ed13d6aa..e6e7436661f 100644 --- a/Mage.Sets/src/mage/cards/d/DrossHopper.java +++ b/Mage.Sets/src/mage/cards/d/DrossHopper.java @@ -24,6 +24,7 @@ public final class DrossHopper extends CardImpl { public DrossHopper(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.INSECT); this.subtype.add(SubType.HORROR); diff --git a/Mage.Sets/src/mage/cards/d/DrossRipper.java b/Mage.Sets/src/mage/cards/d/DrossRipper.java index 836f431631d..76108b2e645 100644 --- a/Mage.Sets/src/mage/cards/d/DrossRipper.java +++ b/Mage.Sets/src/mage/cards/d/DrossRipper.java @@ -22,6 +22,7 @@ public final class DrossRipper extends CardImpl { public DrossRipper (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DOG); this.power = new MageInt(3); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/e/EasternPaladin.java b/Mage.Sets/src/mage/cards/e/EasternPaladin.java index ab42d68cd7e..3175c576afa 100644 --- a/Mage.Sets/src/mage/cards/e/EasternPaladin.java +++ b/Mage.Sets/src/mage/cards/e/EasternPaladin.java @@ -34,6 +34,7 @@ public final class EasternPaladin extends CardImpl { public EasternPaladin(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.KNIGHT); diff --git a/Mage.Sets/src/mage/cards/e/EleshNornGrandCenobite.java b/Mage.Sets/src/mage/cards/e/EleshNornGrandCenobite.java index ad81a30bfcc..de4a49bb3eb 100644 --- a/Mage.Sets/src/mage/cards/e/EleshNornGrandCenobite.java +++ b/Mage.Sets/src/mage/cards/e/EleshNornGrandCenobite.java @@ -25,6 +25,7 @@ public final class EleshNornGrandCenobite extends CardImpl { public EleshNornGrandCenobite (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{W}{W}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.PRAETOR); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/e/EntomberExarch.java b/Mage.Sets/src/mage/cards/e/EntomberExarch.java index 47e20164587..e7cec5acdfa 100644 --- a/Mage.Sets/src/mage/cards/e/EntomberExarch.java +++ b/Mage.Sets/src/mage/cards/e/EntomberExarch.java @@ -30,6 +30,7 @@ public final class EntomberExarch extends CardImpl { public EntomberExarch(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/e/ErtaiTheCorrupted.java b/Mage.Sets/src/mage/cards/e/ErtaiTheCorrupted.java index ee0b64a4713..6dbcf1eb89a 100644 --- a/Mage.Sets/src/mage/cards/e/ErtaiTheCorrupted.java +++ b/Mage.Sets/src/mage/cards/e/ErtaiTheCorrupted.java @@ -35,6 +35,7 @@ public final class ErtaiTheCorrupted extends CardImpl { public ErtaiTheCorrupted(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{U}{B}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/e/EtchedMonstrosity.java b/Mage.Sets/src/mage/cards/e/EtchedMonstrosity.java index 4ff300ff018..d3fd98c5434 100644 --- a/Mage.Sets/src/mage/cards/e/EtchedMonstrosity.java +++ b/Mage.Sets/src/mage/cards/e/EtchedMonstrosity.java @@ -26,6 +26,7 @@ public final class EtchedMonstrosity extends CardImpl { public EtchedMonstrosity(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.GOLEM); this.power = new MageInt(10); this.toughness = new MageInt(10); diff --git a/Mage.Sets/src/mage/cards/e/Eviscerator.java b/Mage.Sets/src/mage/cards/e/Eviscerator.java index bd3f38fa161..409c1b25427 100644 --- a/Mage.Sets/src/mage/cards/e/Eviscerator.java +++ b/Mage.Sets/src/mage/cards/e/Eviscerator.java @@ -20,6 +20,7 @@ public final class Eviscerator extends CardImpl { public Eviscerator(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/e/EzuriClawOfProgress.java b/Mage.Sets/src/mage/cards/e/EzuriClawOfProgress.java index ca7fcb1ec3b..edd8234b6f3 100644 --- a/Mage.Sets/src/mage/cards/e/EzuriClawOfProgress.java +++ b/Mage.Sets/src/mage/cards/e/EzuriClawOfProgress.java @@ -39,6 +39,7 @@ public final class EzuriClawOfProgress extends CardImpl { public EzuriClawOfProgress(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ELF); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/f/FallenFerromancer.java b/Mage.Sets/src/mage/cards/f/FallenFerromancer.java index 09e3454a1ef..c60a8807ae1 100644 --- a/Mage.Sets/src/mage/cards/f/FallenFerromancer.java +++ b/Mage.Sets/src/mage/cards/f/FallenFerromancer.java @@ -23,6 +23,7 @@ public final class FallenFerromancer extends CardImpl { public FallenFerromancer(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SHAMAN); diff --git a/Mage.Sets/src/mage/cards/f/FirstSphereGargantua.java b/Mage.Sets/src/mage/cards/f/FirstSphereGargantua.java index 5b3a6a47700..9d38483cf70 100644 --- a/Mage.Sets/src/mage/cards/f/FirstSphereGargantua.java +++ b/Mage.Sets/src/mage/cards/f/FirstSphereGargantua.java @@ -22,6 +22,7 @@ public final class FirstSphereGargantua extends CardImpl { public FirstSphereGargantua(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(5); this.toughness = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/f/FlamebornViron.java b/Mage.Sets/src/mage/cards/f/FlamebornViron.java index 27c3c1d4642..15f258b7893 100644 --- a/Mage.Sets/src/mage/cards/f/FlamebornViron.java +++ b/Mage.Sets/src/mage/cards/f/FlamebornViron.java @@ -16,6 +16,7 @@ public final class FlamebornViron extends CardImpl { public FlamebornViron(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.INSECT); this.power = new MageInt(6); diff --git a/Mage.Sets/src/mage/cards/f/Flensermite.java b/Mage.Sets/src/mage/cards/f/Flensermite.java index 27d514e28d7..7f85be3f471 100644 --- a/Mage.Sets/src/mage/cards/f/Flensermite.java +++ b/Mage.Sets/src/mage/cards/f/Flensermite.java @@ -19,6 +19,7 @@ public final class Flensermite extends CardImpl { public Flensermite (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.GREMLIN); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/f/FleshEaterImp.java b/Mage.Sets/src/mage/cards/f/FleshEaterImp.java index e4b25d8f784..2471dcd75b2 100644 --- a/Mage.Sets/src/mage/cards/f/FleshEaterImp.java +++ b/Mage.Sets/src/mage/cards/f/FleshEaterImp.java @@ -25,6 +25,7 @@ public final class FleshEaterImp extends CardImpl { public FleshEaterImp(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.IMP); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/f/FleshReaver.java b/Mage.Sets/src/mage/cards/f/FleshReaver.java index 9ae154836ab..4009bc9b55c 100644 --- a/Mage.Sets/src/mage/cards/f/FleshReaver.java +++ b/Mage.Sets/src/mage/cards/f/FleshReaver.java @@ -25,6 +25,7 @@ public final class FleshReaver extends CardImpl { public FleshReaver(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(4); this.toughness = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/f/FumeSpitter.java b/Mage.Sets/src/mage/cards/f/FumeSpitter.java index 951aa294229..e798ede933c 100644 --- a/Mage.Sets/src/mage/cards/f/FumeSpitter.java +++ b/Mage.Sets/src/mage/cards/f/FumeSpitter.java @@ -24,6 +24,7 @@ public final class FumeSpitter extends CardImpl { public FumeSpitter (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/f/FurnaceScamp.java b/Mage.Sets/src/mage/cards/f/FurnaceScamp.java index d9795473611..25619403d9f 100644 --- a/Mage.Sets/src/mage/cards/f/FurnaceScamp.java +++ b/Mage.Sets/src/mage/cards/f/FurnaceScamp.java @@ -20,6 +20,7 @@ public final class FurnaceScamp extends CardImpl { public FurnaceScamp(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/g/Gallowbraid.java b/Mage.Sets/src/mage/cards/g/Gallowbraid.java index 9702ad68c4c..a075db6c244 100644 --- a/Mage.Sets/src/mage/cards/g/Gallowbraid.java +++ b/Mage.Sets/src/mage/cards/g/Gallowbraid.java @@ -21,6 +21,7 @@ public final class Gallowbraid extends CardImpl { public Gallowbraid(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(5); this.toughness = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java b/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java index ce4b6e749ba..ee740491e08 100644 --- a/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java +++ b/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java @@ -36,6 +36,7 @@ public final class GethLordOfTheVault extends CardImpl { public GethLordOfTheVault(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/g/GlissaTheTraitor.java b/Mage.Sets/src/mage/cards/g/GlissaTheTraitor.java index 30cd49b5b11..0a6d9f23efb 100644 --- a/Mage.Sets/src/mage/cards/g/GlissaTheTraitor.java +++ b/Mage.Sets/src/mage/cards/g/GlissaTheTraitor.java @@ -30,6 +30,7 @@ public final class GlissaTheTraitor extends CardImpl { public GlissaTheTraitor (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}{G}{G}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.ELF); diff --git a/Mage.Sets/src/mage/cards/g/GlissasCourier.java b/Mage.Sets/src/mage/cards/g/GlissasCourier.java index 1b0aa00446d..e48b19e29f1 100644 --- a/Mage.Sets/src/mage/cards/g/GlissasCourier.java +++ b/Mage.Sets/src/mage/cards/g/GlissasCourier.java @@ -18,6 +18,7 @@ public final class GlissasCourier extends CardImpl { public GlissasCourier (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/g/GlistenerElf.java b/Mage.Sets/src/mage/cards/g/GlistenerElf.java index 85e1ccabd0c..b6a4ef0e46e 100644 --- a/Mage.Sets/src/mage/cards/g/GlistenerElf.java +++ b/Mage.Sets/src/mage/cards/g/GlistenerElf.java @@ -17,6 +17,7 @@ public final class GlistenerElf extends CardImpl { public GlistenerElf(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ELF); this.subtype.add(SubType.WARRIOR); diff --git a/Mage.Sets/src/mage/cards/g/GoreVassal.java b/Mage.Sets/src/mage/cards/g/GoreVassal.java index 3ee2ca92668..5832065e26e 100644 --- a/Mage.Sets/src/mage/cards/g/GoreVassal.java +++ b/Mage.Sets/src/mage/cards/g/GoreVassal.java @@ -23,6 +23,7 @@ public final class GoreVassal extends CardImpl { public GoreVassal(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DOG); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/g/GrevenPredatorCaptain.java b/Mage.Sets/src/mage/cards/g/GrevenPredatorCaptain.java index 97572ef20d9..1d3da75d417 100644 --- a/Mage.Sets/src/mage/cards/g/GrevenPredatorCaptain.java +++ b/Mage.Sets/src/mage/cards/g/GrevenPredatorCaptain.java @@ -31,6 +31,7 @@ public final class GrevenPredatorCaptain extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{R}"); this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/h/HandOfThePraetors.java b/Mage.Sets/src/mage/cards/h/HandOfThePraetors.java index 4d7f7854bb8..6787226fb5e 100644 --- a/Mage.Sets/src/mage/cards/h/HandOfThePraetors.java +++ b/Mage.Sets/src/mage/cards/h/HandOfThePraetors.java @@ -37,6 +37,7 @@ public final class HandOfThePraetors extends CardImpl { public HandOfThePraetors (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/h/HexParasite.java b/Mage.Sets/src/mage/cards/h/HexParasite.java index 1bcdd38ad9c..05a919f937b 100644 --- a/Mage.Sets/src/mage/cards/h/HexParasite.java +++ b/Mage.Sets/src/mage/cards/h/HexParasite.java @@ -23,6 +23,7 @@ public final class HexParasite extends CardImpl { public HexParasite(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.INSECT); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/h/HollowDogs.java b/Mage.Sets/src/mage/cards/h/HollowDogs.java index 339efb55d8b..bb9d98b219b 100644 --- a/Mage.Sets/src/mage/cards/h/HollowDogs.java +++ b/Mage.Sets/src/mage/cards/h/HollowDogs.java @@ -19,6 +19,7 @@ public final class HollowDogs extends CardImpl { public HollowDogs(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.DOG); diff --git a/Mage.Sets/src/mage/cards/i/IchTekikSalvageSplicer.java b/Mage.Sets/src/mage/cards/i/IchTekikSalvageSplicer.java index 583fc459907..a4550c6ab77 100644 --- a/Mage.Sets/src/mage/cards/i/IchTekikSalvageSplicer.java +++ b/Mage.Sets/src/mage/cards/i/IchTekikSalvageSplicer.java @@ -32,6 +32,7 @@ public final class IchTekikSalvageSplicer extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ARTIFICER); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/i/IchorRats.java b/Mage.Sets/src/mage/cards/i/IchorRats.java index d9a9a13dae6..6c7fcb39b3a 100644 --- a/Mage.Sets/src/mage/cards/i/IchorRats.java +++ b/Mage.Sets/src/mage/cards/i/IchorRats.java @@ -24,6 +24,7 @@ public final class IchorRats extends CardImpl { public IchorRats(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.RAT); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/i/IchorclawMyr.java b/Mage.Sets/src/mage/cards/i/IchorclawMyr.java index db36af568b1..c7441c698cd 100644 --- a/Mage.Sets/src/mage/cards/i/IchorclawMyr.java +++ b/Mage.Sets/src/mage/cards/i/IchorclawMyr.java @@ -20,6 +20,7 @@ public final class IchorclawMyr extends CardImpl { public IchorclawMyr(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MYR); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/i/ImmolatingSouleater.java b/Mage.Sets/src/mage/cards/i/ImmolatingSouleater.java index a7ee6f69730..c795d8e54ec 100644 --- a/Mage.Sets/src/mage/cards/i/ImmolatingSouleater.java +++ b/Mage.Sets/src/mage/cards/i/ImmolatingSouleater.java @@ -22,6 +22,7 @@ public final class ImmolatingSouleater extends CardImpl { public ImmolatingSouleater(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DOG); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/i/ImpalerShrike.java b/Mage.Sets/src/mage/cards/i/ImpalerShrike.java index 8608e617a7d..74a1ee1f339 100644 --- a/Mage.Sets/src/mage/cards/i/ImpalerShrike.java +++ b/Mage.Sets/src/mage/cards/i/ImpalerShrike.java @@ -21,6 +21,7 @@ public final class ImpalerShrike extends CardImpl { public ImpalerShrike(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BIRD); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/i/InquisitorExarch.java b/Mage.Sets/src/mage/cards/i/InquisitorExarch.java index 0c130d6b94f..c2ac1e11f29 100644 --- a/Mage.Sets/src/mage/cards/i/InquisitorExarch.java +++ b/Mage.Sets/src/mage/cards/i/InquisitorExarch.java @@ -22,6 +22,7 @@ public final class InquisitorExarch extends CardImpl { public InquisitorExarch(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/i/InsatiableSouleater.java b/Mage.Sets/src/mage/cards/i/InsatiableSouleater.java index d75eed0c29c..b6e2d3b19c9 100644 --- a/Mage.Sets/src/mage/cards/i/InsatiableSouleater.java +++ b/Mage.Sets/src/mage/cards/i/InsatiableSouleater.java @@ -23,6 +23,7 @@ public final class InsatiableSouleater extends CardImpl { public InsatiableSouleater(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/i/InvaderParasite.java b/Mage.Sets/src/mage/cards/i/InvaderParasite.java index cf730df4127..afce56d2f0c 100644 --- a/Mage.Sets/src/mage/cards/i/InvaderParasite.java +++ b/Mage.Sets/src/mage/cards/i/InvaderParasite.java @@ -30,6 +30,7 @@ public final class InvaderParasite extends CardImpl { public InvaderParasite(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.INSECT); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/j/JinGitaxiasCoreAugur.java b/Mage.Sets/src/mage/cards/j/JinGitaxiasCoreAugur.java index 96f8d89edc5..13961872526 100644 --- a/Mage.Sets/src/mage/cards/j/JinGitaxiasCoreAugur.java +++ b/Mage.Sets/src/mage/cards/j/JinGitaxiasCoreAugur.java @@ -22,6 +22,7 @@ public final class JinGitaxiasCoreAugur extends CardImpl { public JinGitaxiasCoreAugur(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{8}{U}{U}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.PRAETOR); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/k/KeskitTheFleshSculptor.java b/Mage.Sets/src/mage/cards/k/KeskitTheFleshSculptor.java index 8dfd0ab4cff..f1a3716bd85 100644 --- a/Mage.Sets/src/mage/cards/k/KeskitTheFleshSculptor.java +++ b/Mage.Sets/src/mage/cards/k/KeskitTheFleshSculptor.java @@ -42,6 +42,7 @@ public final class KeskitTheFleshSculptor extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ARTIFICER); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/k/KilnWalker.java b/Mage.Sets/src/mage/cards/k/KilnWalker.java index 2d1054fc1b4..ab8c70f078e 100644 --- a/Mage.Sets/src/mage/cards/k/KilnWalker.java +++ b/Mage.Sets/src/mage/cards/k/KilnWalker.java @@ -19,6 +19,7 @@ public final class KilnWalker extends CardImpl { public KilnWalker(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(0); diff --git a/Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java b/Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java index f4aafa65196..e4656e2a872 100644 --- a/Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java +++ b/Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java @@ -43,6 +43,7 @@ public final class KrrikSonOfYawgmoth extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B/P}{B/P}{B/P}"); this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.subtype.add(SubType.MINION); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/l/LostLeonin.java b/Mage.Sets/src/mage/cards/l/LostLeonin.java index b80e4bbf212..d7200e066bc 100644 --- a/Mage.Sets/src/mage/cards/l/LostLeonin.java +++ b/Mage.Sets/src/mage/cards/l/LostLeonin.java @@ -18,6 +18,7 @@ public final class LostLeonin extends CardImpl { public LostLeonin (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CAT); this.subtype.add(SubType.SOLDIER); diff --git a/Mage.Sets/src/mage/cards/l/LoxodonConvert.java b/Mage.Sets/src/mage/cards/l/LoxodonConvert.java index 5b855060575..1232bd23417 100644 --- a/Mage.Sets/src/mage/cards/l/LoxodonConvert.java +++ b/Mage.Sets/src/mage/cards/l/LoxodonConvert.java @@ -16,6 +16,7 @@ public final class LoxodonConvert extends CardImpl { public LoxodonConvert(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ELEPHANT); this.subtype.add(SubType.SOLDIER); diff --git a/Mage.Sets/src/mage/cards/m/MaraudingKnight.java b/Mage.Sets/src/mage/cards/m/MaraudingKnight.java index e40062705a7..5c392aa2a14 100644 --- a/Mage.Sets/src/mage/cards/m/MaraudingKnight.java +++ b/Mage.Sets/src/mage/cards/m/MaraudingKnight.java @@ -27,6 +27,7 @@ public final class MaraudingKnight extends CardImpl { public MaraudingKnight(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.KNIGHT); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/m/MassacreWurm.java b/Mage.Sets/src/mage/cards/m/MassacreWurm.java index 2bbd272e721..efab6b7e597 100644 --- a/Mage.Sets/src/mage/cards/m/MassacreWurm.java +++ b/Mage.Sets/src/mage/cards/m/MassacreWurm.java @@ -28,6 +28,7 @@ public final class MassacreWurm extends CardImpl { public MassacreWurm(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.WURM); this.power = new MageInt(6); diff --git a/Mage.Sets/src/mage/cards/m/MasterSplicer.java b/Mage.Sets/src/mage/cards/m/MasterSplicer.java index 9c88cb61aa9..6ce14383051 100644 --- a/Mage.Sets/src/mage/cards/m/MasterSplicer.java +++ b/Mage.Sets/src/mage/cards/m/MasterSplicer.java @@ -25,6 +25,7 @@ public final class MasterSplicer extends CardImpl { public MasterSplicer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ARTIFICER); diff --git a/Mage.Sets/src/mage/cards/m/MaulSplicer.java b/Mage.Sets/src/mage/cards/m/MaulSplicer.java index 8c4aeef1e4d..6196c8fda5e 100644 --- a/Mage.Sets/src/mage/cards/m/MaulSplicer.java +++ b/Mage.Sets/src/mage/cards/m/MaulSplicer.java @@ -31,6 +31,7 @@ public final class MaulSplicer extends CardImpl { public MaulSplicer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ARTIFICER); diff --git a/Mage.Sets/src/mage/cards/m/MoltensteelDragon.java b/Mage.Sets/src/mage/cards/m/MoltensteelDragon.java index 8a122be8e55..ad9430c080a 100644 --- a/Mage.Sets/src/mage/cards/m/MoltensteelDragon.java +++ b/Mage.Sets/src/mage/cards/m/MoltensteelDragon.java @@ -23,6 +23,7 @@ public final class MoltensteelDragon extends CardImpl { public MoltensteelDragon(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{R/P}{R/P}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DRAGON); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/m/Morinfen.java b/Mage.Sets/src/mage/cards/m/Morinfen.java index db88cd87995..5af5dc21bd9 100644 --- a/Mage.Sets/src/mage/cards/m/Morinfen.java +++ b/Mage.Sets/src/mage/cards/m/Morinfen.java @@ -21,6 +21,7 @@ public final class Morinfen extends CardImpl { public Morinfen(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(5); this.toughness = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/m/MortisDogs.java b/Mage.Sets/src/mage/cards/m/MortisDogs.java index 79e16db707f..8452603ca2e 100644 --- a/Mage.Sets/src/mage/cards/m/MortisDogs.java +++ b/Mage.Sets/src/mage/cards/m/MortisDogs.java @@ -24,6 +24,7 @@ public final class MortisDogs extends CardImpl { public MortisDogs(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DOG); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/m/MycosynthFiend.java b/Mage.Sets/src/mage/cards/m/MycosynthFiend.java index 895c8bde934..e13007a36b0 100644 --- a/Mage.Sets/src/mage/cards/m/MycosynthFiend.java +++ b/Mage.Sets/src/mage/cards/m/MycosynthFiend.java @@ -22,6 +22,7 @@ public final class MycosynthFiend extends CardImpl { public MycosynthFiend(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/m/MyrSire.java b/Mage.Sets/src/mage/cards/m/MyrSire.java index 80b28b593c9..cbbeaf6fbf1 100644 --- a/Mage.Sets/src/mage/cards/m/MyrSire.java +++ b/Mage.Sets/src/mage/cards/m/MyrSire.java @@ -20,6 +20,7 @@ public final class MyrSire extends CardImpl { public MyrSire (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MYR); this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/n/NecrogenScudder.java b/Mage.Sets/src/mage/cards/n/NecrogenScudder.java index 804bd41094f..04093299cdc 100644 --- a/Mage.Sets/src/mage/cards/n/NecrogenScudder.java +++ b/Mage.Sets/src/mage/cards/n/NecrogenScudder.java @@ -20,6 +20,7 @@ public final class NecrogenScudder extends CardImpl { public NecrogenScudder (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/n/Necropede.java b/Mage.Sets/src/mage/cards/n/Necropede.java index 5ec4b67ac1a..5234c9345ba 100644 --- a/Mage.Sets/src/mage/cards/n/Necropede.java +++ b/Mage.Sets/src/mage/cards/n/Necropede.java @@ -23,6 +23,7 @@ public final class Necropede extends CardImpl { public Necropede (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.INSECT); this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/n/NestedGhoul.java b/Mage.Sets/src/mage/cards/n/NestedGhoul.java index bf65048e36b..e1c4a84196d 100644 --- a/Mage.Sets/src/mage/cards/n/NestedGhoul.java +++ b/Mage.Sets/src/mage/cards/n/NestedGhoul.java @@ -23,6 +23,7 @@ public final class NestedGhoul extends CardImpl { public NestedGhoul(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.WARRIOR); diff --git a/Mage.Sets/src/mage/cards/o/Oculus.java b/Mage.Sets/src/mage/cards/o/Oculus.java index ee4129d7b93..0d7450f024c 100644 --- a/Mage.Sets/src/mage/cards/o/Oculus.java +++ b/Mage.Sets/src/mage/cards/o/Oculus.java @@ -19,6 +19,7 @@ public final class Oculus extends CardImpl { public Oculus (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HOMUNCULUS); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/o/OgreMenial.java b/Mage.Sets/src/mage/cards/o/OgreMenial.java index ceffc6711f6..e14899e7726 100644 --- a/Mage.Sets/src/mage/cards/o/OgreMenial.java +++ b/Mage.Sets/src/mage/cards/o/OgreMenial.java @@ -22,6 +22,7 @@ public final class OgreMenial extends CardImpl { public OgreMenial(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.OGRE); this.power = new MageInt(0); diff --git a/Mage.Sets/src/mage/cards/o/OrderOfYawgmoth.java b/Mage.Sets/src/mage/cards/o/OrderOfYawgmoth.java index 89a3089deb1..3f06a90e66b 100644 --- a/Mage.Sets/src/mage/cards/o/OrderOfYawgmoth.java +++ b/Mage.Sets/src/mage/cards/o/OrderOfYawgmoth.java @@ -19,6 +19,7 @@ public final class OrderOfYawgmoth extends CardImpl { public OrderOfYawgmoth(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.KNIGHT); diff --git a/Mage.Sets/src/mage/cards/p/PerilousMyr.java b/Mage.Sets/src/mage/cards/p/PerilousMyr.java index 2c5f45dc876..afbf76a9d9a 100644 --- a/Mage.Sets/src/mage/cards/p/PerilousMyr.java +++ b/Mage.Sets/src/mage/cards/p/PerilousMyr.java @@ -20,6 +20,7 @@ public final class PerilousMyr extends CardImpl { public PerilousMyr(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MYR); this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/p/PestilentSouleater.java b/Mage.Sets/src/mage/cards/p/PestilentSouleater.java index ffb9e5fe880..d9b448d4428 100644 --- a/Mage.Sets/src/mage/cards/p/PestilentSouleater.java +++ b/Mage.Sets/src/mage/cards/p/PestilentSouleater.java @@ -23,6 +23,7 @@ public final class PestilentSouleater extends CardImpl { public PestilentSouleater(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{5}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.INSECT); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianBattleflies.java b/Mage.Sets/src/mage/cards/p/PhyrexianBattleflies.java index 3b2b0c9e611..7d45906c444 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianBattleflies.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianBattleflies.java @@ -22,6 +22,7 @@ public final class PhyrexianBattleflies extends CardImpl { public PhyrexianBattleflies(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.INSECT); this.power = new MageInt(0); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianBloodstock.java b/Mage.Sets/src/mage/cards/p/PhyrexianBloodstock.java index eb56be94700..5b9fe000e32 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianBloodstock.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianBloodstock.java @@ -29,6 +29,7 @@ public final class PhyrexianBloodstock extends CardImpl { public PhyrexianBloodstock(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(3); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianBroodlings.java b/Mage.Sets/src/mage/cards/p/PhyrexianBroodlings.java index b9ad0325b52..f7cfd84feb2 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianBroodlings.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianBroodlings.java @@ -25,6 +25,7 @@ public final class PhyrexianBroodlings extends CardImpl { public PhyrexianBroodlings(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MINION); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianColossus.java b/Mage.Sets/src/mage/cards/p/PhyrexianColossus.java index a8c10394f0d..41efa4e30eb 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianColossus.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianColossus.java @@ -23,6 +23,7 @@ public final class PhyrexianColossus extends CardImpl { public PhyrexianColossus(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{7}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.GOLEM); this.power = new MageInt(8); this.toughness = new MageInt(8); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianCrusader.java b/Mage.Sets/src/mage/cards/p/PhyrexianCrusader.java index 4f866559bc2..8cb0097d494 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianCrusader.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianCrusader.java @@ -21,6 +21,7 @@ public final class PhyrexianCrusader extends CardImpl { public PhyrexianCrusader(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.KNIGHT); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianDebaser.java b/Mage.Sets/src/mage/cards/p/PhyrexianDebaser.java index 04b7d3cd855..d97cbdfaa63 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianDebaser.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianDebaser.java @@ -25,6 +25,7 @@ public final class PhyrexianDebaser extends CardImpl { public PhyrexianDebaser(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CARRIER); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianDefiler.java b/Mage.Sets/src/mage/cards/p/PhyrexianDefiler.java index ef48e2f84b4..6d0a9a24f10 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianDefiler.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianDefiler.java @@ -24,6 +24,7 @@ public final class PhyrexianDefiler extends CardImpl { public PhyrexianDefiler(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CARRIER); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianDelver.java b/Mage.Sets/src/mage/cards/p/PhyrexianDelver.java index cd04e49362f..b7dc555b964 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianDelver.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianDelver.java @@ -27,6 +27,7 @@ public final class PhyrexianDelver extends CardImpl { public PhyrexianDelver(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianDenouncer.java b/Mage.Sets/src/mage/cards/p/PhyrexianDenouncer.java index 430ba97e7b8..5c596ffad95 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianDenouncer.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianDenouncer.java @@ -24,6 +24,7 @@ public final class PhyrexianDenouncer extends CardImpl { public PhyrexianDenouncer(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CARRIER); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianDevourer.java b/Mage.Sets/src/mage/cards/p/PhyrexianDevourer.java index a6bea763ef5..88c41c0f2a9 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianDevourer.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianDevourer.java @@ -32,6 +32,7 @@ public final class PhyrexianDevourer extends CardImpl { public PhyrexianDevourer(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{6}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianDigester.java b/Mage.Sets/src/mage/cards/p/PhyrexianDigester.java index 02f437763db..7f4d7d73622 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianDigester.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianDigester.java @@ -18,6 +18,7 @@ public final class PhyrexianDigester extends CardImpl { public PhyrexianDigester (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(2); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianDreadnought.java b/Mage.Sets/src/mage/cards/p/PhyrexianDreadnought.java index c8f0c49bc24..a036ab16ca5 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianDreadnought.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianDreadnought.java @@ -29,6 +29,7 @@ public final class PhyrexianDreadnought extends CardImpl { public PhyrexianDreadnought(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DREADNOUGHT); this.power = new MageInt(12); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianDriver.java b/Mage.Sets/src/mage/cards/p/PhyrexianDriver.java index cc1c72e13c2..c3f47d64eb9 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianDriver.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianDriver.java @@ -25,6 +25,7 @@ public final class PhyrexianDriver extends CardImpl { public PhyrexianDriver(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.MERCENARY); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianGargantua.java b/Mage.Sets/src/mage/cards/p/PhyrexianGargantua.java index 37dce20cca4..a3f6df076d4 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianGargantua.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianGargantua.java @@ -20,6 +20,7 @@ public final class PhyrexianGargantua extends CardImpl { public PhyrexianGargantua(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianGhoul.java b/Mage.Sets/src/mage/cards/p/PhyrexianGhoul.java index 72c98e9a71b..b8334fd6cb4 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianGhoul.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianGhoul.java @@ -23,6 +23,7 @@ public final class PhyrexianGhoul extends CardImpl { public PhyrexianGhoul(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianGremlins.java b/Mage.Sets/src/mage/cards/p/PhyrexianGremlins.java index ded2cb376a1..a96aeb80ccc 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianGremlins.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianGremlins.java @@ -24,6 +24,7 @@ public final class PhyrexianGremlins extends CardImpl { public PhyrexianGremlins(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.GREMLIN); this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianHulk.java b/Mage.Sets/src/mage/cards/p/PhyrexianHulk.java index 31f33cc063e..477768c9770 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianHulk.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianHulk.java @@ -16,6 +16,7 @@ public final class PhyrexianHulk extends CardImpl { public PhyrexianHulk(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{6}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.GOLEM); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianHydra.java b/Mage.Sets/src/mage/cards/p/PhyrexianHydra.java index 047e72c39cf..9618dc9ec0e 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianHydra.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianHydra.java @@ -28,6 +28,7 @@ public final class PhyrexianHydra extends CardImpl { public PhyrexianHydra(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HYDRA); this.power = new MageInt(7); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianInfiltrator.java b/Mage.Sets/src/mage/cards/p/PhyrexianInfiltrator.java index 0c1b60c6b21..1ff5018dd8a 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianInfiltrator.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianInfiltrator.java @@ -23,6 +23,7 @@ public final class PhyrexianInfiltrator extends CardImpl { public PhyrexianInfiltrator(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MINION); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianIngester.java b/Mage.Sets/src/mage/cards/p/PhyrexianIngester.java index a3663b8f253..333c7b2efdf 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianIngester.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianIngester.java @@ -41,6 +41,7 @@ public final class PhyrexianIngester extends CardImpl { public PhyrexianIngester(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{6}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianIronfoot.java b/Mage.Sets/src/mage/cards/p/PhyrexianIronfoot.java index aedbc1eb91a..8dac37ec770 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianIronfoot.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianIronfoot.java @@ -24,6 +24,7 @@ public final class PhyrexianIronfoot extends CardImpl { public PhyrexianIronfoot(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}"); this.addSuperType(SuperType.SNOW); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(3); this.toughness = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianJuggernaut.java b/Mage.Sets/src/mage/cards/p/PhyrexianJuggernaut.java index b49b5951d31..54d97d43d09 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianJuggernaut.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianJuggernaut.java @@ -19,6 +19,7 @@ public final class PhyrexianJuggernaut extends CardImpl { public PhyrexianJuggernaut (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{6}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.JUGGERNAUT); this.power = new MageInt(5); this.toughness = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianMarauder.java b/Mage.Sets/src/mage/cards/p/PhyrexianMarauder.java index 49572995d8c..4a851f03506 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianMarauder.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianMarauder.java @@ -29,6 +29,7 @@ public final class PhyrexianMarauder extends CardImpl { public PhyrexianMarauder(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{X}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(0); this.toughness = new MageInt(0); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianMonitor.java b/Mage.Sets/src/mage/cards/p/PhyrexianMonitor.java index 3fb874d210a..282168ae6a6 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianMonitor.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianMonitor.java @@ -20,6 +20,7 @@ public final class PhyrexianMonitor extends CardImpl { public PhyrexianMonitor(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SKELETON); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianNegator.java b/Mage.Sets/src/mage/cards/p/PhyrexianNegator.java index 3f22d7d60fb..db1318db6f8 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianNegator.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianNegator.java @@ -26,6 +26,7 @@ public final class PhyrexianNegator extends CardImpl { public PhyrexianNegator(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianObliterator.java b/Mage.Sets/src/mage/cards/p/PhyrexianObliterator.java index 7a317304466..31b0acd27f5 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianObliterator.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianObliterator.java @@ -27,6 +27,7 @@ public final class PhyrexianObliterator extends CardImpl { public PhyrexianObliterator(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}{B}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianPlaguelord.java b/Mage.Sets/src/mage/cards/p/PhyrexianPlaguelord.java index f60ad774345..6c4d05ec56a 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianPlaguelord.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianPlaguelord.java @@ -27,6 +27,7 @@ public final class PhyrexianPlaguelord extends CardImpl { public PhyrexianPlaguelord(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CARRIER); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianProwler.java b/Mage.Sets/src/mage/cards/p/PhyrexianProwler.java index 23e6c2fc698..92db310ee74 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianProwler.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianProwler.java @@ -23,6 +23,7 @@ public final class PhyrexianProwler extends CardImpl { public PhyrexianProwler(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.MERCENARY); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianRager.java b/Mage.Sets/src/mage/cards/p/PhyrexianRager.java index 91a37d4fba3..a3e6ad0e9a0 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianRager.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianRager.java @@ -19,6 +19,7 @@ public final class PhyrexianRager extends CardImpl { public PhyrexianRager(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianReaper.java b/Mage.Sets/src/mage/cards/p/PhyrexianReaper.java index c959a2802b6..3c78c06997b 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianReaper.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianReaper.java @@ -27,6 +27,7 @@ public final class PhyrexianReaper extends CardImpl { public PhyrexianReaper(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(3); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianRevoker.java b/Mage.Sets/src/mage/cards/p/PhyrexianRevoker.java index 06e0e58a258..0f8cec5c36b 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianRevoker.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianRevoker.java @@ -24,6 +24,7 @@ public final class PhyrexianRevoker extends CardImpl { public PhyrexianRevoker(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianScuta.java b/Mage.Sets/src/mage/cards/p/PhyrexianScuta.java index cb3bae29fc7..dc20822ee15 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianScuta.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianScuta.java @@ -23,6 +23,7 @@ public final class PhyrexianScuta extends CardImpl { public PhyrexianScuta(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(3); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianSlayer.java b/Mage.Sets/src/mage/cards/p/PhyrexianSlayer.java index 73fd21fb32a..530a39fc9f8 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianSlayer.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianSlayer.java @@ -28,6 +28,7 @@ public final class PhyrexianSlayer extends CardImpl { public PhyrexianSlayer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MINION); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianSnowcrusher.java b/Mage.Sets/src/mage/cards/p/PhyrexianSnowcrusher.java index 8d6f0d87514..c44cf992ea1 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianSnowcrusher.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianSnowcrusher.java @@ -24,6 +24,7 @@ public final class PhyrexianSnowcrusher extends CardImpl { public PhyrexianSnowcrusher(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{6}"); addSuperType(SuperType.SNOW); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.JUGGERNAUT); this.power = new MageInt(6); this.toughness = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianSoulgorger.java b/Mage.Sets/src/mage/cards/p/PhyrexianSoulgorger.java index 2f978ceb9f0..2fb992c28b5 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianSoulgorger.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianSoulgorger.java @@ -22,6 +22,7 @@ public final class PhyrexianSoulgorger extends CardImpl { public PhyrexianSoulgorger(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); addSuperType(SuperType.SNOW); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(8); this.toughness = new MageInt(8); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianSwarmlord.java b/Mage.Sets/src/mage/cards/p/PhyrexianSwarmlord.java index b392a6e1a17..81cf6a32190 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianSwarmlord.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianSwarmlord.java @@ -22,6 +22,7 @@ public final class PhyrexianSwarmlord extends CardImpl { public PhyrexianSwarmlord(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.INSECT); this.subtype.add(SubType.HORROR); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianTriniform.java b/Mage.Sets/src/mage/cards/p/PhyrexianTriniform.java index d0bc175183b..fbe1b5be0cb 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianTriniform.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianTriniform.java @@ -21,6 +21,7 @@ public final class PhyrexianTriniform extends CardImpl { public PhyrexianTriniform(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{9}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.GOLEM); this.power = new MageInt(9); this.toughness = new MageInt(9); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianVatmother.java b/Mage.Sets/src/mage/cards/p/PhyrexianVatmother.java index 5c7fd054292..b1f88a2b7e5 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianVatmother.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianVatmother.java @@ -26,6 +26,7 @@ public final class PhyrexianVatmother extends CardImpl { public PhyrexianVatmother (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianWalker.java b/Mage.Sets/src/mage/cards/p/PhyrexianWalker.java index 2bb8358176a..63cd908abbb 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianWalker.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianWalker.java @@ -16,6 +16,7 @@ public final class PhyrexianWalker extends CardImpl { public PhyrexianWalker(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{0}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(0); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianWarBeast.java b/Mage.Sets/src/mage/cards/p/PhyrexianWarBeast.java index e1114fa7216..6e90f756ed2 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianWarBeast.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianWarBeast.java @@ -21,6 +21,7 @@ public final class PhyrexianWarBeast extends CardImpl { public PhyrexianWarBeast(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); this.power = new MageInt(3); this.toughness = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/p/PierceStrider.java b/Mage.Sets/src/mage/cards/p/PierceStrider.java index 1b9e8012ce4..ae288f53ed5 100644 --- a/Mage.Sets/src/mage/cards/p/PierceStrider.java +++ b/Mage.Sets/src/mage/cards/p/PierceStrider.java @@ -21,6 +21,7 @@ public final class PierceStrider extends CardImpl { public PierceStrider (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(3); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PithDriller.java b/Mage.Sets/src/mage/cards/p/PithDriller.java index 07b44f03063..4af034313ed 100644 --- a/Mage.Sets/src/mage/cards/p/PithDriller.java +++ b/Mage.Sets/src/mage/cards/p/PithDriller.java @@ -20,6 +20,7 @@ public final class PithDriller extends CardImpl { public PithDriller(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{B/P}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/p/PlagueDogs.java b/Mage.Sets/src/mage/cards/p/PlagueDogs.java index 3ce5d491a27..00dc8bec8ed 100644 --- a/Mage.Sets/src/mage/cards/p/PlagueDogs.java +++ b/Mage.Sets/src/mage/cards/p/PlagueDogs.java @@ -25,6 +25,7 @@ public final class PlagueDogs extends CardImpl { public PlagueDogs(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.DOG); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PlagueMyr.java b/Mage.Sets/src/mage/cards/p/PlagueMyr.java index c8299ae807b..a287eb12d03 100644 --- a/Mage.Sets/src/mage/cards/p/PlagueMyr.java +++ b/Mage.Sets/src/mage/cards/p/PlagueMyr.java @@ -19,6 +19,7 @@ public final class PlagueMyr extends CardImpl { public PlagueMyr (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MYR); this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/p/PlagueSpitter.java b/Mage.Sets/src/mage/cards/p/PlagueSpitter.java index 891f967a046..48cdf8a7abc 100644 --- a/Mage.Sets/src/mage/cards/p/PlagueSpitter.java +++ b/Mage.Sets/src/mage/cards/p/PlagueSpitter.java @@ -21,6 +21,7 @@ public final class PlagueSpitter extends CardImpl { public PlagueSpitter(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/p/PlagueStinger.java b/Mage.Sets/src/mage/cards/p/PlagueStinger.java index 2b7a79919b1..4860c65aa03 100644 --- a/Mage.Sets/src/mage/cards/p/PlagueStinger.java +++ b/Mage.Sets/src/mage/cards/p/PlagueStinger.java @@ -19,6 +19,7 @@ public final class PlagueStinger extends CardImpl { public PlagueStinger (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.INSECT); this.subtype.add(SubType.HORROR); diff --git a/Mage.Sets/src/mage/cards/p/PlaguemawBeast.java b/Mage.Sets/src/mage/cards/p/PlaguemawBeast.java index a179e9745c4..0e8605cf1b5 100644 --- a/Mage.Sets/src/mage/cards/p/PlaguemawBeast.java +++ b/Mage.Sets/src/mage/cards/p/PlaguemawBeast.java @@ -24,6 +24,7 @@ public final class PlaguemawBeast extends CardImpl { public PlaguemawBeast(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/p/PorcelainLegionnaire.java b/Mage.Sets/src/mage/cards/p/PorcelainLegionnaire.java index 0d82ca2d424..8b41e7c4da4 100644 --- a/Mage.Sets/src/mage/cards/p/PorcelainLegionnaire.java +++ b/Mage.Sets/src/mage/cards/p/PorcelainLegionnaire.java @@ -17,6 +17,7 @@ public final class PorcelainLegionnaire extends CardImpl { public PorcelainLegionnaire(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}{W/P}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SOLDIER); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/p/PriestOfGix.java b/Mage.Sets/src/mage/cards/p/PriestOfGix.java index 84ff832bc1f..a6c52f6426f 100644 --- a/Mage.Sets/src/mage/cards/p/PriestOfGix.java +++ b/Mage.Sets/src/mage/cards/p/PriestOfGix.java @@ -19,6 +19,7 @@ public final class PriestOfGix extends CardImpl { public PriestOfGix(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); this.subtype.add(SubType.MINION); diff --git a/Mage.Sets/src/mage/cards/p/PriestOfUrabrask.java b/Mage.Sets/src/mage/cards/p/PriestOfUrabrask.java index d7dd0a8f16e..7188a59cf29 100644 --- a/Mage.Sets/src/mage/cards/p/PriestOfUrabrask.java +++ b/Mage.Sets/src/mage/cards/p/PriestOfUrabrask.java @@ -19,6 +19,7 @@ public final class PriestOfUrabrask extends CardImpl { public PriestOfUrabrask(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); diff --git a/Mage.Sets/src/mage/cards/p/PriestOfYawgmoth.java b/Mage.Sets/src/mage/cards/p/PriestOfYawgmoth.java index 8dbc04fd347..fcf8f65ba77 100644 --- a/Mage.Sets/src/mage/cards/p/PriestOfYawgmoth.java +++ b/Mage.Sets/src/mage/cards/p/PriestOfYawgmoth.java @@ -25,6 +25,7 @@ public final class PriestOfYawgmoth extends CardImpl { public PriestOfYawgmoth(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/p/PriestsOfNorn.java b/Mage.Sets/src/mage/cards/p/PriestsOfNorn.java index 986f99b3c56..58c2da44cab 100644 --- a/Mage.Sets/src/mage/cards/p/PriestsOfNorn.java +++ b/Mage.Sets/src/mage/cards/p/PriestsOfNorn.java @@ -19,6 +19,7 @@ public final class PriestsOfNorn extends CardImpl { public PriestsOfNorn (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/p/PsychosisCrawler.java b/Mage.Sets/src/mage/cards/p/PsychosisCrawler.java index 4b1d2c583f0..63e23e9087e 100644 --- a/Mage.Sets/src/mage/cards/p/PsychosisCrawler.java +++ b/Mage.Sets/src/mage/cards/p/PsychosisCrawler.java @@ -23,6 +23,7 @@ public final class PsychosisCrawler extends CardImpl { public PsychosisCrawler(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(0); diff --git a/Mage.Sets/src/mage/cards/p/Putrefax.java b/Mage.Sets/src/mage/cards/p/Putrefax.java index 57e19ef3166..f024fbf7be9 100644 --- a/Mage.Sets/src/mage/cards/p/Putrefax.java +++ b/Mage.Sets/src/mage/cards/p/Putrefax.java @@ -23,6 +23,7 @@ public final class Putrefax extends CardImpl { public Putrefax (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/q/QuilledSlagwurm.java b/Mage.Sets/src/mage/cards/q/QuilledSlagwurm.java index 60032380a64..12b43c47f79 100644 --- a/Mage.Sets/src/mage/cards/q/QuilledSlagwurm.java +++ b/Mage.Sets/src/mage/cards/q/QuilledSlagwurm.java @@ -17,6 +17,7 @@ public final class QuilledSlagwurm extends CardImpl { public QuilledSlagwurm (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.WURM); this.power = new MageInt(8); diff --git a/Mage.Sets/src/mage/cards/r/Rackling.java b/Mage.Sets/src/mage/cards/r/Rackling.java index 3cbb3f21cff..44c76e398c2 100644 --- a/Mage.Sets/src/mage/cards/r/Rackling.java +++ b/Mage.Sets/src/mage/cards/r/Rackling.java @@ -20,6 +20,7 @@ public final class Rackling extends CardImpl { public Rackling(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/r/RathiFiend.java b/Mage.Sets/src/mage/cards/r/RathiFiend.java index 288abb93a72..faace34319a 100644 --- a/Mage.Sets/src/mage/cards/r/RathiFiend.java +++ b/Mage.Sets/src/mage/cards/r/RathiFiend.java @@ -35,6 +35,7 @@ public final class RathiFiend extends CardImpl { public RathiFiend(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.subtype.add(SubType.MERCENARY); diff --git a/Mage.Sets/src/mage/cards/r/RathiIntimidator.java b/Mage.Sets/src/mage/cards/r/RathiIntimidator.java index b5c282d24fc..2b8bb22a2fe 100644 --- a/Mage.Sets/src/mage/cards/r/RathiIntimidator.java +++ b/Mage.Sets/src/mage/cards/r/RathiIntimidator.java @@ -34,6 +34,7 @@ public final class RathiIntimidator extends CardImpl { public RathiIntimidator(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.subtype.add(SubType.MERCENARY); diff --git a/Mage.Sets/src/mage/cards/r/RavenousSkirge.java b/Mage.Sets/src/mage/cards/r/RavenousSkirge.java index 03d37e43d43..7131d4b54e1 100644 --- a/Mage.Sets/src/mage/cards/r/RavenousSkirge.java +++ b/Mage.Sets/src/mage/cards/r/RavenousSkirge.java @@ -20,6 +20,7 @@ public final class RavenousSkirge extends CardImpl { public RavenousSkirge(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.IMP); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/r/RazorSwine.java b/Mage.Sets/src/mage/cards/r/RazorSwine.java index 27008c282f4..69653b3d333 100644 --- a/Mage.Sets/src/mage/cards/r/RazorSwine.java +++ b/Mage.Sets/src/mage/cards/r/RazorSwine.java @@ -18,6 +18,7 @@ public final class RazorSwine extends CardImpl { public RazorSwine(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BOAR); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/r/ReaperOfSheoldred.java b/Mage.Sets/src/mage/cards/r/ReaperOfSheoldred.java index c8314506266..66d96f9741f 100644 --- a/Mage.Sets/src/mage/cards/r/ReaperOfSheoldred.java +++ b/Mage.Sets/src/mage/cards/r/ReaperOfSheoldred.java @@ -27,6 +27,7 @@ public final class ReaperOfSheoldred extends CardImpl { public ReaperOfSheoldred(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/r/RotWolf.java b/Mage.Sets/src/mage/cards/r/RotWolf.java index e7e4674583e..1d4a0d92c5f 100644 --- a/Mage.Sets/src/mage/cards/r/RotWolf.java +++ b/Mage.Sets/src/mage/cards/r/RotWolf.java @@ -19,6 +19,7 @@ public final class RotWolf extends CardImpl { public RotWolf(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.WOLF); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/r/RottedHystrix.java b/Mage.Sets/src/mage/cards/r/RottedHystrix.java index 1bff74a7420..b45275a4a7b 100644 --- a/Mage.Sets/src/mage/cards/r/RottedHystrix.java +++ b/Mage.Sets/src/mage/cards/r/RottedHystrix.java @@ -16,6 +16,7 @@ public final class RottedHystrix extends CardImpl { public RottedHystrix(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/r/RustedSlasher.java b/Mage.Sets/src/mage/cards/r/RustedSlasher.java index 9e6e9010b43..7dbaf64020f 100644 --- a/Mage.Sets/src/mage/cards/r/RustedSlasher.java +++ b/Mage.Sets/src/mage/cards/r/RustedSlasher.java @@ -28,6 +28,7 @@ public final class RustedSlasher extends CardImpl { public RustedSlasher (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(4); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/s/SanguineGuard.java b/Mage.Sets/src/mage/cards/s/SanguineGuard.java index f1ad156270c..c92605234b2 100644 --- a/Mage.Sets/src/mage/cards/s/SanguineGuard.java +++ b/Mage.Sets/src/mage/cards/s/SanguineGuard.java @@ -22,6 +22,7 @@ public final class SanguineGuard extends CardImpl { public SanguineGuard(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.KNIGHT); diff --git a/Mage.Sets/src/mage/cards/s/SarcomiteMyr.java b/Mage.Sets/src/mage/cards/s/SarcomiteMyr.java index aec0f789693..5a26130a84f 100644 --- a/Mage.Sets/src/mage/cards/s/SarcomiteMyr.java +++ b/Mage.Sets/src/mage/cards/s/SarcomiteMyr.java @@ -25,6 +25,7 @@ public final class SarcomiteMyr extends CardImpl { public SarcomiteMyr(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MYR); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/s/ScourgeServant.java b/Mage.Sets/src/mage/cards/s/ScourgeServant.java index d104e85ab43..bcd1cacd990 100644 --- a/Mage.Sets/src/mage/cards/s/ScourgeServant.java +++ b/Mage.Sets/src/mage/cards/s/ScourgeServant.java @@ -18,6 +18,7 @@ public final class ScourgeServant extends CardImpl { public ScourgeServant (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/s/SeleniaDarkAngel.java b/Mage.Sets/src/mage/cards/s/SeleniaDarkAngel.java index 98fa401c919..6f068b71954 100644 --- a/Mage.Sets/src/mage/cards/s/SeleniaDarkAngel.java +++ b/Mage.Sets/src/mage/cards/s/SeleniaDarkAngel.java @@ -23,6 +23,7 @@ public final class SeleniaDarkAngel extends CardImpl { public SeleniaDarkAngel(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{B}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ANGEL); diff --git a/Mage.Sets/src/mage/cards/s/SensorSplicer.java b/Mage.Sets/src/mage/cards/s/SensorSplicer.java index 2b6f3f277fd..f530bbf39c2 100644 --- a/Mage.Sets/src/mage/cards/s/SensorSplicer.java +++ b/Mage.Sets/src/mage/cards/s/SensorSplicer.java @@ -31,6 +31,7 @@ public final class SensorSplicer extends CardImpl { public SensorSplicer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ARTIFICER); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/s/SepticRats.java b/Mage.Sets/src/mage/cards/s/SepticRats.java index 3e6eea36d44..d2c1ab757f0 100644 --- a/Mage.Sets/src/mage/cards/s/SepticRats.java +++ b/Mage.Sets/src/mage/cards/s/SepticRats.java @@ -26,6 +26,7 @@ public final class SepticRats extends CardImpl { public SepticRats(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.RAT); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/s/SerumRaker.java b/Mage.Sets/src/mage/cards/s/SerumRaker.java index 9055a92de9e..0ad107a9c0b 100644 --- a/Mage.Sets/src/mage/cards/s/SerumRaker.java +++ b/Mage.Sets/src/mage/cards/s/SerumRaker.java @@ -20,6 +20,7 @@ public final class SerumRaker extends CardImpl { public SerumRaker (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DRAKE); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/s/ShatteredAngel.java b/Mage.Sets/src/mage/cards/s/ShatteredAngel.java index 4e894aa6295..dca5cccaf0b 100644 --- a/Mage.Sets/src/mage/cards/s/ShatteredAngel.java +++ b/Mage.Sets/src/mage/cards/s/ShatteredAngel.java @@ -29,6 +29,7 @@ public final class ShatteredAngel extends CardImpl { public ShatteredAngel (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ANGEL); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/s/ShivanZombie.java b/Mage.Sets/src/mage/cards/s/ShivanZombie.java index 5a1e0e3132f..f0cd0a6ea15 100644 --- a/Mage.Sets/src/mage/cards/s/ShivanZombie.java +++ b/Mage.Sets/src/mage/cards/s/ShivanZombie.java @@ -18,6 +18,7 @@ public final class ShivanZombie extends CardImpl { public ShivanZombie(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}{R}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BARBARIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/s/ShriekRaptor.java b/Mage.Sets/src/mage/cards/s/ShriekRaptor.java index 44a4f4b0dcf..d01ac8c6a5a 100644 --- a/Mage.Sets/src/mage/cards/s/ShriekRaptor.java +++ b/Mage.Sets/src/mage/cards/s/ShriekRaptor.java @@ -18,6 +18,7 @@ public final class ShriekRaptor extends CardImpl { public ShriekRaptor(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BIRD); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/s/Skinrender.java b/Mage.Sets/src/mage/cards/s/Skinrender.java index 305fd352001..fa6dd4ec93f 100644 --- a/Mage.Sets/src/mage/cards/s/Skinrender.java +++ b/Mage.Sets/src/mage/cards/s/Skinrender.java @@ -24,6 +24,7 @@ public final class Skinrender extends CardImpl { public Skinrender(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/s/SkirgeFamiliar.java b/Mage.Sets/src/mage/cards/s/SkirgeFamiliar.java index 17882fa725e..b7a95acc200 100644 --- a/Mage.Sets/src/mage/cards/s/SkirgeFamiliar.java +++ b/Mage.Sets/src/mage/cards/s/SkirgeFamiliar.java @@ -23,6 +23,7 @@ public final class SkirgeFamiliar extends CardImpl { public SkirgeFamiliar(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.IMP); this.power = new MageInt(3); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/s/SkithiryxTheBlightDragon.java b/Mage.Sets/src/mage/cards/s/SkithiryxTheBlightDragon.java index 02fcc0eaf08..95279e779e5 100644 --- a/Mage.Sets/src/mage/cards/s/SkithiryxTheBlightDragon.java +++ b/Mage.Sets/src/mage/cards/s/SkithiryxTheBlightDragon.java @@ -28,6 +28,7 @@ public final class SkithiryxTheBlightDragon extends CardImpl { public SkithiryxTheBlightDragon (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DRAGON); this.subtype.add(SubType.SKELETON); diff --git a/Mage.Sets/src/mage/cards/s/SkitteringHorror.java b/Mage.Sets/src/mage/cards/s/SkitteringHorror.java index c976589973e..f685d21d370 100644 --- a/Mage.Sets/src/mage/cards/s/SkitteringHorror.java +++ b/Mage.Sets/src/mage/cards/s/SkitteringHorror.java @@ -19,6 +19,7 @@ public final class SkitteringHorror extends CardImpl { public SkitteringHorror(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(4); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/s/SkitteringSkirge.java b/Mage.Sets/src/mage/cards/s/SkitteringSkirge.java index 57654a9e52f..0623afc013f 100644 --- a/Mage.Sets/src/mage/cards/s/SkitteringSkirge.java +++ b/Mage.Sets/src/mage/cards/s/SkitteringSkirge.java @@ -20,6 +20,7 @@ public final class SkitteringSkirge extends CardImpl { public SkitteringSkirge(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.IMP); this.power = new MageInt(3); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/s/SlagFiend.java b/Mage.Sets/src/mage/cards/s/SlagFiend.java index ed858c3c1cf..d90c39afa63 100644 --- a/Mage.Sets/src/mage/cards/s/SlagFiend.java +++ b/Mage.Sets/src/mage/cards/s/SlagFiend.java @@ -22,6 +22,7 @@ public final class SlagFiend extends CardImpl { public SlagFiend(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(0); diff --git a/Mage.Sets/src/mage/cards/s/SlashPanther.java b/Mage.Sets/src/mage/cards/s/SlashPanther.java index cf54f9b1fe2..f0aecde0e97 100644 --- a/Mage.Sets/src/mage/cards/s/SlashPanther.java +++ b/Mage.Sets/src/mage/cards/s/SlashPanther.java @@ -17,6 +17,7 @@ public final class SlashPanther extends CardImpl { public SlashPanther(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{R/P}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CAT); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/s/SleeperAgent.java b/Mage.Sets/src/mage/cards/s/SleeperAgent.java index 26740b62f07..38ad6e0df9e 100644 --- a/Mage.Sets/src/mage/cards/s/SleeperAgent.java +++ b/Mage.Sets/src/mage/cards/s/SleeperAgent.java @@ -29,6 +29,7 @@ public final class SleeperAgent extends CardImpl { public SleeperAgent(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MINION); this.power = new MageInt(3); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/s/SlinkingSkirge.java b/Mage.Sets/src/mage/cards/s/SlinkingSkirge.java index e1ebd0e38c4..36d65b56eb0 100644 --- a/Mage.Sets/src/mage/cards/s/SlinkingSkirge.java +++ b/Mage.Sets/src/mage/cards/s/SlinkingSkirge.java @@ -23,6 +23,7 @@ public final class SlinkingSkirge extends CardImpl { public SlinkingSkirge(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.IMP); this.power = new MageInt(2); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/s/SoulOfNewPhyrexia.java b/Mage.Sets/src/mage/cards/s/SoulOfNewPhyrexia.java index cbfaf7b84a5..cc289bfa397 100644 --- a/Mage.Sets/src/mage/cards/s/SoulOfNewPhyrexia.java +++ b/Mage.Sets/src/mage/cards/s/SoulOfNewPhyrexia.java @@ -25,6 +25,7 @@ public final class SoulOfNewPhyrexia extends CardImpl { public SoulOfNewPhyrexia(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{6}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.AVATAR); this.power = new MageInt(6); diff --git a/Mage.Sets/src/mage/cards/s/Spellskite.java b/Mage.Sets/src/mage/cards/s/Spellskite.java index 21cad613489..f96b3ef70d4 100644 --- a/Mage.Sets/src/mage/cards/s/Spellskite.java +++ b/Mage.Sets/src/mage/cards/s/Spellskite.java @@ -32,6 +32,7 @@ public final class Spellskite extends CardImpl { public Spellskite(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(0); this.toughness = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/s/Spinebiter.java b/Mage.Sets/src/mage/cards/s/Spinebiter.java index bf935245b15..cb7a129873f 100644 --- a/Mage.Sets/src/mage/cards/s/Spinebiter.java +++ b/Mage.Sets/src/mage/cards/s/Spinebiter.java @@ -18,6 +18,7 @@ public final class Spinebiter extends CardImpl { public Spinebiter(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/s/SpinedThopter.java b/Mage.Sets/src/mage/cards/s/SpinedThopter.java index ac9f578473a..6ab3bdb076e 100644 --- a/Mage.Sets/src/mage/cards/s/SpinedThopter.java +++ b/Mage.Sets/src/mage/cards/s/SpinedThopter.java @@ -17,6 +17,7 @@ public final class SpinedThopter extends CardImpl { public SpinedThopter(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}{U/P}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.THOPTER); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/s/SpinelessThug.java b/Mage.Sets/src/mage/cards/s/SpinelessThug.java index 476c7ccc542..9b76ce7b93b 100644 --- a/Mage.Sets/src/mage/cards/s/SpinelessThug.java +++ b/Mage.Sets/src/mage/cards/s/SpinelessThug.java @@ -17,6 +17,7 @@ public final class SpinelessThug extends CardImpl { public SpinelessThug(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.MERCENARY); diff --git a/Mage.Sets/src/mage/cards/s/SpireMonitor.java b/Mage.Sets/src/mage/cards/s/SpireMonitor.java index 6e93c425d94..c03ca88b553 100644 --- a/Mage.Sets/src/mage/cards/s/SpireMonitor.java +++ b/Mage.Sets/src/mage/cards/s/SpireMonitor.java @@ -18,6 +18,7 @@ public final class SpireMonitor extends CardImpl { public SpireMonitor(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DRAKE); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/s/SpitefulBully.java b/Mage.Sets/src/mage/cards/s/SpitefulBully.java index 5f069b76c4f..e1470a78428 100644 --- a/Mage.Sets/src/mage/cards/s/SpitefulBully.java +++ b/Mage.Sets/src/mage/cards/s/SpitefulBully.java @@ -22,6 +22,7 @@ public final class SpitefulBully extends CardImpl { public SpitefulBully(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.MERCENARY); this.power = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/s/StrongholdAssassin.java b/Mage.Sets/src/mage/cards/s/StrongholdAssassin.java index 1b1d2d772f6..f7e3849f601 100644 --- a/Mage.Sets/src/mage/cards/s/StrongholdAssassin.java +++ b/Mage.Sets/src/mage/cards/s/StrongholdAssassin.java @@ -36,6 +36,7 @@ public final class StrongholdAssassin extends CardImpl { public StrongholdAssassin(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.ASSASSIN); diff --git a/Mage.Sets/src/mage/cards/s/SuturePriest.java b/Mage.Sets/src/mage/cards/s/SuturePriest.java index 6cf412d3590..5baa7e14a62 100644 --- a/Mage.Sets/src/mage/cards/s/SuturePriest.java +++ b/Mage.Sets/src/mage/cards/s/SuturePriest.java @@ -29,6 +29,7 @@ public final class SuturePriest extends CardImpl { public SuturePriest(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/t/TangleAngler.java b/Mage.Sets/src/mage/cards/t/TangleAngler.java index 7c759660a40..923170315fb 100644 --- a/Mage.Sets/src/mage/cards/t/TangleAngler.java +++ b/Mage.Sets/src/mage/cards/t/TangleAngler.java @@ -23,6 +23,7 @@ public final class TangleAngler extends CardImpl { public TangleAngler(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/t/TangleHulk.java b/Mage.Sets/src/mage/cards/t/TangleHulk.java index 962ba1c4ac3..b07d14d693a 100644 --- a/Mage.Sets/src/mage/cards/t/TangleHulk.java +++ b/Mage.Sets/src/mage/cards/t/TangleHulk.java @@ -21,6 +21,7 @@ public final class TangleHulk extends CardImpl { public TangleHulk (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{5}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); this.power = new MageInt(5); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/t/TelJiladFallen.java b/Mage.Sets/src/mage/cards/t/TelJiladFallen.java index 252725852db..53b4d32b42b 100644 --- a/Mage.Sets/src/mage/cards/t/TelJiladFallen.java +++ b/Mage.Sets/src/mage/cards/t/TelJiladFallen.java @@ -20,6 +20,7 @@ public final class TelJiladFallen extends CardImpl { public TelJiladFallen (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ELF); this.subtype.add(SubType.WARRIOR); diff --git a/Mage.Sets/src/mage/cards/t/TetheredSkirge.java b/Mage.Sets/src/mage/cards/t/TetheredSkirge.java index 9057fa2800f..015eb2eb10a 100644 --- a/Mage.Sets/src/mage/cards/t/TetheredSkirge.java +++ b/Mage.Sets/src/mage/cards/t/TetheredSkirge.java @@ -19,6 +19,7 @@ public final class TetheredSkirge extends CardImpl { public TetheredSkirge(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.IMP); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/t/Thrummingbird.java b/Mage.Sets/src/mage/cards/t/Thrummingbird.java index d7dc1578dec..e2e55f1c1b7 100644 --- a/Mage.Sets/src/mage/cards/t/Thrummingbird.java +++ b/Mage.Sets/src/mage/cards/t/Thrummingbird.java @@ -18,6 +18,7 @@ public final class Thrummingbird extends CardImpl { public Thrummingbird(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BIRD); this.subtype.add(SubType.HORROR); diff --git a/Mage.Sets/src/mage/cards/t/ThunderingTanadon.java b/Mage.Sets/src/mage/cards/t/ThunderingTanadon.java index 5bfd2a81b05..986bb4e0b7a 100644 --- a/Mage.Sets/src/mage/cards/t/ThunderingTanadon.java +++ b/Mage.Sets/src/mage/cards/t/ThunderingTanadon.java @@ -17,6 +17,7 @@ public final class ThunderingTanadon extends CardImpl { public ThunderingTanadon(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{G/P}{G/P}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BEAST); this.power = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/t/TineShrike.java b/Mage.Sets/src/mage/cards/t/TineShrike.java index ec3b05cdb7b..1340dd4ce0f 100644 --- a/Mage.Sets/src/mage/cards/t/TineShrike.java +++ b/Mage.Sets/src/mage/cards/t/TineShrike.java @@ -19,6 +19,7 @@ public final class TineShrike extends CardImpl { public TineShrike (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BIRD); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/t/TormentorExarch.java b/Mage.Sets/src/mage/cards/t/TormentorExarch.java index d4aeec1687a..e005ad9d6d8 100644 --- a/Mage.Sets/src/mage/cards/t/TormentorExarch.java +++ b/Mage.Sets/src/mage/cards/t/TormentorExarch.java @@ -22,6 +22,7 @@ public final class TormentorExarch extends CardImpl { public TormentorExarch(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/t/ToxicNim.java b/Mage.Sets/src/mage/cards/t/ToxicNim.java index dd5ef530e08..5e24e935af4 100644 --- a/Mage.Sets/src/mage/cards/t/ToxicNim.java +++ b/Mage.Sets/src/mage/cards/t/ToxicNim.java @@ -21,6 +21,7 @@ public final class ToxicNim extends CardImpl { public ToxicNim(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/t/TrespassingSouleater.java b/Mage.Sets/src/mage/cards/t/TrespassingSouleater.java index 72cf877b71f..6dc1726a4ad 100644 --- a/Mage.Sets/src/mage/cards/t/TrespassingSouleater.java +++ b/Mage.Sets/src/mage/cards/t/TrespassingSouleater.java @@ -22,6 +22,7 @@ public final class TrespassingSouleater extends CardImpl { public TrespassingSouleater(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/t/TsaboTavoc.java b/Mage.Sets/src/mage/cards/t/TsaboTavoc.java index 205410f5d65..3bd7bfbd3ae 100644 --- a/Mage.Sets/src/mage/cards/t/TsaboTavoc.java +++ b/Mage.Sets/src/mage/cards/t/TsaboTavoc.java @@ -36,6 +36,7 @@ public final class TsaboTavoc extends CardImpl { public TsaboTavoc(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}{R}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(7); diff --git a/Mage.Sets/src/mage/cards/t/TsabosAssassin.java b/Mage.Sets/src/mage/cards/t/TsabosAssassin.java index 9ab680eb9b3..38cf883be9f 100644 --- a/Mage.Sets/src/mage/cards/t/TsabosAssassin.java +++ b/Mage.Sets/src/mage/cards/t/TsabosAssassin.java @@ -31,6 +31,7 @@ public final class TsabosAssassin extends CardImpl { public TsabosAssassin(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.ASSASSIN); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/u/UnworthyDead.java b/Mage.Sets/src/mage/cards/u/UnworthyDead.java index 10f52cf38eb..a6acfbdc4b8 100644 --- a/Mage.Sets/src/mage/cards/u/UnworthyDead.java +++ b/Mage.Sets/src/mage/cards/u/UnworthyDead.java @@ -21,6 +21,7 @@ public final class UnworthyDead extends CardImpl { public UnworthyDead(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SKELETON); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/u/UrabraskTheHidden.java b/Mage.Sets/src/mage/cards/u/UrabraskTheHidden.java index 234e1e00208..b70145d94fe 100644 --- a/Mage.Sets/src/mage/cards/u/UrabraskTheHidden.java +++ b/Mage.Sets/src/mage/cards/u/UrabraskTheHidden.java @@ -27,6 +27,7 @@ public final class UrabraskTheHidden extends CardImpl { public UrabraskTheHidden(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{R}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.PRAETOR); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/v/VaultSkirge.java b/Mage.Sets/src/mage/cards/v/VaultSkirge.java index 2e3450585d0..73db74576b4 100644 --- a/Mage.Sets/src/mage/cards/v/VaultSkirge.java +++ b/Mage.Sets/src/mage/cards/v/VaultSkirge.java @@ -18,6 +18,7 @@ public final class VaultSkirge extends CardImpl { public VaultSkirge(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{1}{B/P}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.IMP); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/v/Vebulid.java b/Mage.Sets/src/mage/cards/v/Vebulid.java index 59fc0e50a1c..6f36e1fcb4d 100644 --- a/Mage.Sets/src/mage/cards/v/Vebulid.java +++ b/Mage.Sets/src/mage/cards/v/Vebulid.java @@ -26,6 +26,7 @@ public final class Vebulid extends CardImpl { public Vebulid(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(0); this.toughness = new MageInt(0); diff --git a/Mage.Sets/src/mage/cards/v/VectorAsp.java b/Mage.Sets/src/mage/cards/v/VectorAsp.java index 1414f9c011b..4a5804b4e15 100644 --- a/Mage.Sets/src/mage/cards/v/VectorAsp.java +++ b/Mage.Sets/src/mage/cards/v/VectorAsp.java @@ -23,6 +23,7 @@ public final class VectorAsp extends CardImpl { public VectorAsp (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{1}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SNAKE); this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/v/VedalkenAnatomist.java b/Mage.Sets/src/mage/cards/v/VedalkenAnatomist.java index ecfb5264bfa..b7f57cb519f 100644 --- a/Mage.Sets/src/mage/cards/v/VedalkenAnatomist.java +++ b/Mage.Sets/src/mage/cards/v/VedalkenAnatomist.java @@ -25,6 +25,7 @@ public final class VedalkenAnatomist extends CardImpl { public VedalkenAnatomist(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.VEDALKEN); this.subtype.add(SubType.WIZARD); diff --git a/Mage.Sets/src/mage/cards/v/ViralDrake.java b/Mage.Sets/src/mage/cards/v/ViralDrake.java index 83223a8aebe..3b20768ad5c 100644 --- a/Mage.Sets/src/mage/cards/v/ViralDrake.java +++ b/Mage.Sets/src/mage/cards/v/ViralDrake.java @@ -21,6 +21,7 @@ public final class ViralDrake extends CardImpl { public ViralDrake(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DRAKE); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/v/ViridianBetrayers.java b/Mage.Sets/src/mage/cards/v/ViridianBetrayers.java index f1305c09d40..4ce8889986c 100644 --- a/Mage.Sets/src/mage/cards/v/ViridianBetrayers.java +++ b/Mage.Sets/src/mage/cards/v/ViridianBetrayers.java @@ -28,6 +28,7 @@ public final class ViridianBetrayers extends CardImpl { public ViridianBetrayers(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ELF); this.subtype.add(SubType.WARRIOR); diff --git a/Mage.Sets/src/mage/cards/v/ViridianCorrupter.java b/Mage.Sets/src/mage/cards/v/ViridianCorrupter.java index 9e70cb46ecc..1a73219ba97 100644 --- a/Mage.Sets/src/mage/cards/v/ViridianCorrupter.java +++ b/Mage.Sets/src/mage/cards/v/ViridianCorrupter.java @@ -21,6 +21,7 @@ public final class ViridianCorrupter extends CardImpl { public ViridianCorrupter (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ELF); this.subtype.add(SubType.SHAMAN); diff --git a/Mage.Sets/src/mage/cards/v/ViridianEmissary.java b/Mage.Sets/src/mage/cards/v/ViridianEmissary.java index bf4bae5caa7..43ae5d4e0cd 100644 --- a/Mage.Sets/src/mage/cards/v/ViridianEmissary.java +++ b/Mage.Sets/src/mage/cards/v/ViridianEmissary.java @@ -21,6 +21,7 @@ public final class ViridianEmissary extends CardImpl { public ViridianEmissary(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ELF); this.subtype.add(SubType.SCOUT); diff --git a/Mage.Sets/src/mage/cards/v/Viseling.java b/Mage.Sets/src/mage/cards/v/Viseling.java index 0851a03baf8..b48d058b83b 100644 --- a/Mage.Sets/src/mage/cards/v/Viseling.java +++ b/Mage.Sets/src/mage/cards/v/Viseling.java @@ -22,6 +22,7 @@ public final class Viseling extends CardImpl { public Viseling(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/v/VitalSplicer.java b/Mage.Sets/src/mage/cards/v/VitalSplicer.java index 57be559a9e5..273a495e13e 100644 --- a/Mage.Sets/src/mage/cards/v/VitalSplicer.java +++ b/Mage.Sets/src/mage/cards/v/VitalSplicer.java @@ -34,6 +34,7 @@ public final class VitalSplicer extends CardImpl { public VitalSplicer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ARTIFICER); diff --git a/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java b/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java index 5c02ce8411a..d8e325e3c2a 100644 --- a/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java +++ b/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java @@ -27,6 +27,7 @@ public final class VolrathTheFallen extends CardImpl { public VolrathTheFallen(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}{B}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SHAPESHIFTER); this.power = new MageInt(6); this.toughness = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/v/VolrathTheShapestealer.java b/Mage.Sets/src/mage/cards/v/VolrathTheShapestealer.java index 1772a12e95a..fb45ecb6cef 100644 --- a/Mage.Sets/src/mage/cards/v/VolrathTheShapestealer.java +++ b/Mage.Sets/src/mage/cards/v/VolrathTheShapestealer.java @@ -42,6 +42,7 @@ public final class VolrathTheShapestealer extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{G}{U}"); this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SHAPESHIFTER); this.power = new MageInt(7); this.toughness = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/v/VolrathsShapeshifter.java b/Mage.Sets/src/mage/cards/v/VolrathsShapeshifter.java index 640cb71e713..aa2c8058abe 100644 --- a/Mage.Sets/src/mage/cards/v/VolrathsShapeshifter.java +++ b/Mage.Sets/src/mage/cards/v/VolrathsShapeshifter.java @@ -23,6 +23,7 @@ public final class VolrathsShapeshifter extends CardImpl { public VolrathsShapeshifter(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SHAPESHIFTER); this.power = new MageInt(0); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/v/VorinclexVoiceOfHunger.java b/Mage.Sets/src/mage/cards/v/VorinclexVoiceOfHunger.java index 594dc6c7235..252dcc66d74 100644 --- a/Mage.Sets/src/mage/cards/v/VorinclexVoiceOfHunger.java +++ b/Mage.Sets/src/mage/cards/v/VorinclexVoiceOfHunger.java @@ -30,6 +30,7 @@ public final class VorinclexVoiceOfHunger extends CardImpl { public VorinclexVoiceOfHunger(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{G}{G}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.PRAETOR); this.power = new MageInt(7); diff --git a/Mage.Sets/src/mage/cards/w/WesternPaladin.java b/Mage.Sets/src/mage/cards/w/WesternPaladin.java index 0dee6ec8637..cd00734e1ba 100644 --- a/Mage.Sets/src/mage/cards/w/WesternPaladin.java +++ b/Mage.Sets/src/mage/cards/w/WesternPaladin.java @@ -34,6 +34,7 @@ public final class WesternPaladin extends CardImpl { public WesternPaladin(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.KNIGHT); diff --git a/Mage.Sets/src/mage/cards/w/WhisperingSpecter.java b/Mage.Sets/src/mage/cards/w/WhisperingSpecter.java index b3309a01572..e70cc5d209b 100644 --- a/Mage.Sets/src/mage/cards/w/WhisperingSpecter.java +++ b/Mage.Sets/src/mage/cards/w/WhisperingSpecter.java @@ -26,6 +26,7 @@ public final class WhisperingSpecter extends CardImpl { public WhisperingSpecter(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SPECTER); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/w/WingSplicer.java b/Mage.Sets/src/mage/cards/w/WingSplicer.java index 5cb56fe321f..595bf41e0c6 100644 --- a/Mage.Sets/src/mage/cards/w/WingSplicer.java +++ b/Mage.Sets/src/mage/cards/w/WingSplicer.java @@ -31,6 +31,7 @@ public final class WingSplicer extends CardImpl { public WingSplicer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ARTIFICER); diff --git a/Mage.Sets/src/mage/cards/w/WurmcoilEngine.java b/Mage.Sets/src/mage/cards/w/WurmcoilEngine.java index 37e0a9b0791..1249227af04 100644 --- a/Mage.Sets/src/mage/cards/w/WurmcoilEngine.java +++ b/Mage.Sets/src/mage/cards/w/WurmcoilEngine.java @@ -22,6 +22,7 @@ public final class WurmcoilEngine extends CardImpl { public WurmcoilEngine(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.WURM); this.power = new MageInt(6); this.toughness = new MageInt(6); diff --git a/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java index 41800ad8537..00f1b6d472d 100644 --- a/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java +++ b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java @@ -30,6 +30,7 @@ public final class XantchaSleeperAgent extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}"); this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MINION); this.power = new MageInt(5); this.toughness = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/y/YawgmothDemon.java b/Mage.Sets/src/mage/cards/y/YawgmothDemon.java index 5b62a083daa..dbc0c266458 100644 --- a/Mage.Sets/src/mage/cards/y/YawgmothDemon.java +++ b/Mage.Sets/src/mage/cards/y/YawgmothDemon.java @@ -24,6 +24,7 @@ public final class YawgmothDemon extends CardImpl { public YawgmothDemon(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.DEMON); this.power = new MageInt(6); this.toughness = new MageInt(6); From 5f8d746fc062ccf0d3686dcafbc34b37ae608804 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 10 Jun 2021 20:29:07 -0400 Subject: [PATCH 183/188] updated tokens with phyrexian subtype --- Mage.Sets/src/mage/cards/b/BladeSplicer.java | 4 +- .../cards/b/BrudicladTelchorEngineer.java | 2 +- .../mage/cards/c/ChancellorOfTheForge.java | 7 ++-- .../src/mage/cards/c/ConversionChamber.java | 4 +- .../src/mage/cards/e/EzurisPredation.java | 6 +-- .../mage/cards/i/IchTekikSalvageSplicer.java | 4 +- Mage.Sets/src/mage/cards/m/MasterSplicer.java | 4 +- Mage.Sets/src/mage/cards/m/MaulSplicer.java | 4 +- Mage.Sets/src/mage/cards/m/MyrSire.java | 17 ++++----- Mage.Sets/src/mage/cards/n/NestedGhoul.java | 5 ++- .../src/mage/cards/p/ParasiticImplant.java | 16 ++++---- .../src/mage/cards/p/PhyrexianProcessor.java | 2 +- .../src/mage/cards/p/PhyrexianRebirth.java | 2 +- .../src/mage/cards/p/PhyrexianTriniform.java | 4 +- Mage.Sets/src/mage/cards/s/SensorSplicer.java | 4 +- .../mage/cards/s/ShrineOfLoyalLegions.java | 11 +++--- Mage.Sets/src/mage/cards/s/SplicersSkill.java | 4 +- Mage.Sets/src/mage/cards/v/VitalSplicer.java | 4 +- Mage.Sets/src/mage/cards/w/WingSplicer.java | 4 +- .../src/mage/cards/w/WurmcoilEngine.java | 2 +- .../java/mage/verify/VerifyCardDataTest.java | 1 - .../token/BrudicladTelchorMyrToken.java | 16 +++----- .../mage/game/permanent/token/GermToken.java | 2 +- .../permanent/token/InsectInfectToken.java | 12 +++--- .../game/permanent/token/MinionToken.java | 3 +- .../mage/game/permanent/token/MyrToken.java | 2 +- .../permanent/token/PhyrexianBeastToken.java | 30 +++++++++++++++ .../permanent/token/PhyrexianGoblinToken.java | 36 ++++++++++++++++++ .../permanent/token/PhyrexianGolemToken.java | 38 +++++++++++++++++++ .../permanent/token/PhyrexianMyrToken.java | 26 +++++++++++++ .../token/PhyrexianRebirthHorrorToken.java | 3 +- .../permanent/token/PhyrexianZombieToken.java | 34 +++++++++++++++++ .../token/WurmWithDeathtouchToken.java | 3 +- .../token/WurmWithLifelinkToken.java | 3 +- 34 files changed, 237 insertions(+), 82 deletions(-) create mode 100644 Mage/src/main/java/mage/game/permanent/token/PhyrexianBeastToken.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/PhyrexianGoblinToken.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/PhyrexianGolemToken.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/PhyrexianMyrToken.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/PhyrexianZombieToken.java diff --git a/Mage.Sets/src/mage/cards/b/BladeSplicer.java b/Mage.Sets/src/mage/cards/b/BladeSplicer.java index 28ce2b57257..3fd48e080cf 100644 --- a/Mage.Sets/src/mage/cards/b/BladeSplicer.java +++ b/Mage.Sets/src/mage/cards/b/BladeSplicer.java @@ -13,7 +13,7 @@ import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterPermanent; -import mage.game.permanent.token.GolemToken; +import mage.game.permanent.token.PhyrexianGolemToken; import java.util.UUID; @@ -36,7 +36,7 @@ public final class BladeSplicer extends CardImpl { this.toughness = new MageInt(1); // When Blade Splicer enters the battlefield, create a 3/3 colorless Golem artifact creature token. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GolemToken()))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new PhyrexianGolemToken()))); // Golem creatures you control have first strike. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield, filter))); diff --git a/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java b/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java index c59c29d4bff..dfff1b8ab04 100644 --- a/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java +++ b/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java @@ -70,7 +70,7 @@ class BrudicladTelchorEngineerEffect extends OneShotEffect { public BrudicladTelchorEngineerEffect() { super(Outcome.Sacrifice); - this.staticText = " create a 2/1 blue Myr artifact creature token. Then you may choose a token you control. If you do, each other token you control becomes a copy of that token"; + this.staticText = " create a 2/1 blue Phyrexian Myr artifact creature token. Then you may choose a token you control. If you do, each other token you control becomes a copy of that token"; } public BrudicladTelchorEngineerEffect(final BrudicladTelchorEngineerEffect effect) { diff --git a/Mage.Sets/src/mage/cards/c/ChancellorOfTheForge.java b/Mage.Sets/src/mage/cards/c/ChancellorOfTheForge.java index f96678a9873..c735aa1cacc 100644 --- a/Mage.Sets/src/mage/cards/c/ChancellorOfTheForge.java +++ b/Mage.Sets/src/mage/cards/c/ChancellorOfTheForge.java @@ -16,8 +16,7 @@ import mage.constants.TargetController; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.token.GoblinToken; +import mage.game.permanent.token.PhyrexianGoblinToken; import java.util.UUID; @@ -46,7 +45,7 @@ public final class ChancellorOfTheForge extends CardImpl { // When Chancellor of the Forge enters the battlefield, create X 1/1 red Goblin creature tokens with haste, where X is the number of creatures you control. DynamicValue value = new PermanentsOnBattlefieldCount(filter); - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GoblinToken(true), value), false) + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new PhyrexianGoblinToken(), value), false) .addHint(CreaturesYouControlHint.instance)); } @@ -63,7 +62,7 @@ public final class ChancellorOfTheForge extends CardImpl { class ChancellorOfTheForgeDelayedTriggeredAbility extends DelayedTriggeredAbility { ChancellorOfTheForgeDelayedTriggeredAbility() { - super(new CreateTokenEffect(new GoblinToken(true))); + super(new CreateTokenEffect(new PhyrexianGoblinToken())); } ChancellorOfTheForgeDelayedTriggeredAbility(ChancellorOfTheForgeDelayedTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/cards/c/ConversionChamber.java b/Mage.Sets/src/mage/cards/c/ConversionChamber.java index 3a3a148c576..2664ecbd125 100644 --- a/Mage.Sets/src/mage/cards/c/ConversionChamber.java +++ b/Mage.Sets/src/mage/cards/c/ConversionChamber.java @@ -14,7 +14,7 @@ import mage.constants.CardType; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterArtifactCard; -import mage.game.permanent.token.GolemToken; +import mage.game.permanent.token.PhyrexianGolemToken; import mage.target.common.TargetCardInGraveyard; import java.util.UUID; @@ -33,7 +33,7 @@ public final class ConversionChamber extends CardImpl { ability.addCost(new TapSourceCost()); this.addAbility(ability); // {2}, {T}, Remove a charge counter from Conversion Chamber: Create a 3/3 colorless Golem artifact creature token. - ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new GolemToken()), new GenericManaCost(2)); + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new PhyrexianGolemToken()), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); ability.addCost(new RemoveCountersSourceCost(CounterType.CHARGE.createInstance())); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/e/EzurisPredation.java b/Mage.Sets/src/mage/cards/e/EzurisPredation.java index fd82097d512..3c2b5556728 100644 --- a/Mage.Sets/src/mage/cards/e/EzurisPredation.java +++ b/Mage.Sets/src/mage/cards/e/EzurisPredation.java @@ -14,7 +14,7 @@ import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; -import mage.game.permanent.token.BeastToken2; +import mage.game.permanent.token.PhyrexianBeastToken; import mage.players.Player; import java.util.HashSet; @@ -48,7 +48,7 @@ class EzurisPredationEffect extends OneShotEffect { public EzurisPredationEffect() { super(Outcome.PutCreatureInPlay); - this.staticText = "For each creature your opponents control, create a 4/4 green Beast creature token. Each of those Beasts fights a different one of those creatures"; + this.staticText = "For each creature your opponents control, create a 4/4 green Phyrexian Beast creature token. Each of those Beasts fights a different one of those creatures"; } public EzurisPredationEffect(final EzurisPredationEffect effect) { @@ -81,7 +81,7 @@ class EzurisPredationEffect extends OneShotEffect { List creaturesOfOpponents = game.getBattlefield().getActivePermanents(filterCreature, source.getControllerId(), source.getSourceId(), game); Set morSet = new HashSet<>(); if (!creaturesOfOpponents.isEmpty()) { - CreateTokenEffect effect = new CreateTokenEffect(new BeastToken2(), creaturesOfOpponents.size()); + CreateTokenEffect effect = new CreateTokenEffect(new PhyrexianBeastToken(), creaturesOfOpponents.size()); effect.apply(game, source); for (UUID tokenId : effect.getLastAddedTokenIds()) { Permanent token = game.getPermanent(tokenId); diff --git a/Mage.Sets/src/mage/cards/i/IchTekikSalvageSplicer.java b/Mage.Sets/src/mage/cards/i/IchTekikSalvageSplicer.java index a4550c6ab77..46effe8f592 100644 --- a/Mage.Sets/src/mage/cards/i/IchTekikSalvageSplicer.java +++ b/Mage.Sets/src/mage/cards/i/IchTekikSalvageSplicer.java @@ -17,7 +17,7 @@ import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; -import mage.game.permanent.token.GolemToken; +import mage.game.permanent.token.PhyrexianGolemToken; import java.util.UUID; @@ -39,7 +39,7 @@ public final class IchTekikSalvageSplicer extends CardImpl { this.toughness = new MageInt(1); // When Ich-Tekik, Salvage Splicer enters the battlefield, create a 3/3 colorless Golem artifact creature token. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GolemToken()))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new PhyrexianGolemToken()))); // Whenever an artifact is put into a graveyard from the battlefield, put a +1/+1 counter on Ich-Tekik and a +1/+1 counter on each Golem you control. Ability ability = new PutIntoGraveFromBattlefieldAllTriggeredAbility( diff --git a/Mage.Sets/src/mage/cards/m/MasterSplicer.java b/Mage.Sets/src/mage/cards/m/MasterSplicer.java index 6ce14383051..febf3da2cd0 100644 --- a/Mage.Sets/src/mage/cards/m/MasterSplicer.java +++ b/Mage.Sets/src/mage/cards/m/MasterSplicer.java @@ -12,7 +12,7 @@ import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; -import mage.game.permanent.token.GolemToken; +import mage.game.permanent.token.PhyrexianGolemToken; import java.util.UUID; @@ -32,7 +32,7 @@ public final class MasterSplicer extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GolemToken()))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new PhyrexianGolemToken()))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, false))); } diff --git a/Mage.Sets/src/mage/cards/m/MaulSplicer.java b/Mage.Sets/src/mage/cards/m/MaulSplicer.java index 6196c8fda5e..366ad87e8c1 100644 --- a/Mage.Sets/src/mage/cards/m/MaulSplicer.java +++ b/Mage.Sets/src/mage/cards/m/MaulSplicer.java @@ -13,7 +13,7 @@ import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterPermanent; -import mage.game.permanent.token.GolemToken; +import mage.game.permanent.token.PhyrexianGolemToken; import java.util.UUID; @@ -39,7 +39,7 @@ public final class MaulSplicer extends CardImpl { this.toughness = new MageInt(1); // When Maul Splicer enters the battlefield, create two 3/3 colorless Golem artifact creature tokens. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GolemToken(), 2))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new PhyrexianGolemToken(), 2))); // Golem creatures you control have trample. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield, filter))); diff --git a/Mage.Sets/src/mage/cards/m/MyrSire.java b/Mage.Sets/src/mage/cards/m/MyrSire.java index cbbeaf6fbf1..04adb1cb540 100644 --- a/Mage.Sets/src/mage/cards/m/MyrSire.java +++ b/Mage.Sets/src/mage/cards/m/MyrSire.java @@ -1,8 +1,5 @@ - - package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; @@ -10,24 +7,25 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.game.permanent.token.MyrToken; +import mage.game.permanent.token.PhyrexianMyrToken; + +import java.util.UUID; /** - * * @author Loki */ public final class MyrSire extends CardImpl { - public MyrSire (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}"); + public MyrSire(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.MYR); this.power = new MageInt(1); this.toughness = new MageInt(1); - this.addAbility(new DiesSourceTriggeredAbility(new CreateTokenEffect(new MyrToken()))); + this.addAbility(new DiesSourceTriggeredAbility(new CreateTokenEffect(new PhyrexianMyrToken()))); } - public MyrSire (final MyrSire card) { + public MyrSire(final MyrSire card) { super(card); } @@ -35,5 +33,4 @@ public final class MyrSire extends CardImpl { public MyrSire copy() { return new MyrSire(this); } - } diff --git a/Mage.Sets/src/mage/cards/n/NestedGhoul.java b/Mage.Sets/src/mage/cards/n/NestedGhoul.java index e1c4a84196d..7eecaa1a7ac 100644 --- a/Mage.Sets/src/mage/cards/n/NestedGhoul.java +++ b/Mage.Sets/src/mage/cards/n/NestedGhoul.java @@ -13,6 +13,7 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.game.permanent.token.PhyrexianZombieToken; import mage.game.permanent.token.ZombieToken; /** @@ -46,7 +47,7 @@ public final class NestedGhoul extends CardImpl { class NestedGhoulTriggeredAbility extends TriggeredAbilityImpl { NestedGhoulTriggeredAbility() { - super(Zone.BATTLEFIELD, new CreateTokenEffect(new ZombieToken())); + super(Zone.BATTLEFIELD, new CreateTokenEffect(new PhyrexianZombieToken())); } NestedGhoulTriggeredAbility(final NestedGhoulTriggeredAbility ability) { @@ -70,6 +71,6 @@ class NestedGhoulTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever a source deals damage to {this}, create a 2/2 black Zombie creature token."; + return "Whenever a source deals damage to {this}, create a 2/2 black Phyrexian Zombie creature token."; } } diff --git a/Mage.Sets/src/mage/cards/p/ParasiticImplant.java b/Mage.Sets/src/mage/cards/p/ParasiticImplant.java index 59f030d42fe..79524906bdb 100644 --- a/Mage.Sets/src/mage/cards/p/ParasiticImplant.java +++ b/Mage.Sets/src/mage/cards/p/ParasiticImplant.java @@ -1,7 +1,5 @@ - package mage.cards.p; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -11,33 +9,33 @@ import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.TargetController; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.game.permanent.token.MyrToken; +import mage.game.permanent.token.PhyrexianMyrToken; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author Loki */ public final class ParasiticImplant extends CardImpl { public ParasiticImplant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); this.subtype.add(SubType.AURA); - TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.Sacrifice)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); ability = new BeginningOfUpkeepTriggeredAbility(new ParasiticImplantEffect(), TargetController.YOU, false); - ability.addEffect(new CreateTokenEffect(new MyrToken("NPH"))); + ability.addEffect(new CreateTokenEffect(new PhyrexianMyrToken())); this.addAbility(ability); } @@ -78,4 +76,4 @@ class ParasiticImplantEffect extends OneShotEffect { public ParasiticImplantEffect copy() { return new ParasiticImplantEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianProcessor.java b/Mage.Sets/src/mage/cards/p/PhyrexianProcessor.java index 03852614e85..2333d2abfb8 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianProcessor.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianProcessor.java @@ -92,7 +92,7 @@ class PhyrexianProcessorCreateTokenEffect extends OneShotEffect { PhyrexianProcessorCreateTokenEffect() { super(Outcome.PutCreatureInPlay); - staticText = "Create an X/X black Minion creature token, " + + staticText = "Create an X/X black Phyrexian Minion creature token, " + "where X is the life paid as {this} entered the battlefield."; } diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianRebirth.java b/Mage.Sets/src/mage/cards/p/PhyrexianRebirth.java index 22bd1af0a12..e477bdb797f 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianRebirth.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianRebirth.java @@ -38,7 +38,7 @@ public final class PhyrexianRebirth extends CardImpl { private PhyrexianRebirthEffect() { super(Outcome.DestroyPermanent); - staticText = "Destroy all creatures, then create an X/X colorless Horror artifact creature token, " + + staticText = "Destroy all creatures, then create an X/X colorless Phyrexian Horror artifact creature token, " + "where X is the number of creatures destroyed this way"; } diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianTriniform.java b/Mage.Sets/src/mage/cards/p/PhyrexianTriniform.java index fbe1b5be0cb..c5ac63da431 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianTriniform.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianTriniform.java @@ -9,7 +9,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.game.permanent.token.GolemToken; +import mage.game.permanent.token.PhyrexianGolemToken; import java.util.UUID; @@ -27,7 +27,7 @@ public final class PhyrexianTriniform extends CardImpl { this.toughness = new MageInt(9); // When Phyrexian Triniform dies, create three 3/3 colorless Golem artifact creature tokens. - this.addAbility(new DiesSourceTriggeredAbility(new CreateTokenEffect(new GolemToken(), 3))); + this.addAbility(new DiesSourceTriggeredAbility(new CreateTokenEffect(new PhyrexianGolemToken(), 3))); // Encore {12} this.addAbility(new EncoreAbility(new GenericManaCost(12))); diff --git a/Mage.Sets/src/mage/cards/s/SensorSplicer.java b/Mage.Sets/src/mage/cards/s/SensorSplicer.java index f530bbf39c2..e48902ca1b2 100644 --- a/Mage.Sets/src/mage/cards/s/SensorSplicer.java +++ b/Mage.Sets/src/mage/cards/s/SensorSplicer.java @@ -13,7 +13,7 @@ import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterPermanent; -import mage.game.permanent.token.GolemToken; +import mage.game.permanent.token.PhyrexianGolemToken; import java.util.UUID; @@ -38,7 +38,7 @@ public final class SensorSplicer extends CardImpl { this.toughness = new MageInt(1); // When Sensor Splicer enters the battlefield, create a 3/3 colorless Golem artifact creature token. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GolemToken()))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new PhyrexianGolemToken()))); // Golem creatures you control have vigilance. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, filter))); diff --git a/Mage.Sets/src/mage/cards/s/ShrineOfLoyalLegions.java b/Mage.Sets/src/mage/cards/s/ShrineOfLoyalLegions.java index 3113bd29669..243720cc019 100644 --- a/Mage.Sets/src/mage/cards/s/ShrineOfLoyalLegions.java +++ b/Mage.Sets/src/mage/cards/s/ShrineOfLoyalLegions.java @@ -1,7 +1,5 @@ - package mage.cards.s; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -22,10 +20,11 @@ import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.permanent.token.MyrToken; +import mage.game.permanent.token.PhyrexianMyrToken; + +import java.util.UUID; /** - * * @author North */ public final class ShrineOfLoyalLegions extends CardImpl { @@ -37,7 +36,7 @@ public final class ShrineOfLoyalLegions extends CardImpl { } public ShrineOfLoyalLegions(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); //At the beginning of your upkeep or whenever you cast a white spell, put a charge counter on Shrine of Loyal Legions. this.addAbility(new OrTriggeredAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.CHARGE.createInstance()), @@ -46,7 +45,7 @@ public final class ShrineOfLoyalLegions extends CardImpl { //{3}, {T}, Sacrifice Shrine of Loyal Legions: Create a 1/1 colorless Myr artifact creature token for each charge counter on Shrine of Loyal Legions. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new CreateTokenEffect(new MyrToken("NPH"), new CountersSourceCount(CounterType.CHARGE)), + new CreateTokenEffect(new PhyrexianMyrToken(), new CountersSourceCount(CounterType.CHARGE)), new GenericManaCost(3)); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/s/SplicersSkill.java b/Mage.Sets/src/mage/cards/s/SplicersSkill.java index 36522d00dfd..4b6076ff24c 100644 --- a/Mage.Sets/src/mage/cards/s/SplicersSkill.java +++ b/Mage.Sets/src/mage/cards/s/SplicersSkill.java @@ -5,7 +5,7 @@ import mage.abilities.keyword.SpliceOntoInstantOrSorceryAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.game.permanent.token.GolemToken; +import mage.game.permanent.token.PhyrexianGolemToken; import java.util.UUID; @@ -18,7 +18,7 @@ public final class SplicersSkill extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}"); // Create a 3/3 colorless Golem artifact creature token. - this.getSpellAbility().addEffect(new CreateTokenEffect(new GolemToken())); + this.getSpellAbility().addEffect(new CreateTokenEffect(new PhyrexianGolemToken())); // Splice onto instant or sorcery {3}{W} this.addAbility(new SpliceOntoInstantOrSorceryAbility("{3}{W}")); diff --git a/Mage.Sets/src/mage/cards/v/VitalSplicer.java b/Mage.Sets/src/mage/cards/v/VitalSplicer.java index 273a495e13e..8bf587ebb74 100644 --- a/Mage.Sets/src/mage/cards/v/VitalSplicer.java +++ b/Mage.Sets/src/mage/cards/v/VitalSplicer.java @@ -14,7 +14,7 @@ import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; -import mage.game.permanent.token.GolemToken; +import mage.game.permanent.token.PhyrexianGolemToken; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -42,7 +42,7 @@ public final class VitalSplicer extends CardImpl { this.toughness = new MageInt(1); // When Vital Splicer enters the battlefield, create a 3/3 colorless Golem artifact creature token. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GolemToken()))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new PhyrexianGolemToken()))); // {1}: Regenerate target Golem you control. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), new ManaCostsImpl("{1}")); diff --git a/Mage.Sets/src/mage/cards/w/WingSplicer.java b/Mage.Sets/src/mage/cards/w/WingSplicer.java index 595bf41e0c6..9fb84b1a88c 100644 --- a/Mage.Sets/src/mage/cards/w/WingSplicer.java +++ b/Mage.Sets/src/mage/cards/w/WingSplicer.java @@ -13,7 +13,7 @@ import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterPermanent; -import mage.game.permanent.token.GolemToken; +import mage.game.permanent.token.PhyrexianGolemToken; import java.util.UUID; @@ -39,7 +39,7 @@ public final class WingSplicer extends CardImpl { this.toughness = new MageInt(1); // When Wing Splicer enters the battlefield, create a 3/3 colorless Golem artifact creature token. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GolemToken()))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new PhyrexianGolemToken()))); // Golem creatures you control have flying. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filter))); diff --git a/Mage.Sets/src/mage/cards/w/WurmcoilEngine.java b/Mage.Sets/src/mage/cards/w/WurmcoilEngine.java index 1249227af04..1fb322332da 100644 --- a/Mage.Sets/src/mage/cards/w/WurmcoilEngine.java +++ b/Mage.Sets/src/mage/cards/w/WurmcoilEngine.java @@ -33,7 +33,7 @@ public final class WurmcoilEngine extends CardImpl { // When Wurmcoil Engine dies, create a 3/3 colorless Wurm artifact creature token with deathtouch and a 3/3 colorless Wurm artifact creature token with lifelink. Ability ability = new DiesSourceTriggeredAbility(new CreateTokenEffect(new WurmWithDeathtouchToken()), false); - ability.addEffect(new CreateTokenEffect(new WurmWithLifelinkToken()).setText("and a 3/3 colorless Wurm artifact creature token with lifelink")); + ability.addEffect(new CreateTokenEffect(new WurmWithLifelinkToken()).setText("and a 3/3 colorless Phyrexian Wurm artifact creature token with lifelink")); this.addAbility(ability); } diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 4d2711bb889..98ae4703806 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -114,7 +114,6 @@ public class VerifyCardDataTest { // subtype skipListCreate(SKIP_LIST_SUBTYPE); skipListAddName(SKIP_LIST_SUBTYPE, "UGL", "Miss Demeanor"); - subtypesToIgnore.add("Phyrexian"); // large errata incoming, adding this for now // number skipListCreate(SKIP_LIST_NUMBER); diff --git a/Mage/src/main/java/mage/game/permanent/token/BrudicladTelchorMyrToken.java b/Mage/src/main/java/mage/game/permanent/token/BrudicladTelchorMyrToken.java index 5ac97bf621f..0a429195b3c 100644 --- a/Mage/src/main/java/mage/game/permanent/token/BrudicladTelchorMyrToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/BrudicladTelchorMyrToken.java @@ -1,13 +1,13 @@ package mage.game.permanent.token; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import mage.MageInt; import mage.constants.CardType; import mage.constants.SubType; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public final class BrudicladTelchorMyrToken extends TokenImpl { static final private List tokenImageSets = new ArrayList<>(); @@ -17,14 +17,10 @@ public final class BrudicladTelchorMyrToken extends TokenImpl { } public BrudicladTelchorMyrToken() { - this((String)null); - } - - public BrudicladTelchorMyrToken(String expansionSetCode) { - super("Myr", "2/1 blue Myr artifact creature token"); - this.setOriginalExpansionSetCode(expansionSetCode); + super("Phyrexian Myr", "2/1 blue Phyrexian Myr artifact creature token"); cardType.add(CardType.CREATURE); cardType.add(CardType.ARTIFACT); + subtype.add(SubType.PHYREXIAN); subtype.add(SubType.MYR); color.setBlue(true); power = new MageInt(2); diff --git a/Mage/src/main/java/mage/game/permanent/token/GermToken.java b/Mage/src/main/java/mage/game/permanent/token/GermToken.java index c8a15fa9eb4..c665b8fffdd 100644 --- a/Mage/src/main/java/mage/game/permanent/token/GermToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/GermToken.java @@ -28,7 +28,7 @@ public final class GermToken extends TokenImpl { } public GermToken(String setCode, int tokenType) { - super("Germ", "0/0 black Phyrexian Germ creature token"); + super("Phyrexian Germ", "0/0 black Phyrexian Germ creature token"); availableImageSetCodes = tokenImageSets; setOriginalExpansionSetCode(setCode); cardType.add(CardType.CREATURE); diff --git a/Mage/src/main/java/mage/game/permanent/token/InsectInfectToken.java b/Mage/src/main/java/mage/game/permanent/token/InsectInfectToken.java index 7992ed37368..36b6ad9263a 100644 --- a/Mage/src/main/java/mage/game/permanent/token/InsectInfectToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/InsectInfectToken.java @@ -1,22 +1,20 @@ - - package mage.game.permanent.token; -import mage.constants.CardType; -import mage.constants.SubType; import mage.MageInt; import mage.abilities.keyword.InfectAbility; +import mage.constants.CardType; +import mage.constants.SubType; /** - * * @author nantuko */ public final class InsectInfectToken extends TokenImpl { public InsectInfectToken() { - super("Insect", "1/1 green Insect creature token with infect"); + super("Phyrexian Insect", "1/1 green Phyrexian Insect creature token with infect"); cardType.add(CardType.CREATURE); color.setGreen(true); + subtype.add(SubType.PHYREXIAN); subtype.add(SubType.INSECT); power = new MageInt(1); toughness = new MageInt(1); @@ -31,4 +29,4 @@ public final class InsectInfectToken extends TokenImpl { public InsectInfectToken copy() { return new InsectInfectToken(this); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/game/permanent/token/MinionToken.java b/Mage/src/main/java/mage/game/permanent/token/MinionToken.java index 950cb9a1b33..4a532e2cfa1 100644 --- a/Mage/src/main/java/mage/game/permanent/token/MinionToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/MinionToken.java @@ -17,9 +17,10 @@ public final class MinionToken extends TokenImpl { } public MinionToken(String setCode) { - super("Minion", "X/X black Minion creature token"); + super("Phyrexian Minion", "X/X black Phyrexian Minion creature token"); this.setOriginalExpansionSetCode(setCode); cardType.add(CardType.CREATURE); + subtype.add(SubType.PHYREXIAN); subtype.add(SubType.MINION); color.setBlack(true); power = new MageInt(0); diff --git a/Mage/src/main/java/mage/game/permanent/token/MyrToken.java b/Mage/src/main/java/mage/game/permanent/token/MyrToken.java index a1914b0c904..e9386436eb3 100644 --- a/Mage/src/main/java/mage/game/permanent/token/MyrToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/MyrToken.java @@ -23,8 +23,8 @@ public final class MyrToken extends TokenImpl { public MyrToken(String expansionSetCode) { super("Myr", "1/1 colorless Myr artifact creature token"); this.setOriginalExpansionSetCode(expansionSetCode); - cardType.add(CardType.CREATURE); cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); subtype.add(SubType.MYR); power = new MageInt(1); toughness = new MageInt(1); diff --git a/Mage/src/main/java/mage/game/permanent/token/PhyrexianBeastToken.java b/Mage/src/main/java/mage/game/permanent/token/PhyrexianBeastToken.java new file mode 100644 index 00000000000..6e8fef520e1 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/PhyrexianBeastToken.java @@ -0,0 +1,30 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author TheElk801 + */ +public final class PhyrexianBeastToken extends TokenImpl { + + public PhyrexianBeastToken() { + super("Phyrexian Beast", "4/4 green Phyrexian Beast creature token"); + cardType.add(CardType.CREATURE); + color.setGreen(true); + subtype.add(SubType.PHYREXIAN); + subtype.add(SubType.BEAST); + power = new MageInt(4); + toughness = new MageInt(4); + } + + public PhyrexianBeastToken(final PhyrexianBeastToken token) { + super(token); + } + + @Override + public PhyrexianBeastToken copy() { + return new PhyrexianBeastToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/PhyrexianGoblinToken.java b/Mage/src/main/java/mage/game/permanent/token/PhyrexianGoblinToken.java new file mode 100644 index 00000000000..3bb54a71dff --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/PhyrexianGoblinToken.java @@ -0,0 +1,36 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.keyword.HasteAbility; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.Arrays; + +/** + * @author TheElk801 + */ +public final class PhyrexianGoblinToken extends TokenImpl { + + public PhyrexianGoblinToken() { + super("Phyrexian Goblin", "1/1 red Phyrexian Goblin creature token with haste"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.PHYREXIAN); + subtype.add(SubType.GOBLIN); + color.setRed(true); + power = new MageInt(1); + toughness = new MageInt(1); + + addAbility(HasteAbility.getInstance()); + + availableImageSetCodes = Arrays.asList("NPH"); + } + + public PhyrexianGoblinToken(final PhyrexianGoblinToken token) { + super(token); + } + + public PhyrexianGoblinToken copy() { + return new PhyrexianGoblinToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/PhyrexianGolemToken.java b/Mage/src/main/java/mage/game/permanent/token/PhyrexianGolemToken.java new file mode 100644 index 00000000000..bded6b25ff3 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/PhyrexianGolemToken.java @@ -0,0 +1,38 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.Arrays; + +/** + * @author TheElk801 + */ +public final class PhyrexianGolemToken extends TokenImpl { + + public PhyrexianGolemToken() { + super("Phyrexian Golem", "3/3 colorless Phyrexian Golem artifact creature token"); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + subtype.add(SubType.PHYREXIAN); + subtype.add(SubType.GOLEM); + power = new MageInt(3); + toughness = new MageInt(3); + + availableImageSetCodes = Arrays.asList("MM2", "NPH", "SOM", "MH1", "M20", "CMR"); + } + + public PhyrexianGolemToken(final PhyrexianGolemToken token) { + super(token); + } + + public PhyrexianGolemToken copy() { + return new PhyrexianGolemToken(this); + } + + @Override + public void setExpansionSetCodeForImage(String code) { + super.setExpansionSetCodeForImage(code); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/PhyrexianMyrToken.java b/Mage/src/main/java/mage/game/permanent/token/PhyrexianMyrToken.java new file mode 100644 index 00000000000..852325af146 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/PhyrexianMyrToken.java @@ -0,0 +1,26 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +public final class PhyrexianMyrToken extends TokenImpl { + + public PhyrexianMyrToken() { + super("Phyrexian Myr", "1/1 colorless Phyrexian Myr artifact creature token"); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + subtype.add(SubType.PHYREXIAN); + subtype.add(SubType.MYR); + power = new MageInt(1); + toughness = new MageInt(1); + } + + public PhyrexianMyrToken(final PhyrexianMyrToken token) { + super(token); + } + + public PhyrexianMyrToken copy() { + return new PhyrexianMyrToken(this); + } +} \ No newline at end of file diff --git a/Mage/src/main/java/mage/game/permanent/token/PhyrexianRebirthHorrorToken.java b/Mage/src/main/java/mage/game/permanent/token/PhyrexianRebirthHorrorToken.java index ef7fbf537d3..aaa4c51e60d 100644 --- a/Mage/src/main/java/mage/game/permanent/token/PhyrexianRebirthHorrorToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/PhyrexianRebirthHorrorToken.java @@ -12,9 +12,10 @@ import java.util.Arrays; public final class PhyrexianRebirthHorrorToken extends TokenImpl { public PhyrexianRebirthHorrorToken(int power, int toughness) { - super("Horror", "X/X colorless Horror artifact creature token"); + super("Phyrexian Horror", "X/X colorless Phyrexian Horror artifact creature token"); this.cardType.add(CardType.ARTIFACT); this.cardType.add(CardType.CREATURE); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); this.power = new MageInt(power); this.toughness = new MageInt(toughness); diff --git a/Mage/src/main/java/mage/game/permanent/token/PhyrexianZombieToken.java b/Mage/src/main/java/mage/game/permanent/token/PhyrexianZombieToken.java new file mode 100644 index 00000000000..dd34ca13a25 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/PhyrexianZombieToken.java @@ -0,0 +1,34 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.Arrays; + +/** + * @author TheElk801 + */ +public final class PhyrexianZombieToken extends TokenImpl { + + public PhyrexianZombieToken() { + super("Phyrexian Zombie", "2/2 black Phyrexian Zombie creature token"); + cardType.add(CardType.CREATURE); + color.setBlack(true); + subtype.add(SubType.PHYREXIAN); + subtype.add(SubType.ZOMBIE); + power = new MageInt(2); + toughness = new MageInt(2); + + availableImageSetCodes = Arrays.asList("MBS"); + } + + public PhyrexianZombieToken(final PhyrexianZombieToken token) { + super(token); + } + + @Override + public PhyrexianZombieToken copy() { + return new PhyrexianZombieToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/WurmWithDeathtouchToken.java b/Mage/src/main/java/mage/game/permanent/token/WurmWithDeathtouchToken.java index 4f55a1bcc69..6908ef89ef0 100644 --- a/Mage/src/main/java/mage/game/permanent/token/WurmWithDeathtouchToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/WurmWithDeathtouchToken.java @@ -13,9 +13,10 @@ import java.util.Arrays; public final class WurmWithDeathtouchToken extends TokenImpl { public WurmWithDeathtouchToken() { - super("Wurm", "3/3 colorless Wurm artifact creature token with deathtouch"); + super("Phyrexian Wurm", "3/3 colorless Phyrexian Wurm artifact creature token with deathtouch"); cardType.add(CardType.ARTIFACT); cardType.add(CardType.CREATURE); + subtype.add(SubType.PHYREXIAN); subtype.add(SubType.WURM); power = new MageInt(3); toughness = new MageInt(3); diff --git a/Mage/src/main/java/mage/game/permanent/token/WurmWithLifelinkToken.java b/Mage/src/main/java/mage/game/permanent/token/WurmWithLifelinkToken.java index 8ecc9cad321..8db4b8b82fa 100644 --- a/Mage/src/main/java/mage/game/permanent/token/WurmWithLifelinkToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/WurmWithLifelinkToken.java @@ -13,9 +13,10 @@ import java.util.Arrays; public final class WurmWithLifelinkToken extends TokenImpl { public WurmWithLifelinkToken() { - super("Wurm", "3/3 colorless Wurm artifact creature token with lifelink"); + super("Phyrexian Wurm", "3/3 colorless Phyrexian Wurm artifact creature token with lifelink"); cardType.add(CardType.ARTIFACT); cardType.add(CardType.CREATURE); + subtype.add(SubType.PHYREXIAN); subtype.add(SubType.WURM); power = new MageInt(3); toughness = new MageInt(3); From f5d2befc57553173aa146603eb9ee5394b01ed5b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 10 Jun 2021 20:32:58 -0400 Subject: [PATCH 184/188] added a few missing phyrexian creature types --- Mage.Sets/src/mage/cards/p/PhyrexianMetamorph.java | 1 + Mage.Sets/src/mage/cards/p/PlagueEngineer.java | 1 + Mage.Sets/src/mage/cards/r/RathiAssassin.java | 1 + Mage.Sets/src/mage/cards/s/SheoldredWhisperingOne.java | 1 + 4 files changed, 4 insertions(+) diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianMetamorph.java b/Mage.Sets/src/mage/cards/p/PhyrexianMetamorph.java index eb7773ffb77..e50d5505b89 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianMetamorph.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianMetamorph.java @@ -35,6 +35,7 @@ public final class PhyrexianMetamorph extends CardImpl { public PhyrexianMetamorph(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{U/P}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.SHAPESHIFTER); this.power = new MageInt(0); diff --git a/Mage.Sets/src/mage/cards/p/PlagueEngineer.java b/Mage.Sets/src/mage/cards/p/PlagueEngineer.java index 4fe25a965a1..839d6b6550a 100644 --- a/Mage.Sets/src/mage/cards/p/PlagueEngineer.java +++ b/Mage.Sets/src/mage/cards/p/PlagueEngineer.java @@ -33,6 +33,7 @@ public final class PlagueEngineer extends CardImpl { public PlagueEngineer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.CARRIER); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/r/RathiAssassin.java b/Mage.Sets/src/mage/cards/r/RathiAssassin.java index ee1abc2834c..59ec3cc4a0e 100644 --- a/Mage.Sets/src/mage/cards/r/RathiAssassin.java +++ b/Mage.Sets/src/mage/cards/r/RathiAssassin.java @@ -44,6 +44,7 @@ public final class RathiAssassin extends CardImpl { public RathiAssassin(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.MERCENARY); this.subtype.add(SubType.ASSASSIN); diff --git a/Mage.Sets/src/mage/cards/s/SheoldredWhisperingOne.java b/Mage.Sets/src/mage/cards/s/SheoldredWhisperingOne.java index 5a99b501884..3a6f4b62d4a 100644 --- a/Mage.Sets/src/mage/cards/s/SheoldredWhisperingOne.java +++ b/Mage.Sets/src/mage/cards/s/SheoldredWhisperingOne.java @@ -26,6 +26,7 @@ public final class SheoldredWhisperingOne extends CardImpl { public SheoldredWhisperingOne(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}"); addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.PRAETOR); this.power = new MageInt(6); From a7e57b8352f924fdbf5f19c1411624cc13d421c8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 10 Jun 2021 20:48:31 -0400 Subject: [PATCH 185/188] fixed test failures --- .../src/mage/cards/p/ProfaneTransfusion.java | 2 +- .../abilities/equipped/BatterskullTest.java | 4 ++-- .../cards/abilities/keywords/PersistTest.java | 2 +- .../cards/copy/FlameshadowConjuringTest.java | 2 +- .../test/cards/copy/PhantasmalImageTest.java | 6 +++--- .../cards/replacement/DamageEffectsTest.java | 2 +- .../cards/single/cmr/ProfaneTransfusionTest.java | 16 ++++++++-------- .../duel/CommanderReplaceEffectTest.java | 8 ++++---- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Mage.Sets/src/mage/cards/p/ProfaneTransfusion.java b/Mage.Sets/src/mage/cards/p/ProfaneTransfusion.java index 74134d9e0ef..dc8d2f26fe8 100644 --- a/Mage.Sets/src/mage/cards/p/ProfaneTransfusion.java +++ b/Mage.Sets/src/mage/cards/p/ProfaneTransfusion.java @@ -42,7 +42,7 @@ class ProfaneTransfusionEffect extends OneShotEffect { ProfaneTransfusionEffect() { super(Outcome.Benefit); - staticText = "You create an X/X colorless Horror artifact creature token, " + + staticText = "You create an X/X colorless Phyrexian Horror artifact creature token, " + "where X is the difference between those players' life totals"; } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/equipped/BatterskullTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/equipped/BatterskullTest.java index 8fbac1ca562..b329b52f15b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/equipped/BatterskullTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/equipped/BatterskullTest.java @@ -37,7 +37,7 @@ public class BatterskullTest extends CardTestPlayerBase { assertHandCount(playerA, 0); assertPermanentCount(playerA, "Batterskull", 1); - assertPermanentCount(playerA, "Germ", 1); - assertPowerToughness(playerA, "Germ", 4, 4); + assertPermanentCount(playerA, "Phyrexian Germ", 1); + assertPowerToughness(playerA, "Phyrexian Germ", 4, 4); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/PersistTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/PersistTest.java index dc7b96b5d03..60523a47363 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/PersistTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/PersistTest.java @@ -150,7 +150,7 @@ public class PersistTest extends CardTestPlayerBase { assertLife(playerB, 26); // +6 from lifelink of Wurmcoil assertPermanentCount(playerB, "Wurmcoil Engine", 0); - assertPermanentCount(playerB, "Wurm", 2); + assertPermanentCount(playerB, "Phyrexian Wurm", 2); assertPermanentCount(playerA, "Kitchen Finks", 2); assertPowerToughness(playerA, "Kitchen Finks", 2, 1, Filter.ComparisonScope.All); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/FlameshadowConjuringTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/FlameshadowConjuringTest.java index c44d26f8f1a..dcf3a6ad47e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/FlameshadowConjuringTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/FlameshadowConjuringTest.java @@ -79,7 +79,7 @@ public class FlameshadowConjuringTest extends CardTestPlayerBase { assertLife(playerB, 14); assertLife(playerA, 26); - assertPermanentCount(playerA, "Wurm", 2); + assertPermanentCount(playerA, "Phyrexian Wurm", 2); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java index a38051841fa..07afd1a14c7 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java @@ -382,7 +382,7 @@ public class PhantasmalImageTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Wurmcoil Engine", 1); assertGraveyardCount(playerB, "Phantasmal Image", 1); - assertPermanentCount(playerB, "Wurm", 2); // if triggered ability did not work, the Titan would be in the graveyard instaed + assertPermanentCount(playerB, "Phyrexian Wurm", 2); // if triggered ability did not work, the Titan would be in the graveyard instaed } @@ -574,8 +574,8 @@ public class PhantasmalImageTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Phantasmal Image", 1); assertGraveyardCount(playerB, "Wurmcoil Engine", 1); - assertPermanentCount(playerA, "Wurm", 2); - assertPermanentCount(playerB, "Wurm", 2); + assertPermanentCount(playerA, "Phyrexian Wurm", 2); + assertPermanentCount(playerB, "Phyrexian Wurm", 2); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/DamageEffectsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/DamageEffectsTest.java index 134f2d15f71..263cf64f91a 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/DamageEffectsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/DamageEffectsTest.java @@ -42,7 +42,7 @@ public class DamageEffectsTest extends CardTestPlayerBase { assertGraveyardCount(playerB, "Ob Nixilis, the Fallen", 1); assertGraveyardCount(playerA, "Wurmcoil Engine", 1); - assertPermanentCount(playerA, "Wurm", 2); + assertPermanentCount(playerA, "Phyrexian Wurm", 2); assertLife(playerB, 20); assertLife(playerA, 29); // -2 from Ob Nixilis + 12 from double damage with lifelink from Wurmcoil Engine diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/cmr/ProfaneTransfusionTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/cmr/ProfaneTransfusionTest.java index 74bf1b3060c..756a5258093 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/cmr/ProfaneTransfusionTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/cmr/ProfaneTransfusionTest.java @@ -34,8 +34,8 @@ public class ProfaneTransfusionTest extends CardTestPlayerBase { assertLife(playerA, 16); assertLife(playerB, 24); - assertPermanentCount(playerA, "Horror", 1); - assertPowerToughness(playerA, "Horror", 24 - 16, 24 - 16); + assertPermanentCount(playerA, "Phyrexian Horror", 1); + assertPowerToughness(playerA, "Phyrexian Horror", 24 - 16, 24 - 16); assertGraveyardCount(playerA, transfusion, 1); } @@ -60,8 +60,8 @@ public class ProfaneTransfusionTest extends CardTestPlayerBase { assertLife(playerA, 24); assertLife(playerB, 16); - assertPermanentCount(playerA, "Horror", 1); - assertPowerToughness(playerA, "Horror", 24 - 16, 24 - 16); + assertPermanentCount(playerA, "Phyrexian Horror", 1); + assertPowerToughness(playerA, "Phyrexian Horror", 24 - 16, 24 - 16); assertGraveyardCount(playerA, transfusion, 1); } @@ -86,8 +86,8 @@ public class ProfaneTransfusionTest extends CardTestPlayerBase { assertLife(playerA, 16); assertLife(playerB, 32); - assertPermanentCount(playerA, "Horror", 1); - assertPowerToughness(playerA, "Horror", 32 - 16, 32 - 16); + assertPermanentCount(playerA, "Phyrexian Horror", 1); + assertPowerToughness(playerA, "Phyrexian Horror", 32 - 16, 32 - 16); assertGraveyardCount(playerA, transfusion, 1); } @@ -110,8 +110,8 @@ public class ProfaneTransfusionTest extends CardTestPlayerBase { assertLife(playerA, 20); assertLife(playerB, 17); - assertPermanentCount(playerA, "Horror", 1); - assertPowerToughness(playerA, "Horror", 20 - 17, 20 - 17); + assertPermanentCount(playerA, "Phyrexian Horror", 1); + assertPowerToughness(playerA, "Phyrexian Horror", 20 - 17, 20 - 17); assertGraveyardCount(playerA, transfusion, 1); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/commander/duel/CommanderReplaceEffectTest.java b/Mage.Tests/src/test/java/org/mage/test/commander/duel/CommanderReplaceEffectTest.java index 1461804f897..732936901e6 100644 --- a/Mage.Tests/src/test/java/org/mage/test/commander/duel/CommanderReplaceEffectTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/commander/duel/CommanderReplaceEffectTest.java @@ -45,8 +45,8 @@ public class CommanderReplaceEffectTest extends CardTestCommanderDuelBase { assertPermanentCount(playerA, "Daxos of Meletis", 0); assertGraveyardCount(playerA, "Daxos of Meletis", 0); - assertPermanentCount(playerB, "Horror", 1); - assertPowerToughness(playerB, "Horror", 1, 1); + assertPermanentCount(playerB, "Phyrexian Horror", 1); + assertPowerToughness(playerB, "Phyrexian Horror", 1, 1); } @Test @@ -74,8 +74,8 @@ public class CommanderReplaceEffectTest extends CardTestCommanderDuelBase { setStopAt(3, PhaseStep.UPKEEP); execute(); - assertPermanentCount(playerB, "Horror", 1); - assertPowerToughness(playerB, "Horror", 1, 1); + assertPermanentCount(playerB, "Phyrexian Horror", 1); + assertPowerToughness(playerB, "Phyrexian Horror", 1, 1); assertPermanentCount(playerA, "Daxos of Meletis", 1); assertPermanentCount(playerA, "Gift of Immortality", 1); From d7aefbd33713b5dbd71d82aedeed0b4103269339 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 10 Jun 2021 21:32:51 -0400 Subject: [PATCH 186/188] a few more missed phyrexian erratas --- Mage.Sets/src/mage/cards/i/InkmothNexus.java | 5 +++-- Mage.Sets/src/mage/cards/l/LurkingEvil.java | 5 +++-- Mage.Sets/src/mage/cards/l/LurkingSkirge.java | 5 +++-- Mage.Sets/src/mage/cards/p/PhyrexianTotem.java | 3 ++- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/cards/i/InkmothNexus.java b/Mage.Sets/src/mage/cards/i/InkmothNexus.java index 880d19cf647..ba181f82adc 100644 --- a/Mage.Sets/src/mage/cards/i/InkmothNexus.java +++ b/Mage.Sets/src/mage/cards/i/InkmothNexus.java @@ -33,7 +33,7 @@ public final class InkmothNexus extends CardImpl { // {1}: Inkmoth Nexus becomes a 1/1 Blinkmoth artifact creature with flying and infect until end of turn. It's still a land. (It deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.) Effect effect = new BecomesCreatureSourceEffect(new InkmothNexusToken(), "land", Duration.EndOfTurn); - effect.setText("{this} becomes a 1/1 Blinkmoth artifact creature with flying and infect until end of turn. It's still a land. (It deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)"); + effect.setText("{this} becomes a 1/1 Phyrexian Blinkmoth artifact creature with flying and infect until end of turn. It's still a land. (It deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)"); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(1))); } @@ -49,9 +49,10 @@ public final class InkmothNexus extends CardImpl { class InkmothNexusToken extends TokenImpl { public InkmothNexusToken() { - super("Blinkmoth", "1/1 Blinkmoth artifact creature with flying and infect"); + super("Phyrexian Blinkmoth", "1/1 Phyrexian Blinkmoth artifact creature with flying and infect"); cardType.add(CardType.ARTIFACT); cardType.add(CardType.CREATURE); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.BLINKMOTH); power = new MageInt(1); toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/l/LurkingEvil.java b/Mage.Sets/src/mage/cards/l/LurkingEvil.java index 668b982747f..ac141cce36b 100644 --- a/Mage.Sets/src/mage/cards/l/LurkingEvil.java +++ b/Mage.Sets/src/mage/cards/l/LurkingEvil.java @@ -33,7 +33,7 @@ public final class LurkingEvil extends CardImpl { // Pay half your life, rounded up: Lurking Evil becomes a 4/4 Horror creature with flying. Effect effect = new BecomesCreatureSourceEffect(new LurkingEvilToken(), null, Duration.EndOfGame, true, false); - effect.setText("{this} becomes a 4/4 Horror creature with flying"); + effect.setText("{this} becomes a 4/4 Phyrexian Horror creature with flying"); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new LurkingEvilCost())); } @@ -89,9 +89,10 @@ class LurkingEvilCost extends CostImpl { class LurkingEvilToken extends TokenImpl { LurkingEvilToken() { - super("Horror", "4/4 Horror creature with flying"); + super("Phyrexian Horror", "4/4 Phyrexian Horror creature with flying"); power = new MageInt(4); toughness = new MageInt(4); + subtype.add(SubType.PHYREXIAN); subtype.add(SubType.HORROR); cardType.add(CardType.CREATURE); this.addAbility(FlyingAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/l/LurkingSkirge.java b/Mage.Sets/src/mage/cards/l/LurkingSkirge.java index 09f154f23ac..9c8e474aa5a 100644 --- a/Mage.Sets/src/mage/cards/l/LurkingSkirge.java +++ b/Mage.Sets/src/mage/cards/l/LurkingSkirge.java @@ -36,7 +36,7 @@ public final class LurkingSkirge extends CardImpl { // When a creature is put into an opponent's graveyard from the battlefield, if Lurking Skirge is an enchantment, Lurking Skirge becomes a 3/2 Imp creature with flying. TriggeredAbility ability = new PutIntoGraveFromBattlefieldAllTriggeredAbility(new BecomesCreatureSourceEffect(new LurkingSkirgeToken(), "", Duration.WhileOnBattlefield, true, false), false, filter, false); this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), - "When a creature is put into an opponent's graveyard from the battlefield, if {this} is an enchantment, {this} becomes a 3/2 Imp creature with flying.")); + "When a creature is put into an opponent's graveyard from the battlefield, if {this} is an enchantment, {this} becomes a 3/2 Phyrexian Imp creature with flying.")); } private LurkingSkirge(final LurkingSkirge card) { @@ -52,8 +52,9 @@ public final class LurkingSkirge extends CardImpl { class LurkingSkirgeToken extends TokenImpl { public LurkingSkirgeToken() { - super("Imp", "3/2 Imp with flying."); + super("Phyrexian Imp", "3/2 Phyrexian Imp with flying."); cardType.add(CardType.CREATURE); + subtype.add(SubType.PHYREXIAN); subtype.add(SubType.IMP); power = new MageInt(3); toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianTotem.java b/Mage.Sets/src/mage/cards/p/PhyrexianTotem.java index 5fb1dfdf751..645aec63eec 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianTotem.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianTotem.java @@ -53,10 +53,11 @@ public final class PhyrexianTotem extends CardImpl { private static class PhyrexianTotemToken extends TokenImpl { PhyrexianTotemToken() { - super("Horror", "5/5 black Horror artifact creature with trample"); + super("Phyrexian Horror", "5/5 black Phyrexian Horror artifact creature with trample"); cardType.add(CardType.ARTIFACT); cardType.add(CardType.CREATURE); color.setBlack(true); + this.subtype.add(SubType.PHYREXIAN); this.subtype.add(SubType.HORROR); power = new MageInt(5); toughness = new MageInt(5); From 4ea8b956549dd452cae7e15b2ba212199941f7be Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 11 Jun 2021 06:48:20 -0400 Subject: [PATCH 187/188] [HA5] added set --- .../src/mage/deck/Historic.java | 1 - .../src/mage/sets/HistoricAnthology5.java | 50 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/sets/HistoricAnthology5.java diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Historic.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Historic.java index 2760405e44e..d3925bd8656 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Historic.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Historic.java @@ -101,7 +101,6 @@ public class Historic extends Constructed { banned.add("Mausoleum Turnkey"); banned.add("Reanimate"); banned.add("Scourge of Nel Toth"); - banned.add("Sheoldred, Whispering One"); banned.add("Ball Lightning"); banned.add("Chain Lightning"); banned.add("Draconic Roar"); diff --git a/Mage.Sets/src/mage/sets/HistoricAnthology5.java b/Mage.Sets/src/mage/sets/HistoricAnthology5.java new file mode 100644 index 00000000000..756007e9fb8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/HistoricAnthology5.java @@ -0,0 +1,50 @@ +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author TheElk801 + */ +public final class HistoricAnthology5 extends ExpansionSet { + + private static final HistoricAnthology5 instance = new HistoricAnthology5(); + + public static HistoricAnthology5 getInstance() { + return instance; + } + + private HistoricAnthology5() { + super("Historic Anthology 5", "HA5", ExpansionSet.buildDate(2021, 5, 27), SetType.MAGIC_ARENA); + this.blockName = "Reprint"; + this.hasBoosters = false; + this.hasBasicLands = false; + + cards.add(new SetCardInfo("Ancient Grudge", 12, Rarity.COMMON, mage.cards.a.AncientGrudge.class)); + cards.add(new SetCardInfo("Atarka's Command", 21, Rarity.RARE, mage.cards.a.AtarkasCommand.class)); + cards.add(new SetCardInfo("Court Homunculus", 1, Rarity.COMMON, mage.cards.c.CourtHomunculus.class)); + cards.add(new SetCardInfo("Dragonstorm", 13, Rarity.RARE, mage.cards.d.Dragonstorm.class)); + cards.add(new SetCardInfo("Dromoka's Command", 22, Rarity.RARE, mage.cards.d.DromokasCommand.class)); + cards.add(new SetCardInfo("Elesh Norn, Grand Cenobite", 2, Rarity.MYTHIC, mage.cards.e.EleshNornGrandCenobite.class)); + cards.add(new SetCardInfo("Grisly Salvage", 23, Rarity.COMMON, mage.cards.g.GrislySalvage.class)); + cards.add(new SetCardInfo("Ichor Wellspring", 24, Rarity.COMMON, mage.cards.i.IchorWellspring.class)); + cards.add(new SetCardInfo("Intangible Virtue", 3, Rarity.UNCOMMON, mage.cards.i.IntangibleVirtue.class)); + cards.add(new SetCardInfo("Into the North", 16, Rarity.COMMON, mage.cards.i.IntoTheNorth.class)); + cards.add(new SetCardInfo("Jin-Gitaxias, Core Augur", 5, Rarity.MYTHIC, mage.cards.j.JinGitaxiasCoreAugur.class)); + cards.add(new SetCardInfo("Kolaghan's Command", 20, Rarity.RARE, mage.cards.k.KolaghansCommand.class)); + cards.add(new SetCardInfo("Merfolk Looter", 6, Rarity.COMMON, mage.cards.m.MerfolkLooter.class)); + cards.add(new SetCardInfo("Ojutai's Command", 18, Rarity.RARE, mage.cards.o.OjutaisCommand.class)); + cards.add(new SetCardInfo("Ray of Revelation", 4, Rarity.COMMON, mage.cards.r.RayOfRevelation.class)); + cards.add(new SetCardInfo("Relic of Progenitus", 25, Rarity.COMMON, mage.cards.r.RelicOfProgenitus.class)); + cards.add(new SetCardInfo("Reverse Engineer", 7, Rarity.UNCOMMON, mage.cards.r.ReverseEngineer.class)); + cards.add(new SetCardInfo("Sheoldred, Whispering One", 10, Rarity.MYTHIC, mage.cards.s.SheoldredWhisperingOne.class)); + cards.add(new SetCardInfo("Silumgar's Command", 19, Rarity.RARE, mage.cards.s.SilumgarsCommand.class)); + cards.add(new SetCardInfo("Stifle", 8, Rarity.RARE, mage.cards.s.Stifle.class)); + cards.add(new SetCardInfo("Trash for Treasure", 14, Rarity.UNCOMMON, mage.cards.t.TrashForTreasure.class)); + cards.add(new SetCardInfo("Urabrask the Hidden", 15, Rarity.MYTHIC, mage.cards.u.UrabraskTheHidden.class)); + cards.add(new SetCardInfo("Vault Skirge", 11, Rarity.COMMON, mage.cards.v.VaultSkirge.class)); + cards.add(new SetCardInfo("Vorinclex, Voice of Hunger", 17, Rarity.MYTHIC, mage.cards.v.VorinclexVoiceOfHunger.class)); + cards.add(new SetCardInfo("Whirler Rogue", 9, Rarity.UNCOMMON, mage.cards.w.WhirlerRogue.class)); + } +} From f771dcdb24a1572729657b5b6f56b22dc0b8a521 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 11 Jun 2021 06:48:53 -0400 Subject: [PATCH 188/188] updated historic ban list --- .../Mage.Deck.Constructed/src/mage/deck/Historic.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Historic.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Historic.java index d3925bd8656..2e8a5cd1d70 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Historic.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Historic.java @@ -43,6 +43,7 @@ public class Historic extends Constructed { banned.add("Swords to Plowshares"); banned.add("Teferi, Time Raveler"); banned.add("Thassa's Oracle"); + banned.add("Time Warp"); banned.add("Uro, Titan of Nature's Wrath"); banned.add("Veil of Summer"); banned.add("Wilderness Reclamation");