From 042aa61ad4dfb71a3ec20b74eed7ce6b23bdd22e Mon Sep 17 00:00:00 2001 From: htrajan Date: Fri, 16 Apr 2021 19:16:02 -0700 Subject: [PATCH] [STX] Implement Efreet Flamepainter (#7747) * [STX] Implement Efreet Flamepainter * Add null check * Target needs to be chosen before ability resolution --- .../src/mage/cards/e/EfreetFlamepainter.java | 88 +++++++++++++++++++ Mage.Sets/src/mage/cards/s/SinsOfThePast.java | 46 +--------- .../mage/sets/StrixhavenSchoolOfMages.java | 1 + ...ardEnteringGraveyardReplacementEffect.java | 50 +++++++++++ 4 files changed, 142 insertions(+), 43 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/e/EfreetFlamepainter.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/ExileCardEnteringGraveyardReplacementEffect.java diff --git a/Mage.Sets/src/mage/cards/e/EfreetFlamepainter.java b/Mage.Sets/src/mage/cards/e/EfreetFlamepainter.java new file mode 100644 index 0000000000..b99ecf1142 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EfreetFlamepainter.java @@ -0,0 +1,88 @@ +package mage.cards.e; + +import mage.ApprovingObject; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileCardEnteringGraveyardReplacementEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * + * @author htrajan + */ +public final class EfreetFlamepainter extends CardImpl { + + public EfreetFlamepainter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.EFREET); + this.subtype.add(SubType.SHAMAN); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // Double strike + this.addAbility(DoubleStrikeAbility.getInstance()); + + // Whenever Efreet Flamepainter deals combat damage to a player, you may cast target instant or sorcery card from your graveyard without paying its mana cost. If that spell would be put into your graveyard, exile it instead. + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new EfreetFlamepainterEffect(), false); + ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY)); + this.addAbility(ability); + } + + private EfreetFlamepainter(final EfreetFlamepainter card) { + super(card); + } + + @Override + public EfreetFlamepainter copy() { + return new EfreetFlamepainter(this); + } +} + +class EfreetFlamepainterEffect extends OneShotEffect { + + EfreetFlamepainterEffect() { + super(Outcome.PlayForFree); + staticText = "you may cast target instant or sorcery card from your graveyard without paying its mana cost. If that spell would be put into your graveyard, exile it instead"; + } + + EfreetFlamepainterEffect(EfreetFlamepainterEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + UUID targetId = source.getFirstTarget(); + if (targetId != null) { + Card card = game.getCard(targetId); + if (card != null && controller.chooseUse(outcome, "Cast " + card.getName() + " without paying its mana cost?", source, game)) { + game.addEffect(new ExileCardEnteringGraveyardReplacementEffect(card.getId()), source); + game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE); + controller.cast(controller.chooseAbilityForCast(card, game, true), + game, true, new ApprovingObject(source, game)); + game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null); + } + } + return true; + } + + @Override + public EfreetFlamepainterEffect copy() { + return new EfreetFlamepainterEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SinsOfThePast.java b/Mage.Sets/src/mage/cards/s/SinsOfThePast.java index 0d0a008567..829b2f7138 100644 --- a/Mage.Sets/src/mage/cards/s/SinsOfThePast.java +++ b/Mage.Sets/src/mage/cards/s/SinsOfThePast.java @@ -4,7 +4,7 @@ package mage.cards.s; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.ExileCardEnteringGraveyardReplacementEffect; import mage.abilities.effects.common.ExileSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -12,9 +12,6 @@ import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.common.FilterInstantOrSorceryCard; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; -import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; import mage.target.targetpointer.FixedTarget; @@ -65,10 +62,10 @@ class SinsOfThePastEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Card card = game.getCard(this.getTargetPointer().getFirst(game, source)); if (card != null) { - ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.GRAVEYARD, TargetController.YOU, Duration.EndOfTurn, true);; + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.GRAVEYARD, TargetController.YOU, Duration.EndOfTurn, true); effect.setTargetPointer(new FixedTarget(card, game)); game.addEffect(effect, source); - effect = new SinsOfThePastReplacementEffect(card.getId()); + effect = new ExileCardEnteringGraveyardReplacementEffect(card.getId()); game.addEffect(effect, source); return true; } @@ -76,40 +73,3 @@ class SinsOfThePastEffect extends OneShotEffect { } } -class SinsOfThePastReplacementEffect extends ReplacementEffectImpl { - - private final UUID cardId; - - SinsOfThePastReplacementEffect(UUID cardId) { - super(Duration.EndOfTurn, Outcome.Exile); - this.cardId = cardId; - } - - SinsOfThePastReplacementEffect(final SinsOfThePastReplacementEffect effect) { - super(effect); - this.cardId = effect.cardId; - } - - @Override - public SinsOfThePastReplacementEffect copy() { - return new SinsOfThePastReplacementEffect(this); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - ((ZoneChangeEvent) event).setToZone(Zone.EXILED); - return false; - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ZONE_CHANGE; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - return zEvent.getToZone() == Zone.GRAVEYARD - && zEvent.getTargetId().equals(this.cardId); - } -} diff --git a/Mage.Sets/src/mage/sets/StrixhavenSchoolOfMages.java b/Mage.Sets/src/mage/sets/StrixhavenSchoolOfMages.java index 2c5b9578f9..0477dbbf56 100644 --- a/Mage.Sets/src/mage/sets/StrixhavenSchoolOfMages.java +++ b/Mage.Sets/src/mage/sets/StrixhavenSchoolOfMages.java @@ -99,6 +99,7 @@ public final class StrixhavenSchoolOfMages extends ExpansionSet { cards.add(new SetCardInfo("Dueling Coach", 15, Rarity.UNCOMMON, mage.cards.d.DuelingCoach.class)); cards.add(new SetCardInfo("Eager First-Year", 16, Rarity.COMMON, mage.cards.e.EagerFirstYear.class)); cards.add(new SetCardInfo("Ecological Appreciation", 128, Rarity.MYTHIC, mage.cards.e.EcologicalAppreciation.class)); + cards.add(new SetCardInfo("Efreet Flamepainter", 98, Rarity.RARE, mage.cards.e.EfreetFlamepainter.class)); cards.add(new SetCardInfo("Elemental Expressionist", 181, Rarity.RARE, mage.cards.e.ElementalExpressionist.class)); cards.add(new SetCardInfo("Elemental Masterpiece", 182, Rarity.COMMON, mage.cards.e.ElementalMasterpiece.class)); cards.add(new SetCardInfo("Elemental Summoning", 183, Rarity.COMMON, mage.cards.e.ElementalSummoning.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileCardEnteringGraveyardReplacementEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileCardEnteringGraveyardReplacementEffect.java new file mode 100644 index 0000000000..cdf595971c --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileCardEnteringGraveyardReplacementEffect.java @@ -0,0 +1,50 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; + +import java.util.UUID; + +public class ExileCardEnteringGraveyardReplacementEffect extends ReplacementEffectImpl { + + private final UUID cardId; + + public ExileCardEnteringGraveyardReplacementEffect(UUID cardId) { + super(Duration.EndOfTurn, Outcome.Exile); + this.cardId = cardId; + } + + ExileCardEnteringGraveyardReplacementEffect(final ExileCardEnteringGraveyardReplacementEffect effect) { + super(effect); + this.cardId = effect.cardId; + } + + @Override + public ExileCardEnteringGraveyardReplacementEffect copy() { + return new ExileCardEnteringGraveyardReplacementEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + ((ZoneChangeEvent) event).setToZone(Zone.EXILED); + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + return zEvent.getToZone() == Zone.GRAVEYARD + && zEvent.getTargetId().equals(this.cardId); + } +}