From 199315e48ba60610ba7fd20a655e52be84319e08 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Sun, 18 May 2025 15:59:51 -0400 Subject: [PATCH] [FIC] Implement Vincent, Vengeful Atoner --- .../mage/cards/v/VincentVengefulAtoner.java | 98 +++++++++++++++++++ .../src/mage/sets/FinalFantasyCommander.java | 2 + ...DealsDamageToOpponentTriggeredAbility.java | 26 ++--- 3 files changed, 110 insertions(+), 16 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/v/VincentVengefulAtoner.java diff --git a/Mage.Sets/src/mage/cards/v/VincentVengefulAtoner.java b/Mage.Sets/src/mage/cards/v/VincentVengefulAtoner.java new file mode 100644 index 00000000000..9667d82c503 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VincentVengefulAtoner.java @@ -0,0 +1,98 @@ +package mage.cards.v; + +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.common.OneOrMoreCombatDamagePlayerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.counters.CounterType; +import mage.game.Game; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class VincentVengefulAtoner extends CardImpl { + + public VincentVengefulAtoner(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.ASSASSIN); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Menace + this.addAbility(new MenaceAbility()); + + // Whenever one or more creatures you control deal combat damage to a player, put a +1/+1 counter on Vincent. + this.addAbility(new OneOrMoreCombatDamagePlayerTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()) + )); + + // Chaos -- Whenever Vincent deals combat damage to an opponent, it deals that much damage to each other opponent if Vincent's power is 7 or greater. + this.addAbility(new DealsDamageToOpponentTriggeredAbility( + new VincentVengefulAtonerEffect(), false, true, true + )); + } + + private VincentVengefulAtoner(final VincentVengefulAtoner card) { + super(card); + } + + @Override + public VincentVengefulAtoner copy() { + return new VincentVengefulAtoner(this); + } +} + +class VincentVengefulAtonerEffect extends OneShotEffect { + + VincentVengefulAtonerEffect() { + super(Outcome.Benefit); + staticText = "it deals that much damage to each other opponent if {this}'s power is 7 or greater"; + } + + private VincentVengefulAtonerEffect(final VincentVengefulAtonerEffect effect) { + super(effect); + } + + @Override + public VincentVengefulAtonerEffect copy() { + return new VincentVengefulAtonerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (Optional + .ofNullable(source.getSourcePermanentOrLKI(game)) + .map(MageObject::getPower) + .map(MageInt::getValue) + .orElse(0) < 7) { + return false; + } + int amount = (Integer) getValue("damage"); + if (amount < 1) { + return false; + } + UUID targetId = getTargetPointer().getFirst(game, source); + for (UUID opponentId : game.getOpponents(source.getControllerId())) { + Optional.ofNullable(opponentId) + .filter(uuid -> !uuid.equals(targetId)) + .map(game::getPlayer) + .map(player -> player.damage(amount, source, game)); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/FinalFantasyCommander.java b/Mage.Sets/src/mage/sets/FinalFantasyCommander.java index 408b201a176..636f12c61ec 100644 --- a/Mage.Sets/src/mage/sets/FinalFantasyCommander.java +++ b/Mage.Sets/src/mage/sets/FinalFantasyCommander.java @@ -365,6 +365,8 @@ public final class FinalFantasyCommander extends ExpansionSet { cards.add(new SetCardInfo("Unfinished Business", 259, Rarity.RARE, mage.cards.u.UnfinishedBusiness.class)); cards.add(new SetCardInfo("Vandalblast", 298, Rarity.UNCOMMON, mage.cards.v.Vandalblast.class)); cards.add(new SetCardInfo("Vanquish the Horde", 260, Rarity.RARE, mage.cards.v.VanquishTheHorde.class)); + cards.add(new SetCardInfo("Vincent, Vengeful Atoner", 157, Rarity.RARE, mage.cards.v.VincentVengefulAtoner.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vincent, Vengeful Atoner", 64, Rarity.RARE, mage.cards.v.VincentVengefulAtoner.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vindicate", 330, Rarity.RARE, mage.cards.v.Vindicate.class)); cards.add(new SetCardInfo("Vineglimmer Snarl", 440, Rarity.RARE, mage.cards.v.VineglimmerSnarl.class)); cards.add(new SetCardInfo("Void Rend", 331, Rarity.RARE, mage.cards.v.VoidRend.class)); diff --git a/Mage/src/main/java/mage/abilities/common/DealsDamageToOpponentTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DealsDamageToOpponentTriggeredAbility.java index 5ad6f7c461e..93ce1917be3 100644 --- a/Mage/src/main/java/mage/abilities/common/DealsDamageToOpponentTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DealsDamageToOpponentTriggeredAbility.java @@ -55,22 +55,16 @@ public class DealsDamageToOpponentTriggeredAbility extends TriggeredAbilityImpl @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getSourceId().equals(this.sourceId) - && game.getOpponents(this.getControllerId()).contains(event.getTargetId())) { - if (onlyCombat && event instanceof DamagedPlayerEvent) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - if (!damageEvent.isCombatDamage()) { - return false; - } - } - if (setTargetPointer) { - for (Effect effect : getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getTargetId(), game)); - effect.setValue("damage", event.getAmount()); - } - } - return true; + if (!event.getSourceId().equals(this.getSourceId()) + || !game.getOpponents(this.getControllerId()).contains(event.getTargetId()) + || onlyCombat + && !((DamagedPlayerEvent) event).isCombatDamage()) { + return false; } - return false; + this.getEffects().setValue("damage", event.getAmount()); + if (setTargetPointer) { + this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game)); + } + return true; } }