diff --git a/Mage.Sets/src/mage/cards/c/CosmiumCatalyst.java b/Mage.Sets/src/mage/cards/c/CosmiumCatalyst.java new file mode 100644 index 00000000000..addd304c3f2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CosmiumCatalyst.java @@ -0,0 +1,98 @@ +package mage.cards.c; + +import java.util.UUID; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCardInExile; +import mage.util.CardUtil; + +/** + * Cosmium Catalyst + * Artifact + * {1}{R}, {T}: Choose an exiled card used to craft Cosmium Catalyst at random. You may cast that card without paying its mana cost. + * + * @author DominionSpy + */ +public class CosmiumCatalyst extends CardImpl { + + public CosmiumCatalyst(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); + + this.nightCard = true; + this.color.setRed(true); + + // {1}{R}, {T}: Choose an exiled card used to craft Cosmium Catalyst at random. You may cast that card without paying its mana cost. + Ability ability = new SimpleActivatedAbility(new CosmiumCatalystEffect(), new ManaCostsImpl<>("{1}{R}")); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + private CosmiumCatalyst(CosmiumCatalyst card) { + super(card); + } + + @Override + public CosmiumCatalyst copy() { + return new CosmiumCatalyst(this); + } +} + +class CosmiumCatalystEffect extends OneShotEffect { + + CosmiumCatalystEffect() { + super(Outcome.PlayForFree); + this.staticText = "Choose an exiled card used to craft {this} at random." + + " You may cast that card without paying its mana cost."; + } + + private CosmiumCatalystEffect(CosmiumCatalystEffect effect) { + super(effect); + } + + @Override + public CosmiumCatalystEffect copy() { + return new CosmiumCatalystEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject == null) { + return false; + } + + Target target = new TargetCardInExile(StaticFilters.FILTER_CARD, + CardUtil.getExileZoneId(game, source.getSourceId(), + game.getState().getZoneChangeCounter(source.getSourceId()) - 2 + )); + target.withNotTarget(true); + target.setRandom(true); + if (!target.canChoose(controller.getId(), source, game)) { + return true; + } + controller.chooseTarget(outcome, target, source, game); + Card chosenCard = game.getCard(target.getFirstTarget()); + if (chosenCard != null) { + CardUtil.castSpellWithAttributesForFree(controller, source, game, chosenCard); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/o/OreRichStalactite.java b/Mage.Sets/src/mage/cards/o/OreRichStalactite.java new file mode 100644 index 00000000000..e0b5ea18204 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OreRichStalactite.java @@ -0,0 +1,49 @@ +package mage.cards.o; + +import java.util.UUID; + +import mage.Mana; +import mage.ObjectColor; +import mage.abilities.keyword.CraftAbility; +import mage.abilities.mana.ConditionalColoredManaAbility; +import mage.abilities.mana.builder.common.InstantOrSorcerySpellManaBuilder; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.c.CosmiumCatalyst; +import mage.constants.CardType; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * Ore-Rich Stalactite {1}{R} + * Artifact + * {T}: Add {R}. Spend this mana only to cast an instant or sorcery spell. + * Craft with four or more red instant and/or sorcery cards {3}{R}{R}. + * + * @author DominionSpy + */ +public class OreRichStalactite extends CardImpl { + + public OreRichStalactite(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{R}"); + this.secondSideCardClazz = CosmiumCatalyst.class; + + // {T}: Add {R}. Spend this mana only to cast an instant or sorcery spell. + this.addAbility(new ConditionalColoredManaAbility(Mana.RedMana(1), new InstantOrSorcerySpellManaBuilder())); + + // Craft with four or more red instant and/or sorcery cards {3}{R}{R} + this.addAbility(new CraftAbility("{3}{R}{R}", "four or more red instant and/or sorcery cards", + "red instant and/or sorcery cards in your graveyard", 4, Integer.MAX_VALUE, + new ColorPredicate(ObjectColor.RED), + Predicates.or(CardType.INSTANT.getPredicate(), CardType.SORCERY.getPredicate()))); + } + + private OreRichStalactite(final OreRichStalactite card) { + super(card); + } + + @Override + public OreRichStalactite copy() { + return new OreRichStalactite(this); + } +} diff --git a/Mage.Sets/src/mage/sets/LostCavernsOfIxalanCommander.java b/Mage.Sets/src/mage/sets/LostCavernsOfIxalanCommander.java index 6de32129459..2564b6dd520 100644 --- a/Mage.Sets/src/mage/sets/LostCavernsOfIxalanCommander.java +++ b/Mage.Sets/src/mage/sets/LostCavernsOfIxalanCommander.java @@ -83,6 +83,7 @@ public final class LostCavernsOfIxalanCommander extends ExpansionSet { cards.add(new SetCardInfo("Coralhelm Commander", 148, Rarity.RARE, mage.cards.c.CoralhelmCommander.class)); cards.add(new SetCardInfo("Cordial Vampire", 189, Rarity.RARE, mage.cards.c.CordialVampire.class)); cards.add(new SetCardInfo("Corsair Captain", 149, Rarity.RARE, mage.cards.c.CorsairCaptain.class)); + cards.add(new SetCardInfo("Cosmium Catalyst", 11, Rarity.RARE, mage.cards.c.CosmiumCatalyst.class)); cards.add(new SetCardInfo("Crossway Troublemakers", 190, Rarity.RARE, mage.cards.c.CrosswayTroublemakers.class)); cards.add(new SetCardInfo("Cruel Celebrant", 267, Rarity.UNCOMMON, mage.cards.c.CruelCelebrant.class)); cards.add(new SetCardInfo("Crumbling Necropolis", 326, Rarity.UNCOMMON, mage.cards.c.CrumblingNecropolis.class)); @@ -194,6 +195,7 @@ public final class LostCavernsOfIxalanCommander extends ExpansionSet { cards.add(new SetCardInfo("Nighthawk Scavenger", 203, Rarity.RARE, mage.cards.n.NighthawkScavenger.class)); cards.add(new SetCardInfo("Oathsworn Vampire", 204, Rarity.UNCOMMON, mage.cards.o.OathswornVampire.class)); cards.add(new SetCardInfo("Olivia's Wrath", 205, Rarity.RARE, mage.cards.o.OliviasWrath.class)); + cards.add(new SetCardInfo("Ore-Rich Stalactite", 11, Rarity.RARE, mage.cards.o.OreRichStalactite.class)); cards.add(new SetCardInfo("Order of Sacred Dusk", 97, Rarity.RARE, mage.cards.o.OrderOfSacredDusk.class)); cards.add(new SetCardInfo("Orzhov Basilica", 345, Rarity.COMMON, mage.cards.o.OrzhovBasilica.class)); cards.add(new SetCardInfo("Orzhov Signet", 310, Rarity.UNCOMMON, mage.cards.o.OrzhovSignet.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CraftTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CraftTest.java index 2e15dde9663..9dd11767c96 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CraftTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CraftTest.java @@ -240,4 +240,39 @@ public class CraftTest extends CardTestPlayerBase { setStopAt(1, PhaseStep.END_TURN); execute(); } + + /** + * Ore-Rich Stalactite {1}{R} + * Artifact + * {T}: Add {R}. Spend this mana only to cast an instant or sorcery spell. + * Craft with four or more red instant and/or sorcery cards {3}{R}{R}. + */ + @Test + public void test_OreRichStalactite() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1 + 5); + addCard(Zone.BATTLEFIELD, playerA, "Ore-Rich Stalactite"); + addCard(Zone.GRAVEYARD, playerA, "Ancestral Recall"); + addCard(Zone.GRAVEYARD, playerA, "Arc Lightning"); + addCard(Zone.GRAVEYARD, playerA, "Lightning Helix"); + addCard(Zone.GRAVEYARD, playerA, "Lightning Strike"); + addCard(Zone.HAND, playerA, "Lightning Bolt"); + + // Test that craft cannot be activated yet + checkPlayableAbility("craft not available", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Craft", false); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); + waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN, 1); + + // Test that craft can now be activated + checkPlayableAbility("craft available", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Craft", true); + + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Craft"); + addTarget(playerA, "Lightning Bolt^Lightning Helix^Lightning Strike^Arc Lightning"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Cosmium Catalyst", 1); + } }