From bd6eb91ee2e837ca03e9354c5af5547417578b82 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 19 Aug 2015 10:19:12 +0200 Subject: [PATCH] Fixed that move cards event included cards that were not successful moved (fixes #1211). --- .../triggers/dies/SidisiBroodTyrantTest.java | 44 +++++++++++++++ .../java/org/mage/test/player/TestPlayer.java | 2 +- Mage/src/mage/players/Player.java | 4 +- Mage/src/mage/players/PlayerImpl.java | 55 ++++++++++++------- 4 files changed, 82 insertions(+), 23 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/SidisiBroodTyrantTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/SidisiBroodTyrantTest.java index eaaefeed1d8..63a43d80069 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/SidisiBroodTyrantTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/SidisiBroodTyrantTest.java @@ -112,4 +112,48 @@ public class SidisiBroodTyrantTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Zombie", 2); } + + /* + Sidisi's zombie trigger still resolves even with Anafenza on the battle field. + + Steps: + Cast Anafenza + Pass + Cast Sidisi, mill creature. + Zombie is still created. + + Due to replacement effect of exiling creatures, the second phase of sidisi is null with Anafenza out. + + */ + @Test + public void testWithAnafenza() { + addCard(Zone.BATTLEFIELD, playerA, "Island"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 4); + // {1}{B}{G}{U} + // Whenever Sidisi, Brood Tyrant enters the battlefield or attacks, put the top three cards of your library into your graveyard + // Whenever one or more creature cards are put into your graveyard from your library, put a 2/2 black Zombie creature token onto the battlefield. + addCard(Zone.HAND, playerA, "Sidisi, Brood Tyrant"); // 2/2 {1}{B}{G}{U} + addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 1); + addCard(Zone.LIBRARY, playerA, "Swamp", 1); + addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 1); + skipInitShuffling(); + + // Whenever Anafenza, the Foremost attacks, put a +1/+1 counter on another target tapped creature you control. + // If a creature card would be put into an opponent's graveyard from anywhere, exile it instead. + addCard(Zone.BATTLEFIELD, playerB, "Anafenza, the Foremost"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sidisi, Brood Tyrant"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Sidisi, Brood Tyrant", 1); + assertGraveyardCount(playerA, "Swamp", 1); + assertGraveyardCount(playerA, "Silvercoat Lion", 0); + assertExileCount("Silvercoat Lion", 2); + assertPermanentCount(playerA, "Zombie", 0); + + } + } diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 77263561b37..1b7945ff260 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -1717,7 +1717,7 @@ public class TestPlayer implements Player { } @Override - public boolean moveCardsToGraveyardWithInfo(Set allCards, Ability source, Game game, Zone fromZone) { + public Set moveCardsToGraveyardWithInfo(Set allCards, Ability source, Game game, Zone fromZone) { return computerPlayer.moveCardsToGraveyardWithInfo(allCards, source, game, fromZone); } diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index ffb4dd09615..8e12ba8b251 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -685,9 +685,9 @@ public interface Player extends MageItem, Copyable { * @param source * @param game * @param fromZone if null, this info isn't postet - * @return + * @return Set that were successful moved to graveyard */ - boolean moveCardsToGraveyardWithInfo(Set cards, Ability source, Game game, Zone fromZone); + Set moveCardsToGraveyardWithInfo(Set cards, Ability source, Game game, Zone fromZone); /** * Uses card.moveToZone and posts a inform message about moving the card to diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index ac3222ee895..6aa71a4b972 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -34,6 +34,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -2925,45 +2926,52 @@ public abstract class PlayerImpl implements Player, Serializable { if (cards.isEmpty()) { return true; } - game.fireEvent(new ZoneChangeGroupEvent(cards, source == null ? null : source.getSourceId(), this.getId(), fromZone, toZone)); + Set successfulMovedCards = new LinkedHashSet<>(); switch (toZone) { case EXILED: - boolean result = false; for (Card card : cards) { fromZone = game.getState().getZone(card.getId()); boolean withName = (fromZone.equals(Zone.BATTLEFIELD) || fromZone.equals(Zone.STACK)) || !card.isFaceDown(game); - result |= moveCardToExileWithInfo(card, null, "", source == null ? null : source.getSourceId(), game, fromZone, withName); + if (moveCardToExileWithInfo(card, null, "", source == null ? null : source.getSourceId(), game, fromZone, withName)) { + successfulMovedCards.add(card); + } } - return result; + break; case GRAVEYARD: - return moveCardsToGraveyardWithInfo(cards, source, game, fromZone); + successfulMovedCards = moveCardsToGraveyardWithInfo(cards, source, game, fromZone); + break; case HAND: - result = false; for (Card card : cards) { fromZone = game.getState().getZone(card.getId()); boolean hideCard = fromZone.equals(Zone.LIBRARY) || (card.isFaceDown(game) && !fromZone.equals(Zone.STACK) && !fromZone.equals(Zone.BATTLEFIELD)); - result |= moveCardToHandWithInfo(card, source == null ? null : source.getSourceId(), game, !hideCard); + if (moveCardToHandWithInfo(card, source == null ? null : source.getSourceId(), game, !hideCard)) { + successfulMovedCards.add(card); + } } - return result; + break; case BATTLEFIELD: - result = false; for (Card card : cards) { fromZone = game.getState().getZone(card.getId()); - result |= putOntoBattlefieldWithInfo(card, game, fromZone, source == null ? null : source.getSourceId(), false, !card.isFaceDown(game)); + if (putOntoBattlefieldWithInfo(card, game, fromZone, source == null ? null : source.getSourceId(), false, !card.isFaceDown(game))) { + successfulMovedCards.add(card); + } } - return result; + break; case LIBRARY: - result = false; for (Card card : cards) { fromZone = game.getState().getZone(card.getId()); boolean withName = fromZone.equals(Zone.BATTLEFIELD) || !card.isFaceDown(game); - result |= moveCardToLibraryWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone, true, withName); + if (moveCardToLibraryWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone, true, withName)) { + successfulMovedCards.add(card); + } } - return result; + break; default: throw new UnsupportedOperationException("to Zone not supported yet"); } + game.fireEvent(new ZoneChangeGroupEvent(successfulMovedCards, source == null ? null : source.getSourceId(), this.getId(), fromZone, toZone)); + return successfulMovedCards.size() > 0; } @Override @@ -3016,9 +3024,9 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean moveCardsToGraveyardWithInfo(Set allCards, Ability source, Game game, Zone fromZone) { - boolean result = true; + public Set moveCardsToGraveyardWithInfo(Set allCards, Ability source, Game game, Zone fromZone) { UUID sourceId = source == null ? null : source.getSourceId(); + Set movedCards = new LinkedHashSet<>(); while (!allCards.isEmpty()) { // identify cards from one owner Cards cards = new CardsImpl(); @@ -3058,21 +3066,28 @@ public abstract class PlayerImpl implements Player, Serializable { cards.remove(targetObjectId); if (card != null) { fromZone = game.getState().getZone(card.getId()); - result &= choosingPlayer.moveCardToGraveyardWithInfo(card, sourceId, game, fromZone); + if (choosingPlayer.moveCardToGraveyardWithInfo(card, sourceId, game, fromZone)) { + movedCards.add(card); + } } target.clearChosen(); } if (cards.size() == 1) { - result &= choosingPlayer.moveCardToGraveyardWithInfo(cards.getCards(game).iterator().next(), sourceId, game, fromZone); + Card card = cards.getCards(game).iterator().next(); + if (card != null && choosingPlayer.moveCardToGraveyardWithInfo(card, sourceId, game, fromZone)) { + movedCards.add(card); + } } } else { for (Card card : cards.getCards(game)) { - result &= choosingPlayer.moveCardToGraveyardWithInfo(card, sourceId, game, fromZone); + if (choosingPlayer.moveCardToGraveyardWithInfo(card, sourceId, game, fromZone)) { + movedCards.add(card); + } } } } } - return result; + return movedCards; } @Override