diff --git a/Mage.Sets/src/mage/cards/d/Demilich.java b/Mage.Sets/src/mage/cards/d/Demilich.java new file mode 100644 index 0000000000..cb64df7b96 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/Demilich.java @@ -0,0 +1,168 @@ +package mage.cards.d; + +import java.util.UUID; + +import mage.ApprovingObject; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.Costs; +import mage.abilities.costs.CostsImpl; +import mage.abilities.costs.common.ExileFromGraveCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.cost.SpellCostReductionForEachSourceEffect; +import mage.abilities.hint.ValueHint; +import mage.cards.Card; +import mage.constants.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; +import mage.watchers.common.SpellsCastWatcher; + +/** + * + * @author weirddan455 + */ +public final class Demilich extends CardImpl { + + public Demilich(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{U}{U}{U}"); + + this.subtype.add(SubType.SKELETON); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // This spell costs {U} less to cast for each instant and sorcery you've cast this turn. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionForEachSourceEffect( + new ManaCostsImpl<>("{U}"), DemilichValue.instance + )).addHint(new ValueHint("Instants and sorceries you've cast this turn", DemilichValue.instance)), new SpellsCastWatcher()); + + // Whenever Demilich attacks, exile up to one target instant or sorcery card from your graveyard. Copy it. You may cast the copy. + Ability ability = new AttacksTriggeredAbility(new DemilichCopyEffect()); + ability.addTarget(new TargetCardInYourGraveyard(0, 1, StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD)); + this.addAbility(ability); + + // You may cast Demilich from your graveyard by exiling four instants and/or sorcery cards from your graveyard in addition to paying its other costs. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new DemilichPlayEffect())); + } + + private Demilich(final Demilich card) { + super(card); + } + + @Override + public Demilich copy() { + return new Demilich(this); + } +} + +enum DemilichValue implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + int spells = 0; + SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); + if (watcher != null) { + for (Spell spell : watcher.getSpellsCastThisTurn(sourceAbility.getControllerId())) { + if (spell.isInstantOrSorcery()) { + spells++; + } + } + } + return spells; + } + + @Override + public DemilichValue copy() { + return instance; + } + + @Override + public String getMessage() { + return "instant and sorcery you've cast this turn"; + } +} + +class DemilichCopyEffect extends OneShotEffect { + + public DemilichCopyEffect() { + super(Outcome.Benefit); + this.staticText = "exile up to one target instant or sorcery card from your graveyard. Copy it. You may cast the copy"; + } + + private DemilichCopyEffect(final DemilichCopyEffect effect) { + super(effect); + } + + @Override + public DemilichCopyEffect copy() { + return new DemilichCopyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Card card = game.getCard(targetPointer.getFirst(game, source)); + if (controller == null || card == null) { + return false; + } + controller.moveCards(card, Zone.EXILED, source, game); + if (controller.chooseUse(outcome, "Cast copy of " + card.getName() + '?', source, game)) { + Card copiedCard = game.copyCard(card, source, controller.getId()); + game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE); + controller.cast(controller.chooseAbilityForCast(copiedCard, game, false), + game, false, new ApprovingObject(source, game)); + game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null); + } + return true; + } +} + +class DemilichPlayEffect extends AsThoughEffectImpl { + + public DemilichPlayEffect() { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit); + this.staticText = "You may cast {this} from your graveyard by exiling four instants and/or sorcery cards from your graveyard in addition to paying its other costs"; + } + + private DemilichPlayEffect(final DemilichPlayEffect effect) { + super(effect); + } + + @Override + public DemilichPlayEffect copy() { + return new DemilichPlayEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (source.getSourceId().equals(objectId) && source.isControlledBy(affectedControllerId) + && game.getState().getZone(objectId) == Zone.GRAVEYARD) { + Player controller = game.getPlayer(affectedControllerId); + if (controller != null) { + Costs costs = new CostsImpl<>(); + costs.add(new ExileFromGraveCost(new TargetCardInYourGraveyard(4, StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD))); + controller.setCastSourceIdWithAlternateMana(objectId, new ManaCostsImpl<>("{U}{U}{U}{U}"), costs); + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java b/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java index cb71589931..27697d31a0 100644 --- a/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java +++ b/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java @@ -67,6 +67,7 @@ public final class AdventuresInTheForgottenRealms extends ExpansionSet { cards.add(new SetCardInfo("Death-Priest of Myrkul", 95, Rarity.UNCOMMON, mage.cards.d.DeathPriestOfMyrkul.class)); cards.add(new SetCardInfo("Delina, Wild Mage", 138, Rarity.RARE, mage.cards.d.DelinaWildMage.class)); cards.add(new SetCardInfo("Delver's Torch", 10, Rarity.COMMON, mage.cards.d.DelversTorch.class)); + cards.add(new SetCardInfo("Demilich", 53, Rarity.MYTHIC, mage.cards.d.Demilich.class)); cards.add(new SetCardInfo("Demogorgon's Clutches", 96, Rarity.UNCOMMON, mage.cards.d.DemogorgonsClutches.class)); cards.add(new SetCardInfo("Den of the Bugbear", 254, Rarity.RARE, mage.cards.d.DenOfTheBugbear.class)); cards.add(new SetCardInfo("Devoted Paladin", 11, Rarity.COMMON, mage.cards.d.DevotedPaladin.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionForEachSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionForEachSourceEffect.java index 5b998cbd3b..5025777ff6 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionForEachSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionForEachSourceEffect.java @@ -62,7 +62,7 @@ public class SpellCostReductionForEachSourceEffect extends CostModificationEffec if (reduceManaCosts != null) { // color reduce ManaCosts needReduceMana = new ManaCostsImpl<>(); - for (int i = 0; i <= needReduceAmount; i++) { + for (int i = 0; i < needReduceAmount; i++) { needReduceMana.add(reduceManaCosts.copy()); } CardUtil.adjustCost((SpellAbility) abilityToModify, needReduceMana, false);