diff --git a/Mage.Sets/src/mage/cards/m/MarchOfOtherworldlyLight.java b/Mage.Sets/src/mage/cards/m/MarchOfOtherworldlyLight.java new file mode 100644 index 00000000000..a9f50580546 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MarchOfOtherworldlyLight.java @@ -0,0 +1,74 @@ +package mage.cards.m; + +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.effects.CostsLessForExiledCardsEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.ManaValuePredicate; +import mage.game.Game; +import mage.target.TargetPermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MarchOfOtherworldlyLight extends CardImpl { + + private static final FilterCard filter = new FilterCard("white cards from your hand"); + + static { + filter.add(new ColorPredicate(ObjectColor.WHITE)); + } + + public MarchOfOtherworldlyLight(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{W}"); + + // As an additional cost to cast this spell, you may exile any number of white cards from your hand. This spell costs {2} less to cast for each card exiled this way. + CostsLessForExiledCardsEffect.addCostAndEffect(this, filter); + + // Exile target artifact, creature, or enchantment with mana value X or less. + this.getSpellAbility().addEffect(new ExileTargetEffect( + "exile target artifact, creature, or enchantment with mana value X or less" + )); + this.getSpellAbility().setTargetAdjuster(MarchOfOtherworldlyLightAdjuster.instance); + } + + private MarchOfOtherworldlyLight(final MarchOfOtherworldlyLight card) { + super(card); + } + + @Override + public MarchOfOtherworldlyLight copy() { + return new MarchOfOtherworldlyLight(this); + } +} + +enum MarchOfOtherworldlyLightAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + int xValue = ability.getManaCostsToPay().getX(); + FilterPermanent filter = new FilterPermanent( + "artifact, creature, or enchantment with mana value " + xValue + " or less" + ); + filter.add(Predicates.or( + CardType.ARTIFACT.getPredicate(), + CardType.CREATURE.getPredicate(), + CardType.ENCHANTMENT.getPredicate() + )); + filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, xValue + 1)); + ability.getTargets().clear(); + ability.addTarget(new TargetPermanent(filter)); + } +} diff --git a/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java b/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java index 8f1e40e93c5..5c01ee0b9b3 100644 --- a/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java +++ b/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java @@ -162,6 +162,7 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Lizard Blades", 153, Rarity.RARE, mage.cards.l.LizardBlades.class)); cards.add(new SetCardInfo("Lucky Offering", 27, Rarity.COMMON, mage.cards.l.LuckyOffering.class)); cards.add(new SetCardInfo("Malicious Malfunction", 110, Rarity.UNCOMMON, mage.cards.m.MaliciousMalfunction.class)); + cards.add(new SetCardInfo("March of Otherworldly Light", 28, Rarity.RARE, mage.cards.m.MarchOfOtherworldlyLight.class)); cards.add(new SetCardInfo("Master's Rebuke", 202, Rarity.COMMON, mage.cards.m.MastersRebuke.class)); cards.add(new SetCardInfo("Mech Hangar", 270, Rarity.UNCOMMON, mage.cards.m.MechHangar.class)); cards.add(new SetCardInfo("Memory of Toshiro", 108, Rarity.UNCOMMON, mage.cards.m.MemoryOfToshiro.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/CostsLessForExiledCardsEffect.java b/Mage/src/main/java/mage/abilities/effects/CostsLessForExiledCardsEffect.java new file mode 100644 index 00000000000..45ccbe31d6d --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/CostsLessForExiledCardsEffect.java @@ -0,0 +1,76 @@ +package mage.abilities.effects; + +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.ExileFromHandCost; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.cards.Card; +import mage.constants.CostModificationType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.target.common.TargetCardInHand; +import mage.util.CardUtil; + +/** + * @author TheElk801 + */ +public class CostsLessForExiledCardsEffect extends CostModificationEffectImpl { + + private final FilterCard filter; + + private CostsLessForExiledCardsEffect(FilterCard filter) { + super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST); + this.filter = filter; + } + + private CostsLessForExiledCardsEffect(final CostsLessForExiledCardsEffect effect) { + super(effect); + this.filter = effect.filter; + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + SpellAbility spellAbility = (SpellAbility) abilityToModify; + for (Cost cost : spellAbility.getCosts()) { + if (!(cost instanceof ExileFromHandCost)) { + continue; + } + ExileFromHandCost eCost = (ExileFromHandCost) cost; + int reduction; + if (game.inCheckPlayableState()) { + reduction = game.getPlayer(spellAbility.getControllerId()).getHand().count(filter, game); + } else { + reduction = eCost.getCards().size(); + } + CardUtil.adjustCost(spellAbility, reduction * 2); + break; + } + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + return abilityToModify instanceof SpellAbility + && abilityToModify.getSourceId().equals(source.getSourceId()); + } + + @Override + public CostsLessForExiledCardsEffect copy() { + return new CostsLessForExiledCardsEffect(this); + } + + public static void addCostAndEffect(Card card, FilterCard filter) { + card.getSpellAbility().addCost(new ExileFromHandCost( + new TargetCardInHand(0, Integer.MAX_VALUE, filter) + ).setText("as an additional cost to cast this spell, you may exile any number of " + + filter.getMessage() + ". This spell costs {2} less to cast for each card exiled this way")); + Ability ability = new SimpleStaticAbility(Zone.ALL, new CostsLessForExiledCardsEffect(filter)); + ability.setRuleVisible(false); + card.addAbility(ability); + } +}