[C21] Implemented Elementalist's Palette

This commit is contained in:
Evan Kranzler 2021-04-20 08:47:41 -04:00
parent 6c6311ac71
commit ad5d1e498f
4 changed files with 170 additions and 9 deletions

View file

@ -0,0 +1,161 @@
package mage.cards.e;
import mage.ConditionalMana;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.mana.AnyColorManaAbility;
import mage.abilities.mana.SimpleManaAbility;
import mage.abilities.mana.builder.ConditionalManaBuilder;
import mage.abilities.mana.conditional.ManaCondition;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.VariableManaCostPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ElementalistsPalette extends CardImpl {
private static final FilterSpell filter = new FilterSpell("a spell with {X} in its mana cost");
static {
filter.add(VariableManaCostPredicate.instance);
}
public ElementalistsPalette(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// Whenever you cast a spell with {X} in its mana cost, put two charge counters on Elementalist's Palette.
this.addAbility(new SpellCastControllerTriggeredAbility(
new AddCountersSourceEffect(CounterType.CHARGE.createInstance(2)), filter, false
));
// {T}: Add one mana of any color.
this.addAbility(new AnyColorManaAbility());
// {T}: Add {C} for each charge counter on Elementalist's Palette. Spend this mana only on costs that contain {X}.
this.addAbility(new SimpleManaAbility(
Zone.BATTLEFIELD, new ElementalistsPaletteManaEffect(), new TapSourceCost()
));
}
private ElementalistsPalette(final ElementalistsPalette card) {
super(card);
}
@Override
public ElementalistsPalette copy() {
return new ElementalistsPalette(this);
}
}
class ElementalistsPaletteManaEffect extends ManaEffect {
private final ConditionalManaBuilder manaBuilder = new ElementalistsPaletteManaBuilder();
ElementalistsPaletteManaEffect() {
this.staticText = "add {C} for each charge counter on {this}. Spend this mana only on costs that contain {X}";
}
private ElementalistsPaletteManaEffect(final ElementalistsPaletteManaEffect effect) {
super(effect);
}
@Override
public ElementalistsPaletteManaEffect copy() {
return new ElementalistsPaletteManaEffect(this);
}
@Override
public List<Mana> getNetMana(Game game, Ability source) {
List<Mana> netMana = new ArrayList<>();
if (game == null) {
return netMana;
}
Permanent permanent = source.getSourcePermanentOrLKI(game);
if (permanent != null) {
netMana.add(manaBuilder.setMana(Mana.ColorlessMana(
permanent.getCounters(game).getCount(CounterType.CHARGE)
), source, game).build());
}
return netMana;
}
@Override
public Mana produceMana(Game game, Ability source) {
Mana mana = new Mana();
if (game == null) {
return mana;
}
Permanent permanent = source.getSourcePermanentOrLKI(game);
if (permanent == null) {
return mana;
}
return manaBuilder.setMana(Mana.ColorlessMana(
permanent.getCounters(game).getCount(CounterType.CHARGE)
), source, game).build();
}
}
class ElementalistsPaletteConditionalMana extends ConditionalMana {
ElementalistsPaletteConditionalMana(Mana mana) {
super(mana);
addCondition(new ElementalistsPaletteManaCondition());
}
}
class ElementalistsPaletteManaBuilder extends ConditionalManaBuilder {
@Override
public ConditionalMana build(Object... options) {
return new ElementalistsPaletteConditionalMana(this.mana);
}
@Override
public String getRule() {
return "Spend this mana only on costs that contain {X}";
}
}
class ElementalistsPaletteManaCondition extends ManaCondition {
/*
A cost that contains {X} may be a spells total cost, an activated abilitys cost, a suspend cost, or a cost youre
asked to pay as part of the resolution of a spell or ability (such as Condescend). A spells total cost includes either
its mana cost (printed in the upper right corner) or its alternative cost (such as flashback), as well as any additional
costs (such as kicker). If its something you can spend mana on, its a cost. If that cost includes the {X} symbol in it,
you can spend mana generated by Rosheen on that cost. (2017-11-17)
*/
@Override
public boolean apply(Game game, Ability source, UUID originalId, Cost costToPay) {
boolean result;
if (costToPay instanceof ManaCosts) {
result = !((ManaCosts) costToPay).getVariableCosts().isEmpty();
} else {
result = costToPay instanceof VariableManaCost;
}
if (!result) {
if (game != null && game.inCheckPlayableState()) {
return true; // TODO: Check the card if there are related abilities with {X} costs.
}
}
return result;
}
}

View file

@ -1,7 +1,6 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -15,16 +14,17 @@ import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterSpell;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.VariableManaCostPredicate;
import mage.target.TargetSpell;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class FrontlineMedic extends CardImpl {
@ -32,11 +32,11 @@ public final class FrontlineMedic extends CardImpl {
private static final FilterSpell filter = new FilterSpell("spell with {X} in its mana cost");
static {
filter.add(new VariableManaCostPredicate());
filter.add(VariableManaCostPredicate.instance);
}
public FrontlineMedic(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CLERIC);

View file

@ -106,6 +106,7 @@ public final class Commander2021Edition extends ExpansionSet {
cards.add(new SetCardInfo("Dualcaster Mage", 165, Rarity.RARE, mage.cards.d.DualcasterMage.class));
cards.add(new SetCardInfo("Duelist's Heritage", 90, Rarity.RARE, mage.cards.d.DuelistsHeritage.class));
cards.add(new SetCardInfo("Duplicant", 242, Rarity.RARE, mage.cards.d.Duplicant.class));
cards.add(new SetCardInfo("Elementalist's Palette", 76, Rarity.RARE, mage.cards.e.ElementalistsPalette.class));
cards.add(new SetCardInfo("Elite Scaleguard", 91, Rarity.UNCOMMON, mage.cards.e.EliteScaleguard.class));
cards.add(new SetCardInfo("Elixir of Immortality", 243, Rarity.UNCOMMON, mage.cards.e.ElixirOfImmortality.class));
cards.add(new SetCardInfo("Epic Experiment", 216, Rarity.MYTHIC, mage.cards.e.EpicExperiment.class));

View file

@ -1,4 +1,3 @@
package mage.filter.predicate.mageobject;
import mage.MageObject;
@ -11,12 +10,12 @@ import mage.game.Game;
*
* @author LevelX2
*/
public class VariableManaCostPredicate implements Predicate<MageObject> {
public enum VariableManaCostPredicate implements Predicate<MageObject> {
instance;
@Override
public boolean apply(MageObject input, Game game) {
return input.getManaCost().stream().anyMatch(manaCost -> manaCost instanceof VariableManaCost);
return input.getManaCost().stream().anyMatch(VariableManaCost.class::isInstance);
}
@Override