* Fixed a problem of EndTurnEffect not beeing able to remove stackAbilities and endless looping as a result (fixes #3221).

This commit is contained in:
LevelX2 2017-04-25 21:30:45 +02:00
parent 24b99216f8
commit 80beebccf5
2 changed files with 42 additions and 5 deletions

View file

@ -114,7 +114,7 @@ public class EndTurnEffectTest extends CardTestPlayerBase {
*/ */
@Test @Test
public void testSpellAftermath() { public void testSpellAftermath() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
// Insult Sorcery {2}{R} // Insult Sorcery {2}{R}
// Damage can't be prevented this turn. If a source you control would deal damage this turn, it deals double that damage instead. // Damage can't be prevented this turn. If a source you control would deal damage this turn, it deals double that damage instead.
// Injury Sorcery {2}{R} // Injury Sorcery {2}{R}
@ -122,23 +122,58 @@ public class EndTurnEffectTest extends CardTestPlayerBase {
// Injury deals 2 damage to target creature and 2 damage to target player. // Injury deals 2 damage to target creature and 2 damage to target player.
addCard(Zone.GRAVEYARD, playerA, "Insult // Injury"); addCard(Zone.GRAVEYARD, playerA, "Insult // Injury");
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3);
// End the turn. // End the turn.(Exile all spells and abilities on the stack. Discard down to your maximum hand size. Damage wears off, and \"this turn\" and \"until end of turn\" effects end.)
// At the beginning of your next end step, you lose the game. // At the beginning of your next end step, you lose the game.
addCard(Zone.HAND, playerB, "Glorious End"); //Instant {2}{R} addCard(Zone.HAND, playerB, "Glorious End"); //Instant {2}{R}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Injury", "Silvercoat Lion"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Injury", "Silvercoat Lion");
addTarget(playerA, playerB); addTarget(playerA, playerB);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Glorious End", NO_TARGET, "Injury"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Glorious End", NO_TARGET, "Injury");
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
assertExileCount(playerB, "Glorious End", 1);
assertGraveyardCount(playerA, "Insult // Injury", 0);
assertExileCount(playerA, "Insult // Injury", 1); assertExileCount(playerA, "Insult // Injury", 1);
assertGraveyardCount(playerB, "Glorious End", 0); assertGraveyardCount(playerB, "Glorious End", 0);
assertHandCount(playerA, 0); assertHandCount(playerA, 0);
assertHandCount(playerB, 0); // TODO Check
assertHandCount(playerB, 1); // No idea why playerB has a mountain into hand
}
/**
* Test to end the turn by an ability
*/
@Test
public void testSundialOfTheInfinite() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
addCard(Zone.HAND, playerA, "Mountain", 10);
// {1}, {T}: End the turn. Activate this ability only during your turn.
addCard(Zone.HAND, playerA, "Sundial of the Infinite", 1); // Artifact {2}
addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
// Destroy target artifact or enchantment.
addCard(Zone.HAND, playerB, "Disenchant"); //Instant {1}{W}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sundial of the Infinite");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Disenchant", "Sundial of the Infinite");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},", NO_TARGET, "Disenchant");
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
execute();
assertExileCount(playerB, "Disenchant", 1);
assertPermanentCount(playerA, "Sundial of the Infinite", 1);
assertHandCount(playerA, 7); // Discard to maximum hand size
assertHandCount(playerB, 1); // 1 card drawn at start of 2nd turn
} }
} }

View file

@ -278,10 +278,12 @@ public class Turn implements Serializable {
// 1) All spells and abilities on the stack are exiled. This includes (e.g.) Time Stop, though it will continue to resolve. // 1) All spells and abilities on the stack are exiled. This includes (e.g.) Time Stop, though it will continue to resolve.
// It also includes spells and abilities that can't be countered. // It also includes spells and abilities that can't be countered.
while (!game.getStack().isEmpty()) { while (!game.hasEnded() && !game.getStack().isEmpty()) {
StackObject stackObject = game.getStack().peekFirst(); StackObject stackObject = game.getStack().peekFirst();
if (stackObject instanceof Spell) { if (stackObject instanceof Spell) {
((Spell) stackObject).moveToExile(null, "", source.getSourceId(), game); ((Spell) stackObject).moveToExile(null, "", source.getSourceId(), game);
} else {
game.getStack().remove(stackObject); // stack ability
} }
} }
// 2) All attacking and blocking creatures are removed from combat. // 2) All attacking and blocking creatures are removed from combat.