From b83d76bb08511b606208858f2f501030b4ec1765 Mon Sep 17 00:00:00 2001 From: Jeff Wadsworth Date: Tue, 8 Feb 2022 09:08:50 -0600 Subject: [PATCH] - [NEO] added Eater of Virtue --- Mage.Sets/src/mage/cards/e/EaterOfVirtue.java | 193 ++++++++++++++++++ .../src/mage/sets/KamigawaNeonDynasty.java | 1 + .../common/DiesAttachedTriggeredAbility.java | 13 ++ 3 files changed, 207 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EaterOfVirtue.java diff --git a/Mage.Sets/src/mage/cards/e/EaterOfVirtue.java b/Mage.Sets/src/mage/cards/e/EaterOfVirtue.java new file mode 100644 index 0000000000..8af937ff61 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EaterOfVirtue.java @@ -0,0 +1,193 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.cards.e; + +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.DiesAttachedTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.HexproofAbility; +import mage.abilities.keyword.IndestructibleAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.MenaceAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.abilities.keyword.ReachAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SetTargetPointer; +import mage.constants.SubLayer; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * @author jeffwadsworth + */ +public final class EaterOfVirtue extends CardImpl { + + public EaterOfVirtue(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.EQUIPMENT); + + // Whenever equipped creature dies, exile it. + this.addAbility(new DiesAttachedTriggeredAbility(new EaterOfVirtueExileEffect(), "equipped creature", false, true, SetTargetPointer.CARD)); + + // Equipped creature gets +2/+0. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 0, Duration.WhileOnBattlefield))); + + // As long as a card exiled with Eater of Virtue has flying, equipped creature has flying. The same is true for first strike, double strike, deathtouch, haste, hexproof, indestructible, lifelink, menace, protection, reach, trample, and vigilance. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EaterOfVirtueGainAbilityAttachedEffect())); + + // Equip {1} + this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(1))); + + } + + private EaterOfVirtue(final EaterOfVirtue card) { + super(card); + } + + @Override + public EaterOfVirtue copy() { + return new EaterOfVirtue(this); + } +} + +class EaterOfVirtueExileEffect extends OneShotEffect { + + EaterOfVirtueExileEffect() { + super(Outcome.Neutral); + this.staticText = "exile it"; + } + + EaterOfVirtueExileEffect(final EaterOfVirtueExileEffect effect) { + super(effect); + } + + @Override + public EaterOfVirtueExileEffect copy() { + return new EaterOfVirtueExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent eaterOfVirtue = game.getPermanent(source.getSourceId()); + Card exiledCard = game.getCard(targetPointer.getFirst(game, source)); + if (controller != null + && eaterOfVirtue != null + && exiledCard != null) { + UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString() + "cards exiled by Eater of Virtue", game); + controller.moveCardsToExile(exiledCard, source, game, true, exileId, eaterOfVirtue.getIdName()); + return true; + } + return false; + } +} + +class EaterOfVirtueGainAbilityAttachedEffect extends ContinuousEffectImpl { + + public EaterOfVirtueGainAbilityAttachedEffect() { + super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); + staticText = "As long as a card exiled with Eater of Virtue has flying, equipped creature has flying. The same is true for first strike, double strike, deathtouch, haste, hexproof, indestructible, lifelink, menace, protection, reach, trample, and vigilance"; + } + + public EaterOfVirtueGainAbilityAttachedEffect(final EaterOfVirtueGainAbilityAttachedEffect effect) { + super(effect); + } + + @Override + public EaterOfVirtueGainAbilityAttachedEffect copy() { + return new EaterOfVirtueGainAbilityAttachedEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent eaterOfVirtue = game.getPermanent(source.getSourceId()); + if (eaterOfVirtue != null + && eaterOfVirtue.getAttachedTo() != null) { + Permanent permanent = game.getPermanent(eaterOfVirtue.getAttachedTo()); + if (permanent != null) { + UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString() + "cards exiled by Eater of Virtue", game); + if (game.getState().getExile().getExileZone(exileId) != null + && game.getState().getExile().getExileZone(exileId).size() > 0) { + Set cardsInExile = game.getState().getExile().getExileZone(exileId).getCards(game); + for (Card card : cardsInExile) { + for (Ability a : card.getAbilities()) { + if (a instanceof FlyingAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof FirstStrikeAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof DoubleStrikeAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof DeathtouchAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof HasteAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof HexproofAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof IndestructibleAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof LifelinkAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof MenaceAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof ProtectionAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof IndestructibleAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof ReachAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof TrampleAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + if (a instanceof VigilanceAbility) { + permanent.addAbility(a, source.getSourceId(), game); + } + } + } + } + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java b/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java index d0e3193868..2ce4330e89 100644 --- a/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java +++ b/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java @@ -79,6 +79,7 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Dragonfly Suit", 9, Rarity.COMMON, mage.cards.d.DragonflySuit.class)); cards.add(new SetCardInfo("Dragonspark Reactor", 137, Rarity.UNCOMMON, mage.cards.d.DragonsparkReactor.class)); cards.add(new SetCardInfo("Dramatist's Puppet", 244, Rarity.COMMON, mage.cards.d.DramatistsPuppet.class)); + cards.add(new SetCardInfo("Eater of Virtue", 245, Rarity.RARE, mage.cards.e.EaterOfVirtue.class)); cards.add(new SetCardInfo("Echo of Death's Wail", 124, Rarity.RARE, mage.cards.e.EchoOfDeathsWail.class)); cards.add(new SetCardInfo("Ecologist's Terrarium", 246, Rarity.COMMON, mage.cards.e.EcologistsTerrarium.class)); cards.add(new SetCardInfo("Eiganjo Exemplar", 10, Rarity.COMMON, mage.cards.e.EiganjoExemplar.class)); diff --git a/Mage/src/main/java/mage/abilities/common/DiesAttachedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DiesAttachedTriggeredAbility.java index 204d6119a4..cbea3651f8 100644 --- a/Mage/src/main/java/mage/abilities/common/DiesAttachedTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DiesAttachedTriggeredAbility.java @@ -110,6 +110,19 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl { } } } + // set targetpointer to the creature that died + if (setTargetPointer == SetTargetPointer.CARD + || setTargetPointer == SetTargetPointer.PERMANENT) { + Permanent attachment = game.getPermanentOrLKIBattlefield(getSourceId()); + if (attachment != null + && attachment.getAttachedTo() != null) { + Permanent attachedTo = (Permanent) game.getLastKnownInformation(attachment.getAttachedTo(), + Zone.BATTLEFIELD, attachment.getAttachedToZoneChangeCounter()); + if (attachedTo != null) { + getEffects().setTargetPointer(new FixedTarget(attachedTo.getId())); + } + } + } return true; }