From f740cf0d12c467e7c4ed49d5f64703dec402efcb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 20 Aug 2021 09:11:18 -0400 Subject: [PATCH] [AFC] Implemented Lorcan, Warlock Collector --- .../mage/cards/l/LorcanWarlockCollector.java | 139 ++++++++++++++++++ .../mage/sets/ForgottenRealmsCommander.java | 1 + ...oGraveFromAnywhereAllTriggeredAbility.java | 41 +++--- 3 files changed, 158 insertions(+), 23 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/l/LorcanWarlockCollector.java diff --git a/Mage.Sets/src/mage/cards/l/LorcanWarlockCollector.java b/Mage.Sets/src/mage/cards/l/LorcanWarlockCollector.java new file mode 100644 index 00000000000..0452e412700 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LorcanWarlockCollector.java @@ -0,0 +1,139 @@ +package mage.cards.l; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.PutCardIntoGraveFromAnywhereAllTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.continuous.AddCardSubTypeTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LorcanWarlockCollector extends CardImpl { + + public LorcanWarlockCollector(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.DEVIL); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever a creature card is put into an opponent's graveyard from anywhere, you may pay life equal to its mana value. If you do, put it onto the battlefield under your control. It's a Warlock in addition to its other types. + this.addAbility(new PutCardIntoGraveFromAnywhereAllTriggeredAbility( + new LorcanWarlockCollectorReturnEffect(), + true, StaticFilters.FILTER_CARD_CREATURE_A, + TargetController.OPPONENT, SetTargetPointer.CARD + )); + + // If a Warlock you control would die, exile it instead. + this.addAbility(new SimpleStaticAbility(new LorcanWarlockCollectorReplacementEffect())); + } + + private LorcanWarlockCollector(final LorcanWarlockCollector card) { + super(card); + } + + @Override + public LorcanWarlockCollector copy() { + return new LorcanWarlockCollector(this); + } +} + +class LorcanWarlockCollectorReturnEffect extends OneShotEffect { + + LorcanWarlockCollectorReturnEffect() { + super(Outcome.PutCreatureInPlay); + staticText = "pay life equal to its mana value. If you do, " + + "put it onto the battlefield under your control. " + + "It's a Warlock in addition to its other types"; + } + + private LorcanWarlockCollectorReturnEffect(final LorcanWarlockCollectorReturnEffect effect) { + super(effect); + } + + @Override + public LorcanWarlockCollectorReturnEffect copy() { + return new LorcanWarlockCollectorReturnEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Card card = game.getCard(getTargetPointer().getFirst(game, source)); + if (player == null || card == null) { + return false; + } + Cost cost = new PayLifeCost(card.getManaValue()); + if (!cost.canPay(source, source, source.getControllerId(), game) + || !cost.pay(source, game, source, source.getControllerId(), true)) { + return false; + } + game.addEffect(new AddCardSubTypeTargetEffect(SubType.WARLOCK, Duration.Custom).setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game) + 1)), source); + player.moveCards(card, Zone.BATTLEFIELD, source, game); + return true; + } +} + +class LorcanWarlockCollectorReplacementEffect extends ReplacementEffectImpl { + + LorcanWarlockCollectorReplacementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Exile); + staticText = "if a Warlock you control would die, exile it instead"; + } + + private LorcanWarlockCollectorReplacementEffect(final LorcanWarlockCollectorReplacementEffect effect) { + super(effect); + } + + @Override + public LorcanWarlockCollectorReplacementEffect copy() { + return new LorcanWarlockCollectorReplacementEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent permanent = ((ZoneChangeEvent) event).getTarget(); + if (permanent == null) { + return false; + } + Player player = game.getPlayer(permanent.getControllerId()); + return player != null && player.moveCards(permanent, Zone.EXILED, source, game); + } + + @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.getTarget() != null + && zEvent.getTarget().isControlledBy(source.getControllerId()) + && zEvent.getTarget().hasSubtype(SubType.WARLOCK, game) + && zEvent.isDiesEvent(); + } +} diff --git a/Mage.Sets/src/mage/sets/ForgottenRealmsCommander.java b/Mage.Sets/src/mage/sets/ForgottenRealmsCommander.java index cd755240846..87815989c60 100644 --- a/Mage.Sets/src/mage/sets/ForgottenRealmsCommander.java +++ b/Mage.Sets/src/mage/sets/ForgottenRealmsCommander.java @@ -142,6 +142,7 @@ public final class ForgottenRealmsCommander extends ExpansionSet { cards.add(new SetCardInfo("Knight of Autumn", 187, Rarity.RARE, mage.cards.k.KnightOfAutumn.class)); cards.add(new SetCardInfo("Light Up the Stage", 131, Rarity.UNCOMMON, mage.cards.l.LightUpTheStage.class)); cards.add(new SetCardInfo("Lightning Greaves", 331, Rarity.UNCOMMON, mage.cards.l.LightningGreaves.class)); + cards.add(new SetCardInfo("Lorcan, Warlock Collector", 27, Rarity.RARE, mage.cards.l.LorcanWarlockCollector.class)); cards.add(new SetCardInfo("Loyal Apprentice", 132, Rarity.UNCOMMON, mage.cards.l.LoyalApprentice.class)); cards.add(new SetCardInfo("Lumbering Falls", 247, Rarity.RARE, mage.cards.l.LumberingFalls.class)); cards.add(new SetCardInfo("Maddening Hex", 32, Rarity.RARE, mage.cards.m.MaddeningHex.class)); diff --git a/Mage/src/main/java/mage/abilities/common/PutCardIntoGraveFromAnywhereAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/PutCardIntoGraveFromAnywhereAllTriggeredAbility.java index c6f29a79277..ce40e77eaad 100644 --- a/Mage/src/main/java/mage/abilities/common/PutCardIntoGraveFromAnywhereAllTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/PutCardIntoGraveFromAnywhereAllTriggeredAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; @@ -8,6 +7,7 @@ import mage.constants.SetTargetPointer; import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; @@ -23,7 +23,7 @@ public class PutCardIntoGraveFromAnywhereAllTriggeredAbility extends TriggeredAb private final SetTargetPointer setTargetPointer; public PutCardIntoGraveFromAnywhereAllTriggeredAbility(Effect effect, boolean optional, TargetController targetController) { - this(effect, optional, new FilterCard("a card"), targetController); + this(effect, optional, StaticFilters.FILTER_CARD_A, targetController); } public PutCardIntoGraveFromAnywhereAllTriggeredAbility(Effect effect, boolean optional, FilterCard filter, TargetController targetController) { @@ -77,28 +77,23 @@ public class PutCardIntoGraveFromAnywhereAllTriggeredAbility extends TriggeredAb @Override public boolean checkTrigger(GameEvent event, Game game) { - if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD) { - Card card = game.getCard(event.getTargetId()); - if (card != null - && !card.isCopy() - && filter.match(card, getSourceId(), getControllerId(), game)) { - switch (setTargetPointer) { - case CARD: - for (Effect effect : getEffects()) { - effect.setTargetPointer(new FixedTarget(card, game)); - } - break; - case PLAYER: - for (Effect effect : getEffects()) { - effect.setTargetPointer(new FixedTarget(card.getOwnerId(), 0)); - } - break; - - } - return true; - } + if (((ZoneChangeEvent) event).getToZone() != Zone.GRAVEYARD) { + return false; } - return false; + Card card = game.getCard(event.getTargetId()); + if (card == null || card.isCopy() || !filter.match(card, getSourceId(), getControllerId(), game)) { + return false; + } + switch (setTargetPointer) { + case CARD: + this.getEffects().setTargetPointer(new FixedTarget(card, game)); + break; + case PLAYER: + this.getEffects().setTargetPointer(new FixedTarget(card.getOwnerId(), 0)); + break; + + } + return true; } @Override