Fixed that move cards event included cards that were not successful moved (fixes #1211).

This commit is contained in:
LevelX2 2015-08-19 10:19:12 +02:00
parent 1dbe6243f4
commit bd6eb91ee2
4 changed files with 82 additions and 23 deletions

View file

@ -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);
}
}

View file

@ -1717,7 +1717,7 @@ public class TestPlayer implements Player {
}
@Override
public boolean moveCardsToGraveyardWithInfo(Set<Card> allCards, Ability source, Game game, Zone fromZone) {
public Set<Card> moveCardsToGraveyardWithInfo(Set<Card> allCards, Ability source, Game game, Zone fromZone) {
return computerPlayer.moveCardsToGraveyardWithInfo(allCards, source, game, fromZone);
}

View file

@ -685,9 +685,9 @@ public interface Player extends MageItem, Copyable<Player> {
* @param source
* @param game
* @param fromZone if null, this info isn't postet
* @return
* @return Set<Cards> that were successful moved to graveyard
*/
boolean moveCardsToGraveyardWithInfo(Set<Card> cards, Ability source, Game game, Zone fromZone);
Set<Card> moveCardsToGraveyardWithInfo(Set<Card> cards, Ability source, Game game, Zone fromZone);
/**
* Uses card.moveToZone and posts a inform message about moving the card to

View file

@ -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<Card> 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<Card> allCards, Ability source, Game game, Zone fromZone) {
boolean result = true;
public Set<Card> moveCardsToGraveyardWithInfo(Set<Card> allCards, Ability source, Game game, Zone fromZone) {
UUID sourceId = source == null ? null : source.getSourceId();
Set<Card> 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