From 846c133d04bece69a78579659bd9da694b971ef6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 18 Dec 2018 19:44:55 -0500 Subject: [PATCH 01/10] Implemented Rix Maadi Reveler --- .../src/mage/cards/r/RixMaadiReveler.java | 83 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + .../condition/common/SpectacleCondition.java | 33 ++++++++ .../abilities/keyword/SpectacleAbility.java | 80 ++++++++++++++++++ Utils/keywords.txt | 1 + 5 files changed, 198 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RixMaadiReveler.java create mode 100644 Mage/src/main/java/mage/abilities/condition/common/SpectacleCondition.java create mode 100644 Mage/src/main/java/mage/abilities/keyword/SpectacleAbility.java diff --git a/Mage.Sets/src/mage/cards/r/RixMaadiReveler.java b/Mage.Sets/src/mage/cards/r/RixMaadiReveler.java new file mode 100644 index 0000000000..82136a1ee7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RixMaadiReveler.java @@ -0,0 +1,83 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.SpectacleCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.SpectacleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RixMaadiReveler extends CardImpl { + + public RixMaadiReveler(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SHAMAN); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Spectacle {2}{B}{R} + this.addAbility(new SpectacleAbility(this, new ManaCostsImpl("{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. + this.addAbility(new EntersBattlefieldTriggeredAbility(new RixMaadiRevelerEffect(), false)); + } + + public RixMaadiReveler(final RixMaadiReveler card) { + super(card); + } + + @Override + public RixMaadiReveler copy() { + return new RixMaadiReveler(this); + } +} + +class RixMaadiRevelerEffect extends OneShotEffect { + + RixMaadiRevelerEffect() { + super(Outcome.Benefit); + staticText = "discard a card, then draw a card. " + + "If {this}'s spectacle cost was paid, " + + "instead discard your hand, then draw three cards."; + } + + private RixMaadiRevelerEffect(final RixMaadiRevelerEffect effect) { + super(effect); + } + + @Override + public RixMaadiRevelerEffect copy() { + return new RixMaadiRevelerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + if (SpectacleCondition.instance.apply(game, source)) { + player.discard(player.getHand().size(), false, source, game); + player.drawCards(3, game); + } else { + player.discard(1, false, source, game); + player.drawCards(1, game); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 9c183b651a..7638afdcb6 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("Growth Spiral", 178, Rarity.COMMON, mage.cards.g.GrowthSpiral.class)); cards.add(new SetCardInfo("Mortify", 192, Rarity.UNCOMMON, mage.cards.m.Mortify.class)); + cards.add(new SetCardInfo("Rix Maadi Reveler", 109, Rarity.RARE, mage.cards.r.RixMaadiReveler.class)); cards.add(new SetCardInfo("The Haunt of Hightower", 273, Rarity.MYTHIC, mage.cards.t.TheHauntOfHightower.class)); } diff --git a/Mage/src/main/java/mage/abilities/condition/common/SpectacleCondition.java b/Mage/src/main/java/mage/abilities/condition/common/SpectacleCondition.java new file mode 100644 index 0000000000..8082411944 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/condition/common/SpectacleCondition.java @@ -0,0 +1,33 @@ + +package mage.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.keyword.SpectacleAbility; +import mage.constants.AbilityType; +import mage.game.Game; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author TheElk801 + */ +public enum SpectacleCondition implements Condition { + + instance; + + @Override + public boolean apply(Game game, Ability source) { + if (source.getAbilityType() == AbilityType.TRIGGERED) { + @SuppressWarnings("unchecked") + List<Integer> spectacleActivations = (ArrayList) game.getState().getValue(SpectacleAbility.SPECTACLE_ACTIVATION_VALUE_KEY + source.getSourceId()); + if (spectacleActivations != null) { + return spectacleActivations.contains(game.getState().getZoneChangeCounter(source.getSourceId()) - 1); + } + return false; + } else { + return source instanceof SpectacleAbility; + } + } +} diff --git a/Mage/src/main/java/mage/abilities/keyword/SpectacleAbility.java b/Mage/src/main/java/mage/abilities/keyword/SpectacleAbility.java new file mode 100644 index 0000000000..e646742d6a --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/SpectacleAbility.java @@ -0,0 +1,80 @@ + +package mage.abilities.keyword; + +import mage.abilities.SpellAbility; +import mage.abilities.costs.mana.ManaCost; +import mage.cards.Card; +import mage.constants.SpellAbilityType; +import mage.constants.Zone; +import mage.game.Game; +import mage.watchers.common.PlayerLostLifeWatcher; + +import java.util.ArrayList; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class SpectacleAbility extends SpellAbility { + + public static final String SPECTACLE_ACTIVATION_VALUE_KEY = "spectacleActivation"; + + private String rule; + + public SpectacleAbility(Card card, ManaCost spectacleCosts) { + super(spectacleCosts, card.getName() + " with spectacle", Zone.HAND, SpellAbilityType.BASE_ALTERNATE); + this.getCosts().addAll(card.getSpellAbility().getCosts().copy()); + this.getEffects().addAll(card.getSpellAbility().getEffects().copy()); + this.getTargets().addAll(card.getSpellAbility().getTargets().copy()); + this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE; + this.timing = card.getSpellAbility().getTiming(); + this.setRuleAtTheTop(true); + this.rule = "Spectacle " + spectacleCosts.getText() + + " <i>(You may cast this spell for its spectacle cost rather than its mana cost if an opponent lost life this turn.)</i>"; + } + + public SpectacleAbility(final SpectacleAbility ability) { + super(ability); + this.rule = ability.rule; + } + + @Override + public ActivationStatus canActivate(UUID playerId, Game game) { + PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get(PlayerLostLifeWatcher.class.getSimpleName()); + if (watcher != null && watcher.getAllOppLifeLost(playerId, game) > 0) { + return super.canActivate(playerId, game); + } + return ActivationStatus.getFalse(); + } + + @Override + @SuppressWarnings("unchecked") + public boolean activate(Game game, boolean noMana) { + if (super.activate(game, noMana)) { + ArrayList<Integer> spectacleActivations = (ArrayList) game.getState().getValue(SPECTACLE_ACTIVATION_VALUE_KEY + getSourceId()); + if (spectacleActivations == null) { + spectacleActivations = new ArrayList<>(); // zoneChangeCounter + game.getState().setValue(SPECTACLE_ACTIVATION_VALUE_KEY + getSourceId(), spectacleActivations); + } + spectacleActivations.add(game.getState().getZoneChangeCounter(getSourceId())); + return true; + } + return false; + } + + @Override + public SpectacleAbility copy() { + return new SpectacleAbility(this); + } + + @Override + public String getRule(boolean all) { + return getRule(); + } + + @Override + public String getRule() { + return rule; + } + +} diff --git a/Utils/keywords.txt b/Utils/keywords.txt index c108ac7d90..bef1ffec8a 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -82,6 +82,7 @@ Shroud|instance| Soulbond|instance| Soulshift|number| Skulk|new| +Spectacle|card, cost| Storm|new| Sunburst|new| Swampcycling|cost| From 777285d663acd1326c38b617afb6ff9ea9413a84 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 18 Dec 2018 19:45:49 -0500 Subject: [PATCH 02/10] updated GRN 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 7d02178392..2bad0f7770 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 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.| Growth Spiral|Ravnica Allegiance|178|C|{G}{U}|Instant|||Draw a card. You may put a land card from your hand onto the battlefield.| +Imperious Oligarch|Ravnica Allegiance|184|C|{W}{B}|Creature - Human Cleric|2|1|Vigilance$Afterlife 1| 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.| 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.| From 4416834e2ccdf737a31c9a88b5c7f0c586cc4c86 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 18 Dec 2018 19:47:36 -0500 Subject: [PATCH 03/10] Implemented Imperious Oligarch --- .../src/mage/cards/i/ImperiousOligarch.java | 41 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 42 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/ImperiousOligarch.java diff --git a/Mage.Sets/src/mage/cards/i/ImperiousOligarch.java b/Mage.Sets/src/mage/cards/i/ImperiousOligarch.java new file mode 100644 index 0000000000..0a4a81eb5f --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/ImperiousOligarch.java @@ -0,0 +1,41 @@ +package mage.cards.i; + +import mage.MageInt; +import mage.abilities.keyword.AfterlifeAbility; +import mage.abilities.keyword.VigilanceAbility; +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 ImperiousOligarch extends CardImpl { + + public ImperiousOligarch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Afterlife 1 + this.addAbility(new AfterlifeAbility(1)); + } + + public ImperiousOligarch(final ImperiousOligarch card) { + super(card); + } + + @Override + public ImperiousOligarch copy() { + return new ImperiousOligarch(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 7638afdcb6..70a4afac9f 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -33,6 +33,7 @@ public final class RavnicaAllegiance extends ExpansionSet { this.maxCardNumberInBooster = 259; cards.add(new SetCardInfo("Growth Spiral", 178, Rarity.COMMON, mage.cards.g.GrowthSpiral.class)); + cards.add(new SetCardInfo("Imperious Oligarch", 184, Rarity.COMMON, mage.cards.i.ImperiousOligarch.class)); cards.add(new SetCardInfo("Mortify", 192, Rarity.UNCOMMON, mage.cards.m.Mortify.class)); cards.add(new SetCardInfo("Rix Maadi Reveler", 109, Rarity.RARE, mage.cards.r.RixMaadiReveler.class)); cards.add(new SetCardInfo("The Haunt of Hightower", 273, Rarity.MYTHIC, mage.cards.t.TheHauntOfHightower.class)); From 226628bb1bb87aa1eccb6e07edb90d042eb0caee Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 18 Dec 2018 19:56:04 -0500 Subject: [PATCH 04/10] Implemented Rafter Demon --- Mage.Sets/src/mage/cards/r/RafterDemon.java | 53 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 54 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RafterDemon.java diff --git a/Mage.Sets/src/mage/cards/r/RafterDemon.java b/Mage.Sets/src/mage/cards/r/RafterDemon.java new file mode 100644 index 0000000000..10e7f1afef --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RafterDemon.java @@ -0,0 +1,53 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.SpectacleCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; +import mage.abilities.keyword.SpectacleAbility; +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 RafterDemon extends CardImpl { + + public RafterDemon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}"); + + this.subtype.add(SubType.DEMON); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + // Spectacle {3}{B}{R} + this.addAbility(new SpectacleAbility(this, new ManaCostsImpl("{3}{B}{R}"))); + + // When Rafter Demon enters the battlefield, if its spectacle cost was paid, each opponent discards a card. + this.addAbility(new ConditionalInterveningIfTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new DiscardEachPlayerEffect( + new StaticValue(1), false, TargetController.OPPONENT + )), SpectacleCondition.instance, + "When {this} enters the battlefield, " + + "if its spectacle cost was paid, " + + "each opponent discards a card." + )); + } + + public RafterDemon(final RafterDemon card) { + super(card); + } + + @Override + public RafterDemon copy() { + return new RafterDemon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 70a4afac9f..299c61e350 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -35,6 +35,7 @@ public final class RavnicaAllegiance extends ExpansionSet { cards.add(new SetCardInfo("Growth Spiral", 178, Rarity.COMMON, mage.cards.g.GrowthSpiral.class)); cards.add(new SetCardInfo("Imperious Oligarch", 184, Rarity.COMMON, mage.cards.i.ImperiousOligarch.class)); cards.add(new SetCardInfo("Mortify", 192, Rarity.UNCOMMON, mage.cards.m.Mortify.class)); + cards.add(new SetCardInfo("Rafter Demon", 196, Rarity.COMMON, mage.cards.r.RafterDemon.class)); cards.add(new SetCardInfo("Rix Maadi Reveler", 109, Rarity.RARE, mage.cards.r.RixMaadiReveler.class)); cards.add(new SetCardInfo("The Haunt of Hightower", 273, Rarity.MYTHIC, mage.cards.t.TheHauntOfHightower.class)); } From abf859b7548e0a768ec5bdf5114f42c92c90374a Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 18 Dec 2018 20:59:47 -0500 Subject: [PATCH 05/10] Implemented Gate Colossus --- Mage.Sets/src/mage/cards/g/GateColossus.java | 101 ++++++++++++++++++ .../src/mage/cards/g/GearseekerSerpent.java | 2 +- .../src/mage/sets/RavnicaAllegiance.java | 1 + 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/g/GateColossus.java diff --git a/Mage.Sets/src/mage/cards/g/GateColossus.java b/Mage.Sets/src/mage/cards/g/GateColossus.java new file mode 100644 index 0000000000..161b449d1d --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GateColossus.java @@ -0,0 +1,101 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.common.SimpleEvasionAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.PutOnLibrarySourceEffect; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GateColossus extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with power 2 or less"); + + static { + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3)); + } + + public GateColossus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{8}"); + + this.subtype.add(SubType.CONSTRUCT); + this.power = new MageInt(8); + this.toughness = new MageInt(8); + + // This spell costs {1} less to cast for each Gate you control. + this.addAbility(new SimpleStaticAbility(Zone.STACK, new GateColossusCostReductionEffect())); + + // Gate Colossus can't be blocked by creatures with power 2 or less. + this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); + + // Whenever a Gate enters the battlefield under your control, you may put Gate Colossus from your graveyard on top of your library. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + Zone.GRAVEYARD, + new PutOnLibrarySourceEffect( + true, "put {this} from your graveyard on top of your library" + ), GateColossusCostReductionEffect.filter, true + )); + } + + public GateColossus(final GateColossus card) { + super(card); + } + + @Override + public GateColossus copy() { + return new GateColossus(this); + } +} + +class GateColossusCostReductionEffect extends CostModificationEffectImpl { + + static final FilterControlledPermanent filter = new FilterControlledPermanent(); + + static { + filter.add(new SubtypePredicate(SubType.GATE)); + } + + public GateColossusCostReductionEffect() { + super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST); + staticText = "This spell costs {1} less to cast for each Gate you control"; + } + + protected GateColossusCostReductionEffect(final GateColossusCostReductionEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + int count = game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game).size(); + if (count > 0) { + CardUtil.reduceCost(abilityToModify, count); + } + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + return abilityToModify.getSourceId().equals(source.getSourceId()); + } + + @Override + public GateColossusCostReductionEffect copy() { + return new GateColossusCostReductionEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GearseekerSerpent.java b/Mage.Sets/src/mage/cards/g/GearseekerSerpent.java index 9cd4533298..1bc10b186e 100644 --- a/Mage.Sets/src/mage/cards/g/GearseekerSerpent.java +++ b/Mage.Sets/src/mage/cards/g/GearseekerSerpent.java @@ -58,7 +58,7 @@ class GearseekerSerpentCostReductionEffect extends CostModificationEffectImpl { public GearseekerSerpentCostReductionEffect() { super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST); - staticText = "{this} costs {1} less to cast for each artifact you control"; + staticText = "This spell costs {1} less to cast for each artifact you control"; } protected GearseekerSerpentCostReductionEffect(final GearseekerSerpentCostReductionEffect effect) { diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 299c61e350..a140b3ad76 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -32,6 +32,7 @@ public final class RavnicaAllegiance extends ExpansionSet { this.ratioBoosterMythic = 8; this.maxCardNumberInBooster = 259; + cards.add(new SetCardInfo("Gate Colossus", 232, Rarity.UNCOMMON, mage.cards.g.GateColossus.class)); cards.add(new SetCardInfo("Growth Spiral", 178, Rarity.COMMON, mage.cards.g.GrowthSpiral.class)); cards.add(new SetCardInfo("Imperious Oligarch", 184, Rarity.COMMON, mage.cards.i.ImperiousOligarch.class)); cards.add(new SetCardInfo("Mortify", 192, Rarity.UNCOMMON, mage.cards.m.Mortify.class)); From c7bc799f86395a9338996c2765016981ed70f360 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 18 Dec 2018 21:23:35 -0500 Subject: [PATCH 06/10] Implemented Light Up the Stage --- .../src/mage/cards/c/CommuneWithLava.java | 7 +- .../src/mage/cards/l/LightUpTheStage.java | 127 ++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 3 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/l/LightUpTheStage.java diff --git a/Mage.Sets/src/mage/cards/c/CommuneWithLava.java b/Mage.Sets/src/mage/cards/c/CommuneWithLava.java index 08cf2112e7..6f4f3bb193 100644 --- a/Mage.Sets/src/mage/cards/c/CommuneWithLava.java +++ b/Mage.Sets/src/mage/cards/c/CommuneWithLava.java @@ -1,7 +1,5 @@ package mage.cards.c; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; @@ -15,6 +13,9 @@ import mage.players.Player; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.Set; +import java.util.UUID; + /** * * @author jeffwadsworth @@ -78,7 +79,7 @@ class CommuneWithLavaEffect extends OneShotEffect { class CommuneWithLavaMayPlayEffect extends AsThoughEffectImpl { - int castOnTurn = 0; + private int castOnTurn = 0; public CommuneWithLavaMayPlayEffect() { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit); diff --git a/Mage.Sets/src/mage/cards/l/LightUpTheStage.java b/Mage.Sets/src/mage/cards/l/LightUpTheStage.java new file mode 100644 index 0000000000..2a48c3106c --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LightUpTheStage.java @@ -0,0 +1,127 @@ +package mage.cards.l; + +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.SpectacleAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 and jeffwadsworth + */ +public final class LightUpTheStage extends CardImpl { + + public LightUpTheStage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); + + // Spectacle {R} + this.addAbility(new SpectacleAbility(this, new ManaCostsImpl("{R}"))); + + // Exile the top two cards of your library. Until the end of your next turn, you may play those cards. + this.getSpellAbility().addEffect(new LightUpTheStageEffect()); + } + + public LightUpTheStage(final LightUpTheStage card) { + super(card); + } + + @Override + public LightUpTheStage copy() { + return new LightUpTheStage(this); + } +} + +class LightUpTheStageEffect extends OneShotEffect { + + public LightUpTheStageEffect() { + super(Outcome.PlayForFree); + this.staticText = "Exile the top two cards of your library. Until the end of your next turn, you may play those cards"; + } + + public LightUpTheStageEffect(final LightUpTheStageEffect effect) { + super(effect); + } + + @Override + public LightUpTheStageEffect copy() { + return new LightUpTheStageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Card sourceCard = game.getCard(source.getSourceId()); + if (controller != null) { + Set<Card> cards = controller.getLibrary().getTopCards(game, 2); + controller.moveCardsToExile(cards, source, game, true, CardUtil.getCardExileZoneId(game, source), sourceCard.getIdName()); + + for (Card card : cards) { + ContinuousEffect effect = new LightUpTheStageMayPlayEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); + } + + return true; + } + return false; + } +} + +class LightUpTheStageMayPlayEffect extends AsThoughEffectImpl { + + private int castOnTurn = 0; + + public LightUpTheStageMayPlayEffect() { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit); + this.staticText = "Until the end of your next turn, you may play that card."; + } + + public LightUpTheStageMayPlayEffect(final LightUpTheStageMayPlayEffect effect) { + super(effect); + castOnTurn = effect.castOnTurn; + } + + @Override + public LightUpTheStageMayPlayEffect copy() { + return new LightUpTheStageMayPlayEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + castOnTurn = game.getTurnNum(); + } + + @Override + public boolean isInactive(Ability source, Game game) { + if (castOnTurn != game.getTurnNum() && game.getPhase().getStep().getType() == PhaseStep.END_TURN) { + if (game.isActivePlayer(source.getControllerId())) { + return true; + } + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + return source.isControlledBy(affectedControllerId) + && getTargetPointer().getTargets(game, source).contains(sourceId); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index a140b3ad76..242c82fa44 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -35,6 +35,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("Growth Spiral", 178, Rarity.COMMON, mage.cards.g.GrowthSpiral.class)); cards.add(new SetCardInfo("Imperious Oligarch", 184, Rarity.COMMON, mage.cards.i.ImperiousOligarch.class)); + cards.add(new SetCardInfo("Light Up the Stage", 107, Rarity.UNCOMMON, mage.cards.l.LightUpTheStage.class)); cards.add(new SetCardInfo("Mortify", 192, Rarity.UNCOMMON, mage.cards.m.Mortify.class)); cards.add(new SetCardInfo("Rafter Demon", 196, Rarity.COMMON, mage.cards.r.RafterDemon.class)); cards.add(new SetCardInfo("Rix Maadi Reveler", 109, Rarity.RARE, mage.cards.r.RixMaadiReveler.class)); From ed461efc797b9e653000a75de2542711f36cb769 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 19 Dec 2018 18:04:15 -0500 Subject: [PATCH 07/10] 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 2bad0f7770..2204d03159 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -34579,6 +34579,8 @@ Impervious Greatwurm|Guilds of Ravnica|273|M|{7}{G}{G}{G}|Creature - Wurm|16|16| 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| 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.| +Aeromunculus|Ravnica Allegiance|152|C|{1}{G}{U}|Creature - Homunculus Mutant|2|3|Flying${2}{G}{U}: Adapt 1.| +Bedevil|Ravnica Allegiance|157|R|{B}{B}{R}|Instant|||Destroy target artifact, creature, or planeswalker.| Growth Spiral|Ravnica Allegiance|178|C|{G}{U}|Instant|||Draw a card. You may put a land card from your hand onto the battlefield.| Imperious Oligarch|Ravnica Allegiance|184|C|{W}{B}|Creature - Human Cleric|2|1|Vigilance$Afterlife 1| 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.| @@ -34586,5 +34588,6 @@ Mortify|Ravnica Allegiance|192|U|{1}{W}{B}|Instant|||Destroy target creature or 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.| 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.| +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.| Gate Colossus|Ravnica Allegiance|232|U|{8}|Artifact Creature - Construct|8|8|This spell costs {1} less to cast for each Gate you control.$Gate Colossus can't be blocked by creatures with power 2 or less.$Whenever a Gate enters the battlefield under your control, you may put Gate Colossus from your graveyard on top of your library.| The Haunt of Hightower|Ravnica Allegiance|273|M|{4}{B}{B}|Legendary Creature - Vampire|3|3|Flying, lifelink$Whenever The Haunt of Hightower attacks, defending player discards a card.$Whenever a card is put into an opponent's graveyard from anywhere, put a +1/+1 counter on The Haunt of Hightower.| \ No newline at end of file From fd25ac8ccbced3101324818faa23a5f7d1571c8f Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 19 Dec 2018 18:19:49 -0500 Subject: [PATCH 08/10] Implemented Aeromunculus --- Mage.Sets/src/mage/cards/a/Aeromunculus.java | 45 +++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + .../effects/keyword/AdaptEffect.java | 48 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/Aeromunculus.java create mode 100644 Mage/src/main/java/mage/abilities/effects/keyword/AdaptEffect.java diff --git a/Mage.Sets/src/mage/cards/a/Aeromunculus.java b/Mage.Sets/src/mage/cards/a/Aeromunculus.java new file mode 100644 index 0000000000..0dca6864e6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/Aeromunculus.java @@ -0,0 +1,45 @@ +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.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Aeromunculus extends CardImpl { + + public Aeromunculus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{U}"); + + this.subtype.add(SubType.HOMUNCULUS); + this.subtype.add(SubType.MUTANT); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {2}{G}{U}: Adapt 1. + this.addAbility(new SimpleActivatedAbility( + new AdaptEffect(1), new ManaCostsImpl("{2}{G}{U}") + )); + } + + public Aeromunculus(final Aeromunculus card) { + super(card); + } + + @Override + public Aeromunculus copy() { + return new Aeromunculus(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 242c82fa44..1eb775a000 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -32,6 +32,7 @@ public final class RavnicaAllegiance extends ExpansionSet { this.ratioBoosterMythic = 8; this.maxCardNumberInBooster = 259; + cards.add(new SetCardInfo("Aeromunculus", 152, Rarity.COMMON, mage.cards.a.Aeromunculus.class)); cards.add(new SetCardInfo("Gate Colossus", 232, Rarity.UNCOMMON, mage.cards.g.GateColossus.class)); cards.add(new SetCardInfo("Growth Spiral", 178, Rarity.COMMON, mage.cards.g.GrowthSpiral.class)); cards.add(new SetCardInfo("Imperious Oligarch", 184, Rarity.COMMON, mage.cards.i.ImperiousOligarch.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/AdaptEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/AdaptEffect.java new file mode 100644 index 0000000000..0bbc9ebbb5 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/keyword/AdaptEffect.java @@ -0,0 +1,48 @@ +package mage.abilities.effects.keyword; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; + +/** + * @author TheElk801 + */ +public class AdaptEffect extends OneShotEffect { + + private final int adaptNumber; + + public AdaptEffect(int adaptNumber) { + super(Outcome.BoostCreature); + this.adaptNumber = adaptNumber; + staticText = "Adapt " + adaptNumber + + " <i>(If this creature has no +1/+1 counters on it, put " + + CardUtil.numberToText(adaptNumber) + " +1/+1 counter" + + (adaptNumber > 1 ? "s" : "") + " on it.)</i>"; + } + + private AdaptEffect(final AdaptEffect effect) { + super(effect); + this.adaptNumber = effect.adaptNumber; + } + + @Override + public AdaptEffect copy() { + return new AdaptEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + return false; + } + if (permanent.getCounters(game).getCount(CounterType.P1P1) == 0) { + permanent.addCounters(CounterType.P1P1.createInstance(adaptNumber), source, game); + } + return true; + } +} From 02406e2c7cf7bec9377de85d878dbe8634af08cd Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 19 Dec 2018 18:22:57 -0500 Subject: [PATCH 09/10] Implemented Bedevil --- Mage.Sets/src/mage/cards/b/Bedevil.java | 45 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 46 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/Bedevil.java diff --git a/Mage.Sets/src/mage/cards/b/Bedevil.java b/Mage.Sets/src/mage/cards/b/Bedevil.java new file mode 100644 index 0000000000..83e9390810 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/Bedevil.java @@ -0,0 +1,45 @@ +package mage.cards.b; + +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Bedevil extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("artifact, creature, or planeswalker"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.CREATURE), + new CardTypePredicate(CardType.PLANESWALKER) + )); + } + + public Bedevil(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}{B}{R}"); + + // Destroy target artifact, creature, or planeswalker. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + } + + public Bedevil(final Bedevil card) { + super(card); + } + + @Override + public Bedevil copy() { + return new Bedevil(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index 1eb775a000..e0f226ae83 100644 --- a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java +++ b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java @@ -33,6 +33,7 @@ public final class RavnicaAllegiance extends ExpansionSet { this.maxCardNumberInBooster = 259; cards.add(new SetCardInfo("Aeromunculus", 152, Rarity.COMMON, mage.cards.a.Aeromunculus.class)); + cards.add(new SetCardInfo("Bedevil", 157, Rarity.RARE, mage.cards.b.Bedevil.class)); cards.add(new SetCardInfo("Gate Colossus", 232, Rarity.UNCOMMON, mage.cards.g.GateColossus.class)); cards.add(new SetCardInfo("Growth Spiral", 178, Rarity.COMMON, mage.cards.g.GrowthSpiral.class)); cards.add(new SetCardInfo("Imperious Oligarch", 184, Rarity.COMMON, mage.cards.i.ImperiousOligarch.class)); From 9c1b4b9f608fb98f0afa98df6e8eb268d6f332b0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 19 Dec 2018 18:33:12 -0500 Subject: [PATCH 10/10] Implemented Zegana, Utopian Speaker --- .../mage/cards/z/ZeganaUtopianSpeaker.java | 81 +++++++++++++++++++ .../src/mage/sets/RavnicaAllegiance.java | 1 + 2 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/z/ZeganaUtopianSpeaker.java diff --git a/Mage.Sets/src/mage/cards/z/ZeganaUtopianSpeaker.java b/Mage.Sets/src/mage/cards/z/ZeganaUtopianSpeaker.java new file mode 100644 index 0000000000..d373a86a37 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZeganaUtopianSpeaker.java @@ -0,0 +1,81 @@ +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.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.CounterPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ZeganaUtopianSpeaker extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent(); + private static final FilterPermanent filter2 = new FilterControlledCreaturePermanent(); + + static { + filter.add(new CounterPredicate(CounterType.P1P1)); + filter.add(new AnotherPredicate()); + filter2.add(new CounterPredicate(CounterType.P1P1)); + } + + public ZeganaUtopianSpeaker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // When Zegana, Utopian Speaker enters the battlefield, if you control another creature with a +1/+1 counter on it, draw a card. + this.addAbility(new ConditionalInterveningIfTriggeredAbility( + new EntersBattlefieldTriggeredAbility( + new DrawCardSourceControllerEffect(1), false + ), new PermanentsOnTheBattlefieldCondition(filter), + "When {this} enters the battlefield, " + + "if you control another creature " + + "with a +1/+1 counter on it, draw a card." + )); + + // {4}{G}{U}: Adapt 4. + this.addAbility(new SimpleActivatedAbility( + new AdaptEffect(4), new ManaCostsImpl("{4}{G}{U}") + )); + + // Each creature you control with a +1/+1 counter on it has trample. + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new GainAbilityAllEffect( + TrampleAbility.getInstance(), Duration.WhileOnBattlefield, + filter2, "Each creature you control with a +1/+1 counter on it has trample" + ) + )); + } + + public ZeganaUtopianSpeaker(final ZeganaUtopianSpeaker card) { + super(card); + } + + @Override + public ZeganaUtopianSpeaker copy() { + return new ZeganaUtopianSpeaker(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaAllegiance.java b/Mage.Sets/src/mage/sets/RavnicaAllegiance.java index e0f226ae83..6a28803835 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("Rafter Demon", 196, Rarity.COMMON, mage.cards.r.RafterDemon.class)); cards.add(new SetCardInfo("Rix Maadi Reveler", 109, Rarity.RARE, mage.cards.r.RixMaadiReveler.class)); cards.add(new SetCardInfo("The Haunt of Hightower", 273, Rarity.MYTHIC, mage.cards.t.TheHauntOfHightower.class)); + cards.add(new SetCardInfo("Zegana, Utopian Speaker", 214, Rarity.RARE, mage.cards.z.ZeganaUtopianSpeaker.class)); } @Override