From cc4a5f995926cc51d28f364bd3b5b12ee3534754 Mon Sep 17 00:00:00 2001 From: Susucre <34709007+Susucre@users.noreply.github.com> Date: Sat, 9 Sep 2023 05:56:31 +0200 Subject: [PATCH] Fix DamagedPlayerBatchOnePlayerEvent not checking the target is the player. (#11128) --- .../single/ori/ThopterSpyNetworkTest.java | 122 ++++++++++++++++++ Mage/src/main/java/mage/game/GameState.java | 4 +- 2 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/ori/ThopterSpyNetworkTest.java diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ori/ThopterSpyNetworkTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ori/ThopterSpyNetworkTest.java new file mode 100644 index 00000000000..22b4dd5c329 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ori/ThopterSpyNetworkTest.java @@ -0,0 +1,122 @@ +package org.mage.test.cards.single.ori; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class ThopterSpyNetworkTest extends CardTestPlayerBase { + + /** + * Thopter Spy Network + * {2}{U}{U} + * Enchantment + * + * At the beginning of your upkeep, if you control an artifact, create a 1/1 colorless Thopter artifact creature token with flying. + * Whenever one or more artifact creatures you control deal combat damage to a player, draw a card. + */ + private static final String network = "Thopter Spy Network"; + + private static final String memnite = "Memnite"; // 1/1 Artifact + private static final String ornithopter = "Ornithopter"; // 0/2 Artifact Flying + + private static final String squire = "Squire"; // 1/2 + + @Test + public void Simple() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, network); + addCard(Zone.BATTLEFIELD, playerA, memnite); + + attack(1, playerA, memnite); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertHandCount(playerA, 1); + assertLife(playerB, 20 - 1); + } + + @Test + public void NotArtifactNoTrigger() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, network); + addCard(Zone.BATTLEFIELD, playerA, squire); + + attack(1, playerA, squire); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertHandCount(playerA, 0); + assertLife(playerB, 20 - 1); + } + + @Test + public void TwoAttackOneTrigger() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, network); + addCard(Zone.BATTLEFIELD, playerA, memnite, 2); + + attack(1, playerA, memnite); + attack(1, playerA, memnite); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertHandCount(playerA, 1); + assertLife(playerB, 20 - 2); + } + + @Test + public void BlockedNoTrigger() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, network); + addCard(Zone.BATTLEFIELD, playerA, memnite, 1); + addCard(Zone.BATTLEFIELD, playerB, ornithopter, 1); + + attack(1, playerA, memnite); + block(1, playerB, ornithopter, memnite); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertHandCount(playerA, 0); + assertLife(playerB, 20); + } + + @Test + public void BeingDamageNoTrigger() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, network); + addCard(Zone.BATTLEFIELD, playerB, memnite); + + attack(2, playerB, memnite); + + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertHandCount(playerA, 0); + assertLife(playerA, 20 - 1); + } + + @Test + public void BlockedDamageNoTrigger() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, network); + addCard(Zone.BATTLEFIELD, playerB, memnite); + addCard(Zone.BATTLEFIELD, playerA, memnite); + + attack(2, playerB, memnite); + block(2, playerA, memnite, memnite); + + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertHandCount(playerA, 0); + assertLife(playerA, 20); + } +} diff --git a/Mage/src/main/java/mage/game/GameState.java b/Mage/src/main/java/mage/game/GameState.java index 8118b40bc72..470e608bce3 100644 --- a/Mage/src/main/java/mage/game/GameState.java +++ b/Mage/src/main/java/mage/game/GameState.java @@ -845,7 +845,7 @@ public class GameState implements Serializable, Copyable { if (event instanceof DamagedPlayerBatchOnePlayerEvent) { DamagedPlayerBatchOnePlayerEvent eventForPlayer = (DamagedPlayerBatchOnePlayerEvent) event; if (eventForPlayer.getDamageClazz().isInstance(damagedEvent) - && event.getPlayerId().equals(damagedEvent.getPlayerId())) { + && event.getPlayerId().equals(damagedEvent.getTargetId())) { // existing batch for damage of that damage class to the same player eventForPlayer.addEvent(damagedEvent); @@ -859,7 +859,7 @@ public class GameState implements Serializable, Copyable { // new batch for any kind of damage, creating a fresh one with damagedEvent inside. addSimultaneousEvent(DamagedBatchEvent.makeEvent(damagedEvent), game); } - if (!flagBatchForPlayer && damagedEvent.getPlayerId() != null) { + if (!flagBatchForPlayer && damagedEvent.getPlayerId() != null && damagedEvent.getPlayerId().equals(damagedEvent.getTargetId())) { // new batch for damage from any source to the specific damaged player, // creating a fresh one with damagedEvent inside. DamagedBatchEvent event = new DamagedPlayerBatchOnePlayerEvent(damagedEvent.getPlayerId());