From 925a820f09b03f670ca825b3952d430c70ee5e65 Mon Sep 17 00:00:00 2001 From: Correl Roush Date: Thu, 7 Aug 2025 00:38:32 -0400 Subject: [PATCH] Fix Nahiri, Forged in Fury trigger (#13893) Fixes the trigger firing for all attacking creatures, not just equipped ones. Restores the equipped predicate removed in commit db193bd4 (#13707) and adds tests to prevent future regressions. --- .../src/mage/cards/n/NahiriForgedInFury.java | 5 + .../single/mat/NahiriForgedInFuryTest.java | 98 +++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/mat/NahiriForgedInFuryTest.java diff --git a/Mage.Sets/src/mage/cards/n/NahiriForgedInFury.java b/Mage.Sets/src/mage/cards/n/NahiriForgedInFury.java index 291781b2532..4f578491bc0 100644 --- a/Mage.Sets/src/mage/cards/n/NahiriForgedInFury.java +++ b/Mage.Sets/src/mage/cards/n/NahiriForgedInFury.java @@ -11,6 +11,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.EquippedPredicate; import mage.game.Game; import mage.players.Player; @@ -24,6 +25,10 @@ public final class NahiriForgedInFury extends CardImpl { private static final FilterControlledCreaturePermanent equippedFilter = new FilterControlledCreaturePermanent( "an equipped creature you control"); + static { + equippedFilter.add(EquippedPredicate.instance); + } + public NahiriForgedInFury(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{W}"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mat/NahiriForgedInFuryTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mat/NahiriForgedInFuryTest.java new file mode 100644 index 00000000000..39cce6a4160 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mat/NahiriForgedInFuryTest.java @@ -0,0 +1,98 @@ +package org.mage.test.cards.single.mat; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + + +/** + * @author correl + */ +public class NahiriForgedInFuryTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.n.NahiriForgedInFury} {4}{R}{W} + * Legendary Creature - Kor Artificer + * + * Affinity for Equipment + * + * Whenever an equipped creature you control attacks, exile the top card of + * your library. You may play that card this turn. You may cast Equipment + * spells this way without paying their mana costs. + */ + private static final String nahiri = "Nahiri, Forged in Fury"; + + private final String boots = "Swiftfoot Boots"; + private final String cleaver = "The Reaver Cleaver"; + private final String giant = "Hill Giant"; + private final String greaves = "Lightning Greaves"; + private final String lions = "Savannah Lions"; + private final String sword = "Sword of Feast and Famine"; + + @Test + public void test_CostReducedByEquipment() { + // Nahiri in hand, four equipment in play, and enough to pay RW + addCard(Zone.HAND, playerA, nahiri); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + addCard(Zone.BATTLEFIELD, playerA, boots); + addCard(Zone.BATTLEFIELD, playerA, cleaver); + addCard(Zone.BATTLEFIELD, playerA, greaves); + addCard(Zone.BATTLEFIELD, playerA, sword); + + // Cast for RW (Reduced by 4) + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, nahiri); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + } + + @Test + public void test_EquippedAttackTriggers() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); + addCard(Zone.BATTLEFIELD, playerA, nahiri); + addCard(Zone.BATTLEFIELD, playerA, lions); + addCard(Zone.BATTLEFIELD, playerA, giant); + addCard(Zone.BATTLEFIELD, playerA, boots); + addCard(Zone.BATTLEFIELD, playerA, greaves); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {0}", lions); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {1}", giant); + + // Attack with three creatures, two of which are equipped + attack(1, playerA, nahiri); + attack(1, playerA, lions); + attack(1, playerA, giant); + + // Order the 2 Nahiri triggers + setChoice(playerA, "Whenever an equipped creature you control attacks"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + // Triggered twice, exiling two cards + assertExileCount(playerA, 2); + } + + @Test + public void test_CanCastExiledEquipmentForFree() { + addCard(Zone.BATTLEFIELD, playerA, nahiri); + addCard(Zone.BATTLEFIELD, playerA, greaves); + skipInitShuffling(); + addCard(Zone.LIBRARY, playerA, sword); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {0}", nahiri); + + // Attack with one equipped creature, exiling the sword + attack(1, playerA, nahiri); + + // Cast sword for free + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, sword); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.END_TURN); + execute(); + } +}