From fe3ed92539ee17aea777711f0f7fdd98baf756a3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 12:45:00 -0500 Subject: [PATCH 01/44] Implemented Depose // Deploy --- Mage.Sets/src/mage/cards/d/DeposeDeploy.java | 54 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 55 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DeposeDeploy.java diff --git a/Mage.Sets/src/mage/cards/d/DeposeDeploy.java b/Mage.Sets/src/mage/cards/d/DeposeDeploy.java new file mode 100644 index 00000000000..b7a040e204f --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeposeDeploy.java @@ -0,0 +1,54 @@ +package mage.cards.d; + +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GainLifeEffect; +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.game.permanent.token.ThopterColorlessToken; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DeposeDeploy extends SplitCard { + + public DeposeDeploy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W/U}", "{2}{W}{U}", SpellAbilityType.SPLIT); + + // Depose + // Tap target creature. + // Draw a card. + this.getLeftHalfCard().getSpellAbility().addEffect(new TapTargetEffect()); + this.getLeftHalfCard().getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getLeftHalfCard().getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + + // Deploy + // Creature two 1/1 colorless Thopter artifact creature tokens with flying, then you gain 1 life for each creature you control. + this.getRightHalfCard().getSpellAbility().addEffect( + new CreateTokenEffect(new ThopterColorlessToken(), 2) + ); + this.getRightHalfCard().getSpellAbility().addEffect( + new GainLifeEffect(new PermanentsOnBattlefieldCount( + StaticFilters.FILTER_CONTROLLED_CREATURES + )).setText(", then you gain 1 life for each creature you control.") + ); + + } + + private DeposeDeploy(final DeposeDeploy card) { + super(card); + } + + @Override + public DeposeDeploy copy() { + return new DeposeDeploy(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index ee7c41ee8a5..b2a0f3aa050 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -40,6 +40,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Bedevil", 157, Rarity.RARE, mage.cards.b.Bedevil.class)); cards.add(new SetCardInfo("Blood Crypt", 245, Rarity.RARE, mage.cards.b.BloodCrypt.class)); cards.add(new SetCardInfo("Breeding Pool", 246, Rarity.RARE, mage.cards.b.BreedingPool.class)); + cards.add(new SetCardInfo("Depose // Deploy", 225, Rarity.UNCOMMON, mage.cards.d.DeposeDeploy.class)); cards.add(new SetCardInfo("Deputy of Detention", 165, Rarity.RARE, mage.cards.d.DeputyOfDetention.class)); cards.add(new SetCardInfo("Dovin, Grand Arbiter", 167, Rarity.MYTHIC, mage.cards.d.DovinGrandArbiter.class)); cards.add(new SetCardInfo("Emergency Powers", 169, Rarity.MYTHIC, mage.cards.e.EmergencyPowers.class)); From 233e62358fc0311f992ff217b6629bb77a67019f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 12:48:32 -0500 Subject: [PATCH 02/44] Implemented Bolrac-Clan Crusher --- .../src/mage/cards/b/BolracClanCrusher.java | 47 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 48 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BolracClanCrusher.java diff --git a/Mage.Sets/src/mage/cards/b/BolracClanCrusher.java b/Mage.Sets/src/mage/cards/b/BolracClanCrusher.java new file mode 100644 index 00000000000..5b41bafcf18 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BolracClanCrusher.java @@ -0,0 +1,47 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveCounterCost; +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.constants.SubType; +import mage.counters.CounterType; +import mage.target.common.TargetAnyTarget; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BolracClanCrusher extends CardImpl { + + public BolracClanCrusher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}"); + + this.subtype.add(SubType.OGRE); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // {T}, Remove a +1/+1 counter from a creature you control: Bolrac-Clan Crusher deals 2 damage to any target. + Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(2), new TapSourceCost()); + ability.addCost(new RemoveCounterCost(new TargetControlledCreaturePermanent(), CounterType.P1P1)); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability); + } + + private BolracClanCrusher(final BolracClanCrusher card) { + super(card); + } + + @Override + public BolracClanCrusher copy() { + return new BolracClanCrusher(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index b2a0f3aa050..75476b02f40 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -39,6 +39,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Azorius Locket", 231, Rarity.COMMON, mage.cards.a.AzoriusLocket.class)); cards.add(new SetCardInfo("Bedevil", 157, Rarity.RARE, mage.cards.b.Bedevil.class)); cards.add(new SetCardInfo("Blood Crypt", 245, Rarity.RARE, mage.cards.b.BloodCrypt.class)); + cards.add(new SetCardInfo("Bolrac-Clan Crusher", 159, Rarity.UNCOMMON, mage.cards.b.BolracClanCrusher.class)); cards.add(new SetCardInfo("Breeding Pool", 246, Rarity.RARE, mage.cards.b.BreedingPool.class)); cards.add(new SetCardInfo("Depose // Deploy", 225, Rarity.UNCOMMON, mage.cards.d.DeposeDeploy.class)); cards.add(new SetCardInfo("Deputy of Detention", 165, Rarity.RARE, mage.cards.d.DeputyOfDetention.class)); From ca7d7b023ebb3e1ad773132dd9b36974c12b4093 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 13:10:56 -0500 Subject: [PATCH 03/44] Implemented Growth-Chamber Guardian --- .../mage/cards/g/GrowthChamberGuardian.java | 96 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 97 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GrowthChamberGuardian.java diff --git a/Mage.Sets/src/mage/cards/g/GrowthChamberGuardian.java b/Mage.Sets/src/mage/cards/g/GrowthChamberGuardian.java new file mode 100644 index 00000000000..07dc7cb94c9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GrowthChamberGuardian.java @@ -0,0 +1,96 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.effects.keyword.AdaptEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GrowthChamberGuardian extends CardImpl { + + public GrowthChamberGuardian(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.CRAB); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {2}{G}: Adapt 2. + this.addAbility(new SimpleActivatedAbility( + new AdaptEffect(2), new ManaCostsImpl("{2}{G}") + )); + + // Whenever one or more +1/+1 counters are put on Growth-Chamber Guardian, you may search your library for a card named Growth-Chamber Guardian, reveal it, put it into your hand, then shuffle your library. + this.addAbility(new GrowthChamberGuardianTriggeredAbility()); + } + + private GrowthChamberGuardian(final GrowthChamberGuardian card) { + super(card); + } + + @Override + public GrowthChamberGuardian copy() { + return new GrowthChamberGuardian(this); + } +} + +class GrowthChamberGuardianTriggeredAbility extends TriggeredAbilityImpl { + + private static final FilterCard filter + = new FilterCard("a card named Growth-Chamber Guardian"); + + static { + filter.add(new NamePredicate("Growth-Chamber Guardian")); + } + + GrowthChamberGuardianTriggeredAbility() { + super(Zone.BATTLEFIELD, new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true), true); + } + + private GrowthChamberGuardianTriggeredAbility(final GrowthChamberGuardianTriggeredAbility ability) { + super(ability); + } + + @Override + public GrowthChamberGuardianTriggeredAbility copy() { + return new GrowthChamberGuardianTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.COUNTERS_ADDED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return event.getData().equals(CounterType.P1P1.getName()) + && event.getAmount() > 0 + && event.getTargetId().equals(this.getSourceId()); + } + + @Override + public String getRule() { + return "Whenever one or more +1/+1 counters are put on {this}, " + + "you may search your library for a card named Growth-Chamber Guardian, " + + "reveal it, put it into your hand, then shuffle your library."; + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 75476b02f40..6fc8757b041 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -49,6 +49,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Gate Colossus", 232, Rarity.UNCOMMON, mage.cards.g.GateColossus.class)); cards.add(new SetCardInfo("Godless Shrine", 248, Rarity.RARE, mage.cards.g.GodlessShrine.class)); cards.add(new SetCardInfo("Growth Spiral", 178, Rarity.COMMON, mage.cards.g.GrowthSpiral.class)); + cards.add(new SetCardInfo("Growth-Chamber Guardian", 128, Rarity.RARE, mage.cards.g.GrowthChamberGuardian.class)); cards.add(new SetCardInfo("Gruul Guildgate", 249, Rarity.COMMON, mage.cards.g.GruulGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gruul Guildgate", 250, Rarity.COMMON, mage.cards.g.GruulGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gruul Locket", 234, Rarity.COMMON, mage.cards.g.GruulLocket.class)); From 369c2b4e192a170f3506419ca71bf069da30ff37 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 13:14:38 -0500 Subject: [PATCH 04/44] Implemented Seraph of the Scales --- .../src/mage/cards/s/SeraphOfTheScales.java | 65 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SeraphOfTheScales.java diff --git a/Mage.Sets/src/mage/cards/s/SeraphOfTheScales.java b/Mage.Sets/src/mage/cards/s/SeraphOfTheScales.java new file mode 100644 index 00000000000..d21c04c48f7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SeraphOfTheScales.java @@ -0,0 +1,65 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.AfterlifeAbility; +import mage.abilities.keyword.DeathtouchAbility; +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.constants.Zone; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SeraphOfTheScales extends CardImpl { + + public SeraphOfTheScales(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{B}"); + + this.subtype.add(SubType.ANGEL); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {W}: Seraph of the Scales gains vigilance until end of turn. + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new GainAbilitySourceEffect( + VigilanceAbility.getInstance(), + Duration.EndOfTurn + ), new ManaCostsImpl("{W}") + )); + + // {B}: Seraph of the Scales gains deathtouch until end of turn. + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new GainAbilitySourceEffect( + DeathtouchAbility.getInstance(), + Duration.EndOfTurn + ), new ManaCostsImpl("{B}") + )); + + // Afterlife 2 + this.addAbility(new AfterlifeAbility(2)); + } + + private SeraphOfTheScales(final SeraphOfTheScales card) { + super(card); + } + + @Override + public SeraphOfTheScales copy() { + return new SeraphOfTheScales(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 6fc8757b041..b13d3789125 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -72,6 +72,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Rakdos Guildgate", 256, Rarity.COMMON, mage.cards.r.RakdosGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rakdos Locket", 237, Rarity.COMMON, mage.cards.r.RakdosLocket.class)); cards.add(new SetCardInfo("Rix Maadi Reveler", 109, Rarity.RARE, mage.cards.r.RixMaadiReveler.class)); + cards.add(new SetCardInfo("Seraph of the Scales", 205, Rarity.MYTHIC, mage.cards.s.SeraphOfTheScales.class)); cards.add(new SetCardInfo("Simic Ascendancy", 207, Rarity.RARE, mage.cards.s.SimicAscendancy.class)); cards.add(new SetCardInfo("Simic Guildgate", 257, Rarity.COMMON, mage.cards.s.SimicGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Simic Guildgate", 258, Rarity.COMMON, mage.cards.s.SimicGuildgate.class, NON_FULL_USE_VARIOUS)); From 9dbfab364e96ae62a9f8bd3ea636f32d550293c9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 13:24:32 -0500 Subject: [PATCH 05/44] Implemented Precognitive Perception --- .../mage/cards/p/PrecognitivePerception.java | 68 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 69 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PrecognitivePerception.java diff --git a/Mage.Sets/src/mage/cards/p/PrecognitivePerception.java b/Mage.Sets/src/mage/cards/p/PrecognitivePerception.java new file mode 100644 index 00000000000..eea0c0d9c4d --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PrecognitivePerception.java @@ -0,0 +1,68 @@ +package mage.cards.p; + +import mage.abilities.Ability; +import mage.abilities.condition.common.MyMainPhaseCondition; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PrecognitivePerception extends CardImpl { + + public PrecognitivePerception(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{U}"); + + // Draw three cards. + // Addendum — If you cast this spell during your main phase, instead scry 3, then draw three cards. + this.getSpellAbility().addEffect(new PrecognitivePerceptionEffect()); + } + + private PrecognitivePerception(final PrecognitivePerception card) { + super(card); + } + + @Override + public PrecognitivePerception copy() { + return new PrecognitivePerception(this); + } +} + +class PrecognitivePerceptionEffect extends OneShotEffect { + + PrecognitivePerceptionEffect() { + super(Outcome.Benefit); + staticText = "Draw three cards.
Addendum — " + + "If you cast this spell during your main phase, " + + "instead scry 3, then draw three cards."; + } + + private PrecognitivePerceptionEffect(final PrecognitivePerceptionEffect effect) { + super(effect); + } + + @Override + public PrecognitivePerceptionEffect copy() { + return new PrecognitivePerceptionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + if (MyMainPhaseCondition.instance.apply(game, source)) { + controller.scry(3, source, game); + } + controller.drawCards(3, game); + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index b13d3789125..07f39d13eea 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -66,6 +66,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Orzhov Guildgate", 252, Rarity.COMMON, mage.cards.o.OrzhovGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Orzhov Guildgate", 253, Rarity.COMMON, mage.cards.o.OrzhovGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Orzhov Locket", 236, Rarity.COMMON, mage.cards.o.OrzhovLocket.class)); + cards.add(new SetCardInfo("Precognitive Perception", 45, Rarity.RARE, mage.cards.p.PrecognitivePerception.class)); cards.add(new SetCardInfo("Rafter Demon", 196, Rarity.COMMON, mage.cards.r.RafterDemon.class)); cards.add(new SetCardInfo("Rakdos Firewheeler", 197, Rarity.UNCOMMON, mage.cards.r.RakdosFirewheeler.class)); cards.add(new SetCardInfo("Rakdos Guildgate", 255, Rarity.COMMON, mage.cards.r.RakdosGuildgate.class, NON_FULL_USE_VARIOUS)); From cd68ccadf92f128cee8c761a79782b50bda587b9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 13:27:11 -0500 Subject: [PATCH 06/44] Implemented Wilderness Reclamation --- .../mage/cards/w/WildernessReclamation.java | 36 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 37 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WildernessReclamation.java diff --git a/Mage.Sets/src/mage/cards/w/WildernessReclamation.java b/Mage.Sets/src/mage/cards/w/WildernessReclamation.java new file mode 100644 index 00000000000..b15ee0e26f3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WildernessReclamation.java @@ -0,0 +1,36 @@ +package mage.cards.w; + +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.effects.common.UntapAllControllerEffect; +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 WildernessReclamation extends CardImpl { + + public WildernessReclamation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); + + // At the beginning of your end step, untap all lands you control. + this.addAbility(new BeginningOfEndStepTriggeredAbility( + new UntapAllControllerEffect(StaticFilters.FILTER_LANDS), + TargetController.YOU, false + )); + } + + private WildernessReclamation(final WildernessReclamation card) { + super(card); + } + + @Override + public WildernessReclamation copy() { + return new WildernessReclamation(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 07f39d13eea..4ced3df05f1 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -83,6 +83,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Stomping Ground", 259, Rarity.RARE, mage.cards.s.StompingGround.class)); cards.add(new SetCardInfo("The Haunt of Hightower", 273, Rarity.MYTHIC, mage.cards.t.TheHauntOfHightower.class)); cards.add(new SetCardInfo("Tithe Taker", 27, Rarity.RARE, mage.cards.t.TitheTaker.class)); + cards.add(new SetCardInfo("Wilderness Reclamation", 140, Rarity.UNCOMMON, mage.cards.w.WildernessReclamation.class)); cards.add(new SetCardInfo("Zegana, Utopian Speaker", 214, Rarity.RARE, mage.cards.z.ZeganaUtopianSpeaker.class)); } From 82c34d81172bdd64074314e1186e5fe3ef8a78d1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 13:39:35 -0500 Subject: [PATCH 07/44] Implemented Spawn of Mayhem --- Mage.Sets/src/mage/cards/s/SpawnOfMayhem.java | 94 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 95 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SpawnOfMayhem.java diff --git a/Mage.Sets/src/mage/cards/s/SpawnOfMayhem.java b/Mage.Sets/src/mage/cards/s/SpawnOfMayhem.java new file mode 100644 index 00000000000..3e0215662e7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpawnOfMayhem.java @@ -0,0 +1,94 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.SpectacleAbility; +import mage.abilities.keyword.TrampleAbility; +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.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SpawnOfMayhem extends CardImpl { + + public SpawnOfMayhem(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + + this.subtype.add(SubType.DEMON); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Spectacle {1}{B}{B} + this.addAbility(new SpectacleAbility(this, new ManaCostsImpl("{1}{B}{B}"))); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // At the beginning of your upkeep, Spawn of Mayhem deals 1 damage to each player. Then if you have 10 or less life, put a +1/+1 counter on Spawn of Mayhem. + Ability ability = new BeginningOfUpkeepTriggeredAbility( + new DamagePlayersEffect(1, TargetController.ANY), + TargetController.YOU, false + ); + ability.addEffect(new SpawnOfMayhemEffect()); + this.addAbility(ability); + } + + private SpawnOfMayhem(final SpawnOfMayhem card) { + super(card); + } + + @Override + public SpawnOfMayhem copy() { + return new SpawnOfMayhem(this); + } +} + +class SpawnOfMayhemEffect extends OneShotEffect { + + SpawnOfMayhemEffect() { + super(Outcome.Benefit); + staticText = "Then if you have 10 or less life, put a +1/+1 counter on {this}."; + } + + private SpawnOfMayhemEffect(final SpawnOfMayhemEffect effect) { + super(effect); + } + + @Override + public SpawnOfMayhemEffect copy() { + return new SpawnOfMayhemEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + if (player.getLife() < 11) { + return new AddCountersSourceEffect( + CounterType.P1P1.createInstance() + ).apply(game, source); + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 4ced3df05f1..4d18f1fec3f 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -78,6 +78,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Simic Guildgate", 257, Rarity.COMMON, mage.cards.s.SimicGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Simic Guildgate", 258, Rarity.COMMON, mage.cards.s.SimicGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Simic Locket", 240, Rarity.COMMON, mage.cards.s.SimicLocket.class)); + cards.add(new SetCardInfo("Spawn of Mayhem", 85, Rarity.MYTHIC, mage.cards.s.SpawnOfMayhem.class)); cards.add(new SetCardInfo("Sphinx of Foresight", 55, Rarity.RARE, mage.cards.s.SphinxOfForesight.class)); cards.add(new SetCardInfo("Sphinx's Insight", 209, Rarity.COMMON, mage.cards.s.SphinxsInsight.class)); cards.add(new SetCardInfo("Stomping Ground", 259, Rarity.RARE, mage.cards.s.StompingGround.class)); From 1375a08453bffbb7ff369dff042f81ffcc1201c1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 13:41:06 -0500 Subject: [PATCH 08/44] updated RNA spoiler --- Utils/mtg-cards-data.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index bb197d6fa9e..7122b45bc2e 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -34584,7 +34584,7 @@ Spawn of Mayhem|Ravnica Allegiance|85|M|{2}{B}{B}|Creature - Demon|4|4|Spectacle Amplifire|Ravnica Allegiance|92|R|{2}{R}{R}|Creature - Elemental|1|1|At the beginning of your upkeep, reveal cards from he top of your library until you reveal a creature card. Until your next turn, Amplifire's base power becomes twice that card's power and its base toughness becomes twice that card's toughness. Put the revealed cards on the bottom of your library in a random order.| Light Up the Stage|Ravnica Allegiance|107|U|{2}{R}|Sorcery|||Spectacle {R}$Exile the top two cards of your library. Until the end of your next turn, you may play those cards.| Rix Maadi Reveler|Ravnica Allegiance|109|R|{1}{R}|Creature - Human Shaman|2|2|Spectacle {2}{B}{R}$When Rix Maadi Reveler enters the battlefield, discard a card, then draw a card. If Rix Maadi Reveler's spectacle cost was paid, instead discard your hand, then draw three cards.| -Sharrgan Hellkite|Ravnica Allegiance|114|M|{3}{R}{R}|Creature - Dragon|4|4|Riot$Flying${3}{R}: Sharrgan Hellkite deals 2 damage divided as you choose among one or two targets. Activate this ability only if Sharrgan Hellkite has a +1/+1 counter on it.| +Skarrgan Hellkite|Ravnica Allegiance|114|M|{3}{R}{R}|Creature - Dragon|4|4|Riot$Flying${3}{R}: Sharrgan Hellkite deals 2 damage divided as you choose among one or two targets. Activate this ability only if Sharrgan Hellkite has a +1/+1 counter on it.| Growth-Chamber Guardian|Ravnica Allegiance|128|R|{1}{G}|Creature - Elf Crab Warrior|2|2|{2}{G}: Adapt 2.$Whenever one or more +1/+1 counters are put on Growth-Chamber Guardian, you may search your library for a card named Growth-Chamber Guardian, reveal it, put it into your hand, then shuffle your library.| Wilderness Reclamation|Ravnica Allegiance|140|U|{3}{G}|Enchantment|||At the beginning of your end step, untap all lands you control.| Absorb|Ravnica Allegiance|151|R|{W}{U}{U}|Instant|||Counter target spell. You gain 3 life.| From 618300cdc3a582fc006256e9c470a06192ec7315 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 14:41:08 -0500 Subject: [PATCH 09/44] updated RNA spoiler --- Utils/mtg-cards-data.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 7122b45bc2e..e4fe7d59817 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -34580,11 +34580,13 @@ Tithe Taker|Ravnica Allegiance|27|R|{1}{W}|Creature - Human Soldier|2|1|During y Mass Manipulation|Ravnica Allegiance|42|R|{X}{X}{U}{U}{U}{U}|Sorcery|||Gain control of X target creatures and/or planeswalkers.| Precognitive Perception|Ravnica Allegiance|45|R|{3}{U}{U}|Instant|||Draw three cards.$Addendum — If you cast this spell during your main phase, instead scry 3, then draw three cards.| Sphinx of Foresight|Ravnica Allegiance|55|R|{2}{U}{U}|Creature - Sphinx|4|4|You may reveal this card from your opening hand. If you do, scry 3 at the beginning of your first upkeep.$Flying$At the beginning of your upkeep, scry 1.| +Pestilent Spirit|Ravnica Allegiance|81|R|{2}{B}|Creature - Spirit|3|2|Menace, deathtouch$Instant and sorcery spells you control have deathtouch.| Spawn of Mayhem|Ravnica Allegiance|85|M|{2}{B}{B}|Creature - Demon|4|4|Spectacle {1}{B}{B}$Flying, trample$At the beginning of your upkeep, Spawn of Mayhem deals 1 damage to each player. Then if you have 10 or less life, put a +1/+1 counter on Spawn of Mayhem.| Amplifire|Ravnica Allegiance|92|R|{2}{R}{R}|Creature - Elemental|1|1|At the beginning of your upkeep, reveal cards from he top of your library until you reveal a creature card. Until your next turn, Amplifire's base power becomes twice that card's power and its base toughness becomes twice that card's toughness. Put the revealed cards on the bottom of your library in a random order.| Light Up the Stage|Ravnica Allegiance|107|U|{2}{R}|Sorcery|||Spectacle {R}$Exile the top two cards of your library. Until the end of your next turn, you may play those cards.| Rix Maadi Reveler|Ravnica Allegiance|109|R|{1}{R}|Creature - Human Shaman|2|2|Spectacle {2}{B}{R}$When Rix Maadi Reveler enters the battlefield, discard a card, then draw a card. If Rix Maadi Reveler's spectacle cost was paid, instead discard your hand, then draw three cards.| Skarrgan Hellkite|Ravnica Allegiance|114|M|{3}{R}{R}|Creature - Dragon|4|4|Riot$Flying${3}{R}: Sharrgan Hellkite deals 2 damage divided as you choose among one or two targets. Activate this ability only if Sharrgan Hellkite has a +1/+1 counter on it.| +End-Raze Forerunners|Ravnica Allegiance|124|R|{5}{G}{G}{G}|Creature - Boar|7|7|Vigilance, trample, haste$When End-Raze Forerunners enters the battlefield, other creatures you control get +2/+2 and gain vigilance and trample until end of turn.| Growth-Chamber Guardian|Ravnica Allegiance|128|R|{1}{G}|Creature - Elf Crab Warrior|2|2|{2}{G}: Adapt 2.$Whenever one or more +1/+1 counters are put on Growth-Chamber Guardian, you may search your library for a card named Growth-Chamber Guardian, reveal it, put it into your hand, then shuffle your library.| Wilderness Reclamation|Ravnica Allegiance|140|U|{3}{G}|Enchantment|||At the beginning of your end step, untap all lands you control.| Absorb|Ravnica Allegiance|151|R|{W}{U}{U}|Instant|||Counter target spell. You gain 3 life.| @@ -34604,6 +34606,7 @@ Judith, the Scourge Diva|Ravnica Allegiance|185|R|{1}{B}{R}|Legendary Creature - Kaya, Orzhov Usurper|Ravnica Allegiance|186|M|{1}{W}{B}|Legendary Planeswalker - Kaya|3|+1: Exile up to two target cards from a single graveyard. You gain 2 life if at least one creature card was exiled this way.$-1: Exile target nonland permanent with converted mana cost 1 or less.$-5: Kaya, Orzhov Usurper deals damage to target player equal to the number of cards that player owns in exile and you gain that much life.| Lavinia, Azorius Renegade|Ravnica Allegiance|189|R|{W}{U}|Legendary Creature - Human Soldier|2|2|Each opponent can't cast noncreature spells with converted mana cost greater than the number of lands that player controls.$Whenever an opponent casts a spell, if no mana was spent to cast it, counter that spell.| Mortify|Ravnica Allegiance|192|U|{1}{W}{B}|Instant|||Destroy target creature or enchantment.| +Prime Speaker Vannifar|Ravnica Allegiance|195|M|{2}{G}{U}|Legendary Creature - Elf Ooze Wizard|2|4|{T}, Sacrifice another creature: Search your library for a creature card with converted mana cost equal to 1 plus the sacrifices creature's converted mana cost, put that card onto the battlefield, then shuffle your library. Activate this ability only any time you could cast a sorcery.| Rafter Demon|Ravnica Allegiance|196|C|{2}{B}{R}|Creature - Demon|4|2|Spectacle {3}{B}{R}$When Rafter Demon enters the battlefield, if its spectacle cost was paid, each opponent discards a card.| Rakdos Firewheeler|Ravnica Allegiance|197|U|{B}{B}{R}{R}|Creature - Human Rogue|4|3|When Rakdos Firewheeler enters the battlefield, it deals 2 damage to target opponent and 2 damage to up to one target creature or planeswalker.| Rakdos, the Showstopper|Ravnica Allegiance|199|M|{4}{B}{R}|Legendary Creature - Demon|6|6|Flying, trample$When Rakdos, the Showstopper enters the battlefield, flip a coin for each creature that isn't a Demon, Devil, or Imp. Destroy each creature whose coin comes up tails.| From 965fa971a3a083ddce2cad57f587a71cf5c31603 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 16:20:36 -0500 Subject: [PATCH 10/44] updated implementation of Adapt --- Mage.Sets/src/mage/cards/a/Aeromunculus.java | 8 ++---- .../mage/cards/g/GrowthChamberGuardian.java | 8 ++---- .../mage/cards/z/ZeganaUtopianSpeaker.java | 8 ++---- .../effects/keyword/AdaptEffect.java | 12 +++++++-- .../mage/abilities/keyword/AdaptAbility.java | 27 +++++++++++++++++++ .../main/java/mage/game/events/GameEvent.java | 13 ++++----- 6 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/keyword/AdaptAbility.java diff --git a/Mage.Sets/src/mage/cards/a/Aeromunculus.java b/Mage.Sets/src/mage/cards/a/Aeromunculus.java index 0dca6864e6e..4f2d962f01d 100644 --- a/Mage.Sets/src/mage/cards/a/Aeromunculus.java +++ b/Mage.Sets/src/mage/cards/a/Aeromunculus.java @@ -1,9 +1,7 @@ package mage.cards.a; import mage.MageInt; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.keyword.AdaptEffect; +import mage.abilities.keyword.AdaptAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -29,9 +27,7 @@ public final class Aeromunculus extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // {2}{G}{U}: Adapt 1. - this.addAbility(new SimpleActivatedAbility( - new AdaptEffect(1), new ManaCostsImpl("{2}{G}{U}") - )); + this.addAbility(new AdaptAbility(1, "{2}{G}{U}")); } public Aeromunculus(final Aeromunculus card) { diff --git a/Mage.Sets/src/mage/cards/g/GrowthChamberGuardian.java b/Mage.Sets/src/mage/cards/g/GrowthChamberGuardian.java index 07dc7cb94c9..8048b31642a 100644 --- a/Mage.Sets/src/mage/cards/g/GrowthChamberGuardian.java +++ b/Mage.Sets/src/mage/cards/g/GrowthChamberGuardian.java @@ -2,10 +2,8 @@ package mage.cards.g; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.abilities.effects.keyword.AdaptEffect; +import mage.abilities.keyword.AdaptAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -35,9 +33,7 @@ public final class GrowthChamberGuardian extends CardImpl { this.toughness = new MageInt(2); // {2}{G}: Adapt 2. - this.addAbility(new SimpleActivatedAbility( - new AdaptEffect(2), new ManaCostsImpl("{2}{G}") - )); + this.addAbility(new AdaptAbility(2, "{2}{G}")); // Whenever one or more +1/+1 counters are put on Growth-Chamber Guardian, you may search your library for a card named Growth-Chamber Guardian, reveal it, put it into your hand, then shuffle your library. this.addAbility(new GrowthChamberGuardianTriggeredAbility()); diff --git a/Mage.Sets/src/mage/cards/z/ZeganaUtopianSpeaker.java b/Mage.Sets/src/mage/cards/z/ZeganaUtopianSpeaker.java index d373a86a37b..1fbf2ef563f 100644 --- a/Mage.Sets/src/mage/cards/z/ZeganaUtopianSpeaker.java +++ b/Mage.Sets/src/mage/cards/z/ZeganaUtopianSpeaker.java @@ -2,14 +2,12 @@ package mage.cards.z; import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.continuous.GainAbilityAllEffect; -import mage.abilities.effects.keyword.AdaptEffect; +import mage.abilities.keyword.AdaptAbility; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -56,9 +54,7 @@ public final class ZeganaUtopianSpeaker extends CardImpl { )); // {4}{G}{U}: Adapt 4. - this.addAbility(new SimpleActivatedAbility( - new AdaptEffect(4), new ManaCostsImpl("{4}{G}{U}") - )); + this.addAbility(new AdaptAbility(4, "{4}{G}{U}")); // Each creature you control with a +1/+1 counter on it has trample. this.addAbility(new SimpleStaticAbility( diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/AdaptEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/AdaptEffect.java index 0bbc9ebbb52..ed29b59aea6 100644 --- a/Mage/src/main/java/mage/abilities/effects/keyword/AdaptEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/keyword/AdaptEffect.java @@ -5,6 +5,7 @@ import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.counters.CounterType; import mage.game.Game; +import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.util.CardUtil; @@ -40,8 +41,15 @@ public class AdaptEffect extends OneShotEffect { if (permanent == null) { return false; } - if (permanent.getCounters(game).getCount(CounterType.P1P1) == 0) { - permanent.addCounters(CounterType.P1P1.createInstance(adaptNumber), source, game); + GameEvent event = new GameEvent( + GameEvent.EventType.ADAPT, source.getSourceId(), source.getSourceId(), + source.getControllerId(), adaptNumber, false + ); + if (game.replaceEvent(event)) { + return false; + } + if (permanent.getCounters(game).getCount(CounterType.P1P1) == 0 || event.getFlag()) { + permanent.addCounters(CounterType.P1P1.createInstance(event.getAmount()), source, game); } return true; } diff --git a/Mage/src/main/java/mage/abilities/keyword/AdaptAbility.java b/Mage/src/main/java/mage/abilities/keyword/AdaptAbility.java new file mode 100644 index 00000000000..634c38bd4df --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/AdaptAbility.java @@ -0,0 +1,27 @@ + + +package mage.abilities.keyword; + +import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.keyword.AdaptEffect; +import mage.constants.Zone; + +/** + * @author TheElk801 + */ +public class AdaptAbility extends ActivatedAbilityImpl { + + public AdaptAbility(int adaptNumber, String manaCost) { + super(Zone.BATTLEFIELD, new AdaptEffect(adaptNumber), new ManaCostsImpl(manaCost)); + } + + public AdaptAbility(final AdaptAbility ability) { + super(ability); + } + + @Override + public AdaptAbility copy() { + return new AdaptAbility(this); + } +} diff --git a/Mage/src/main/java/mage/game/events/GameEvent.java b/Mage/src/main/java/mage/game/events/GameEvent.java index eeb746ce952..622ee3eaddd 100644 --- a/Mage/src/main/java/mage/game/events/GameEvent.java +++ b/Mage/src/main/java/mage/game/events/GameEvent.java @@ -1,14 +1,14 @@ package mage.game.events; +import mage.MageObjectReference; +import mage.constants.Zone; + import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.UUID; -import mage.MageObjectReference; -import mage.constants.Zone; /** - * * @author BetaSteward_at_googlemail.com */ public class GameEvent implements Serializable { @@ -232,6 +232,7 @@ public class GameEvent implements Serializable { FLIP, FLIPPED, UNFLIP, UNFLIPPED, TRANSFORM, TRANSFORMED, + ADAPT, BECOMES_MONSTROUS, BECOMES_EXERTED, /* BECOMES_EXERTED @@ -383,12 +384,12 @@ public class GameEvent implements Serializable { } private GameEvent(EventType type, UUID customEventType, - UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag) { + UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag) { this(type, customEventType, targetId, sourceId, playerId, amount, flag, null); } private GameEvent(EventType type, UUID customEventType, - UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag, MageObjectReference reference) { + UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag, MageObjectReference reference) { this.type = type; this.customEventType = customEventType; this.targetId = targetId; @@ -466,7 +467,7 @@ public class GameEvent implements Serializable { /** * used to store which replacement effects were already applied to an event * or or any modified events that may replace it - * + *

