From 847df3eeb854ab50168de515ad8347e8b43b0994 Mon Sep 17 00:00:00 2001 From: dilnu Date: Sun, 9 Feb 2020 11:56:13 -0500 Subject: [PATCH 1/2] Check zone change counters in PutOnLibrarySourceEffect --- .../triggers/dies/MurderousRiderTest.java | 57 +++++++++++++++++++ .../common/PutOnLibrarySourceEffect.java | 4 +- 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/MurderousRiderTest.java diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/MurderousRiderTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/MurderousRiderTest.java new file mode 100644 index 00000000000..272f482f9c0 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/MurderousRiderTest.java @@ -0,0 +1,57 @@ +package org.mage.test.cards.triggers.dies; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class MurderousRiderTest extends CardTestPlayerBase { + @Test + public void testAlreadyMoved() { + // When Murderous Rider dies, put it on the bottom of its owner's library. + addCard(Zone.BATTLEFIELD, playerA, "Murderous Rider"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + // When target creature dies this turn, return that card to the battlefield under its owner's control. + addCard(Zone.HAND, playerA, "Graceful Reprieve"); + + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3); + // Destroy target creature + addCard(Zone.HAND, playerB, "Murder"); + + castSpell(1, PhaseStep.UPKEEP, playerA,"Graceful Reprieve"); + addTarget(playerA, "Murderous Rider"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Murder"); + addTarget(playerB, "Murderous Rider"); + setChoice(playerA, "When {this} dies"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + setStrictChooseMode(true); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Murderous Rider", 1); + } + + @Test + public void testStandard() { + // When Murderous Rider dies, put it on the bottom of its owner's library. + addCard(Zone.BATTLEFIELD, playerA, "Murderous Rider"); + + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3); + // Destroy target creature + addCard(Zone.HAND, playerB, "Murder"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Murder"); + addTarget(playerB, "Murderous Rider"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + setStrictChooseMode(true); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Murderous Rider", 0); + assertGraveyardCount(playerA, "Murderous Rider", 0); + assertLibraryCount(playerA, "Murderous Rider", 1); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/PutOnLibrarySourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PutOnLibrarySourceEffect.java index 6cc9c8bde46..ce7c44b71f5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PutOnLibrarySourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PutOnLibrarySourceEffect.java @@ -47,12 +47,12 @@ public class PutOnLibrarySourceEffect extends OneShotEffect { switch (game.getState().getZone(source.getSourceId())) { case BATTLEFIELD: Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null) { + if (permanent != null && source.getSourceObjectZoneChangeCounter() == permanent.getZoneChangeCounter(game)) { result |= permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, onTop); } case GRAVEYARD: Card card = game.getCard(source.getSourceId()); - if (card != null) { + if (card != null && source.getSourceObjectZoneChangeCounter() == card.getZoneChangeCounter(game)) { for (Player player : game.getPlayers().values()) { if (player.getGraveyard().contains(card.getId())) { player.getGraveyard().remove(card); From a089b70d649c2cfd207b49a6100fa8a97643d70e Mon Sep 17 00:00:00 2001 From: dilnu Date: Sun, 9 Feb 2020 13:40:26 -0500 Subject: [PATCH 2/2] Use getSourceObjectIfItStillExists. --- .../common/PutOnLibrarySourceEffect.java | 35 +++++++++---------- ...vealAndShuffleIntoLibrarySourceEffect.java | 2 +- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/PutOnLibrarySourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PutOnLibrarySourceEffect.java index ce7c44b71f5..cd7f43bddb8 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PutOnLibrarySourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PutOnLibrarySourceEffect.java @@ -1,6 +1,7 @@ package mage.abilities.effects.common; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; @@ -43,25 +44,23 @@ public class PutOnLibrarySourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - boolean result = false; - switch (game.getState().getZone(source.getSourceId())) { - case BATTLEFIELD: - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null && source.getSourceObjectZoneChangeCounter() == permanent.getZoneChangeCounter(game)) { - result |= permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, onTop); - } - case GRAVEYARD: - Card card = game.getCard(source.getSourceId()); - if (card != null && source.getSourceObjectZoneChangeCounter() == card.getZoneChangeCounter(game)) { - for (Player player : game.getPlayers().values()) { - if (player.getGraveyard().contains(card.getId())) { - player.getGraveyard().remove(card); - result |= card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, onTop); - } - } - } + MageObject sourceObject = source.getSourceObjectIfItStillExists(game); + if (sourceObject == null) { + return false; } - return result; + if (sourceObject instanceof Permanent) { + ((Permanent) sourceObject).moveToZone(Zone.LIBRARY, source.getSourceId(), game, onTop); + return true; + } else if (sourceObject instanceof Card && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { + for (Player player : game.getPlayers().values()) { + if (player.getGraveyard().contains(sourceObject.getId())) { + player.getGraveyard().remove(((Card) sourceObject)); + ((Card) sourceObject).moveToZone(Zone.LIBRARY, source.getSourceId(), game, onTop); + return true; + } + } + } + return false; } @Override diff --git a/Mage/src/main/java/mage/abilities/effects/common/RevealAndShuffleIntoLibrarySourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/RevealAndShuffleIntoLibrarySourceEffect.java index 18fb81369b4..d14a23b5154 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/RevealAndShuffleIntoLibrarySourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/RevealAndShuffleIntoLibrarySourceEffect.java @@ -34,7 +34,7 @@ public class RevealAndShuffleIntoLibrarySourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - MageObject sourceObject = game.getObject(source.getSourceId()); + MageObject sourceObject = source.getSourceObjectIfItStillExists(game); Player controller = game.getPlayer(source.getControllerId()); if (sourceObject != null && controller != null) { Player owner = null;