mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 19:41:59 -08:00
[LCC] Implement Ore-Rich Stalactite (#11687)
* [LCC] Implement Ore-Rich Stalactite * Address PR comments --------- Co-authored-by: Matthew Wilson <matthew_w@vaadin.com>
This commit is contained in:
parent
063f91ed4b
commit
7628c6618f
4 changed files with 184 additions and 0 deletions
98
Mage.Sets/src/mage/cards/c/CosmiumCatalyst.java
Normal file
98
Mage.Sets/src/mage/cards/c/CosmiumCatalyst.java
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
49
Mage.Sets/src/mage/cards/o/OreRichStalactite.java
Normal file
49
Mage.Sets/src/mage/cards/o/OreRichStalactite.java
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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("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("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("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("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("Cruel Celebrant", 267, Rarity.UNCOMMON, mage.cards.c.CruelCelebrant.class));
|
||||||
cards.add(new SetCardInfo("Crumbling Necropolis", 326, Rarity.UNCOMMON, mage.cards.c.CrumblingNecropolis.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("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("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("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("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 Basilica", 345, Rarity.COMMON, mage.cards.o.OrzhovBasilica.class));
|
||||||
cards.add(new SetCardInfo("Orzhov Signet", 310, Rarity.UNCOMMON, mage.cards.o.OrzhovSignet.class));
|
cards.add(new SetCardInfo("Orzhov Signet", 310, Rarity.UNCOMMON, mage.cards.o.OrzhovSignet.class));
|
||||||
|
|
|
||||||
|
|
@ -240,4 +240,39 @@ public class CraftTest extends CardTestPlayerBase {
|
||||||
setStopAt(1, PhaseStep.END_TURN);
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
execute();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue