From cb900eb799bef971b37db196a1f25111f27f0b2e Mon Sep 17 00:00:00 2001 From: xenohedron <12538125+xenohedron@users.noreply.github.com> Date: Thu, 16 Oct 2025 01:05:05 -0400 Subject: [PATCH] fix Glamer Spinners, add test (fix #14022) --- .../src/mage/cards/g/GlamerSpinners.java | 13 ++-- .../cards/single/shm/GlamerSpinnersTest.java | 74 +++++++++++++++++++ 2 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/shm/GlamerSpinnersTest.java diff --git a/Mage.Sets/src/mage/cards/g/GlamerSpinners.java b/Mage.Sets/src/mage/cards/g/GlamerSpinners.java index ca9d183bce6..497cf129071 100644 --- a/Mage.Sets/src/mage/cards/g/GlamerSpinners.java +++ b/Mage.Sets/src/mage/cards/g/GlamerSpinners.java @@ -21,6 +21,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; +import java.util.LinkedList; import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -102,17 +103,19 @@ class GlamerSpinnersEffect extends OneShotEffect { if (!game.getBattlefield().contains(filter, source.getControllerId(), source, game, 1)) { return false; } + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } TargetPermanent target = new TargetPermanent(filter); target.withNotTarget(true); - Optional.ofNullable(source) - .map(Controllable::getControllerId) - .map(game::getPlayer) - .ifPresent(player -> player.choose(outcome, target, source, game)); + player.choose(Outcome.AIDontUseIt, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent == null) { return false; } - for (UUID attachmentId : targetPermanent.getAttachments()) { + // new list to avoid concurrent modification + for (UUID attachmentId : new LinkedList<>(targetPermanent.getAttachments())) { permanent.addAttachment(attachmentId, source, game); } return true; diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/shm/GlamerSpinnersTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/shm/GlamerSpinnersTest.java new file mode 100644 index 00000000000..b1277b678a2 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/shm/GlamerSpinnersTest.java @@ -0,0 +1,74 @@ +package org.mage.test.cards.single.shm; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author xenohedron + */ +public class GlamerSpinnersTest extends CardTestPlayerBase { + + /* + Glamer Spinners + {4}{WU} + Creature - Faerie Wizard + Flash + Flying + When Glamer Spinners enters the battlefield, attach all Auras enchanting target permanent to another permanent with the same controller. + 2/4 + */ + private static final String glamerSpinners = "Glamer Spinners"; + + /* + Feral Invocation + {2}{G} + Enchantment - Aura + Flash (You may cast this spell any time you could cast an instant.) + Enchant creature + Enchanted creature gets +2/+2. + */ + private static final String feralInvocation = "Feral Invocation"; + + /* + Memnite + {0} + Artifact Creature - Construct + 1/1 + */ + private static final String memnite = "Memnite"; + + /* + Kraken Hatchling + {U} + Creature - Kraken + 0/4 + */ + private static final String krakenHatchling = "Kraken Hatchling"; + + @Test + public void testGlamerSpinners() { + addCard(Zone.HAND, playerA, glamerSpinners); + addCard(Zone.BATTLEFIELD, playerA, "Island", 5); + addCard(Zone.HAND, playerB, feralInvocation); + addCard(Zone.BATTLEFIELD, playerB, "Forest", 3); + addCard(Zone.BATTLEFIELD, playerB, memnite); + addCard(Zone.BATTLEFIELD, playerB, krakenHatchling); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, feralInvocation, memnite); + checkPT("enchanted", 1, PhaseStep.BEGIN_COMBAT, playerB, memnite, 3, 3); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, glamerSpinners); + addTarget(playerA, memnite); + setChoice(playerA, krakenHatchling); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, glamerSpinners, 1); + assertPowerToughness(playerB, memnite, 1, 1); + assertPowerToughness(playerB, krakenHatchling, 2, 6); + } +}