* 614.5. A replacement effect doesn't invoke itself repeatedly; it gets * only one opportunity to affect an event or any modified events that may * replace it. Example: A player controls two permanents, each with an From ee00ce34da45931c7e756ceed9c555019edc03a5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 17:35:43 -0500 Subject: [PATCH 11/44] Implemented Biomancer's Familiar --- .../src/mage/cards/b/BiomancersFamiliar.java | 159 ++++++++++++++++++ .../src/mage/cards/t/TrainingGrounds.java | 26 ++- .../src/mage/sets/RavnicaAllegiance.java | 1 + 3 files changed, 170 insertions(+), 16 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/b/BiomancersFamiliar.java diff --git a/Mage.Sets/src/mage/cards/b/BiomancersFamiliar.java b/Mage.Sets/src/mage/cards/b/BiomancersFamiliar.java new file mode 100644 index 00000000000..4adf05b96ef --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BiomancersFamiliar.java @@ -0,0 +1,159 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.ActivatedAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.ChoiceImpl; +import mage.constants.*; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.util.CardUtil; + +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BiomancersFamiliar extends CardImpl { + + public BiomancersFamiliar(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{U}"); + + this.subtype.add(SubType.MUTANT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Activated abilities of creatures you control cost {2} less to activate. This effect can't reduce the amount of mana an ability costs to activate to less than one mana. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BiomancersFamiliarCostReductionEffect())); + + // {T}: The next time target creature adapts this turn, it adapts as though it had no +1/+1 counters on it. + Ability ability = new SimpleActivatedAbility( + new BiomancersFamiliarReplacementEffect(), new TapSourceCost() + ); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + private BiomancersFamiliar(final BiomancersFamiliar card) { + super(card); + } + + @Override + public BiomancersFamiliar copy() { + return new BiomancersFamiliar(this); + } +} + +class BiomancersFamiliarCostReductionEffect extends CostModificationEffectImpl { + + private static final String effectText = "Activated abilities of creatures you control cost {2} less to activate. " + + "This effect can't reduce the amount of mana an ability costs to activate to less than one mana"; + + BiomancersFamiliarCostReductionEffect() { + super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST); + staticText = effectText; + } + + private BiomancersFamiliarCostReductionEffect(final BiomancersFamiliarCostReductionEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + Player controller = game.getPlayer(abilityToModify.getControllerId()); + if (controller != null) { + Mana mana = abilityToModify.getManaCostsToPay().getMana(); + int reduceMax = mana.getGeneric(); + if (reduceMax > 0 && mana.count() == mana.getGeneric()) { + reduceMax--; + } + if (reduceMax > 2) { + reduceMax = 2; + } + if (reduceMax > 0) { + ChoiceImpl choice = new ChoiceImpl(true); + Set set = new LinkedHashSet<>(); + + for (int i = 0; i <= reduceMax; i++) { + set.add(String.valueOf(i)); + } + choice.setChoices(set); + choice.setMessage("Reduce ability cost"); + if (!controller.choose(Outcome.Benefit, choice, game)) { + return false; + } + int reduce = Integer.parseInt(choice.getChoice()); + CardUtil.reduceCost(abilityToModify, reduce); + } + return true; + } + + return false; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + if (abilityToModify.getAbilityType() == AbilityType.ACTIVATED + || (abilityToModify.getAbilityType() == AbilityType.MANA && abilityToModify instanceof ActivatedAbility)) { + //Activated abilities of creatures you control + Permanent permanent = game.getPermanent(abilityToModify.getSourceId()); + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { + return true; + } + } + return false; + } + + @Override + public BiomancersFamiliarCostReductionEffect copy() { + return new BiomancersFamiliarCostReductionEffect(this); + } +} + +class BiomancersFamiliarReplacementEffect extends ReplacementEffectImpl { + + BiomancersFamiliarReplacementEffect() { + super(Duration.EndOfTurn, Outcome.Benefit); + staticText = "The next time target creature adapts this turn, " + + "it adapts as though it had no +1/+1 counters on it."; + } + + private BiomancersFamiliarReplacementEffect(final BiomancersFamiliarReplacementEffect effect) { + super(effect); + } + + @Override + public BiomancersFamiliarReplacementEffect copy() { + return new BiomancersFamiliarReplacementEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ADAPT; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return event.getTargetId().equals(targetPointer.getFirst(game, source)); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setFlag(true); + discard(); + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/t/TrainingGrounds.java b/Mage.Sets/src/mage/cards/t/TrainingGrounds.java index 8a3b02c03ab..663138e691c 100644 --- a/Mage.Sets/src/mage/cards/t/TrainingGrounds.java +++ b/Mage.Sets/src/mage/cards/t/TrainingGrounds.java @@ -1,9 +1,6 @@ package mage.cards.t; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.UUID; import mage.Mana; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; @@ -12,20 +9,17 @@ import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.choices.ChoiceImpl; -import mage.constants.AbilityType; -import mage.constants.CardType; -import mage.constants.CostModificationType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.common.FilterControlledCreaturePermanent; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.util.CardUtil; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; + /** - * * @author maurer.it_at_gmail.com */ public final class TrainingGrounds extends CardImpl { @@ -49,15 +43,15 @@ public final class TrainingGrounds extends CardImpl { class TrainingGroundsEffect extends CostModificationEffectImpl { - private static final String effectText = "Activated abilities of creatures you control cost up to {2} less to activate. This effect can't reduce the amount of mana an ability costs to activate to less than one mana"; - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); + private static final String effectText = "Activated abilities of creatures you control cost {2} less to activate. " + + "This effect can't reduce the amount of mana an ability costs to activate to less than one mana"; - public TrainingGroundsEffect() { + TrainingGroundsEffect() { super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST); staticText = effectText; } - public TrainingGroundsEffect(final TrainingGroundsEffect effect) { + private TrainingGroundsEffect(final TrainingGroundsEffect effect) { super(effect); } @@ -100,7 +94,7 @@ class TrainingGroundsEffect extends CostModificationEffectImpl { || (abilityToModify.getAbilityType() == AbilityType.MANA && (abilityToModify instanceof ActivatedAbility))) { //Activated abilities of creatures you control Permanent permanent = game.getPermanent(abilityToModify.getSourceId()); - if (permanent != null && filter.match(permanent, source.getSourceId(), source.getControllerId(), game)) { + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 4d18f1fec3f..61389e9bd2e 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -38,6 +38,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Azorius Guildgate", 244, Rarity.COMMON, mage.cards.a.AzoriusGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Azorius Locket", 231, Rarity.COMMON, mage.cards.a.AzoriusLocket.class)); cards.add(new SetCardInfo("Bedevil", 157, Rarity.RARE, mage.cards.b.Bedevil.class)); + cards.add(new SetCardInfo("Biomancer's Familiar", 158, Rarity.RARE, mage.cards.b.BiomancersFamiliar.class)); cards.add(new SetCardInfo("Blood Crypt", 245, Rarity.RARE, mage.cards.b.BloodCrypt.class)); cards.add(new SetCardInfo("Bolrac-Clan Crusher", 159, Rarity.UNCOMMON, mage.cards.b.BolracClanCrusher.class)); cards.add(new SetCardInfo("Breeding Pool", 246, Rarity.RARE, mage.cards.b.BreedingPool.class)); From 48a9a5ab6528235c7ef3aff1b6e634db5daa36ef Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 17:50:49 -0500 Subject: [PATCH 12/44] Implemented End-Raze Forerunners --- .../src/mage/cards/e/EndRazeForerunners.java | 65 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EndRazeForerunners.java diff --git a/Mage.Sets/src/mage/cards/e/EndRazeForerunners.java b/Mage.Sets/src/mage/cards/e/EndRazeForerunners.java new file mode 100644 index 00000000000..f189c0b9ab3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EndRazeForerunners.java @@ -0,0 +1,65 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.TrampleAbility; +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.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EndRazeForerunners extends CardImpl { + + public EndRazeForerunners(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}{G}"); + + this.subtype.add(SubType.BOAR); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // When End-Raze Forerunners enters the battlefield, other creatures you control get +2/+2 and gain vigilance and trample until end of turn. + Ability ability = new EntersBattlefieldTriggeredAbility(new BoostControlledEffect( + 2, 2, Duration.EndOfTurn, + StaticFilters.FILTER_PERMANENT_CREATURE, true + ).setText("other creatures you control get +2/+2")); + ability.addEffect(new GainAbilityControlledEffect( + VigilanceAbility.getInstance(), Duration.EndOfTurn, + StaticFilters.FILTER_PERMANENT_CREATURE, true + ).setText("and gain vigilance")); + ability.addEffect(new GainAbilityControlledEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn, + StaticFilters.FILTER_PERMANENT_CREATURE, true + ).setText("and trample until end of turn")); + this.addAbility(ability); + } + + private EndRazeForerunners(final EndRazeForerunners card) { + super(card); + } + + @Override + public EndRazeForerunners copy() { + return new EndRazeForerunners(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 61389e9bd2e..1c7a5a16d7b 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -46,6 +46,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Deputy of Detention", 165, Rarity.RARE, mage.cards.d.DeputyOfDetention.class)); cards.add(new SetCardInfo("Dovin, Grand Arbiter", 167, Rarity.MYTHIC, mage.cards.d.DovinGrandArbiter.class)); cards.add(new SetCardInfo("Emergency Powers", 169, Rarity.MYTHIC, mage.cards.e.EmergencyPowers.class)); + cards.add(new SetCardInfo("End-Raze Forerunners", 124, Rarity.RARE, mage.cards.e.EndRazeForerunners.class)); cards.add(new SetCardInfo("Frenzied Arynx", 173, Rarity.COMMON, mage.cards.f.FrenziedArynx.class)); cards.add(new SetCardInfo("Gate Colossus", 232, Rarity.UNCOMMON, mage.cards.g.GateColossus.class)); cards.add(new SetCardInfo("Godless Shrine", 248, Rarity.RARE, mage.cards.g.GodlessShrine.class)); From 49acc318c59c5b3e55f137b1ebc8be7d054d42ba Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 17:55:00 -0500 Subject: [PATCH 13/44] Implemented Pestilent Spirit --- .../src/mage/cards/p/PestilentSpirit.java | 63 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PestilentSpirit.java diff --git a/Mage.Sets/src/mage/cards/p/PestilentSpirit.java b/Mage.Sets/src/mage/cards/p/PestilentSpirit.java new file mode 100644 index 00000000000..56f1611be3b --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PestilentSpirit.java @@ -0,0 +1,63 @@ +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.GainAbilitySpellsEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterObject; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PestilentSpirit extends CardImpl { + + private static final FilterObject filter = new FilterObject("instant and sorcery spells you control"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY) + )); + } + + public PestilentSpirit(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.SPIRIT); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Menace + this.addAbility(new MenaceAbility()); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // Instant and sorcery spells you control have deathtouch. + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new GainAbilitySpellsEffect( + DeathtouchAbility.getInstance(), filter + ).setText("Instant and sorcery spells you control have deathtouch") + )); + } + + private PestilentSpirit(final PestilentSpirit card) { + super(card); + } + + @Override + public PestilentSpirit copy() { + return new PestilentSpirit(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 1c7a5a16d7b..1d3518e2b79 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -68,6 +68,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Orzhov Guildgate", 252, Rarity.COMMON, mage.cards.o.OrzhovGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Orzhov Guildgate", 253, Rarity.COMMON, mage.cards.o.OrzhovGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Orzhov Locket", 236, Rarity.COMMON, mage.cards.o.OrzhovLocket.class)); + cards.add(new SetCardInfo("Pestilent Spirit", 81, Rarity.RARE, mage.cards.p.PestilentSpirit.class)); cards.add(new SetCardInfo("Precognitive Perception", 45, Rarity.RARE, mage.cards.p.PrecognitivePerception.class)); cards.add(new SetCardInfo("Rafter Demon", 196, Rarity.COMMON, mage.cards.r.RafterDemon.class)); cards.add(new SetCardInfo("Rakdos Firewheeler", 197, Rarity.UNCOMMON, mage.cards.r.RakdosFirewheeler.class)); From 27e21132a074c797fc1e292e79ef1dbbf5107e1b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 18:04:39 -0500 Subject: [PATCH 14/44] Implemented Skarrgan Hellkite --- .../src/mage/cards/s/SkarrganHellkite.java | 58 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 59 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SkarrganHellkite.java diff --git a/Mage.Sets/src/mage/cards/s/SkarrganHellkite.java b/Mage.Sets/src/mage/cards/s/SkarrganHellkite.java new file mode 100644 index 00000000000..91818d5cc2a --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SkarrganHellkite.java @@ -0,0 +1,58 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.condition.common.SourceHasCounterCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.common.DamageMultiEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.RiotAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.common.TargetAnyTargetAmount; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SkarrganHellkite extends CardImpl { + + public SkarrganHellkite(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + + this.subtype.add(SubType.DRAGON); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Riot + this.addAbility(new RiotAbility()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {3}{R}: Skarrgan Hellkite deals 2 damage divided as you choose among one or two targets. Activate this ability only if Skarrgan Hellkite has a +1/+1 counter on it. + Ability ability = new ConditionalActivatedAbility( + Zone.BATTLEFIELD, new DamageMultiEffect(2), + new ManaCostsImpl("{3}{R}"), new SourceHasCounterCondition(CounterType.P1P1), + "{3}{R}: {this} deals 2 damage divided as you choose among one or two targets. " + + "Activate this ability only if {this} has a +1/+1 counter on it." + ); + ability.addTarget(new TargetAnyTargetAmount(2)); + this.addAbility(ability); + } + + private SkarrganHellkite(final SkarrganHellkite card) { + super(card); + } + + @Override + public SkarrganHellkite copy() { + return new SkarrganHellkite(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 1d3518e2b79..d9ef5730794 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -81,6 +81,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Simic Guildgate", 257, Rarity.COMMON, mage.cards.s.SimicGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Simic Guildgate", 258, Rarity.COMMON, mage.cards.s.SimicGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Simic Locket", 240, Rarity.COMMON, mage.cards.s.SimicLocket.class)); + cards.add(new SetCardInfo("Skarrgan Hellkite", 114, Rarity.MYTHIC, mage.cards.s.SkarrganHellkite.class)); cards.add(new SetCardInfo("Spawn of Mayhem", 85, Rarity.MYTHIC, mage.cards.s.SpawnOfMayhem.class)); cards.add(new SetCardInfo("Sphinx of Foresight", 55, Rarity.RARE, mage.cards.s.SphinxOfForesight.class)); cards.add(new SetCardInfo("Sphinx's Insight", 209, Rarity.COMMON, mage.cards.s.SphinxsInsight.class)); From dba955ab290010d2d625c976f77f700ee8613df1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 18:27:18 -0500 Subject: [PATCH 15/44] Implemented Teysa Karlov --- Mage.Sets/src/mage/cards/t/TeysaKarlov.java | 111 ++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 112 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TeysaKarlov.java diff --git a/Mage.Sets/src/mage/cards/t/TeysaKarlov.java b/Mage.Sets/src/mage/cards/t/TeysaKarlov.java new file mode 100644 index 00000000000..461fbb03a52 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TeysaKarlov.java @@ -0,0 +1,111 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.NumberOfTriggersEvent; +import mage.game.events.ZoneChangeEvent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TeysaKarlov extends CardImpl { + + public TeysaKarlov(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{B}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ADVISOR); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // If a creature dying causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TeysaKarlovEffect())); + + // Creature tokens you control have vigilance and lifelink. + Ability ability = new SimpleStaticAbility( + Zone.BATTLEFIELD, + new GainAbilityControlledEffect( + VigilanceAbility.getInstance(), + Duration.WhileOnBattlefield, + StaticFilters.FILTER_CREATURE_TOKENS + ).setText("creature tokens you control have vigilance") + ); + ability.addEffect(new GainAbilityControlledEffect( + LifelinkAbility.getInstance(), + Duration.WhileOnBattlefield, + StaticFilters.FILTER_CREATURE_TOKENS + ).setText("and lifelink")); + this.addAbility(ability); + } + + private TeysaKarlov(final TeysaKarlov card) { + super(card); + } + + @Override + public TeysaKarlov copy() { + return new TeysaKarlov(this); + } +} + +class TeysaKarlovEffect extends ReplacementEffectImpl { + + TeysaKarlovEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "If a creature dying causes a triggered ability of a permanent you control to trigger, " + + "that ability triggers an additional time."; + } + + private TeysaKarlovEffect(final TeysaKarlovEffect effect) { + super(effect); + } + + @Override + public TeysaKarlovEffect copy() { + return new TeysaKarlovEffect(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) { + NumberOfTriggersEvent numberOfTriggersEvent = (NumberOfTriggersEvent) event; + if (source.isControlledBy(event.getPlayerId()) + && game.getPermanent(numberOfTriggersEvent.getSourceId()) != null + && numberOfTriggersEvent.getSourceEvent() instanceof ZoneChangeEvent) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) numberOfTriggersEvent.getSourceEvent(); + if (zEvent.getFromZone() == Zone.BATTLEFIELD + && zEvent.getToZone() == Zone.GRAVEYARD + && zEvent.getTarget() != null + && zEvent.getTarget().isCreature()) { + return true; + } + } + } + return false; + } + + @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/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index d9ef5730794..a206d14f279 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -86,6 +86,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Sphinx of Foresight", 55, Rarity.RARE, mage.cards.s.SphinxOfForesight.class)); cards.add(new SetCardInfo("Sphinx's Insight", 209, Rarity.COMMON, mage.cards.s.SphinxsInsight.class)); cards.add(new SetCardInfo("Stomping Ground", 259, Rarity.RARE, mage.cards.s.StompingGround.class)); + cards.add(new SetCardInfo("Teysa Karlov", 213, Rarity.RARE, mage.cards.t.TeysaKarlov.class)); cards.add(new SetCardInfo("The Haunt of Hightower", 273, Rarity.MYTHIC, mage.cards.t.TheHauntOfHightower.class)); cards.add(new SetCardInfo("Tithe Taker", 27, Rarity.RARE, mage.cards.t.TitheTaker.class)); cards.add(new SetCardInfo("Wilderness Reclamation", 140, Rarity.UNCOMMON, mage.cards.w.WildernessReclamation.class)); From 1a1c4f1f7cc3c31695832727ef57565b6b1eb958 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 18:29:11 -0500 Subject: [PATCH 16/44] updated RNA spoiler --- Utils/mtg-cards-data.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index e4fe7d59817..6ffcf8a85dc 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -34585,12 +34585,13 @@ Spawn of Mayhem|Ravnica Allegiance|85|M|{2}{B}{B}|Creature - Demon|4|4|Spectacle Amplifire|Ravnica Allegiance|92|R|{2}{R}{R}|Creature - Elemental|1|1|At the beginning of your upkeep, reveal cards from he top of your library until you reveal a creature card. Until your next turn, Amplifire's base power becomes twice that card's power and its base toughness becomes twice that card's toughness. Put the revealed cards on the bottom of your library in a random order.| Light Up the Stage|Ravnica Allegiance|107|U|{2}{R}|Sorcery|||Spectacle {R}$Exile the top two cards of your library. Until the end of your next turn, you may play those cards.| Rix Maadi Reveler|Ravnica Allegiance|109|R|{1}{R}|Creature - Human Shaman|2|2|Spectacle {2}{B}{R}$When Rix Maadi Reveler enters the battlefield, discard a card, then draw a card. If Rix Maadi Reveler's spectacle cost was paid, instead discard your hand, then draw three cards.| -Skarrgan Hellkite|Ravnica Allegiance|114|M|{3}{R}{R}|Creature - Dragon|4|4|Riot$Flying${3}{R}: Sharrgan Hellkite deals 2 damage divided as you choose among one or two targets. Activate this ability only if Sharrgan Hellkite has a +1/+1 counter on it.| +Skarrgan Hellkite|Ravnica Allegiance|114|M|{3}{R}{R}|Creature - Dragon|4|4|Riot$Flying${3}{R}: Skarrgan Hellkite deals 2 damage divided as you choose among one or two targets. Activate this ability only if Skarrgan Hellkite has a +1/+1 counter on it.| End-Raze Forerunners|Ravnica Allegiance|124|R|{5}{G}{G}{G}|Creature - Boar|7|7|Vigilance, trample, haste$When End-Raze Forerunners enters the battlefield, other creatures you control get +2/+2 and gain vigilance and trample until end of turn.| Growth-Chamber Guardian|Ravnica Allegiance|128|R|{1}{G}|Creature - Elf Crab Warrior|2|2|{2}{G}: Adapt 2.$Whenever one or more +1/+1 counters are put on Growth-Chamber Guardian, you may search your library for a card named Growth-Chamber Guardian, reveal it, put it into your hand, then shuffle your library.| Wilderness Reclamation|Ravnica Allegiance|140|U|{3}{G}|Enchantment|||At the beginning of your end step, untap all lands you control.| Absorb|Ravnica Allegiance|151|R|{W}{U}{U}|Instant|||Counter target spell. You gain 3 life.| Aeromunculus|Ravnica Allegiance|152|C|{1}{G}{U}|Creature - Homunculus Mutant|2|3|Flying${2}{G}{U}: Adapt 1.| +Basilica Bell-Haunt|Ravnica Allegiance|156|U|{W}{W}{B}{B}|Creature - Spirit|3|4|When Basilica Bell-Haunt enters the battlefield, each opponent discards a card and you gain 3 life.| Bedevil|Ravnica Allegiance|157|R|{B}{B}{R}|Instant|||Destroy target artifact, creature, or planeswalker.| Biomancer's Familiar|Ravnica Allegiance|158|R|{G}{U}|Creature - Mutant|2|2|Activated abilities of creatures you control cost {2} less to activate. This effect can't reduce the amount of mana an ability costs to activate to less than one mana.${T}: The next time target creature adapts this turn, it adapts as though it had no +1/+1 counters on it.| Bolrac-Clan Crusher|Ravnica Allegiance|159|U|{3}{R}{G}|Creature - Ogre Warrior|4|4|{T}, Remove a +1/+1 counter from a creature you control: Bolrac-Clan Crusher deals 2 damage to any target.| @@ -34606,7 +34607,8 @@ Judith, the Scourge Diva|Ravnica Allegiance|185|R|{1}{B}{R}|Legendary Creature - Kaya, Orzhov Usurper|Ravnica Allegiance|186|M|{1}{W}{B}|Legendary Planeswalker - Kaya|3|+1: Exile up to two target cards from a single graveyard. You gain 2 life if at least one creature card was exiled this way.$-1: Exile target nonland permanent with converted mana cost 1 or less.$-5: Kaya, Orzhov Usurper deals damage to target player equal to the number of cards that player owns in exile and you gain that much life.| Lavinia, Azorius Renegade|Ravnica Allegiance|189|R|{W}{U}|Legendary Creature - Human Soldier|2|2|Each opponent can't cast noncreature spells with converted mana cost greater than the number of lands that player controls.$Whenever an opponent casts a spell, if no mana was spent to cast it, counter that spell.| Mortify|Ravnica Allegiance|192|U|{1}{W}{B}|Instant|||Destroy target creature or enchantment.| -Prime Speaker Vannifar|Ravnica Allegiance|195|M|{2}{G}{U}|Legendary Creature - Elf Ooze Wizard|2|4|{T}, Sacrifice another creature: Search your library for a creature card with converted mana cost equal to 1 plus the sacrifices creature's converted mana cost, put that card onto the battlefield, then shuffle your library. Activate this ability only any time you could cast a sorcery.| +Pitiless Pontiff|Ravnica Allegiance|194|U|{W}{B}|Creature - Vampire Cleric|||{1}, Sacrifice another creature: Pitiless Pontiff gains deathtouch and indestructible until end of turn.| +Prime Speaker Vannifar|Ravnica Allegiance|195|M|{2}{G}{U}|Legendary Creature - Elf Ooze Wizard|2|4|{T}, Sacrifice another creature: Search your library for a creature card with converted mana cost equal to 1 plus the sacrificed creature's converted mana cost, put that card onto the battlefield, then shuffle your library. Activate this ability only any time you could cast a sorcery.| Rafter Demon|Ravnica Allegiance|196|C|{2}{B}{R}|Creature - Demon|4|2|Spectacle {3}{B}{R}$When Rafter Demon enters the battlefield, if its spectacle cost was paid, each opponent discards a card.| Rakdos Firewheeler|Ravnica Allegiance|197|U|{B}{B}{R}{R}|Creature - Human Rogue|4|3|When Rakdos Firewheeler enters the battlefield, it deals 2 damage to target opponent and 2 damage to up to one target creature or planeswalker.| Rakdos, the Showstopper|Ravnica Allegiance|199|M|{4}{B}{R}|Legendary Creature - Demon|6|6|Flying, trample$When Rakdos, the Showstopper enters the battlefield, flip a coin for each creature that isn't a Demon, Devil, or Imp. Destroy each creature whose coin comes up tails.| @@ -34616,7 +34618,7 @@ Simic Ascendancy|Ravnica Allegiance|207|R|{G}{U}|Enchantment|||{1}{G}{U}: Put a Sphinx's Insight|Ravnica Allegiance|209|C|{2}{W}{U}|Instant|||Draw two cards.$Addendum — If you cast this spell during your main phase, you gain 2 life.| Teysa Karlov|Ravnica Allegiance|213|R|{2}{W}{B}|Legendary Creature - Human Advisor|2|4|If a creature dying causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.$Creature tokens you control have vigilance and lifelink.| Zegana, Utopian Speaker|Ravnica Allegiance|214|R|{2}{G}{U}|Legendary Creature - Merfolk Wizard|4|4|When Zegana, Utopian Speaker enters the battlefield, if you control another creature with a +1/+1 counter on it, draw a card.${4}{G}{U}: Adapt 4.$Each creature you control with a +1/+1 counter on it has trample.| -Deploy|Ravnica Allegiance|225|U|{2}{W}{U}|Instant|||Creature two 1/1 colorless Thopter artifact creature tokens with flying, then you gain 1 life for each creature you control.| +Deploy|Ravnica Allegiance|225|U|{2}{W}{U}|Instant|||Create two 1/1 colorless Thopter artifact creature tokens with flying, then you gain 1 life for each creature you control.| Depose|Ravnica Allegiance|225|U|{1}{W/U}|Instant|||Tap target creature.$Draw a card.| Incongruity|Ravnica Allegiance|226|U|{1}{G}{U}|Instant|||Exile target creature. That creature's controller creates a 3/3 green Frog Lizard creature token.| Incubation|Ravnica Allegiance|226|U|{G/U}|Sorcery|||Look at the top five cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.| From bf441d127c41efc7de8ecccf916176ddb5e645ab Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 18:43:14 -0500 Subject: [PATCH 17/44] Implemented Basilica Bell-Haunt --- .../src/mage/cards/b/BasilicaBellHaunt.java | 42 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 43 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BasilicaBellHaunt.java diff --git a/Mage.Sets/src/mage/cards/b/BasilicaBellHaunt.java b/Mage.Sets/src/mage/cards/b/BasilicaBellHaunt.java new file mode 100644 index 00000000000..1fd93559398 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BasilicaBellHaunt.java @@ -0,0 +1,42 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BasilicaBellHaunt extends CardImpl { + + public BasilicaBellHaunt(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{W}{B}{B}"); + + this.subtype.add(SubType.SPIRIT); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // When Basilica Bell-Haunt enters the battlefield, each opponent discards a card and you gain 3 life. + Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardEachPlayerEffect(TargetController.OPPONENT)); + ability.addEffect(new GainLifeEffect(3).setText("and you gain 3 life")); + this.addAbility(ability); + } + + private BasilicaBellHaunt(final BasilicaBellHaunt card) { + super(card); + } + + @Override + public BasilicaBellHaunt copy() { + return new BasilicaBellHaunt(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index a206d14f279..128fc38a9a8 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -37,6 +37,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Azorius Guildgate", 243, Rarity.COMMON, mage.cards.a.AzoriusGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Azorius Guildgate", 244, Rarity.COMMON, mage.cards.a.AzoriusGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Azorius Locket", 231, Rarity.COMMON, mage.cards.a.AzoriusLocket.class)); + cards.add(new SetCardInfo("Basilica Bell-Haunt", 156, Rarity.UNCOMMON, mage.cards.b.BasilicaBellHaunt.class)); cards.add(new SetCardInfo("Bedevil", 157, Rarity.RARE, mage.cards.b.Bedevil.class)); cards.add(new SetCardInfo("Biomancer's Familiar", 158, Rarity.RARE, mage.cards.b.BiomancersFamiliar.class)); cards.add(new SetCardInfo("Blood Crypt", 245, Rarity.RARE, mage.cards.b.BloodCrypt.class)); From e642ed5ac250d1a7c8916a2f64b3a7ac6097c865 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 18:51:26 -0500 Subject: [PATCH 18/44] Implemented Pitiless Pontiff --- .../src/mage/cards/p/PitilessPontiff.java | 52 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 53 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PitilessPontiff.java diff --git a/Mage.Sets/src/mage/cards/p/PitilessPontiff.java b/Mage.Sets/src/mage/cards/p/PitilessPontiff.java new file mode 100644 index 00000000000..9eff7865c15 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PitilessPontiff.java @@ -0,0 +1,52 @@ +package mage.cards.p; + +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.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.IndestructibleAbility; +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 mage.target.common.TargetControlledPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PitilessPontiff extends CardImpl { + + public PitilessPontiff(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{B}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.CLERIC); + + // {1}, Sacrifice another creature: Pitiless Pontiff gains deathtouch and indestructible until end of turn. + Ability ability = new SimpleActivatedAbility(new GainAbilitySourceEffect( + DeathtouchAbility.getInstance(), Duration.EndOfTurn + ).setText("{this} gains deathtouch"), new GenericManaCost(1)); + ability.addEffect(new GainAbilitySourceEffect( + IndestructibleAbility.getInstance(), Duration.EndOfTurn + ).setText("and indestructible until end of turn")); + ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( + StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE + ))); + this.addAbility(ability); + } + + private PitilessPontiff(final PitilessPontiff card) { + super(card); + } + + @Override + public PitilessPontiff copy() { + return new PitilessPontiff(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 128fc38a9a8..4bfd4bdd24c 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -70,6 +70,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Orzhov Guildgate", 253, Rarity.COMMON, mage.cards.o.OrzhovGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Orzhov Locket", 236, Rarity.COMMON, mage.cards.o.OrzhovLocket.class)); cards.add(new SetCardInfo("Pestilent Spirit", 81, Rarity.RARE, mage.cards.p.PestilentSpirit.class)); + cards.add(new SetCardInfo("Pitiless Pontiff", 194, Rarity.UNCOMMON, mage.cards.p.PitilessPontiff.class)); cards.add(new SetCardInfo("Precognitive Perception", 45, Rarity.RARE, mage.cards.p.PrecognitivePerception.class)); cards.add(new SetCardInfo("Rafter Demon", 196, Rarity.COMMON, mage.cards.r.RafterDemon.class)); cards.add(new SetCardInfo("Rakdos Firewheeler", 197, Rarity.UNCOMMON, mage.cards.r.RakdosFirewheeler.class)); From b459c208e4eda1b6348a660b3bb5de671ecf8766 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 20:53:29 -0500 Subject: [PATCH 19/44] updated RNA spoiler --- Utils/mtg-cards-data.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 6ffcf8a85dc..5c2af735283 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -34580,6 +34580,7 @@ Tithe Taker|Ravnica Allegiance|27|R|{1}{W}|Creature - Human Soldier|2|1|During y Mass Manipulation|Ravnica Allegiance|42|R|{X}{X}{U}{U}{U}{U}|Sorcery|||Gain control of X target creatures and/or planeswalkers.| Precognitive Perception|Ravnica Allegiance|45|R|{3}{U}{U}|Instant|||Draw three cards.$Addendum — If you cast this spell during your main phase, instead scry 3, then draw three cards.| Sphinx of Foresight|Ravnica Allegiance|55|R|{2}{U}{U}|Creature - Sphinx|4|4|You may reveal this card from your opening hand. If you do, scry 3 at the beginning of your first upkeep.$Flying$At the beginning of your upkeep, scry 1.| +Gutterbones|Ravnica Allegiance|76|R|{B}|Creature - Skeleton Warrior|2|1|Gutterbones enters the battlefield tapped.${1}{B}: Return Gutterbones from your graveyard to your hand. Activate this ability only during your turn and only if an opponent lost life this turn.| Pestilent Spirit|Ravnica Allegiance|81|R|{2}{B}|Creature - Spirit|3|2|Menace, deathtouch$Instant and sorcery spells you control have deathtouch.| Spawn of Mayhem|Ravnica Allegiance|85|M|{2}{B}{B}|Creature - Demon|4|4|Spectacle {1}{B}{B}$Flying, trample$At the beginning of your upkeep, Spawn of Mayhem deals 1 damage to each player. Then if you have 10 or less life, put a +1/+1 counter on Spawn of Mayhem.| Amplifire|Ravnica Allegiance|92|R|{2}{R}{R}|Creature - Elemental|1|1|At the beginning of your upkeep, reveal cards from he top of your library until you reveal a creature card. Until your next turn, Amplifire's base power becomes twice that card's power and its base toughness becomes twice that card's toughness. Put the revealed cards on the bottom of your library in a random order.| From a7b0f058905782b6ed72fbb507b514445440d596 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 21:09:39 -0500 Subject: [PATCH 20/44] Implemented Ravager Wurm --- Mage.Sets/src/mage/cards/r/RavagerWurm.java | 82 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + Mage/src/main/java/mage/abilities/Modes.java | 14 ++-- 3 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/r/RavagerWurm.java diff --git a/Mage.Sets/src/mage/cards/r/RavagerWurm.java b/Mage.Sets/src/mage/cards/r/RavagerWurm.java new file mode 100644 index 00000000000..b3691662deb --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RavagerWurm.java @@ -0,0 +1,82 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.FightTargetSourceEffect; +import mage.abilities.keyword.RiotAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityType; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +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 RavagerWurm extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("land with an activated ability that isn't a mana ability"); + + static { + filter.add(RavagerWurmPredicate.instance); + } + + public RavagerWurm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}{G}"); + + this.subtype.add(SubType.WURM); + this.power = new MageInt(4); + this.toughness = new MageInt(5); + + // Riot + this.addAbility(new RiotAbility()); + + // When Ravager Wurm enters the battlefield, choose up to one — + // • Ravager Wurm fights target creature you don't control. + Ability ability = new EntersBattlefieldTriggeredAbility(new FightTargetSourceEffect().setText("{this} fights target creature you don't control"), false); + ability.getModes().setMinModes(0); + ability.getModes().setMaxModes(1); + + // • Destroy target land with an activated ability that isn't a mana ability. + Mode mode = new Mode(new DestroyTargetEffect()); + mode.addTarget(new TargetPermanent(filter)); + ability.addMode(mode); + this.addAbility(ability); + } + + private RavagerWurm(final RavagerWurm card) { + super(card); + } + + @Override + public RavagerWurm copy() { + return new RavagerWurm(this); + } +} + +enum RavagerWurmPredicate implements Predicate { + instance; + + @Override + public boolean apply(Permanent input, Game game) { + if (input == null || !input.isLand()) { + return false; + } + for (Ability ability : input.getAbilities()) { + if (ability.getAbilityType() == AbilityType.ACTIVATED) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 4bfd4bdd24c..6f170cbf430 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -77,6 +77,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Rakdos Guildgate", 255, Rarity.COMMON, mage.cards.r.RakdosGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rakdos Guildgate", 256, Rarity.COMMON, mage.cards.r.RakdosGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rakdos Locket", 237, Rarity.COMMON, mage.cards.r.RakdosLocket.class)); + cards.add(new SetCardInfo("Ravager Wurm", 200, Rarity.MYTHIC, mage.cards.r.RavagerWurm.class)); cards.add(new SetCardInfo("Rix Maadi Reveler", 109, Rarity.RARE, mage.cards.r.RixMaadiReveler.class)); cards.add(new SetCardInfo("Seraph of the Scales", 205, Rarity.MYTHIC, mage.cards.s.SeraphOfTheScales.class)); cards.add(new SetCardInfo("Simic Ascendancy", 207, Rarity.RARE, mage.cards.s.SimicAscendancy.class)); diff --git a/Mage/src/main/java/mage/abilities/Modes.java b/Mage/src/main/java/mage/abilities/Modes.java index 712dba5b529..98def5bddb6 100644 --- a/Mage/src/main/java/mage/abilities/Modes.java +++ b/Mage/src/main/java/mage/abilities/Modes.java @@ -1,13 +1,6 @@ package mage.abilities; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; import mage.abilities.costs.OptionalAdditionalModeSourceCosts; import mage.cards.Card; import mage.constants.Outcome; @@ -18,8 +11,9 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetOpponent; +import java.util.*; + /** - * * @author BetaSteward_at_googlemail.com */ public class Modes extends LinkedHashMap { @@ -340,7 +334,9 @@ public class Modes extends LinkedHashMap { StringBuilder sb = new StringBuilder(); if (this.getMaxModesFilter() != null) { sb.append("choose one or more. Each mode must target ").append(getMaxModesFilter().getMessage()); - } else if (this.getMinModes() == 1 && this.getMaxModes() == 3) { + } else if (this.getMinModes() == 0 && this.getMaxModes() == 1) { + sb.append("choose up to one "); + } else if (this.getMinModes() == 1 && this.getMaxModes() > 2) { sb.append("choose one or more "); } else if (this.getMinModes() == 1 && this.getMaxModes() == 2) { sb.append("choose one or both "); From 5c0084699bfcada6ff1e7025cc8b037d80f7be35 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 21:22:42 -0500 Subject: [PATCH 21/44] Implemented Prime Speaker Vannifar --- Mage.Sets/src/mage/cards/b/BirthingPod.java | 46 ++++---- .../mage/cards/p/PrimeSpeakerVannifar.java | 107 ++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 3 files changed, 134 insertions(+), 20 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/p/PrimeSpeakerVannifar.java diff --git a/Mage.Sets/src/mage/cards/b/BirthingPod.java b/Mage.Sets/src/mage/cards/b/BirthingPod.java index 2242e3886d6..179040611b0 100644 --- a/Mage.Sets/src/mage/cards/b/BirthingPod.java +++ b/Mage.Sets/src/mage/cards/b/BirthingPod.java @@ -1,7 +1,6 @@ package mage.cards.b; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.Cost; @@ -17,7 +16,7 @@ import mage.constants.ComparisonType; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterCard; -import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; +import mage.filter.StaticFilters; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; @@ -26,6 +25,8 @@ import mage.players.Player; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + /** * @author Loki */ @@ -36,9 +37,13 @@ public final class BirthingPod extends CardImpl { // {1}{G/P}, {tap}, Sacrifice a creature: Search your library for a creature card with converted mana cost equal to 1 plus the sacrificed creature's converted mana cost, // put that card onto the battlefield, then shuffle your library. Activate this ability only any time you could cast a sorcery. - Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new BirthingPodEffect(), new ManaCostsImpl("{1}{G/P}")); + Ability ability = new ActivateAsSorceryActivatedAbility( + Zone.BATTLEFIELD, new BirthingPodEffect(), new ManaCostsImpl("{1}{G/P}") + ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent( + StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT + ))); this.addAbility(ability); } @@ -56,11 +61,12 @@ class BirthingPodEffect extends OneShotEffect { BirthingPodEffect() { super(Outcome.Benefit); - staticText = "Search your library for a creature card with converted mana cost equal to 1 plus the sacrificed creature's converted mana cost, put that card " - + "onto the battlefield, then shuffle your library"; + staticText = "Search your library for a creature card with converted mana cost equal to 1 " + + "plus the sacrificed creature's converted mana cost, put that card " + + "onto the battlefield, then shuffle your library"; } - BirthingPodEffect(final BirthingPodEffect effect) { + private BirthingPodEffect(final BirthingPodEffect effect) { super(effect); } @@ -77,20 +83,20 @@ class BirthingPodEffect extends OneShotEffect { } } Player controller = game.getPlayer(source.getControllerId()); - if (sacrificedPermanent != null && controller != null) { - int newConvertedCost = sacrificedPermanent.getConvertedManaCost() + 1; - FilterCard filter = new FilterCard("creature card with converted mana cost " + newConvertedCost); - filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, newConvertedCost)); - filter.add(new CardTypePredicate(CardType.CREATURE)); - TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (controller.searchLibrary(target, game)) { - Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); - controller.moveCards(card, Zone.BATTLEFIELD, source, game); - } - controller.shuffleLibrary(source, game); - return true; + if (sacrificedPermanent == null || controller == null) { + return false; } - return false; + int newConvertedCost = sacrificedPermanent.getConvertedManaCost() + 1; + FilterCard filter = new FilterCard("creature card with converted mana cost " + newConvertedCost); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, newConvertedCost)); + filter.add(new CardTypePredicate(CardType.CREATURE)); + TargetCardInLibrary target = new TargetCardInLibrary(filter); + if (controller.searchLibrary(target, game)) { + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + } + controller.shuffleLibrary(source, game); + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/p/PrimeSpeakerVannifar.java b/Mage.Sets/src/mage/cards/p/PrimeSpeakerVannifar.java new file mode 100644 index 00000000000..3554ba25ade --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PrimeSpeakerVannifar.java @@ -0,0 +1,107 @@ +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 and Loki + */ +public final class PrimeSpeakerVannifar extends CardImpl { + + public PrimeSpeakerVannifar(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.OOZE); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // {T}, Sacrifice another creature: Search your library for a creature card with converted mana cost equal to 1 plus the sacrificed creature's converted mana cost, put that card onto the battlefield, then shuffle your library. Activate this ability only any time you could cast a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + Zone.BATTLEFIELD, new PrimeSpeakerVannifarEffect(), new TapSourceCost() + ); + ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent( + StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE + ))); + this.addAbility(ability); + } + + private PrimeSpeakerVannifar(final PrimeSpeakerVannifar card) { + super(card); + } + + @Override + public PrimeSpeakerVannifar copy() { + return new PrimeSpeakerVannifar(this); + } +} + +class PrimeSpeakerVannifarEffect extends OneShotEffect { + + PrimeSpeakerVannifarEffect() { + super(Outcome.Benefit); + staticText = "Search your library for a creature card with converted mana cost equal to 1 " + + "plus the sacrificed creature's converted mana cost, put that card " + + "onto the battlefield, then shuffle your library"; + } + + private PrimeSpeakerVannifarEffect(final PrimeSpeakerVannifarEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sacrificedPermanent = null; + for (Cost cost : source.getCosts()) { + if (cost instanceof SacrificeTargetCost) { + SacrificeTargetCost sacrificeCost = (SacrificeTargetCost) cost; + if (!sacrificeCost.getPermanents().isEmpty()) { + sacrificedPermanent = sacrificeCost.getPermanents().get(0); + } + break; + } + } + Player controller = game.getPlayer(source.getControllerId()); + if (sacrificedPermanent == null || controller == null) { + return false; + } + int newConvertedCost = sacrificedPermanent.getConvertedManaCost() + 1; + FilterCard filter = new FilterCard("creature card with converted mana cost " + newConvertedCost); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, newConvertedCost)); + filter.add(new CardTypePredicate(CardType.CREATURE)); + TargetCardInLibrary target = new TargetCardInLibrary(filter); + if (controller.searchLibrary(target, game)) { + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + } + controller.shuffleLibrary(source, game); + return true; + } + + @Override + public PrimeSpeakerVannifarEffect copy() { + return new PrimeSpeakerVannifarEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 6f170cbf430..0159ef9a49e 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -72,6 +72,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Pestilent Spirit", 81, Rarity.RARE, mage.cards.p.PestilentSpirit.class)); cards.add(new SetCardInfo("Pitiless Pontiff", 194, Rarity.UNCOMMON, mage.cards.p.PitilessPontiff.class)); cards.add(new SetCardInfo("Precognitive Perception", 45, Rarity.RARE, mage.cards.p.PrecognitivePerception.class)); + cards.add(new SetCardInfo("Prime Speaker Vannifar", 195, Rarity.MYTHIC, mage.cards.p.PrimeSpeakerVannifar.class)); cards.add(new SetCardInfo("Rafter Demon", 196, Rarity.COMMON, mage.cards.r.RafterDemon.class)); cards.add(new SetCardInfo("Rakdos Firewheeler", 197, Rarity.UNCOMMON, mage.cards.r.RakdosFirewheeler.class)); cards.add(new SetCardInfo("Rakdos Guildgate", 255, Rarity.COMMON, mage.cards.r.RakdosGuildgate.class, NON_FULL_USE_VARIOUS)); From 3e092805d9ee1ef6c173b8d8fa146360adf0c8e7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 21:47:42 -0500 Subject: [PATCH 22/44] Implemented Amplifire --- Mage.Sets/src/mage/cards/a/Amplifire.java | 90 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 91 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/Amplifire.java diff --git a/Mage.Sets/src/mage/cards/a/Amplifire.java b/Mage.Sets/src/mage/cards/a/Amplifire.java new file mode 100644 index 00000000000..273435ab00c --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/Amplifire.java @@ -0,0 +1,90 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; +import mage.cards.*; +import mage.constants.*; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Amplifire extends CardImpl { + + public Amplifire(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // At the beginning of your upkeep, reveal cards from the top of your library until you reveal a creature card. Until your next turn, Amplifire's base power becomes twice that card's power and its base toughness becomes twice that card's toughness. Put the revealed cards on the bottom of your library in a random order. + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + new AmplifireEffect(), TargetController.YOU, false + )); + } + + private Amplifire(final Amplifire card) { + super(card); + } + + @Override + public Amplifire copy() { + return new Amplifire(this); + } +} + +class AmplifireEffect extends OneShotEffect { + + AmplifireEffect() { + super(Outcome.Benefit); + staticText = "reveal cards from the top of your library until you reveal a creature card. " + + "Until your next turn, {this}'s base power becomes twice that card's power " + + "and its base toughness becomes twice that card's toughness. " + + "Put the revealed cards on the bottom of your library in a random order."; + } + + private AmplifireEffect(final AmplifireEffect effect) { + super(effect); + } + + @Override + public AmplifireEffect copy() { + return new AmplifireEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cards cards = new CardsImpl(); + Card lastCard = null; + for (Card card : player.getLibrary().getCards(game)) { + if (card != null) { + cards.add(card); + if (card.isCreature()) { + lastCard = card; + break; + } + } + } + player.revealCards(source, cards, game); + if (lastCard != null) { + game.addEffect(new SetPowerToughnessSourceEffect( + 2 * lastCard.getPower().getValue(), + 2 * lastCard.getToughness().getValue(), + Duration.UntilYourNextTurn + ), source); + } + player.putCardsOnBottomOfLibrary(cards, game, source, false); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 0159ef9a49e..ffec7aae16e 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -34,6 +34,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Absorb", 151, Rarity.RARE, mage.cards.a.Absorb.class)); cards.add(new SetCardInfo("Aeromunculus", 152, Rarity.COMMON, mage.cards.a.Aeromunculus.class)); + cards.add(new SetCardInfo("Amplifire", 92, Rarity.RARE, mage.cards.a.Amplifire.class)); cards.add(new SetCardInfo("Azorius Guildgate", 243, Rarity.COMMON, mage.cards.a.AzoriusGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Azorius Guildgate", 244, Rarity.COMMON, mage.cards.a.AzoriusGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Azorius Locket", 231, Rarity.COMMON, mage.cards.a.AzoriusLocket.class)); From 4196dec963f5030d45415d17c3e80d4b91d67023 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 22:01:48 -0500 Subject: [PATCH 23/44] fixed some minor card errors --- Mage.Sets/src/mage/cards/p/PitilessPontiff.java | 3 +++ Mage.Sets/src/mage/cards/{ => s}/SimicAscendancy.java | 0 Mage.Sets/src/mage/sets/RavnicaAllegiance.java | 4 ++-- Utils/mtg-cards-data.txt | 8 ++++---- 4 files changed, 9 insertions(+), 6 deletions(-) rename Mage.Sets/src/mage/cards/{ => s}/SimicAscendancy.java (100%) diff --git a/Mage.Sets/src/mage/cards/p/PitilessPontiff.java b/Mage.Sets/src/mage/cards/p/PitilessPontiff.java index 9eff7865c15..4b342f2c18e 100644 --- a/Mage.Sets/src/mage/cards/p/PitilessPontiff.java +++ b/Mage.Sets/src/mage/cards/p/PitilessPontiff.java @@ -1,5 +1,6 @@ package mage.cards.p; +import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; @@ -27,6 +28,8 @@ public final class PitilessPontiff extends CardImpl { this.subtype.add(SubType.VAMPIRE); this.subtype.add(SubType.CLERIC); + this.power = new MageInt(2); + this.toughness = new MageInt(2); // {1}, Sacrifice another creature: Pitiless Pontiff gains deathtouch and indestructible until end of turn. Ability ability = new SimpleActivatedAbility(new GainAbilitySourceEffect( diff --git a/Mage.Sets/src/mage/cards/SimicAscendancy.java b/Mage.Sets/src/mage/cards/s/SimicAscendancy.java similarity index 100% rename from Mage.Sets/src/mage/cards/SimicAscendancy.java rename to Mage.Sets/src/mage/cards/s/SimicAscendancy.java diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index ffec7aae16e..5c15a086ca9 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -91,10 +91,10 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Sphinx of Foresight", 55, Rarity.RARE, mage.cards.s.SphinxOfForesight.class)); cards.add(new SetCardInfo("Sphinx's Insight", 209, Rarity.COMMON, mage.cards.s.SphinxsInsight.class)); cards.add(new SetCardInfo("Stomping Ground", 259, Rarity.RARE, mage.cards.s.StompingGround.class)); - cards.add(new SetCardInfo("Teysa Karlov", 213, Rarity.RARE, mage.cards.t.TeysaKarlov.class)); + cards.add(new SetCardInfo("Teysa Karlov", 212, Rarity.RARE, mage.cards.t.TeysaKarlov.class)); cards.add(new SetCardInfo("The Haunt of Hightower", 273, Rarity.MYTHIC, mage.cards.t.TheHauntOfHightower.class)); cards.add(new SetCardInfo("Tithe Taker", 27, Rarity.RARE, mage.cards.t.TitheTaker.class)); - cards.add(new SetCardInfo("Wilderness Reclamation", 140, Rarity.UNCOMMON, mage.cards.w.WildernessReclamation.class)); + cards.add(new SetCardInfo("Wilderness Reclamation", 149, Rarity.UNCOMMON, mage.cards.w.WildernessReclamation.class)); cards.add(new SetCardInfo("Zegana, Utopian Speaker", 214, Rarity.RARE, mage.cards.z.ZeganaUtopianSpeaker.class)); } diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 5c2af735283..ab76d6e1555 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -34583,13 +34583,13 @@ Sphinx of Foresight|Ravnica Allegiance|55|R|{2}{U}{U}|Creature - Sphinx|4|4|You Gutterbones|Ravnica Allegiance|76|R|{B}|Creature - Skeleton Warrior|2|1|Gutterbones enters the battlefield tapped.${1}{B}: Return Gutterbones from your graveyard to your hand. Activate this ability only during your turn and only if an opponent lost life this turn.| Pestilent Spirit|Ravnica Allegiance|81|R|{2}{B}|Creature - Spirit|3|2|Menace, deathtouch$Instant and sorcery spells you control have deathtouch.| Spawn of Mayhem|Ravnica Allegiance|85|M|{2}{B}{B}|Creature - Demon|4|4|Spectacle {1}{B}{B}$Flying, trample$At the beginning of your upkeep, Spawn of Mayhem deals 1 damage to each player. Then if you have 10 or less life, put a +1/+1 counter on Spawn of Mayhem.| -Amplifire|Ravnica Allegiance|92|R|{2}{R}{R}|Creature - Elemental|1|1|At the beginning of your upkeep, reveal cards from he top of your library until you reveal a creature card. Until your next turn, Amplifire's base power becomes twice that card's power and its base toughness becomes twice that card's toughness. Put the revealed cards on the bottom of your library in a random order.| +Amplifire|Ravnica Allegiance|92|R|{2}{R}{R}|Creature - Elemental|1|1|At the beginning of your upkeep, reveal cards from the top of your library until you reveal a creature card. Until your next turn, Amplifire's base power becomes twice that card's power and its base toughness becomes twice that card's toughness. Put the revealed cards on the bottom of your library in a random order.| Light Up the Stage|Ravnica Allegiance|107|U|{2}{R}|Sorcery|||Spectacle {R}$Exile the top two cards of your library. Until the end of your next turn, you may play those cards.| Rix Maadi Reveler|Ravnica Allegiance|109|R|{1}{R}|Creature - Human Shaman|2|2|Spectacle {2}{B}{R}$When Rix Maadi Reveler enters the battlefield, discard a card, then draw a card. If Rix Maadi Reveler's spectacle cost was paid, instead discard your hand, then draw three cards.| Skarrgan Hellkite|Ravnica Allegiance|114|M|{3}{R}{R}|Creature - Dragon|4|4|Riot$Flying${3}{R}: Skarrgan Hellkite deals 2 damage divided as you choose among one or two targets. Activate this ability only if Skarrgan Hellkite has a +1/+1 counter on it.| End-Raze Forerunners|Ravnica Allegiance|124|R|{5}{G}{G}{G}|Creature - Boar|7|7|Vigilance, trample, haste$When End-Raze Forerunners enters the battlefield, other creatures you control get +2/+2 and gain vigilance and trample until end of turn.| Growth-Chamber Guardian|Ravnica Allegiance|128|R|{1}{G}|Creature - Elf Crab Warrior|2|2|{2}{G}: Adapt 2.$Whenever one or more +1/+1 counters are put on Growth-Chamber Guardian, you may search your library for a card named Growth-Chamber Guardian, reveal it, put it into your hand, then shuffle your library.| -Wilderness Reclamation|Ravnica Allegiance|140|U|{3}{G}|Enchantment|||At the beginning of your end step, untap all lands you control.| +Wilderness Reclamation|Ravnica Allegiance|149|U|{3}{G}|Enchantment|||At the beginning of your end step, untap all lands you control.| Absorb|Ravnica Allegiance|151|R|{W}{U}{U}|Instant|||Counter target spell. You gain 3 life.| Aeromunculus|Ravnica Allegiance|152|C|{1}{G}{U}|Creature - Homunculus Mutant|2|3|Flying${2}{G}{U}: Adapt 1.| Basilica Bell-Haunt|Ravnica Allegiance|156|U|{W}{W}{B}{B}|Creature - Spirit|3|4|When Basilica Bell-Haunt enters the battlefield, each opponent discards a card and you gain 3 life.| @@ -34608,7 +34608,7 @@ Judith, the Scourge Diva|Ravnica Allegiance|185|R|{1}{B}{R}|Legendary Creature - Kaya, Orzhov Usurper|Ravnica Allegiance|186|M|{1}{W}{B}|Legendary Planeswalker - Kaya|3|+1: Exile up to two target cards from a single graveyard. You gain 2 life if at least one creature card was exiled this way.$-1: Exile target nonland permanent with converted mana cost 1 or less.$-5: Kaya, Orzhov Usurper deals damage to target player equal to the number of cards that player owns in exile and you gain that much life.| Lavinia, Azorius Renegade|Ravnica Allegiance|189|R|{W}{U}|Legendary Creature - Human Soldier|2|2|Each opponent can't cast noncreature spells with converted mana cost greater than the number of lands that player controls.$Whenever an opponent casts a spell, if no mana was spent to cast it, counter that spell.| Mortify|Ravnica Allegiance|192|U|{1}{W}{B}|Instant|||Destroy target creature or enchantment.| -Pitiless Pontiff|Ravnica Allegiance|194|U|{W}{B}|Creature - Vampire Cleric|||{1}, Sacrifice another creature: Pitiless Pontiff gains deathtouch and indestructible until end of turn.| +Pitiless Pontiff|Ravnica Allegiance|194|U|{W}{B}|Creature - Vampire Cleric|2|2|{1}, Sacrifice another creature: Pitiless Pontiff gains deathtouch and indestructible until end of turn.| Prime Speaker Vannifar|Ravnica Allegiance|195|M|{2}{G}{U}|Legendary Creature - Elf Ooze Wizard|2|4|{T}, Sacrifice another creature: Search your library for a creature card with converted mana cost equal to 1 plus the sacrificed creature's converted mana cost, put that card onto the battlefield, then shuffle your library. Activate this ability only any time you could cast a sorcery.| Rafter Demon|Ravnica Allegiance|196|C|{2}{B}{R}|Creature - Demon|4|2|Spectacle {3}{B}{R}$When Rafter Demon enters the battlefield, if its spectacle cost was paid, each opponent discards a card.| Rakdos Firewheeler|Ravnica Allegiance|197|U|{B}{B}{R}{R}|Creature - Human Rogue|4|3|When Rakdos Firewheeler enters the battlefield, it deals 2 damage to target opponent and 2 damage to up to one target creature or planeswalker.| @@ -34617,7 +34617,7 @@ Ravager Wurm|Ravnica Allegiance|200|M|{3}{R}{G}{G}|Creature - Wurm|4|5|Riot$When Seraph of the Scales|Ravnica Allegiance|205|M|{2}{W}{B}|Creature - Angel|4|3|Flying${W}: Seraph of the Scales gains vigilance until end of turn.${B}: Seraph of the Scales gains deathtouch until end of turn.$Afterlife 2| Simic Ascendancy|Ravnica Allegiance|207|R|{G}{U}|Enchantment|||{1}{G}{U}: Put a +1/+1 counter on target creature you control.$Whenever one or more +1/+1 counters are put on a creature you control, put that many growth counters on Simic Ascendancy.$At the beginning of your upkeep, if Simic Ascendancy has twenty or more growth counters on it, you win the game.| Sphinx's Insight|Ravnica Allegiance|209|C|{2}{W}{U}|Instant|||Draw two cards.$Addendum — If you cast this spell during your main phase, you gain 2 life.| -Teysa Karlov|Ravnica Allegiance|213|R|{2}{W}{B}|Legendary Creature - Human Advisor|2|4|If a creature dying causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.$Creature tokens you control have vigilance and lifelink.| +Teysa Karlov|Ravnica Allegiance|212|R|{2}{W}{B}|Legendary Creature - Human Advisor|2|4|If a creature dying causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.$Creature tokens you control have vigilance and lifelink.| Zegana, Utopian Speaker|Ravnica Allegiance|214|R|{2}{G}{U}|Legendary Creature - Merfolk Wizard|4|4|When Zegana, Utopian Speaker enters the battlefield, if you control another creature with a +1/+1 counter on it, draw a card.${4}{G}{U}: Adapt 4.$Each creature you control with a +1/+1 counter on it has trample.| Deploy|Ravnica Allegiance|225|U|{2}{W}{U}|Instant|||Create two 1/1 colorless Thopter artifact creature tokens with flying, then you gain 1 life for each creature you control.| Depose|Ravnica Allegiance|225|U|{1}{W/U}|Instant|||Tap target creature.$Draw a card.| From 43427e0f93b3c6700da48280dfe06b111a7810c5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 22:09:50 -0500 Subject: [PATCH 24/44] Implemented Rakdos, the Showstopper --- .../mage/cards/r/RakdosTheShowstopper.java | 88 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 89 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RakdosTheShowstopper.java diff --git a/Mage.Sets/src/mage/cards/r/RakdosTheShowstopper.java b/Mage.Sets/src/mage/cards/r/RakdosTheShowstopper.java new file mode 100644 index 00000000000..aa8661c8a0d --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RakdosTheShowstopper.java @@ -0,0 +1,88 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RakdosTheShowstopper extends CardImpl { + + public RakdosTheShowstopper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.DEMON); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // When Rakdos, the Showstopper enters the battlefield, flip a coin for each creature that isn't a Demon, Devil, or Imp. Destroy each creature whose coin comes up tails. + this.addAbility(new EntersBattlefieldTriggeredAbility(new RakdosTheShowstopperEffect(), false)); + } + + private RakdosTheShowstopper(final RakdosTheShowstopper card) { + super(card); + } + + @Override + public RakdosTheShowstopper copy() { + return new RakdosTheShowstopper(this); + } +} + +class RakdosTheShowstopperEffect extends OneShotEffect { + + RakdosTheShowstopperEffect() { + super(Outcome.Benefit); + staticText = "flip a coin for each creature that isn't a Demon, Devil, or Imp." + + " Destroy each creature whose coin comes up tails."; + } + + private RakdosTheShowstopperEffect(final RakdosTheShowstopperEffect effect) { + super(effect); + } + + @Override + public RakdosTheShowstopperEffect copy() { + return new RakdosTheShowstopperEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + for (Permanent permanent : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { + if (permanent != null + && !permanent.hasSubtype(SubType.DEMON, game) + && !permanent.hasSubtype(SubType.DEVIL, game) + && !permanent.hasSubtype(SubType.IMP, game) + && !player.flipCoin(game)) { + permanent.destroy(source.getSourceId(), game, false); + } + } + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 5c15a086ca9..aaf4721e0a0 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -79,6 +79,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Rakdos Guildgate", 255, Rarity.COMMON, mage.cards.r.RakdosGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rakdos Guildgate", 256, Rarity.COMMON, mage.cards.r.RakdosGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rakdos Locket", 237, Rarity.COMMON, mage.cards.r.RakdosLocket.class)); + cards.add(new SetCardInfo("Rakdos, the Showstopper", 199, Rarity.MYTHIC, mage.cards.r.RakdosTheShowstopper.class)); cards.add(new SetCardInfo("Ravager Wurm", 200, Rarity.MYTHIC, mage.cards.r.RavagerWurm.class)); cards.add(new SetCardInfo("Rix Maadi Reveler", 109, Rarity.RARE, mage.cards.r.RixMaadiReveler.class)); cards.add(new SetCardInfo("Seraph of the Scales", 205, Rarity.MYTHIC, mage.cards.s.SeraphOfTheScales.class)); From 53ebc6b1b46de07d5ceed0c10f450b21e6e3cb0b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Jan 2019 22:25:46 -0500 Subject: [PATCH 25/44] Implemented Gutterbones --- Mage.Sets/src/mage/cards/g/Gutterbones.java | 69 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/Gutterbones.java diff --git a/Mage.Sets/src/mage/cards/g/Gutterbones.java b/Mage.Sets/src/mage/cards/g/Gutterbones.java new file mode 100644 index 00000000000..5868a3db67a --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/Gutterbones.java @@ -0,0 +1,69 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.Game; +import mage.watchers.common.PlayerLostLifeWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Gutterbones extends CardImpl { + + public Gutterbones(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); + + this.subtype.add(SubType.SKELETON); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Gutterbones enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // {1}{B}: Return Gutterbones from your graveyard to your hand. Activate this ability only during your turn and only if an opponent lost life this turn. + this.addAbility(new ConditionalActivatedAbility( + Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), + new ManaCostsImpl("{1}{B}"), GutterbonesCondition.instance + )); + } + + private Gutterbones(final Gutterbones card) { + super(card); + } + + @Override + public Gutterbones copy() { + return new Gutterbones(this); + } +} + +enum GutterbonesCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + if (game.isActivePlayer(source.getControllerId())) { + PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get(PlayerLostLifeWatcher.class.getSimpleName()); + return watcher != null && watcher.getAllOppLifeLost(source.getControllerId(), game) > 0; + } + return false; + } + + @Override + public String toString() { + return "during your turn and only if an opponent lost life this turn"; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index aaf4721e0a0..cd4334865a0 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -58,6 +58,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Gruul Guildgate", 250, Rarity.COMMON, mage.cards.g.GruulGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gruul Locket", 234, Rarity.COMMON, mage.cards.g.GruulLocket.class)); cards.add(new SetCardInfo("Gruul Spellbreaker", 179, Rarity.RARE, mage.cards.g.GruulSpellbreaker.class)); + cards.add(new SetCardInfo("Gutterbones", 76, Rarity.RARE, mage.cards.g.Gutterbones.class)); cards.add(new SetCardInfo("Hallowed Fountain", 251, Rarity.RARE, mage.cards.h.HallowedFountain.class)); cards.add(new SetCardInfo("Hydroid Krasis", 183, Rarity.MYTHIC, mage.cards.h.HydroidKrasis.class)); cards.add(new SetCardInfo("Imperious Oligarch", 184, Rarity.COMMON, mage.cards.i.ImperiousOligarch.class)); From 416cc8c0dddb2304d7873bb86ac1a2cf3153e0de Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 09:44:06 -0500 Subject: [PATCH 26/44] updated RNA spoiler --- Utils/mtg-cards-data.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index ab76d6e1555..8f88b5a3b2c 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -34576,6 +34576,7 @@ Kraul Raider|Guilds of Ravnica|270|C|{2}{B}|Creature - Insect Warrior|2|3|Menace Attendant of Vraska|Guilds of Ravnica|271|U|{1}{B}{G}|Creature - Zombie Soldier|3|3|When Attendant of Vraska dies, if you control a Vraska planeswalker, you gain life equal to Attendant of Vraska's power.| Vraska's Stoneglare|Guilds of Ravnica|272|R|{4}{B}{G}|Sorcery|||Destroy target creature. You gain life equal to its toughness. You may search your library and/or graveyard for a card named Vraska, Regal Gorgon, reveal it, and put it into your hand. If you search your library this way, shuffle it.| Impervious Greatwurm|Guilds of Ravnica|273|M|{7}{G}{G}{G}|Creature - Wurm|16|16|Convoke$Indestructible| +Smothering Tithe|Ravnica Allegiance|22|R|{3}{W}|Enchantment|||Whenever an opponent draws a card, that player may pay {2}. If the player doesn't, you create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color."| Tithe Taker|Ravnica Allegiance|27|R|{1}{W}|Creature - Human Soldier|2|1|During your turn, spells your opponents cast cost {1} more to cast and abilities your opponents activate cost {1} more to activate unless they're mana abilities.$Afterlife 1| Mass Manipulation|Ravnica Allegiance|42|R|{X}{X}{U}{U}{U}{U}|Sorcery|||Gain control of X target creatures and/or planeswalkers.| Precognitive Perception|Ravnica Allegiance|45|R|{3}{U}{U}|Instant|||Draw three cards.$Addendum — If you cast this spell during your main phase, instead scry 3, then draw three cards.| @@ -34589,6 +34590,7 @@ Rix Maadi Reveler|Ravnica Allegiance|109|R|{1}{R}|Creature - Human Shaman|2|2|Sp Skarrgan Hellkite|Ravnica Allegiance|114|M|{3}{R}{R}|Creature - Dragon|4|4|Riot$Flying${3}{R}: Skarrgan Hellkite deals 2 damage divided as you choose among one or two targets. Activate this ability only if Skarrgan Hellkite has a +1/+1 counter on it.| End-Raze Forerunners|Ravnica Allegiance|124|R|{5}{G}{G}{G}|Creature - Boar|7|7|Vigilance, trample, haste$When End-Raze Forerunners enters the battlefield, other creatures you control get +2/+2 and gain vigilance and trample until end of turn.| Growth-Chamber Guardian|Ravnica Allegiance|128|R|{1}{G}|Creature - Elf Crab Warrior|2|2|{2}{G}: Adapt 2.$Whenever one or more +1/+1 counters are put on Growth-Chamber Guardian, you may search your library for a card named Growth-Chamber Guardian, reveal it, put it into your hand, then shuffle your library.| +Rampage of the Clans|Ravnica Allegiance|134|R|{3}{G}|Instant|||Destroy all artifacts and enchantments. For each permanent destroyed this way, its controller creates a 3/3 green Centaur creature token.| Wilderness Reclamation|Ravnica Allegiance|149|U|{3}{G}|Enchantment|||At the beginning of your end step, untap all lands you control.| Absorb|Ravnica Allegiance|151|R|{W}{U}{U}|Instant|||Counter target spell. You gain 3 life.| Aeromunculus|Ravnica Allegiance|152|C|{1}{G}{U}|Creature - Homunculus Mutant|2|3|Flying${2}{G}{U}: Adapt 1.| @@ -34619,6 +34621,7 @@ Simic Ascendancy|Ravnica Allegiance|207|R|{G}{U}|Enchantment|||{1}{G}{U}: Put a Sphinx's Insight|Ravnica Allegiance|209|C|{2}{W}{U}|Instant|||Draw two cards.$Addendum — If you cast this spell during your main phase, you gain 2 life.| Teysa Karlov|Ravnica Allegiance|212|R|{2}{W}{B}|Legendary Creature - Human Advisor|2|4|If a creature dying causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.$Creature tokens you control have vigilance and lifelink.| Zegana, Utopian Speaker|Ravnica Allegiance|214|R|{2}{G}{U}|Legendary Creature - Merfolk Wizard|4|4|When Zegana, Utopian Speaker enters the battlefield, if you control another creature with a +1/+1 counter on it, draw a card.${4}{G}{U}: Adapt 4.$Each creature you control with a +1/+1 counter on it has trample.| +Zhur-Taa Goblin|Ravnica Allegiance|215|U|{R}{G}|Creature - Goblin Berserker|2|2|Riot| Deploy|Ravnica Allegiance|225|U|{2}{W}{U}|Instant|||Create two 1/1 colorless Thopter artifact creature tokens with flying, then you gain 1 life for each creature you control.| Depose|Ravnica Allegiance|225|U|{1}{W/U}|Instant|||Tap target creature.$Draw a card.| Incongruity|Ravnica Allegiance|226|U|{1}{G}{U}|Instant|||Exile target creature. That creature's controller creates a 3/3 green Frog Lizard creature token.| From 161c4ee1dd31c7cf0211be79cb9879a1a9d9329b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 09:45:17 -0500 Subject: [PATCH 27/44] Implemented Zhur-Taa Goblin --- Mage.Sets/src/mage/cards/z/ZhurTaaGoblin.java | 37 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/z/ZhurTaaGoblin.java diff --git a/Mage.Sets/src/mage/cards/z/ZhurTaaGoblin.java b/Mage.Sets/src/mage/cards/z/ZhurTaaGoblin.java new file mode 100644 index 00000000000..79256c778af --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZhurTaaGoblin.java @@ -0,0 +1,37 @@ +package mage.cards.z; + +import mage.MageInt; +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 ZhurTaaGoblin extends CardImpl { + + public ZhurTaaGoblin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.BERSERKER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Riot + this.addAbility(new RiotAbility()); + } + + private ZhurTaaGoblin(final ZhurTaaGoblin card) { + super(card); + } + + @Override + public ZhurTaaGoblin copy() { + return new ZhurTaaGoblin(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index cd4334865a0..4976a9af0fe 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -98,6 +98,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Tithe Taker", 27, Rarity.RARE, mage.cards.t.TitheTaker.class)); cards.add(new SetCardInfo("Wilderness Reclamation", 149, Rarity.UNCOMMON, mage.cards.w.WildernessReclamation.class)); cards.add(new SetCardInfo("Zegana, Utopian Speaker", 214, Rarity.RARE, mage.cards.z.ZeganaUtopianSpeaker.class)); + cards.add(new SetCardInfo("Zhur-Taa Goblin", 215, Rarity.UNCOMMON, mage.cards.z.ZhurTaaGoblin.class)); } @Override From d6dc4c2fcf9b3a5292afcc324b95563caea16dee Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 11:08:55 -0500 Subject: [PATCH 28/44] Implemented Smothering Tithe --- .../src/mage/cards/s/SmotheringTithe.java | 74 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 75 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SmotheringTithe.java diff --git a/Mage.Sets/src/mage/cards/s/SmotheringTithe.java b/Mage.Sets/src/mage/cards/s/SmotheringTithe.java new file mode 100644 index 00000000000..4e7023ea4f5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SmotheringTithe.java @@ -0,0 +1,74 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.common.DrawCardOpponentTriggeredAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.token.TreasureToken; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SmotheringTithe extends CardImpl { + + public SmotheringTithe(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // Whenever an opponent draws a card, that player may pay {2}. If the player doesn't, you create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color." + this.addAbility(new DrawCardOpponentTriggeredAbility( + new SmotheringTitheEffect(), false, true + )); + } + + private SmotheringTithe(final SmotheringTithe card) { + super(card); + } + + @Override + public SmotheringTithe copy() { + return new SmotheringTithe(this); + } +} + +class SmotheringTitheEffect extends OneShotEffect { + + SmotheringTitheEffect() { + super(Outcome.Benefit); + staticText = "that player may pay {2}. If the player doesn't, " + + "you create a colorless Treasure artifact token " + + "with \"{T}, Sacrifice this artifact: Add one mana of any color.\""; + } + + private SmotheringTitheEffect(final SmotheringTitheEffect effect) { + super(effect); + } + + @Override + public SmotheringTitheEffect copy() { + return new SmotheringTitheEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + if (player == null) { + return false; + } + Cost cost = new GenericManaCost(2); + if (!player.chooseUse(Outcome.Detriment, "Pay {2} to prevent this effect?", source, game) + || !cost.pay(source, game, source.getSourceId(), player.getId(), false)) { + return new CreateTokenEffect(new TreasureToken()).apply(game, source); + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 4976a9af0fe..993d01fa8e9 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -89,6 +89,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Simic Guildgate", 258, Rarity.COMMON, mage.cards.s.SimicGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Simic Locket", 240, Rarity.COMMON, mage.cards.s.SimicLocket.class)); cards.add(new SetCardInfo("Skarrgan Hellkite", 114, Rarity.MYTHIC, mage.cards.s.SkarrganHellkite.class)); + cards.add(new SetCardInfo("Smothering Tithe", 22, Rarity.RARE, mage.cards.s.SmotheringTithe.class)); cards.add(new SetCardInfo("Spawn of Mayhem", 85, Rarity.MYTHIC, mage.cards.s.SpawnOfMayhem.class)); cards.add(new SetCardInfo("Sphinx of Foresight", 55, Rarity.RARE, mage.cards.s.SphinxOfForesight.class)); cards.add(new SetCardInfo("Sphinx's Insight", 209, Rarity.COMMON, mage.cards.s.SphinxsInsight.class)); From 50cd0af6018637c7907c26a58a7f2d71604d2f06 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 4 Jan 2019 17:21:07 +0100 Subject: [PATCH 29/44] * Kess, Dissident Mage - Fixed that it did not allow split cards from graveyard. Fixed some other problems with the card. --- .../src/mage/cards/d/DaruSpiritualist.java | 11 +- .../src/mage/cards/k/KessDissidentMage.java | 130 ++++++------------ .../abilities/effects/ContinuousEffects.java | 6 +- 3 files changed, 51 insertions(+), 96 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DaruSpiritualist.java b/Mage.Sets/src/mage/cards/d/DaruSpiritualist.java index 1e684d94f6d..dbf5f6a79d5 100644 --- a/Mage.Sets/src/mage/cards/d/DaruSpiritualist.java +++ b/Mage.Sets/src/mage/cards/d/DaruSpiritualist.java @@ -1,4 +1,3 @@ - package mage.cards.d; import java.util.UUID; @@ -12,8 +11,6 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -50,12 +47,6 @@ public final class DaruSpiritualist extends CardImpl { class DaruSpiritualistTriggeredAbility extends TriggeredAbilityImpl { - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Cleric creature you control"); - - static { - filter.add(new SubtypePredicate(SubType.CLERIC)); - } - public DaruSpiritualistTriggeredAbility(Effect effect) { super(Zone.BATTLEFIELD, effect); } @@ -77,7 +68,7 @@ class DaruSpiritualistTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent creature = game.getPermanent(event.getTargetId()); - if (creature != null && filter.match(creature, getSourceId(), getControllerId(), game)) { + if (creature != null && creature.hasSubtype(SubType.CLERIC, game) && creature.getControllerId().equals(getControllerId()) && creature.isCreature()) { this.getEffects().setTargetPointer(new FixedTarget(creature, game)); return true; } diff --git a/Mage.Sets/src/mage/cards/k/KessDissidentMage.java b/Mage.Sets/src/mage/cards/k/KessDissidentMage.java index bc3cc94473f..ecc36205857 100644 --- a/Mage.Sets/src/mage/cards/k/KessDissidentMage.java +++ b/Mage.Sets/src/mage/cards/k/KessDissidentMage.java @@ -1,14 +1,15 @@ - package mage.cards.k; -import java.util.Optional; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.AsThoughEffectImpl; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.keyword.FlashbackAbility; import mage.abilities.keyword.FlyingAbility; @@ -18,22 +19,16 @@ import mage.cards.CardSetInfo; import mage.constants.AsThoughEffectType; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Layer; import mage.constants.Outcome; -import mage.constants.SubLayer; import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.WatcherScope; import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.game.stack.Spell; import mage.players.Player; -import mage.target.targetpointer.FixedTarget; import mage.watchers.Watcher; /** @@ -55,7 +50,9 @@ public final class KessDissidentMage extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // During each of your turns, you may cast an instant or sorcery card from your graveyard. If a card cast this way would be put into your graveyard this turn, exile it instead. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KessDissidentMageContinuousEffect()), new KessDissidentMageWatcher()); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new KessDissidentMageCastFromGraveyardEffect()); + ability.addEffect(new KessDissidentMageReplacementEffect()); + this.addAbility(ability, new KessDissidentMageWatcher()); } public KessDissidentMage(final KessDissidentMage card) { @@ -68,56 +65,11 @@ public final class KessDissidentMage extends CardImpl { } } -class KessDissidentMageContinuousEffect extends ContinuousEffectImpl { - - private static final FilterCard filter = new FilterCard("Instant or sorcery spell"); - - static { - filter.add(Predicates.or( - new CardTypePredicate(CardType.INSTANT), - new CardTypePredicate(CardType.SORCERY) - )); - } - - KessDissidentMageContinuousEffect() { - super(Duration.WhileOnBattlefield, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit); - staticText = "During each of your turns, you may cast an instant or sorcery card from your graveyard. If a card cast this way would be put into your graveyard, exile it instead"; - } - - KessDissidentMageContinuousEffect(final KessDissidentMageContinuousEffect effect) { - super(effect); - } - - @Override - public KessDissidentMageContinuousEffect copy() { - return new KessDissidentMageContinuousEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - if (!game.isActivePlayer(player.getId())) { - return false; - } - for (Card card : player.getGraveyard().getCards(filter, game)) { - ContinuousEffect effect = new KessDissidentMageCastFromGraveyardEffect(); - effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); - effect = new KessDissidentMageReplacementEffect(card.getId()); - game.addEffect(effect, source); - } - return true; - } - return false; - } -} - class KessDissidentMageCastFromGraveyardEffect extends AsThoughEffectImpl { KessDissidentMageCastFromGraveyardEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - staticText = "You may cast an instant or sorcery card from your graveyard"; + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "During each of your turns, you may cast an instant or sorcery card from your graveyard"; } KessDissidentMageCastFromGraveyardEffect(final KessDissidentMageCastFromGraveyardEffect effect) { @@ -136,14 +88,13 @@ class KessDissidentMageCastFromGraveyardEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (objectId.equals(getTargetPointer().getFirst(game, source))) { - if (affectedControllerId.equals(source.getControllerId())) { - if (game.isActivePlayer(source.getControllerId())) { - KessDissidentMageWatcher watcher = (KessDissidentMageWatcher) game.getState().getWatchers().get(KessDissidentMageWatcher.class.getSimpleName(), source.getSourceId()); - if (!(source instanceof FlashbackAbility)) { - return !watcher.isAbilityUsed(); - } - } + if (!(source instanceof FlashbackAbility) && affectedControllerId.equals(source.getControllerId()) && game.isActivePlayer(source.getControllerId())) { + Card card = game.getCard(objectId); + if (card != null && (card.isInstant() || card.isSorcery()) + && game.getState().getZone(objectId).equals(Zone.GRAVEYARD)) { + // check if not already a card was cast this turn with this ability + KessDissidentMageWatcher watcher = (KessDissidentMageWatcher) game.getState().getWatchers().get(KessDissidentMageWatcher.class.getSimpleName()); + return !watcher.isAbilityUsed(new MageObjectReference(source.getSourceId(), game)); } } return false; @@ -152,17 +103,13 @@ class KessDissidentMageCastFromGraveyardEffect extends AsThoughEffectImpl { class KessDissidentMageReplacementEffect extends ReplacementEffectImpl { - private final UUID cardId; - - KessDissidentMageReplacementEffect(UUID cardId) { - super(Duration.EndOfTurn, Outcome.Exile); - this.cardId = cardId; + KessDissidentMageReplacementEffect() { + super(Duration.EndOfGame, Outcome.Exile); staticText = "If a card cast this way would be put into your graveyard, exile it instead"; } KessDissidentMageReplacementEffect(final KessDissidentMageReplacementEffect effect) { super(effect); - this.cardId = effect.cardId; } @Override @@ -173,9 +120,9 @@ class KessDissidentMageReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player controller = game.getPlayer(source.getControllerId()); - Card card = game.getCard(this.cardId); + Card card = game.getCard(event.getTargetId()); if (controller != null && card != null) { - controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.STACK, true); + controller.moveCards(card, Zone.EXILED, source, game); return true; } return false; @@ -189,31 +136,39 @@ class KessDissidentMageReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - return zEvent.getToZone() == Zone.GRAVEYARD - && zEvent.getTargetId().equals(this.cardId); + if (zEvent.getToZone() == Zone.GRAVEYARD) { + KessDissidentMageWatcher watcher = (KessDissidentMageWatcher) game.getState().getWatchers().get(KessDissidentMageWatcher.class.getSimpleName()); + if (source.getSourceId().equals(watcher.spellCastWasAllowedBy(new MageObjectReference(event.getTargetId(), game)))) { + return true; + } + } + return false; } } class KessDissidentMageWatcher extends Watcher { - boolean abilityUsed = false; + // Which kess object did cast which spell from graveyard + private final Set allowingObjects = new HashSet<>(); + private final Map castSpells = new HashMap<>(); KessDissidentMageWatcher() { - super(KessDissidentMageWatcher.class.getSimpleName(), WatcherScope.CARD); + super(KessDissidentMageWatcher.class.getSimpleName(), WatcherScope.GAME); } KessDissidentMageWatcher(final KessDissidentMageWatcher watcher) { super(watcher); - this.abilityUsed = watcher.abilityUsed; + this.allowingObjects.addAll(watcher.allowingObjects); + this.castSpells.putAll(watcher.castSpells); } @Override public void watch(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.SPELL_CAST && event.getZone() == Zone.GRAVEYARD) { Spell spell = (Spell) game.getObject(event.getTargetId()); - if (spell.isInstant() || spell.isSorcery()) { - Optional source = game.getAbility(event.getSourceId(), event.getSourceId()); - abilityUsed = true; + if (null != event.getAdditionalReference() && spell.isInstant() || spell.isSorcery()) { + allowingObjects.add(event.getAdditionalReference()); + castSpells.put(new MageObjectReference(spell.getSourceId(), game), event.getAdditionalReference().getSourceId()); } } } @@ -226,10 +181,15 @@ class KessDissidentMageWatcher extends Watcher { @Override public void reset() { super.reset(); - abilityUsed = false; + allowingObjects.clear(); } - public boolean isAbilityUsed() { - return abilityUsed; + public boolean isAbilityUsed(MageObjectReference mor) { + return allowingObjects.contains(mor); } + + public UUID spellCastWasAllowedBy(MageObjectReference mor) { + return castSpells.getOrDefault(mor, null); + } + } diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java index ce14ca33b45..5f1bad6e5b9 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java @@ -494,7 +494,11 @@ public class ContinuousEffects implements Serializable { if (affectedAbility != null && affectedAbility.getSourceObject(game) instanceof SplitCardHalf) { idToCheck = ((SplitCardHalf) affectedAbility.getSourceObject(game)).getParentCard().getId(); } else { - idToCheck = objectId; + if (game.getObject(objectId) instanceof SplitCardHalf) { + idToCheck = ((SplitCardHalf) game.getObject(objectId)).getParentCard().getId(); + } else { + idToCheck = objectId; + } } for (AsThoughEffect effect : asThoughEffectsList) { Set abilities = asThoughEffectsMap.get(type).getAbility(effect.getId()); From aa8d484c89905468bfc42eef081efdacc8cac4e1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 11:27:48 -0500 Subject: [PATCH 30/44] updated RNA spoiler --- Utils/mtg-cards-data.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 8f88b5a3b2c..cec8afbc0e9 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -34585,6 +34585,7 @@ Gutterbones|Ravnica Allegiance|76|R|{B}|Creature - Skeleton Warrior|2|1|Gutterbo Pestilent Spirit|Ravnica Allegiance|81|R|{2}{B}|Creature - Spirit|3|2|Menace, deathtouch$Instant and sorcery spells you control have deathtouch.| Spawn of Mayhem|Ravnica Allegiance|85|M|{2}{B}{B}|Creature - Demon|4|4|Spectacle {1}{B}{B}$Flying, trample$At the beginning of your upkeep, Spawn of Mayhem deals 1 damage to each player. Then if you have 10 or less life, put a +1/+1 counter on Spawn of Mayhem.| Amplifire|Ravnica Allegiance|92|R|{2}{R}{R}|Creature - Elemental|1|1|At the beginning of your upkeep, reveal cards from the top of your library until you reveal a creature card. Until your next turn, Amplifire's base power becomes twice that card's power and its base toughness becomes twice that card's toughness. Put the revealed cards on the bottom of your library in a random order.| +Electrodominance|Ravnica Allegiance|99|R|{X}{R}{R}|Instant|||Electrodominance deals X damage to any target. You may cast a card with converted mana cost X or less from your hand without paying its mana cost.| Light Up the Stage|Ravnica Allegiance|107|U|{2}{R}|Sorcery|||Spectacle {R}$Exile the top two cards of your library. Until the end of your next turn, you may play those cards.| Rix Maadi Reveler|Ravnica Allegiance|109|R|{1}{R}|Creature - Human Shaman|2|2|Spectacle {2}{B}{R}$When Rix Maadi Reveler enters the battlefield, discard a card, then draw a card. If Rix Maadi Reveler's spectacle cost was paid, instead discard your hand, then draw three cards.| Skarrgan Hellkite|Ravnica Allegiance|114|M|{3}{R}{R}|Creature - Dragon|4|4|Riot$Flying${3}{R}: Skarrgan Hellkite deals 2 damage divided as you choose among one or two targets. Activate this ability only if Skarrgan Hellkite has a +1/+1 counter on it.| @@ -34602,6 +34603,7 @@ Deputy of Detention|Ravnica Allegiance|165|R|{1}{W}{U}|Creature - Vedalken Wizar Dovin, Grand Arbiter|Ravnica Allegiance|167|M|{1}{W}{U}|Legendary Planeswalker - Dovin|3|+1: Until end of turn, whenever a creature you control deals combat damage to a player, put a loyalty counter on Dovin, Grand Arbiter.$-1: Create a 1/1 colorless Thopter artifact creature token with flying. You gain 1 life.$-7: Look at the top ten cards of your library. Put three of them into your hand and the rest on the bottom of your library in a random order.| Emergency Powers|Ravnica Allegiance|169|M|{5}{W}{U}|Instant|||Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Emergency Powers.$Addendum — If you cast this spell during your main phase, you may put a permanent card with converted mana cost 7 or less from your hand onto the battlefield.| Frenzied Arynx|Ravnica Allegiance|173|C|{2}{R}{G}|Creature - Cat Beast|3|3|Riot$Trample${4}{R}{G}: Frenzied Arynx gets +3/+0 until end of turn.| +Frilled Mystic|Ravnica Allegiance|174|U|{U}{G}{U}{G}|Creature - Elf Lizard Wizard|3|2|Flash$When Frilled Mystic enters the battlefield, you may counter target spell.| Growth Spiral|Ravnica Allegiance|178|C|{G}{U}|Instant|||Draw a card. You may put a land card from your hand onto the battlefield.| Gruul Spellbreaker|Ravnica Allegiance|179|R|{1}{R}{G}|Creature - Ogre Warrior|3|3|Riot$Trample$As long as it's your turn, you and Gruul Spellbreaker have hexproof.| Hydroid Krasis|Ravnica Allegiance|183|M|{X}{G}{U}|Creature - Jellyfish Hydra Beast|0|0|When you cast this spell, you gain half X life and draw half X cards. Round down each time.$Flying, trample$Hydroid Krasis enters the battlefield with X +1/+1 counters on it.| From e7cd4fea9679c22da09e01dc08fd2f26dcee60d6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 11:31:17 -0500 Subject: [PATCH 31/44] Implemented Frilled Mystic --- Mage.Sets/src/mage/cards/f/FrilledMystic.java | 48 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 49 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FrilledMystic.java diff --git a/Mage.Sets/src/mage/cards/f/FrilledMystic.java b/Mage.Sets/src/mage/cards/f/FrilledMystic.java new file mode 100644 index 00000000000..63b4f8d81ea --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FrilledMystic.java @@ -0,0 +1,48 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.TargetSpell; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FrilledMystic extends CardImpl { + + public FrilledMystic(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{G}{U}{G}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.LIZARD); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // When Frilled Mystic enters the battlefield, you may counter target spell. + Ability ability = new EntersBattlefieldTriggeredAbility(new CounterTargetEffect(), true); + ability.addTarget(new TargetSpell()); + this.addAbility(ability); + } + + private FrilledMystic(final FrilledMystic card) { + super(card); + } + + @Override + public FrilledMystic copy() { + return new FrilledMystic(this); + } +} +// nonagon infinity opens the door \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 993d01fa8e9..134733df049 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -50,6 +50,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Emergency Powers", 169, Rarity.MYTHIC, mage.cards.e.EmergencyPowers.class)); cards.add(new SetCardInfo("End-Raze Forerunners", 124, Rarity.RARE, mage.cards.e.EndRazeForerunners.class)); cards.add(new SetCardInfo("Frenzied Arynx", 173, Rarity.COMMON, mage.cards.f.FrenziedArynx.class)); + cards.add(new SetCardInfo("Frilled Mystic", 174, Rarity.UNCOMMON, mage.cards.f.FrilledMystic.class)); cards.add(new SetCardInfo("Gate Colossus", 232, Rarity.UNCOMMON, mage.cards.g.GateColossus.class)); cards.add(new SetCardInfo("Godless Shrine", 248, Rarity.RARE, mage.cards.g.GodlessShrine.class)); cards.add(new SetCardInfo("Growth Spiral", 178, Rarity.COMMON, mage.cards.g.GrowthSpiral.class)); From a21d481755f51f4da9220389d73447f052bfe435 Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 4 Jan 2019 10:39:16 -0600 Subject: [PATCH 32/44] - Fixed #5488 --- Mage.Sets/src/mage/cards/g/GraveBetrayal.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/g/GraveBetrayal.java b/Mage.Sets/src/mage/cards/g/GraveBetrayal.java index 888925283e9..fb1ccc708ad 100644 --- a/Mage.Sets/src/mage/cards/g/GraveBetrayal.java +++ b/Mage.Sets/src/mage/cards/g/GraveBetrayal.java @@ -162,7 +162,7 @@ class GraveBetrayalReplacementEffect extends ReplacementEffectImpl { ContinuousEffect effect = new BecomesBlackZombieAdditionEffect(); effect.setTargetPointer(new FixedTarget(creature.getId(), creature.getZoneChangeCounter(game) + 1)); game.addEffect(effect, source); - discard(); + //discard(); why? } return false; } From d49cd6f3049f357c8020ff5aa95ff523f225ebf4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 11:40:11 -0500 Subject: [PATCH 33/44] Implemented Electrodominance --- .../src/mage/cards/e/Electrodominance.java | 35 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + .../cost/CastWithoutPayingManaCostEffect.java | 20 +++++++---- 3 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/e/Electrodominance.java diff --git a/Mage.Sets/src/mage/cards/e/Electrodominance.java b/Mage.Sets/src/mage/cards/e/Electrodominance.java new file mode 100644 index 00000000000..2d87841a40c --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/Electrodominance.java @@ -0,0 +1,35 @@ +package mage.cards.e; + +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.cost.CastWithoutPayingManaCostEffect; +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 Electrodominance extends CardImpl { + + public Electrodominance(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}{R}"); + + // Electrodominance deals X damage to any target. You may cast a card with converted mana cost X or less from your hand without paying its mana cost. + this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue())); + this.getSpellAbility().addTarget(new TargetAnyTarget()); + this.getSpellAbility().addEffect(new CastWithoutPayingManaCostEffect(new ManacostVariableValue())); + } + + private Electrodominance(final Electrodominance card) { + super(card); + } + + @Override + public Electrodominance copy() { + return new Electrodominance(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 134733df049..01b7e974e41 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -47,6 +47,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Depose // Deploy", 225, Rarity.UNCOMMON, mage.cards.d.DeposeDeploy.class)); cards.add(new SetCardInfo("Deputy of Detention", 165, Rarity.RARE, mage.cards.d.DeputyOfDetention.class)); cards.add(new SetCardInfo("Dovin, Grand Arbiter", 167, Rarity.MYTHIC, mage.cards.d.DovinGrandArbiter.class)); + cards.add(new SetCardInfo("Electrodominance", 99, Rarity.RARE, mage.cards.e.Electrodominance.class)); cards.add(new SetCardInfo("Emergency Powers", 169, Rarity.MYTHIC, mage.cards.e.EmergencyPowers.class)); cards.add(new SetCardInfo("End-Raze Forerunners", 124, Rarity.RARE, mage.cards.e.EndRazeForerunners.class)); cards.add(new SetCardInfo("Frenzied Arynx", 173, Rarity.COMMON, mage.cards.f.FrenziedArynx.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/CastWithoutPayingManaCostEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/CastWithoutPayingManaCostEffect.java index 91bb40fba53..90e19e1c133 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/CastWithoutPayingManaCostEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/CastWithoutPayingManaCostEffect.java @@ -3,10 +3,13 @@ package mage.abilities.effects.common.cost; import mage.MageObjectReference; import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.constants.ComparisonType; import mage.constants.Outcome; +import mage.filter.FilterCard; import mage.filter.common.FilterNonlandCard; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; @@ -25,23 +28,23 @@ import org.apache.log4j.Logger; */ public class CastWithoutPayingManaCostEffect extends OneShotEffect { - private final FilterNonlandCard filter; - private final int manaCost; + private final DynamicValue manaCost; /** * @param maxCost Maximum converted mana cost for this effect to apply to */ public CastWithoutPayingManaCostEffect(int maxCost) { + this(new StaticValue(maxCost)); + } + + public CastWithoutPayingManaCostEffect(DynamicValue maxCost) { super(Outcome.PlayForFree); - filter = new FilterNonlandCard("card with converted mana cost " + maxCost + " or less from your hand"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, maxCost + 1)); this.manaCost = maxCost; this.staticText = "you may cast a card with converted mana cost " + maxCost + " or less from your hand without paying its mana cost"; } public CastWithoutPayingManaCostEffect(final CastWithoutPayingManaCostEffect effect) { super(effect); - this.filter = effect.filter.copy(); this.manaCost = effect.manaCost; } @@ -52,11 +55,14 @@ public class CastWithoutPayingManaCostEffect extends OneShotEffect { if (controller == null) { return false; } + int cmc = manaCost.calculate(game, source, this); + FilterCard filter = new FilterNonlandCard("card with converted mana cost " + cmc + " or less from your hand"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, cmc + 1)); Target target = new TargetCardInHand(filter); if (target.canChoose(source.getSourceId(), controller.getId(), game) - && controller.chooseUse(outcome, "Cast a card with converted mana cost " + manaCost - + " or less from your hand without paying its mana cost?", source, game)) { + && controller.chooseUse(outcome, "Cast a card with converted mana cost " + cmc + + " or less from your hand without paying its mana cost?", source, game)) { Card cardToCast = null; boolean cancel = false; while (controller.canRespond() && !cancel) { From c5624a7c58b815c2707885bff1c66e394e17b23b Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 4 Jan 2019 10:44:20 -0600 Subject: [PATCH 34/44] - Added Oath of Lim-Dul and Stench of Evil. --- Mage.Sets/src/mage/cards/o/OathOfLimDul.java | 139 +++++++++++++++++++ Mage.Sets/src/mage/cards/s/StenchOfEvil.java | 81 +++++++++++ Mage.Sets/src/mage/sets/IceAge.java | 2 + 3 files changed, 222 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OathOfLimDul.java create mode 100644 Mage.Sets/src/mage/cards/s/StenchOfEvil.java diff --git a/Mage.Sets/src/mage/cards/o/OathOfLimDul.java b/Mage.Sets/src/mage/cards/o/OathOfLimDul.java new file mode 100644 index 00000000000..a703139bb37 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OathOfLimDul.java @@ -0,0 +1,139 @@ +package mage.cards.o; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author jeffwadsworth + */ +public final class OathOfLimDul extends CardImpl { + + public OathOfLimDul(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); + + // Whenever you lose life, for each 1 life you lost, sacrifice a permanent other than Oath of Lim-Dul unless you discard a card. + this.addAbility(new OathOfLimDulTriggeredAbility()); + + // {B}{B}: Draw a card. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{B}{B}"))); + + } + + private OathOfLimDul(final OathOfLimDul card) { + super(card); + } + + @Override + public OathOfLimDul copy() { + return new OathOfLimDul(this); + } +} + +class OathOfLimDulTriggeredAbility extends TriggeredAbilityImpl { + + public OathOfLimDulTriggeredAbility() { + super(Zone.BATTLEFIELD, new OathOfLimDulEffect()); + } + + public OathOfLimDulTriggeredAbility(final OathOfLimDulTriggeredAbility ability) { + super(ability); + } + + @Override + public OathOfLimDulTriggeredAbility copy() { + return new OathOfLimDulTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.LOST_LIFE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getPlayerId().equals(controllerId)) { + game.getState().setValue(sourceId.toString() + "oathOfLimDul", event.getAmount()); + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever you lose life, for each 1 life you lost, sacrifice a permanent other than {this} unless you discard a card."; + } +} + +class OathOfLimDulEffect extends OneShotEffect { + + private final static FilterControlledPermanent filter = new FilterControlledPermanent("controlled permanent other than Oath of Lim-Dul"); + + static { + filter.add(new AnotherPredicate()); + } + + public OathOfLimDulEffect() { + super(Outcome.Neutral); + } + + public OathOfLimDulEffect(final OathOfLimDulEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + int amount = (int) game.getState().getValue(source.getSourceId().toString() + "oathOfLimDul"); + if (amount > 0 + && controller != null) { + for (int i = 0; i < amount; i++) { + TargetControlledPermanent target = new TargetControlledPermanent(filter); + target.setNotTarget(true); + if (target.canChoose(controller.getId(), game) + && controller.choose(Outcome.Sacrifice, target, source.getSourceId(), game)) { + Cost cost = new DiscardTargetCost(new TargetCardInHand()); + if (cost.canPay(source, source.getSourceId(), controller.getId(), game) + && controller.chooseUse(Outcome.Benefit, + "Do you wish to discard a card rather than sacrifice the target permanent?", source, game)) { + cost.pay(source, game, source.getSourceId(), controller.getId(), true); + } else { + Permanent targetPermanent = game.getPermanent(target.getFirstTarget()); + if (targetPermanent != null) { + targetPermanent.sacrifice(source.getSourceId(), game); + } + } + } + } + return true; + } + return false; + } + + @Override + public OathOfLimDulEffect copy() { + return new OathOfLimDulEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/cards/s/StenchOfEvil.java b/Mage.Sets/src/mage/cards/s/StenchOfEvil.java new file mode 100644 index 00000000000..b85fcf0603d --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StenchOfEvil.java @@ -0,0 +1,81 @@ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.ManaCostsImpl; +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.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author jeffwadsworth + */ +public final class StenchOfEvil extends CardImpl { + + public StenchOfEvil(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{B}"); + + // Destroy all Plains. For each land destroyed this way, Stench of Evil deals 1 damage to that land's controller unless he or she pays {2}. + this.getSpellAbility().addEffect(new StenchOfEvilEffect()); + + } + + private StenchOfEvil(final StenchOfEvil card) { + super(card); + } + + @Override + public StenchOfEvil copy() { + return new StenchOfEvil(this); + } +} + +class StenchOfEvilEffect extends OneShotEffect { + + private static final FilterLandPermanent filter = new FilterLandPermanent(); + + static { + filter.add(new SubtypePredicate(SubType.PLAINS)); + } + + public StenchOfEvilEffect() { + super(Outcome.Benefit); + this.staticText = "Destroy all Plains. For each land destroyed this way, {this} deals 1 damage to that land's controller unless he or she pays {2}"; + } + + public StenchOfEvilEffect(final StenchOfEvilEffect effect) { + super(effect); + } + + @Override + public StenchOfEvilEffect copy() { + return new StenchOfEvilEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (Permanent land : game.getBattlefield().getAllActivePermanents(filter, game)) { + UUID landControllerId = land.getControllerId(); + if (land.destroy(source.getSourceId(), game, false)) { + Cost cost = new ManaCostsImpl("{2}"); + Player landController = game.getPlayer(landControllerId); + if (landController != null + && cost.canPay(source, source.getSourceId(), landControllerId, game) + && !cost.pay(source, game, source.getSourceId(), landControllerId, false)) { + landController.damage(1, source.getSourceId(), game, false, true); + } + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index dda83722aa0..85599405b47 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -238,6 +238,7 @@ public final class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Nature's Lore", 255, Rarity.UNCOMMON, mage.cards.n.NaturesLore.class)); cards.add(new SetCardInfo("Necropotence", 154, Rarity.RARE, mage.cards.n.Necropotence.class)); cards.add(new SetCardInfo("Norritt", 155, Rarity.COMMON, mage.cards.n.Norritt.class)); + cards.add(new SetCardInfo("Oath of Lim-Dul", 44, Rarity.RARE, mage.cards.o.OathOfLimDul.class)); cards.add(new SetCardInfo("Onyx Talisman", 331, Rarity.UNCOMMON, mage.cards.o.OnyxTalisman.class)); cards.add(new SetCardInfo("Orcish Cannoneers", 205, Rarity.UNCOMMON, mage.cards.o.OrcishCannoneers.class)); cards.add(new SetCardInfo("Orcish Healer", 208, Rarity.UNCOMMON, mage.cards.o.OrcishHealer.class)); @@ -304,6 +305,7 @@ public final class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Spoils of Evil", 163, Rarity.RARE, mage.cards.s.SpoilsOfEvil.class)); cards.add(new SetCardInfo("Staff of the Ages", 340, Rarity.RARE, mage.cards.s.StaffOfTheAges.class)); cards.add(new SetCardInfo("Stampede", 265, Rarity.RARE, mage.cards.s.Stampede.class)); + cards.add(new SetCardInfo("Stench of Evil", 165, Rarity.UNCOMMON, mage.cards.s.StenchOfEvil.class)); cards.add(new SetCardInfo("Stone Rain", 217, Rarity.COMMON, mage.cards.s.StoneRain.class)); cards.add(new SetCardInfo("Stone Spirit", 218, Rarity.UNCOMMON, mage.cards.s.StoneSpirit.class)); cards.add(new SetCardInfo("Stonehands", 219, Rarity.COMMON, mage.cards.s.Stonehands.class)); From b756a4c8f71f21d79911d709e66a1d8466552159 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 11:50:59 -0500 Subject: [PATCH 35/44] updated RNA spoiler --- Utils/mtg-cards-data.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index cec8afbc0e9..fbf34a4ed0a 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -34581,6 +34581,9 @@ Tithe Taker|Ravnica Allegiance|27|R|{1}{W}|Creature - Human Soldier|2|1|During y Mass Manipulation|Ravnica Allegiance|42|R|{X}{X}{U}{U}{U}{U}|Sorcery|||Gain control of X target creatures and/or planeswalkers.| Precognitive Perception|Ravnica Allegiance|45|R|{3}{U}{U}|Instant|||Draw three cards.$Addendum — If you cast this spell during your main phase, instead scry 3, then draw three cards.| Sphinx of Foresight|Ravnica Allegiance|55|R|{2}{U}{U}|Creature - Sphinx|4|4|You may reveal this card from your opening hand. If you do, scry 3 at the beginning of your first upkeep.$Flying$At the beginning of your upkeep, scry 1.| +Bankrupt in Blood|Ravnica Allegiance|62|U|{1}{B}|Sorcery|||As an additional cost to cast this spell, sacrifice two creatures.$Draw three cards.| +Blade Juggler|Ravnica Allegiance|63|C|{5}{B}|Creature - Human Rogue|3|2|Spectacle {2}{B}$When Blade Juggler enters the battlefield, it deals 1 damage to you and you draw a card.| +Cry of the Carnarium|Ravnica Allegiance|70|U|{1}{B}{B}|Sorcery|||All creatures get -2/-2 until end of turn. Exile all creature cards in all graveyards that were put there from the battlefield this turn. If a creature would die this turn, exile it instead.| Gutterbones|Ravnica Allegiance|76|R|{B}|Creature - Skeleton Warrior|2|1|Gutterbones enters the battlefield tapped.${1}{B}: Return Gutterbones from your graveyard to your hand. Activate this ability only during your turn and only if an opponent lost life this turn.| Pestilent Spirit|Ravnica Allegiance|81|R|{2}{B}|Creature - Spirit|3|2|Menace, deathtouch$Instant and sorcery spells you control have deathtouch.| Spawn of Mayhem|Ravnica Allegiance|85|M|{2}{B}{B}|Creature - Demon|4|4|Spectacle {1}{B}{B}$Flying, trample$At the beginning of your upkeep, Spawn of Mayhem deals 1 damage to each player. Then if you have 10 or less life, put a +1/+1 counter on Spawn of Mayhem.| @@ -34589,6 +34592,7 @@ Electrodominance|Ravnica Allegiance|99|R|{X}{R}{R}|Instant|||Electrodominance de Light Up the Stage|Ravnica Allegiance|107|U|{2}{R}|Sorcery|||Spectacle {R}$Exile the top two cards of your library. Until the end of your next turn, you may play those cards.| Rix Maadi Reveler|Ravnica Allegiance|109|R|{1}{R}|Creature - Human Shaman|2|2|Spectacle {2}{B}{R}$When Rix Maadi Reveler enters the battlefield, discard a card, then draw a card. If Rix Maadi Reveler's spectacle cost was paid, instead discard your hand, then draw three cards.| Skarrgan Hellkite|Ravnica Allegiance|114|M|{3}{R}{R}|Creature - Dragon|4|4|Riot$Flying${3}{R}: Skarrgan Hellkite deals 2 damage divided as you choose among one or two targets. Activate this ability only if Skarrgan Hellkite has a +1/+1 counter on it.| +Smelt-Ward Ignus|Ravnica Allegiance|116|U|{1}{R}|Creature - Elemental|2|1|{2}{R}, Sacrifice Smelt-Ward Ignus: Gain control of target creature with power 3 or less until end of turn. Untap that creature. It gains haste until end of turn. Activate this ability only any time you could cast a sorcery.| End-Raze Forerunners|Ravnica Allegiance|124|R|{5}{G}{G}{G}|Creature - Boar|7|7|Vigilance, trample, haste$When End-Raze Forerunners enters the battlefield, other creatures you control get +2/+2 and gain vigilance and trample until end of turn.| Growth-Chamber Guardian|Ravnica Allegiance|128|R|{1}{G}|Creature - Elf Crab Warrior|2|2|{2}{G}: Adapt 2.$Whenever one or more +1/+1 counters are put on Growth-Chamber Guardian, you may search your library for a card named Growth-Chamber Guardian, reveal it, put it into your hand, then shuffle your library.| Rampage of the Clans|Ravnica Allegiance|134|R|{3}{G}|Instant|||Destroy all artifacts and enchantments. For each permanent destroyed this way, its controller creates a 3/3 green Centaur creature token.| @@ -34606,6 +34610,7 @@ Frenzied Arynx|Ravnica Allegiance|173|C|{2}{R}{G}|Creature - Cat Beast|3|3|Riot$ Frilled Mystic|Ravnica Allegiance|174|U|{U}{G}{U}{G}|Creature - Elf Lizard Wizard|3|2|Flash$When Frilled Mystic enters the battlefield, you may counter target spell.| Growth Spiral|Ravnica Allegiance|178|C|{G}{U}|Instant|||Draw a card. You may put a land card from your hand onto the battlefield.| Gruul Spellbreaker|Ravnica Allegiance|179|R|{1}{R}{G}|Creature - Ogre Warrior|3|3|Riot$Trample$As long as it's your turn, you and Gruul Spellbreaker have hexproof.| +High Alert|Ravnica Allegiance|182|U|{1}{W}{U}|Enchantment|||Each creature you control assigns combat damage equal to its toughness rather than its power.$Creatures you control can attack as though they didn't have defender.${2}{W}{U}: Untap target creature.| Hydroid Krasis|Ravnica Allegiance|183|M|{X}{G}{U}|Creature - Jellyfish Hydra Beast|0|0|When you cast this spell, you gain half X life and draw half X cards. Round down each time.$Flying, trample$Hydroid Krasis enters the battlefield with X +1/+1 counters on it.| Imperious Oligarch|Ravnica Allegiance|184|C|{W}{B}|Creature - Human Cleric|2|1|Vigilance$Afterlife 1| Judith, the Scourge Diva|Ravnica Allegiance|185|R|{1}{B}{R}|Legendary Creature - Human Shaman|2|2|Other creatures you control get +1/+0.$Whenever a nontoken creature you control dies, Judith, the Scourge Diva deals 1 damage to any target.| @@ -34624,6 +34629,10 @@ Sphinx's Insight|Ravnica Allegiance|209|C|{2}{W}{U}|Instant|||Draw two cards.$Ad Teysa Karlov|Ravnica Allegiance|212|R|{2}{W}{B}|Legendary Creature - Human Advisor|2|4|If a creature dying causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.$Creature tokens you control have vigilance and lifelink.| Zegana, Utopian Speaker|Ravnica Allegiance|214|R|{2}{G}{U}|Legendary Creature - Merfolk Wizard|4|4|When Zegana, Utopian Speaker enters the battlefield, if you control another creature with a +1/+1 counter on it, draw a card.${4}{G}{U}: Adapt 4.$Each creature you control with a +1/+1 counter on it has trample.| Zhur-Taa Goblin|Ravnica Allegiance|215|U|{R}{G}|Creature - Goblin Berserker|2|2|Riot| +Carnage|Ravnica Allegiance|222|U|{2}{B}{R}|Sorcery|||Carnage deals 3 damage to target opponent. That player discards two cards.| +Carnival|Ravnica Allegiance|222|U|{B/R}|Instant|||Carnival deals 1 damage to target creature or planeswalker and 1 damage to that permanent's controller.| +Consecrate|Ravnica Allegiance|224|U|{1}{W/B}|Instant|||Exile target card from a graveyard.$Draw a card.| +Consume|Ravnica Allegiance|224|U|{2}{W}{B}|Sorcery|||Target player sacrifices a creature with the greatest power among creatures they controls. You gain life equal to its power.| Deploy|Ravnica Allegiance|225|U|{2}{W}{U}|Instant|||Create two 1/1 colorless Thopter artifact creature tokens with flying, then you gain 1 life for each creature you control.| Depose|Ravnica Allegiance|225|U|{1}{W/U}|Instant|||Tap target creature.$Draw a card.| Incongruity|Ravnica Allegiance|226|U|{1}{G}{U}|Instant|||Exile target creature. That creature's controller creates a 3/3 green Frog Lizard creature token.| From 1f24af8716b2f8b87a2eff4716c0f0b821f7393e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 12:28:14 -0500 Subject: [PATCH 36/44] Implemented Carnival // Carnage --- .../src/mage/cards/c/CarnivalCarnage.java | 82 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + .../java/mage/game/permanent/Permanent.java | 9 +- .../mage/game/permanent/PermanentImpl.java | 5 ++ Mage/src/main/java/mage/players/Player.java | 7 +- .../main/java/mage/players/PlayerImpl.java | 7 +- 6 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/c/CarnivalCarnage.java diff --git a/Mage.Sets/src/mage/cards/c/CarnivalCarnage.java b/Mage.Sets/src/mage/cards/c/CarnivalCarnage.java new file mode 100644 index 00000000000..e5cdc2a4437 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CarnivalCarnage.java @@ -0,0 +1,82 @@ +package mage.cards.c; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.cards.CardSetInfo; +import mage.cards.SplitCard; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SpellAbilityType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreatureOrPlaneswalker; +import mage.target.common.TargetOpponent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class CarnivalCarnage extends SplitCard { + + public CarnivalCarnage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, new CardType[]{CardType.SORCERY}, "{B/R}", "{2}{B}{R}", SpellAbilityType.SPLIT); + + // Carnival + // Carnival deals 1 damage to target creature or planeswalker and 1 damage to that permanent's controller. + this.getLeftHalfCard().getSpellAbility().addEffect(new CarnivalEffect()); + this.getLeftHalfCard().getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker()); + + // Carnage + // Carnage deals 3 damage to target opponent. That player discards two cards. + this.getRightHalfCard().getSpellAbility().addEffect(new DamageTargetEffect(3)); + this.getRightHalfCard().getSpellAbility().addEffect( + new DiscardTargetEffect(2).setText("That player discards two cards.") + ); + this.getRightHalfCard().getSpellAbility().addTarget(new TargetOpponent()); + } + + private CarnivalCarnage(final CarnivalCarnage card) { + super(card); + } + + @Override + public CarnivalCarnage copy() { + return new CarnivalCarnage(this); + } +} + +class CarnivalEffect extends OneShotEffect { + + CarnivalEffect() { + super(Outcome.Benefit); + staticText = "{this} deals 1 damage to target creature or planeswalker " + + "and 1 damage to that permanent's controller"; + } + + private CarnivalEffect(final CarnivalEffect effect) { + super(effect); + } + + @Override + public CarnivalEffect copy() { + return new CarnivalEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent == null) { + return false; + } + permanent.damage(1, source.getSourceId(), game); + Player player = game.getPlayer(permanent.getControllerId()); + if (player != null) { + player.damage(1, source.getSourceId(), game); + } + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 01b7e974e41..c058c6883a8 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -44,6 +44,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Blood Crypt", 245, Rarity.RARE, mage.cards.b.BloodCrypt.class)); cards.add(new SetCardInfo("Bolrac-Clan Crusher", 159, Rarity.UNCOMMON, mage.cards.b.BolracClanCrusher.class)); cards.add(new SetCardInfo("Breeding Pool", 246, Rarity.RARE, mage.cards.b.BreedingPool.class)); + cards.add(new SetCardInfo("Carnival // Carnage", 222, Rarity.UNCOMMON, mage.cards.c.CarnivalCarnage.class)); cards.add(new SetCardInfo("Depose // Deploy", 225, Rarity.UNCOMMON, mage.cards.d.DeposeDeploy.class)); cards.add(new SetCardInfo("Deputy of Detention", 165, Rarity.RARE, mage.cards.d.DeputyOfDetention.class)); cards.add(new SetCardInfo("Dovin, Grand Arbiter", 167, Rarity.MYTHIC, mage.cards.d.DovinGrandArbiter.class)); diff --git a/Mage/src/main/java/mage/game/permanent/Permanent.java b/Mage/src/main/java/mage/game/permanent/Permanent.java index 1e17d0e8a9a..b23e848f305 100644 --- a/Mage/src/main/java/mage/game/permanent/Permanent.java +++ b/Mage/src/main/java/mage/game/permanent/Permanent.java @@ -1,9 +1,6 @@ package mage.game.permanent; -import java.util.List; -import java.util.Set; -import java.util.UUID; import mage.MageObject; import mage.MageObjectReference; import mage.abilities.Ability; @@ -14,6 +11,10 @@ import mage.game.Controllable; import mage.game.Game; import mage.game.GameState; +import java.util.List; +import java.util.Set; +import java.util.UUID; + public interface Permanent extends Card, Controllable { void setControllerId(UUID controllerId); @@ -106,6 +107,8 @@ public interface Permanent extends Card, Controllable { int getDamage(); + int damage(int damage, UUID sourceId, Game game); + int damage(int damage, UUID sourceId, Game game, boolean combat, boolean preventable); int damage(int damage, UUID sourceId, Game game, boolean combat, boolean preventable, List appliedEffects); diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index 800ccba21d0..c0794f0ca06 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -711,6 +711,11 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { return this.damage; } + @Override + public int damage(int damage, UUID sourceId, Game game) { + return damage(damage, sourceId, game, true, false, false, null); + } + @Override public int damage(int damage, UUID sourceId, Game game, boolean combat, boolean preventable) { return damage(damage, sourceId, game, preventable, combat, false, null); diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index dab98647ec4..7c97be707a3 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -1,7 +1,5 @@ package mage.players; -import java.io.Serializable; -import java.util.*; import mage.MageItem; import mage.MageObject; import mage.MageObjectReference; @@ -39,6 +37,9 @@ import mage.target.TargetCard; import mage.target.common.TargetCardInLibrary; import mage.util.Copyable; +import java.io.Serializable; +import java.util.*; + /** * @author BetaSteward_at_googlemail.com */ @@ -84,6 +85,8 @@ public interface Player extends MageItem, Copyable { int gainLife(int amount, Game game, UUID sourceId); + int damage(int damage, UUID sourceId, Game game); + int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable); int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable, List appliedEffects); diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 5f0d1fe40bb..6a6eda0b92d 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -1919,6 +1919,11 @@ public abstract class PlayerImpl implements Player, Serializable { return 0; } + @Override + public int damage(int damage, UUID sourceId, Game game) { + return doDamage(damage, sourceId, game, true, false, null); + } + @Override public int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable) { return doDamage(damage, sourceId, game, combatDamage, preventable, null); @@ -2491,7 +2496,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public void lookAtAllLibraries(Ability source, Game game) { - for(UUID playerId : game.getState().getPlayersInRange(this.getId(), game)){ + for (UUID playerId : game.getState().getPlayersInRange(this.getId(), game)) { Player player = game.getPlayer(playerId); String playerName = this.getName().equals(player.getName()) ? "Your " : player.getName() + "'s "; playerName += "library"; From 0ad967a5b3f2f0c987513cecc160c61ff369aaaa Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 12:31:10 -0500 Subject: [PATCH 37/44] small update to previous commit --- .../src/test/java/org/mage/test/player/TestPlayer.java | 5 +++++ .../src/test/java/org/mage/test/stub/PlayerStub.java | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index afdbc2270e0..b87b7c0a9dd 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -2368,6 +2368,11 @@ public class TestPlayer implements Player { return computerPlayer.gainLife(amount, game, sourceId); } + @Override + public int damage(int damage, UUID sourceId, Game game) { + return computerPlayer.damage(damage, sourceId, game); + } + @Override public int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable) { return computerPlayer.damage(damage, sourceId, game, combatDamage, preventable); diff --git a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java index 360bd942514..502be627e4c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java +++ b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java @@ -138,6 +138,11 @@ public class PlayerStub implements Player { return 0; } + @Override + public int damage(int damage, UUID sourceId, Game game) { + return 0; + } + @Override public int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable) { return 0; @@ -598,7 +603,8 @@ public class PlayerStub implements Player { } @Override - public void lookAtAllLibraries(Ability source, Game game) {} + public void lookAtAllLibraries(Ability source, Game game) { + } @Override public boolean canPlayLand() { From 129c7be92ca34c3c51b2546766e7e32f0ca3f5a4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 12:56:49 -0500 Subject: [PATCH 38/44] Implemented Consecrate // Consume --- .../src/mage/cards/c/ConsecrateConsume.java | 94 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 95 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ConsecrateConsume.java diff --git a/Mage.Sets/src/mage/cards/c/ConsecrateConsume.java b/Mage.Sets/src/mage/cards/c/ConsecrateConsume.java new file mode 100644 index 00000000000..72fc2b36a95 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ConsecrateConsume.java @@ -0,0 +1,94 @@ +package mage.cards.c; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.cards.CardSetInfo; +import mage.cards.SplitCard; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Outcome; +import mage.constants.SpellAbilityType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ConsecrateConsume extends SplitCard { + + public ConsecrateConsume(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, new CardType[]{CardType.SORCERY}, "{1}{W/B}", "{2}{W}{B}", SpellAbilityType.SPLIT); + + // Consecrate + // Exile target card from a graveyard. + this.getLeftHalfCard().getSpellAbility().addEffect(new ExileTargetEffect()); + this.getLeftHalfCard().getSpellAbility().addTarget(new TargetCardInGraveyard()); + + // Draw a card. + this.getLeftHalfCard().getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + + // Consume + // Target player sacrifices a creature with the greatest power among creatures they control. You gain life equal to its power. + this.getRightHalfCard().getSpellAbility().addEffect(new ConsumeEffect()); + this.getRightHalfCard().getSpellAbility().addTarget(new TargetPlayer()); + } + + private ConsecrateConsume(final ConsecrateConsume card) { + super(card); + } + + @Override + public ConsecrateConsume copy() { + return new ConsecrateConsume(this); + } +} + +class ConsumeEffect extends OneShotEffect { + + ConsumeEffect() { + super(Outcome.Benefit); + staticText = "Target player sacrifices a creature " + + "with the greatest power among creatures they control. " + + "You gain life equal to its power."; + } + + private ConsumeEffect(final ConsumeEffect effect) { + super(effect); + } + + @Override + public ConsumeEffect copy() { + return new ConsumeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player player = game.getPlayer(source.getFirstTarget()); + if (player == null || controller == null) { + return false; + } + int greatestPower = 0; + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(player.getId())) { + if (permanent != null && permanent.isCreature()) { + greatestPower = Math.max(permanent.getPower().getValue(), greatestPower); + } + } + FilterPermanent filter = new FilterCreaturePermanent("creature with power " + greatestPower); + filter.add(new PowerPredicate(ComparisonType.EQUAL_TO, greatestPower)); + new SacrificeEffect(filter, 1, "").apply(game, source); + controller.gainLife(greatestPower, game, source); + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index c058c6883a8..78847cf8ee1 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -45,6 +45,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Bolrac-Clan Crusher", 159, Rarity.UNCOMMON, mage.cards.b.BolracClanCrusher.class)); cards.add(new SetCardInfo("Breeding Pool", 246, Rarity.RARE, mage.cards.b.BreedingPool.class)); cards.add(new SetCardInfo("Carnival // Carnage", 222, Rarity.UNCOMMON, mage.cards.c.CarnivalCarnage.class)); + cards.add(new SetCardInfo("Consecrate // Consume", 224, Rarity.UNCOMMON, mage.cards.c.ConsecrateConsume.class)); cards.add(new SetCardInfo("Depose // Deploy", 225, Rarity.UNCOMMON, mage.cards.d.DeposeDeploy.class)); cards.add(new SetCardInfo("Deputy of Detention", 165, Rarity.RARE, mage.cards.d.DeputyOfDetention.class)); cards.add(new SetCardInfo("Dovin, Grand Arbiter", 167, Rarity.MYTHIC, mage.cards.d.DovinGrandArbiter.class)); From 66d9cd9468d8f24ba3786faa6ea0fb4c1cd158da Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 12:58:34 -0500 Subject: [PATCH 39/44] updated RNA spoiler --- Mage.Sets/src/mage/cards/f/FrilledMystic.java | 2 +- Utils/mtg-cards-data.txt | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/f/FrilledMystic.java b/Mage.Sets/src/mage/cards/f/FrilledMystic.java index 63b4f8d81ea..c8332b4a853 100644 --- a/Mage.Sets/src/mage/cards/f/FrilledMystic.java +++ b/Mage.Sets/src/mage/cards/f/FrilledMystic.java @@ -19,7 +19,7 @@ import java.util.UUID; public final class FrilledMystic extends CardImpl { public FrilledMystic(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{G}{U}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{G}{U}{U}"); this.subtype.add(SubType.ELF); this.subtype.add(SubType.LIZARD); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index fbf34a4ed0a..993acd38de4 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -34580,9 +34580,10 @@ Smothering Tithe|Ravnica Allegiance|22|R|{3}{W}|Enchantment|||Whenever an oppone Tithe Taker|Ravnica Allegiance|27|R|{1}{W}|Creature - Human Soldier|2|1|During your turn, spells your opponents cast cost {1} more to cast and abilities your opponents activate cost {1} more to activate unless they're mana abilities.$Afterlife 1| Mass Manipulation|Ravnica Allegiance|42|R|{X}{X}{U}{U}{U}{U}|Sorcery|||Gain control of X target creatures and/or planeswalkers.| Precognitive Perception|Ravnica Allegiance|45|R|{3}{U}{U}|Instant|||Draw three cards.$Addendum — If you cast this spell during your main phase, instead scry 3, then draw three cards.| +Quench|Ravnica Allegiance|48|C|{1}{U}|Instant|||Counter target spell unless its controller pays {2}.| Sphinx of Foresight|Ravnica Allegiance|55|R|{2}{U}{U}|Creature - Sphinx|4|4|You may reveal this card from your opening hand. If you do, scry 3 at the beginning of your first upkeep.$Flying$At the beginning of your upkeep, scry 1.| Bankrupt in Blood|Ravnica Allegiance|62|U|{1}{B}|Sorcery|||As an additional cost to cast this spell, sacrifice two creatures.$Draw three cards.| -Blade Juggler|Ravnica Allegiance|63|C|{5}{B}|Creature - Human Rogue|3|2|Spectacle {2}{B}$When Blade Juggler enters the battlefield, it deals 1 damage to you and you draw a card.| +Blade Juggler|Ravnica Allegiance|63|C|{4}{B}|Creature - Human Rogue|3|2|Spectacle {2}{B}$When Blade Juggler enters the battlefield, it deals 1 damage to you and you draw a card.| Cry of the Carnarium|Ravnica Allegiance|70|U|{1}{B}{B}|Sorcery|||All creatures get -2/-2 until end of turn. Exile all creature cards in all graveyards that were put there from the battlefield this turn. If a creature would die this turn, exile it instead.| Gutterbones|Ravnica Allegiance|76|R|{B}|Creature - Skeleton Warrior|2|1|Gutterbones enters the battlefield tapped.${1}{B}: Return Gutterbones from your graveyard to your hand. Activate this ability only during your turn and only if an opponent lost life this turn.| Pestilent Spirit|Ravnica Allegiance|81|R|{2}{B}|Creature - Spirit|3|2|Menace, deathtouch$Instant and sorcery spells you control have deathtouch.| @@ -34593,9 +34594,11 @@ Light Up the Stage|Ravnica Allegiance|107|U|{2}{R}|Sorcery|||Spectacle {R}$Exile Rix Maadi Reveler|Ravnica Allegiance|109|R|{1}{R}|Creature - Human Shaman|2|2|Spectacle {2}{B}{R}$When Rix Maadi Reveler enters the battlefield, discard a card, then draw a card. If Rix Maadi Reveler's spectacle cost was paid, instead discard your hand, then draw three cards.| Skarrgan Hellkite|Ravnica Allegiance|114|M|{3}{R}{R}|Creature - Dragon|4|4|Riot$Flying${3}{R}: Skarrgan Hellkite deals 2 damage divided as you choose among one or two targets. Activate this ability only if Skarrgan Hellkite has a +1/+1 counter on it.| Smelt-Ward Ignus|Ravnica Allegiance|116|U|{1}{R}|Creature - Elemental|2|1|{2}{R}, Sacrifice Smelt-Ward Ignus: Gain control of target creature with power 3 or less until end of turn. Untap that creature. It gains haste until end of turn. Activate this ability only any time you could cast a sorcery.| +Biogenic Upgrade|Ravnica Allegiance|123|U|{4}{G}{G}|Sorcery|||Distribute three +1/+1 counters among one, two, or three target creatures, then double the number of +1/+1 counters on each of those creatures.| End-Raze Forerunners|Ravnica Allegiance|124|R|{5}{G}{G}{G}|Creature - Boar|7|7|Vigilance, trample, haste$When End-Raze Forerunners enters the battlefield, other creatures you control get +2/+2 and gain vigilance and trample until end of turn.| Growth-Chamber Guardian|Ravnica Allegiance|128|R|{1}{G}|Creature - Elf Crab Warrior|2|2|{2}{G}: Adapt 2.$Whenever one or more +1/+1 counters are put on Growth-Chamber Guardian, you may search your library for a card named Growth-Chamber Guardian, reveal it, put it into your hand, then shuffle your library.| Rampage of the Clans|Ravnica Allegiance|134|R|{3}{G}|Instant|||Destroy all artifacts and enchantments. For each permanent destroyed this way, its controller creates a 3/3 green Centaur creature token.| +Titanic Brawl|Ravnica Allegiance|146|C|{1}{G}|Instant|||This spell costs {1} less to cast if it targets a creature you control with a +1/+1 counter on it.| Wilderness Reclamation|Ravnica Allegiance|149|U|{3}{G}|Enchantment|||At the beginning of your end step, untap all lands you control.| Absorb|Ravnica Allegiance|151|R|{W}{U}{U}|Instant|||Counter target spell. You gain 3 life.| Aeromunculus|Ravnica Allegiance|152|C|{1}{G}{U}|Creature - Homunculus Mutant|2|3|Flying${2}{G}{U}: Adapt 1.| @@ -34607,7 +34610,7 @@ Deputy of Detention|Ravnica Allegiance|165|R|{1}{W}{U}|Creature - Vedalken Wizar Dovin, Grand Arbiter|Ravnica Allegiance|167|M|{1}{W}{U}|Legendary Planeswalker - Dovin|3|+1: Until end of turn, whenever a creature you control deals combat damage to a player, put a loyalty counter on Dovin, Grand Arbiter.$-1: Create a 1/1 colorless Thopter artifact creature token with flying. You gain 1 life.$-7: Look at the top ten cards of your library. Put three of them into your hand and the rest on the bottom of your library in a random order.| Emergency Powers|Ravnica Allegiance|169|M|{5}{W}{U}|Instant|||Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Emergency Powers.$Addendum — If you cast this spell during your main phase, you may put a permanent card with converted mana cost 7 or less from your hand onto the battlefield.| Frenzied Arynx|Ravnica Allegiance|173|C|{2}{R}{G}|Creature - Cat Beast|3|3|Riot$Trample${4}{R}{G}: Frenzied Arynx gets +3/+0 until end of turn.| -Frilled Mystic|Ravnica Allegiance|174|U|{U}{G}{U}{G}|Creature - Elf Lizard Wizard|3|2|Flash$When Frilled Mystic enters the battlefield, you may counter target spell.| +Frilled Mystic|Ravnica Allegiance|174|U|{G}{G}{U}{U}|Creature - Elf Lizard Wizard|3|2|Flash$When Frilled Mystic enters the battlefield, you may counter target spell.| Growth Spiral|Ravnica Allegiance|178|C|{G}{U}|Instant|||Draw a card. You may put a land card from your hand onto the battlefield.| Gruul Spellbreaker|Ravnica Allegiance|179|R|{1}{R}{G}|Creature - Ogre Warrior|3|3|Riot$Trample$As long as it's your turn, you and Gruul Spellbreaker have hexproof.| High Alert|Ravnica Allegiance|182|U|{1}{W}{U}|Enchantment|||Each creature you control assigns combat damage equal to its toughness rather than its power.$Creatures you control can attack as though they didn't have defender.${2}{W}{U}: Untap target creature.| From dcaaeaa0586d34423bc65f09ccc0d762e5f0efb3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 13:26:55 -0500 Subject: [PATCH 40/44] Implemented Bankrupt in Blood --- .../src/mage/cards/b/BankruptInBlood.java | 35 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 36 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BankruptInBlood.java diff --git a/Mage.Sets/src/mage/cards/b/BankruptInBlood.java b/Mage.Sets/src/mage/cards/b/BankruptInBlood.java new file mode 100644 index 00000000000..f858051b679 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BankruptInBlood.java @@ -0,0 +1,35 @@ +package mage.cards.b; + +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BankruptInBlood extends CardImpl { + + public BankruptInBlood(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); + + // As an additional cost to cast this spell, sacrifice two creatures. + this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(2))); + + // Draw three cards. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(3)); + } + + private BankruptInBlood(final BankruptInBlood card) { + super(card); + } + + @Override + public BankruptInBlood copy() { + return new BankruptInBlood(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 78847cf8ee1..80c6849d0e3 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -38,6 +38,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Azorius Guildgate", 243, Rarity.COMMON, mage.cards.a.AzoriusGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Azorius Guildgate", 244, Rarity.COMMON, mage.cards.a.AzoriusGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Azorius Locket", 231, Rarity.COMMON, mage.cards.a.AzoriusLocket.class)); + cards.add(new SetCardInfo("Bankrupt in Blood", 62, Rarity.UNCOMMON, mage.cards.b.BankruptInBlood.class)); cards.add(new SetCardInfo("Basilica Bell-Haunt", 156, Rarity.UNCOMMON, mage.cards.b.BasilicaBellHaunt.class)); cards.add(new SetCardInfo("Bedevil", 157, Rarity.RARE, mage.cards.b.Bedevil.class)); cards.add(new SetCardInfo("Biomancer's Familiar", 158, Rarity.RARE, mage.cards.b.BiomancersFamiliar.class)); From 8ce752179d56d505043ba372701e3979b214acfe Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 13:32:07 -0500 Subject: [PATCH 41/44] Implemented Blade Juggler --- Mage.Sets/src/mage/cards/b/BladeJuggler.java | 49 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 50 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BladeJuggler.java diff --git a/Mage.Sets/src/mage/cards/b/BladeJuggler.java b/Mage.Sets/src/mage/cards/b/BladeJuggler.java new file mode 100644 index 00000000000..a9c5e82aee6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BladeJuggler.java @@ -0,0 +1,49 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageControllerEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.SpectacleAbility; +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 BladeJuggler extends CardImpl { + + public BladeJuggler(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Spectacle {2}{B} + this.addAbility(new SpectacleAbility(this, new ManaCostsImpl("{2}{B}"))); + + // When Blade Juggler enters the battlefield, it deals 1 damage to you and you draw a card. + Ability ability = new EntersBattlefieldTriggeredAbility( + new DamageControllerEffect(1, "it") + ); + ability.addEffect(new DrawCardSourceControllerEffect(1).setText("and you draw a card")); + this.addAbility(ability); + } + + private BladeJuggler(final BladeJuggler card) { + super(card); + } + + @Override + public BladeJuggler copy() { + return new BladeJuggler(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 80c6849d0e3..e3bf974fc3a 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -42,6 +42,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Basilica Bell-Haunt", 156, Rarity.UNCOMMON, mage.cards.b.BasilicaBellHaunt.class)); cards.add(new SetCardInfo("Bedevil", 157, Rarity.RARE, mage.cards.b.Bedevil.class)); cards.add(new SetCardInfo("Biomancer's Familiar", 158, Rarity.RARE, mage.cards.b.BiomancersFamiliar.class)); + cards.add(new SetCardInfo("Blade Juggler", 63, Rarity.COMMON, mage.cards.b.BladeJuggler.class)); cards.add(new SetCardInfo("Blood Crypt", 245, Rarity.RARE, mage.cards.b.BloodCrypt.class)); cards.add(new SetCardInfo("Bolrac-Clan Crusher", 159, Rarity.UNCOMMON, mage.cards.b.BolracClanCrusher.class)); cards.add(new SetCardInfo("Breeding Pool", 246, Rarity.RARE, mage.cards.b.BreedingPool.class)); From 66676f7833172d84cf9fd32af4907cf8c0c06bc2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 13:33:35 -0500 Subject: [PATCH 42/44] Implemented Quench --- Mage.Sets/src/mage/cards/q/Quench.java | 33 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 34 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/q/Quench.java diff --git a/Mage.Sets/src/mage/cards/q/Quench.java b/Mage.Sets/src/mage/cards/q/Quench.java new file mode 100644 index 00000000000..e1ca7a659fd --- /dev/null +++ b/Mage.Sets/src/mage/cards/q/Quench.java @@ -0,0 +1,33 @@ +package mage.cards.q; + +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CounterUnlessPaysEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetSpell; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Quench extends CardImpl { + + public Quench(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + // Counter target spell unless its controller pays {2}. + this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new GenericManaCost(2))); + this.getSpellAbility().addTarget(new TargetSpell()); + } + + private Quench(final Quench card) { + super(card); + } + + @Override + public Quench copy() { + return new Quench(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index e3bf974fc3a..1b8ff751259 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -81,6 +81,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Pitiless Pontiff", 194, Rarity.UNCOMMON, mage.cards.p.PitilessPontiff.class)); cards.add(new SetCardInfo("Precognitive Perception", 45, Rarity.RARE, mage.cards.p.PrecognitivePerception.class)); cards.add(new SetCardInfo("Prime Speaker Vannifar", 195, Rarity.MYTHIC, mage.cards.p.PrimeSpeakerVannifar.class)); + cards.add(new SetCardInfo("Quench", 48, Rarity.COMMON, mage.cards.q.Quench.class)); cards.add(new SetCardInfo("Rafter Demon", 196, Rarity.COMMON, mage.cards.r.RafterDemon.class)); cards.add(new SetCardInfo("Rakdos Firewheeler", 197, Rarity.UNCOMMON, mage.cards.r.RakdosFirewheeler.class)); cards.add(new SetCardInfo("Rakdos Guildgate", 255, Rarity.COMMON, mage.cards.r.RakdosGuildgate.class, NON_FULL_USE_VARIOUS)); From 89454f9c8e6d0fdd2acecf2cf93bcf768be2dc1b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 14:19:05 -0500 Subject: [PATCH 43/44] Implemented High Alert --- .../mage/cards/a/ArcadesTheStrategist.java | 61 +++--------------- .../src/mage/cards/a/AssaultFormation.java | 58 ++++------------- .../mage/cards/b/BelligerentBrontodon.java | 57 +++-------------- .../src/mage/cards/d/DoranTheSiegeTower.java | 58 +++++------------ Mage.Sets/src/mage/cards/h/HighAlert.java | 60 ++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + .../CombatDamageByToughnessEffect.java | 62 +++++++++++++++++++ 7 files changed, 165 insertions(+), 192 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/h/HighAlert.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessEffect.java diff --git a/Mage.Sets/src/mage/cards/a/ArcadesTheStrategist.java b/Mage.Sets/src/mage/cards/a/ArcadesTheStrategist.java index 028bc5bfcab..0dbc363239b 100644 --- a/Mage.Sets/src/mage/cards/a/ArcadesTheStrategist.java +++ b/Mage.Sets/src/mage/cards/a/ArcadesTheStrategist.java @@ -1,43 +1,36 @@ package mage.cards.a; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.combat.CanAttackAsThoughItDidntHaveDefenderAllEffect; +import mage.abilities.effects.common.ruleModifying.CombatDamageByToughnessEffect; import mage.abilities.keyword.DefenderAbility; -import mage.constants.SubType; -import mage.constants.SuperType; 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.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.AbilityPredicate; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class ArcadesTheStrategist extends CardImpl { private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature with defender"); + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent(); static { filter.add(new AbilityPredicate(DefenderAbility.class)); + filter2.add(new AbilityPredicate(DefenderAbility.class)); } public ArcadesTheStrategist(UUID ownerId, CardSetInfo setInfo) { @@ -61,14 +54,14 @@ public final class ArcadesTheStrategist extends CardImpl { )); // Each creature you control with defender assigns combat damage equal to its toughness rather than its power and can attack as though it didn't have defender. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ArcadesTheStrategistCombatDamageRuleEffect()); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new CombatDamageByToughnessEffect(filter2, true).setText("Each creature you control with defender assigns combat damage equal to its toughness rather than its power")); ability.addEffect(new CanAttackAsThoughItDidntHaveDefenderAllEffect( Duration.WhileOnBattlefield, filter ).setText("and can attack as though it didn't have defender")); this.addAbility(ability); } - public ArcadesTheStrategist(final ArcadesTheStrategist card) { + private ArcadesTheStrategist(final ArcadesTheStrategist card) { super(card); } @@ -77,41 +70,3 @@ public final class ArcadesTheStrategist extends CardImpl { return new ArcadesTheStrategist(this); } } - -class ArcadesTheStrategistCombatDamageRuleEffect extends ContinuousEffectImpl { - - public ArcadesTheStrategistCombatDamageRuleEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Each creature you control with defender assigns combat damage equal to its toughness rather than its power"; - } - - public ArcadesTheStrategistCombatDamageRuleEffect(final ArcadesTheStrategistCombatDamageRuleEffect effect) { - super(effect); - } - - @Override - public ArcadesTheStrategistCombatDamageRuleEffect copy() { - return new ArcadesTheStrategistCombatDamageRuleEffect(this); - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - // Change the rule - FilterCreaturePermanent filter = new FilterCreaturePermanent(); - filter.add(new ControllerIdPredicate(source.getControllerId())); - filter.add(new AbilityPredicate(DefenderAbility.class)); - game.getCombat().setUseToughnessForDamage(true); - game.getCombat().addUseToughnessForDamageFilter(filter); - return true; - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } -} diff --git a/Mage.Sets/src/mage/cards/a/AssaultFormation.java b/Mage.Sets/src/mage/cards/a/AssaultFormation.java index 8895519cf38..645fec98a5e 100644 --- a/Mage.Sets/src/mage/cards/a/AssaultFormation.java +++ b/Mage.Sets/src/mage/cards/a/AssaultFormation.java @@ -1,26 +1,27 @@ package mage.cards.a; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.combat.CanAttackAsThoughItDidntHaveDefenderTargetEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.ruleModifying.CombatDamageByToughnessEffect; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.AbilityPredicate; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class AssaultFormation extends CardImpl { @@ -32,10 +33,10 @@ public final class AssaultFormation extends CardImpl { } public AssaultFormation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); // Each creature you control assigns combat damage equal to its toughness rather than its power. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AssaultFormationCombatDamageRuleEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CombatDamageByToughnessEffect(StaticFilters.FILTER_PERMANENT_CREATURE, true))); // {G}: Target creature with defender can attack this turn as though it didn't have defender. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CanAttackAsThoughItDidntHaveDefenderTargetEffect(Duration.EndOfTurn), new ManaCostsImpl("{G}")); @@ -43,11 +44,11 @@ public final class AssaultFormation extends CardImpl { this.addAbility(ability); // {2}{G}: Creatures you control get +0/+1 until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostControlledEffect(0,1,Duration.EndOfTurn), new ManaCostsImpl("{2}{G}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostControlledEffect(0, 1, Duration.EndOfTurn), new ManaCostsImpl("{2}{G}"))); } - public AssaultFormation(final AssaultFormation card) { + private AssaultFormation(final AssaultFormation card) { super(card); } @@ -56,40 +57,3 @@ public final class AssaultFormation extends CardImpl { return new AssaultFormation(this); } } - -class AssaultFormationCombatDamageRuleEffect extends ContinuousEffectImpl { - - public AssaultFormationCombatDamageRuleEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Each creature you control assigns combat damage equal to its toughness rather than its power"; - } - - public AssaultFormationCombatDamageRuleEffect(final AssaultFormationCombatDamageRuleEffect effect) { - super(effect); - } - - @Override - public AssaultFormationCombatDamageRuleEffect copy() { - return new AssaultFormationCombatDamageRuleEffect(this); - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - // Change the rule - FilterCreaturePermanent filter = new FilterCreaturePermanent(); - filter.add(new ControllerIdPredicate(source.getControllerId())); - game.getCombat().setUseToughnessForDamage(true); - game.getCombat().addUseToughnessForDamageFilter(filter); - return true; - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } -} diff --git a/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java index a5de154190f..e6243b73c8c 100644 --- a/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java +++ b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java @@ -1,21 +1,19 @@ package mage.cards.b; -import java.util.UUID; - import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.ruleModifying.CombatDamageByToughnessEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.StaticFilters; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class BelligerentBrontodon extends CardImpl { @@ -28,10 +26,10 @@ public final class BelligerentBrontodon extends CardImpl { this.toughness = new MageInt(6); // Each creature you control assigns combat damage equal to its toughness rather than its power. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BelligerentBrontodonCombatDamageRuleEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CombatDamageByToughnessEffect(StaticFilters.FILTER_PERMANENT_CREATURE, true))); } - public BelligerentBrontodon(final BelligerentBrontodon card) { + private BelligerentBrontodon(final BelligerentBrontodon card) { super(card); } @@ -40,40 +38,3 @@ public final class BelligerentBrontodon extends CardImpl { return new BelligerentBrontodon(this); } } - -class BelligerentBrontodonCombatDamageRuleEffect extends ContinuousEffectImpl { - - public BelligerentBrontodonCombatDamageRuleEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Each creature you control assigns combat damage equal to its toughness rather than its power"; - } - - public BelligerentBrontodonCombatDamageRuleEffect(final BelligerentBrontodonCombatDamageRuleEffect effect) { - super(effect); - } - - @Override - public BelligerentBrontodonCombatDamageRuleEffect copy() { - return new BelligerentBrontodonCombatDamageRuleEffect(this); - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - // Change the rule - FilterCreaturePermanent filter = new FilterCreaturePermanent(); - filter.add(new ControllerIdPredicate(source.getControllerId())); - game.getCombat().setUseToughnessForDamage(true); - game.getCombat().addUseToughnessForDamageFilter(filter); - return true; - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } -} diff --git a/Mage.Sets/src/mage/cards/d/DoranTheSiegeTower.java b/Mage.Sets/src/mage/cards/d/DoranTheSiegeTower.java index 03c4f0c6f18..984b2342ec1 100644 --- a/Mage.Sets/src/mage/cards/d/DoranTheSiegeTower.java +++ b/Mage.Sets/src/mage/cards/d/DoranTheSiegeTower.java @@ -1,19 +1,20 @@ package mage.cards.d; -import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.ruleModifying.CombatDamageByToughnessEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.game.Game; + +import java.util.UUID; /** - * * 613.10. Some continuous effects affect game rules rather than objects. For * example, effects may modify a player's maximum hand size, or say that a * creature must attack this turn if able. These effects are applied after all @@ -22,7 +23,6 @@ import mage.game.Game; * in rule 601.2e. All other such effects are applied in timestamp order. See * also the rules for timestamp order and dependency (rules 613.6 and 613.7) * - * * @author LevelX2 */ public final class DoranTheSiegeTower extends CardImpl { @@ -37,10 +37,15 @@ public final class DoranTheSiegeTower extends CardImpl { this.toughness = new MageInt(5); // Each creature assigns combat damage equal to its toughness rather than its power. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DoranTheSiegeTowerCombatDamageRuleEffect())); + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new CombatDamageByToughnessEffect( + StaticFilters.FILTER_PERMANENT_CREATURE, false + ) + )); } - public DoranTheSiegeTower(final DoranTheSiegeTower card) { + private DoranTheSiegeTower(final DoranTheSiegeTower card) { super(card); } @@ -49,38 +54,3 @@ public final class DoranTheSiegeTower extends CardImpl { return new DoranTheSiegeTower(this); } } - -class DoranTheSiegeTowerCombatDamageRuleEffect extends ContinuousEffectImpl { - - public DoranTheSiegeTowerCombatDamageRuleEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Each creature assigns combat damage equal to its toughness rather than its power"; - } - - public DoranTheSiegeTowerCombatDamageRuleEffect(final DoranTheSiegeTowerCombatDamageRuleEffect effect) { - super(effect); - } - - @Override - public DoranTheSiegeTowerCombatDamageRuleEffect copy() { - return new DoranTheSiegeTowerCombatDamageRuleEffect(this); - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - // Change the rule - game.getCombat().setUseToughnessForDamage(true); - game.getCombat().addUseToughnessForDamageFilter(StaticFilters.FILTER_PERMANENT_CREATURES); - return true; - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } -} diff --git a/Mage.Sets/src/mage/cards/h/HighAlert.java b/Mage.Sets/src/mage/cards/h/HighAlert.java new file mode 100644 index 00000000000..c846241de82 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HighAlert.java @@ -0,0 +1,60 @@ +package mage.cards.h; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.combat.CanAttackAsThoughItDidntHaveDefenderAllEffect; +import mage.abilities.effects.common.ruleModifying.CombatDamageByToughnessEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HighAlert extends CardImpl { + + public HighAlert(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{U}"); + + + // Each creature you control assigns combat damage equal to its toughness rather than its power. + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new CombatDamageByToughnessEffect( + StaticFilters.FILTER_PERMANENT_CREATURE, true + ) + )); + + // Creatures you control can attack as though they didn't have defender. + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new CanAttackAsThoughItDidntHaveDefenderAllEffect( + Duration.WhileOnBattlefield, + StaticFilters.FILTER_CONTROLLED_CREATURES + ) + )); + + // {2}{W}{U}: Untap target creature. + Ability ability = new SimpleActivatedAbility(new UntapTargetEffect(), new ManaCostsImpl("{2}{W}{U}")); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + private HighAlert(final HighAlert card) { + super(card); + } + + @Override + public HighAlert copy() { + return new HighAlert(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 1b8ff751259..ac67287d565 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -66,6 +66,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Gruul Spellbreaker", 179, Rarity.RARE, mage.cards.g.GruulSpellbreaker.class)); cards.add(new SetCardInfo("Gutterbones", 76, Rarity.RARE, mage.cards.g.Gutterbones.class)); cards.add(new SetCardInfo("Hallowed Fountain", 251, Rarity.RARE, mage.cards.h.HallowedFountain.class)); + cards.add(new SetCardInfo("High Alert", 182, Rarity.UNCOMMON, mage.cards.h.HighAlert.class)); cards.add(new SetCardInfo("Hydroid Krasis", 183, Rarity.MYTHIC, mage.cards.h.HydroidKrasis.class)); cards.add(new SetCardInfo("Imperious Oligarch", 184, Rarity.COMMON, mage.cards.i.ImperiousOligarch.class)); cards.add(new SetCardInfo("Incubation // Incongruity", 226, Rarity.UNCOMMON, mage.cards.i.IncubationIncongruity.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessEffect.java new file mode 100644 index 00000000000..3afcf0161f6 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessEffect.java @@ -0,0 +1,62 @@ + +package mage.abilities.effects.common.ruleModifying; + +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; + +/** + * @author TheElk801 + */ +public class CombatDamageByToughnessEffect extends ContinuousEffectImpl { + + private final FilterCreaturePermanent filter; + private final boolean onlyControlled; + + public CombatDamageByToughnessEffect(FilterCreaturePermanent filter, boolean onlyControlled) { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + this.filter = filter; + this.onlyControlled = onlyControlled; + staticText = "Each " + filter.getMessage() + (onlyControlled ? " you control" : "") + + " assigns combat damage equal to its toughness rather than its power"; + } + + public CombatDamageByToughnessEffect(final CombatDamageByToughnessEffect effect) { + super(effect); + this.filter = effect.filter; + this.onlyControlled = effect.onlyControlled; + } + + @Override + public CombatDamageByToughnessEffect copy() { + return new CombatDamageByToughnessEffect(this); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + // Change the rule + FilterCreaturePermanent filterPermanent = filter.copy(); + if (onlyControlled) { + filterPermanent.add(new ControllerIdPredicate(source.getControllerId())); + } + game.getCombat().setUseToughnessForDamage(true); + game.getCombat().addUseToughnessForDamageFilter(filterPermanent); + return true; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean hasLayer(Layer layer) { + return layer == Layer.RulesEffects; + } +} From 5021907032431a09b503896f7875633e34bd805a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 4 Jan 2019 14:20:33 -0500 Subject: [PATCH 44/44] implemented RNA spoiler --- Utils/mtg-cards-data.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 993acd38de4..163f0e8ede8 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -34576,6 +34576,7 @@ Kraul Raider|Guilds of Ravnica|270|C|{2}{B}|Creature - Insect Warrior|2|3|Menace Attendant of Vraska|Guilds of Ravnica|271|U|{1}{B}{G}|Creature - Zombie Soldier|3|3|When Attendant of Vraska dies, if you control a Vraska planeswalker, you gain life equal to Attendant of Vraska's power.| Vraska's Stoneglare|Guilds of Ravnica|272|R|{4}{B}{G}|Sorcery|||Destroy target creature. You gain life equal to its toughness. You may search your library and/or graveyard for a card named Vraska, Regal Gorgon, reveal it, and put it into your hand. If you search your library this way, shuffle it.| Impervious Greatwurm|Guilds of Ravnica|273|M|{7}{G}{G}{G}|Creature - Wurm|16|16|Convoke$Indestructible| +Angelic Exaltation|Ravnica Allegiance|2|U|{3}{W}|Enchantment|||Whenever a creature you control attacks alone, it gets +X/+X until end of turn, where X is the number of creatures you control.| Smothering Tithe|Ravnica Allegiance|22|R|{3}{W}|Enchantment|||Whenever an opponent draws a card, that player may pay {2}. If the player doesn't, you create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color."| Tithe Taker|Ravnica Allegiance|27|R|{1}{W}|Creature - Human Soldier|2|1|During your turn, spells your opponents cast cost {1} more to cast and abilities your opponents activate cost {1} more to activate unless they're mana abilities.$Afterlife 1| Mass Manipulation|Ravnica Allegiance|42|R|{X}{X}{U}{U}{U}{U}|Sorcery|||Gain control of X target creatures and/or planeswalkers.| @@ -34589,6 +34590,7 @@ Gutterbones|Ravnica Allegiance|76|R|{B}|Creature - Skeleton Warrior|2|1|Gutterbo Pestilent Spirit|Ravnica Allegiance|81|R|{2}{B}|Creature - Spirit|3|2|Menace, deathtouch$Instant and sorcery spells you control have deathtouch.| Spawn of Mayhem|Ravnica Allegiance|85|M|{2}{B}{B}|Creature - Demon|4|4|Spectacle {1}{B}{B}$Flying, trample$At the beginning of your upkeep, Spawn of Mayhem deals 1 damage to each player. Then if you have 10 or less life, put a +1/+1 counter on Spawn of Mayhem.| Amplifire|Ravnica Allegiance|92|R|{2}{R}{R}|Creature - Elemental|1|1|At the beginning of your upkeep, reveal cards from the top of your library until you reveal a creature card. Until your next turn, Amplifire's base power becomes twice that card's power and its base toughness becomes twice that card's toughness. Put the revealed cards on the bottom of your library in a random order.| +Burning-Tree Vandal|Ravnica Allegiance|94|C|{2}{R}|Creature - Human Rogue|2|1|Riot$Whenever Burning-Tree Vandal attacks, you may discard a card. If you do, draw a card.| Electrodominance|Ravnica Allegiance|99|R|{X}{R}{R}|Instant|||Electrodominance deals X damage to any target. You may cast a card with converted mana cost X or less from your hand without paying its mana cost.| Light Up the Stage|Ravnica Allegiance|107|U|{2}{R}|Sorcery|||Spectacle {R}$Exile the top two cards of your library. Until the end of your next turn, you may play those cards.| Rix Maadi Reveler|Ravnica Allegiance|109|R|{1}{R}|Creature - Human Shaman|2|2|Spectacle {2}{B}{R}$When Rix Maadi Reveler enters the battlefield, discard a card, then draw a card. If Rix Maadi Reveler's spectacle cost was paid, instead discard your hand, then draw three cards.| @@ -34598,7 +34600,7 @@ Biogenic Upgrade|Ravnica Allegiance|123|U|{4}{G}{G}|Sorcery|||Distribute three + End-Raze Forerunners|Ravnica Allegiance|124|R|{5}{G}{G}{G}|Creature - Boar|7|7|Vigilance, trample, haste$When End-Raze Forerunners enters the battlefield, other creatures you control get +2/+2 and gain vigilance and trample until end of turn.| Growth-Chamber Guardian|Ravnica Allegiance|128|R|{1}{G}|Creature - Elf Crab Warrior|2|2|{2}{G}: Adapt 2.$Whenever one or more +1/+1 counters are put on Growth-Chamber Guardian, you may search your library for a card named Growth-Chamber Guardian, reveal it, put it into your hand, then shuffle your library.| Rampage of the Clans|Ravnica Allegiance|134|R|{3}{G}|Instant|||Destroy all artifacts and enchantments. For each permanent destroyed this way, its controller creates a 3/3 green Centaur creature token.| -Titanic Brawl|Ravnica Allegiance|146|C|{1}{G}|Instant|||This spell costs {1} less to cast if it targets a creature you control with a +1/+1 counter on it.| +Titanic Brawl|Ravnica Allegiance|146|C|{1}{G}|Instant|||This spell costs {1} less to cast if it targets a creature you control with a +1/+1 counter on it.$Target creature you control fights target creature you don't control.| Wilderness Reclamation|Ravnica Allegiance|149|U|{3}{G}|Enchantment|||At the beginning of your end step, untap all lands you control.| Absorb|Ravnica Allegiance|151|R|{W}{U}{U}|Instant|||Counter target spell. You gain 3 life.| Aeromunculus|Ravnica Allegiance|152|C|{1}{G}{U}|Creature - Homunculus Mutant|2|3|Flying${2}{G}{U}: Adapt 1.| @@ -34611,6 +34613,7 @@ Dovin, Grand Arbiter|Ravnica Allegiance|167|M|{1}{W}{U}|Legendary Planeswalker - Emergency Powers|Ravnica Allegiance|169|M|{5}{W}{U}|Instant|||Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Emergency Powers.$Addendum — If you cast this spell during your main phase, you may put a permanent card with converted mana cost 7 or less from your hand onto the battlefield.| Frenzied Arynx|Ravnica Allegiance|173|C|{2}{R}{G}|Creature - Cat Beast|3|3|Riot$Trample${4}{R}{G}: Frenzied Arynx gets +3/+0 until end of turn.| Frilled Mystic|Ravnica Allegiance|174|U|{G}{G}{U}{U}|Creature - Elf Lizard Wizard|3|2|Flash$When Frilled Mystic enters the battlefield, you may counter target spell.| +Grasping Thrull|Ravnica Allegiance|177|C|{3}{W}{B}|Creature - Thrull|3|3|Flying$When Grasping Thrull enters the battlefield, it deals 2 damage to each opponent and you gain 2 life.| Growth Spiral|Ravnica Allegiance|178|C|{G}{U}|Instant|||Draw a card. You may put a land card from your hand onto the battlefield.| Gruul Spellbreaker|Ravnica Allegiance|179|R|{1}{R}{G}|Creature - Ogre Warrior|3|3|Riot$Trample$As long as it's your turn, you and Gruul Spellbreaker have hexproof.| High Alert|Ravnica Allegiance|182|U|{1}{W}{U}|Enchantment|||Each creature you control assigns combat damage equal to its toughness rather than its power.$Creatures you control can attack as though they didn't have defender.${2}{W}{U}: Untap target creature.|