diff --git a/Mage.Sets/src/mage/cards/p/ProfaneProcession.java b/Mage.Sets/src/mage/cards/p/ProfaneProcession.java new file mode 100644 index 0000000000..be2b250fcf --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/ProfaneProcession.java @@ -0,0 +1,115 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.t.TombOfTheDuskRose; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.game.ExileZone; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class ProfaneProcession extends CardImpl { + + public ProfaneProcession(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{B}"); + + this.addSuperType(SuperType.LEGENDARY); + + this.transformable = true; + this.secondSideCardClazz = TombOfTheDuskRose.class; + + // {3}{W}{B}: Exile target creature. Then if there are three or more cards exiled with Profane Procession, transform it. + this.addAbility(new TransformAbility()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ProfaneProcessionEffect(), new ManaCostsImpl<>("{3}{W}{B}")); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public ProfaneProcession(final ProfaneProcession card) { + super(card); + } + + @Override + public ProfaneProcession copy() { + return new ProfaneProcession(this); + } +} + +class ProfaneProcessionEffect extends OneShotEffect { + + public ProfaneProcessionEffect() { + super(Outcome.Exile); + this.staticText = "Exile target creature. Then if there are three or more cards exiled with {this}, transform it."; + } + + public ProfaneProcessionEffect(final ProfaneProcessionEffect effect) { + super(effect); + } + + @Override + public ProfaneProcessionEffect copy() { + return new ProfaneProcessionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + UUID exileId = CardUtil.getCardExileZoneId(game, source); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && exileId != null && sourceObject != null) { + new ExileTargetEffect(exileId, sourceObject.getIdName()).setTargetPointer(targetPointer).apply(game, source); + game.applyEffects(); + ExileZone exileZone = game.getExile().getExileZone(exileId); + if (exileZone.size() > 2) { + new TransformSourceEffect(true).apply(game, source); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TombOfTheDuskRose.java b/Mage.Sets/src/mage/cards/t/TombOfTheDuskRose.java new file mode 100644 index 0000000000..ea4ca583c8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TombOfTheDuskRose.java @@ -0,0 +1,125 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.ExileZone; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class TombOfTheDuskRose extends CardImpl { + + public TombOfTheDuskRose(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.addSuperType(SuperType.LEGENDARY); + + this.nightCard = true; + + // (Transforms from Profane Procession.) + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new InfoEffect("(Transforms from Profane Procession.)")).setRuleAtTheTop(true)); + + // {T}: Add one mana of any color to your mana pool. + this.addAbility(new AnyColorManaAbility()); + + // {2}{W}{B},{T} : Put a creature card exiled with this permanent onto the battlefield under your control. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TombOfTheDuskRoseEffect(), new ManaCostsImpl<>("{2}{W}{B}")); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + public TombOfTheDuskRose(final TombOfTheDuskRose card) { + super(card); + } + + @Override + public TombOfTheDuskRose copy() { + return new TombOfTheDuskRose(this); + } +} + +class TombOfTheDuskRoseEffect extends OneShotEffect { + + public TombOfTheDuskRoseEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "Put a creature card exiled with this permanent onto the battlefield under your control"; + } + + public TombOfTheDuskRoseEffect(final TombOfTheDuskRoseEffect effect) { + super(effect); + } + + @Override + public TombOfTheDuskRoseEffect copy() { + return new TombOfTheDuskRoseEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + UUID exileId = CardUtil.getCardExileZoneId(game, source); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && exileId != null && sourceObject != null) { + ExileZone exileZone = game.getExile().getExileZone(exileId); + if (exileZone != null) { + TargetCard targetCard = new TargetCard(Zone.EXILED, StaticFilters.FILTER_CARD_CREATURE); + controller.chooseTarget(outcome, exileZone, targetCard, source, game); + Card card = game.getCard(targetCard.getFirstTarget()); + if (card != null) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TwilightProphet.java b/Mage.Sets/src/mage/cards/t/TwilightProphet.java new file mode 100644 index 0000000000..18096b66ed --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TwilightProphet.java @@ -0,0 +1,129 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.condition.common.CitysBlessingCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.abilities.keyword.AscendAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class TwilightProphet extends CardImpl { + + public TwilightProphet(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Ascend + this.addAbility(new AscendAbility()); + + // At the beginning of your upkeep, if you have the city's blessing, reveal the top card of your library and put it into your hand. + // Each opponent loses X life and you gain X life, where X is that card's converted mana cost. + this.addAbility(new ConditionalTriggeredAbility(new BeginningOfUpkeepTriggeredAbility( + new TwilightProphetEffect(), TargetController.YOU, false), CitysBlessingCondition.instance, + "At the beginning of your upkeep, if you have the city's blessing, reveal the top card of your library and put it into your hand." + + "Each opponent loses X life and you gain X life, where X is that card's converted mana cost.")); + + } + + public TwilightProphet(final TwilightProphet card) { + super(card); + } + + @Override + public TwilightProphet copy() { + return new TwilightProphet(this); + } +} + +class TwilightProphetEffect extends OneShotEffect { + + public TwilightProphetEffect() { + super(Outcome.Benefit); + this.staticText = "if you have the city's blessing, reveal the top card of your library and put it into your hand. " + + "Each opponent loses X life and you gain X life, where X is that card's converted mana cost."; + } + + public TwilightProphetEffect(final TwilightProphetEffect effect) { + super(effect); + } + + @Override + public TwilightProphetEffect copy() { + return new TwilightProphetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + controller.revealCards(sourceObject.getIdName(), new CardsImpl(card), game); + controller.moveCards(card, Zone.HAND, source, game); + game.applyEffects(); + int amount = card.getConvertedManaCost(); + if (amount > 0) { + new LoseLifeOpponentsEffect(amount).apply(game, source); + controller.gainLife(amount, game); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java index dcb40eecd9..708323a5fd 100644 --- a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java @@ -102,6 +102,7 @@ public class RivalsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Ghalta, Primal Hunger", 130, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class)); cards.add(new SetCardInfo("Giltgrove Stalker", 131, Rarity.COMMON, mage.cards.g.GiltgroveStalker.class)); cards.add(new SetCardInfo("Goblin Trailblazer", 105, Rarity.COMMON, mage.cards.g.GoblinTrailblazer.class)); + cards.add(new SetCardInfo("Profane Procession", 166, Rarity.RARE, mage.cards.p.ProfaneProcession.class)); cards.add(new SetCardInfo("Radiant Destiny", 18, Rarity.RARE, mage.cards.r.RadiantDestiny.class)); cards.add(new SetCardInfo("Hardy Veteran", 132, Rarity.COMMON, mage.cards.h.HardyVeteran.class)); cards.add(new SetCardInfo("Hadana's Climb", 158, Rarity.RARE, mage.cards.h.HadanasClimb.class)); @@ -144,6 +145,7 @@ public class RivalsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Plains", 192, Rarity.COMMON, mage.cards.basiclands.Plains.class)); cards.add(new SetCardInfo("Plummet", 143, Rarity.COMMON, mage.cards.p.Plummet.class)); cards.add(new SetCardInfo("Polyraptor", 144, Rarity.MYTHIC, mage.cards.p.Polyraptor.class)); + cards.add(new SetCardInfo("Profane Procession", 166, Rarity.RARE, mage.cards.p.ProfaneProcession.class)); cards.add(new SetCardInfo("Raging Regisaur", 168, Rarity.UNCOMMON, mage.cards.r.RagingRegisaur.class)); cards.add(new SetCardInfo("Raptor Companion", 19, Rarity.COMMON, mage.cards.r.RaptorCompanion.class)); cards.add(new SetCardInfo("Ravenous Chupacabra", 82, Rarity.COMMON, mage.cards.r.RavenousChupacabra.class)); @@ -174,8 +176,10 @@ public class RivalsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("The Immortal Sun", 180, Rarity.MYTHIC, mage.cards.t.TheImmortalSun.class)); cards.add(new SetCardInfo("Thrashing Brontodon", 148, Rarity.UNCOMMON, mage.cards.t.ThrashingBrontodon.class)); cards.add(new SetCardInfo("Thunderherd Migration", 149, Rarity.UNCOMMON, mage.cards.t.ThunderherdMigration.class)); + cards.add(new SetCardInfo("Tomb of the Dusk Rose", 166, Rarity.RARE, mage.cards.t.TombOfTheDuskRose.class)); cards.add(new SetCardInfo("Traveler's Amulet", 184, Rarity.COMMON, mage.cards.t.TravelersAmulet.class)); cards.add(new SetCardInfo("Trapjaw Tyrant", 29, Rarity.MYTHIC, mage.cards.t.TrapjawTyrant.class)); + cards.add(new SetCardInfo("Twilight Prophet", 88, Rarity.MYTHIC, mage.cards.t.TwilightProphet.class)); cards.add(new SetCardInfo("Vampire Champion", 198, Rarity.COMMON, mage.cards.v.VampireChampion.class)); cards.add(new SetCardInfo("Vampire Revenant", 89, Rarity.COMMON, mage.cards.v.VampireRevenant.class)); cards.add(new SetCardInfo("Vault of Catlacan", 173, Rarity.RARE, mage.cards.v.VaultOfCatlacan.class)); diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index bd11aa94fe..6b6823ce81 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -31,6 +31,7 @@ public final class StaticFilters { public static final FilterArtifactCard FILTER_CARD_ARTIFACT = new FilterArtifactCard(); public static final FilterCard FILTER_CARD_ARTIFACT_OR_CREATURE = new FilterCard("artifact or creature card"); + public static final FilterCreatureCard FILTER_CARD_CREATURE = new FilterCreatureCard(); public static final FilterCreatureCard FILTER_CARD_CREATURE_YOUR_GRAVEYARD = new FilterCreatureCard("creature card from your graveyard"); public static final FilterCard FILTER_CARD_LAND = new FilterLandCard(); public static final FilterNonlandCard FILTER_CARD_NON_LAND = new FilterNonlandCard();