From 0dcc2a85b8a77ef23b5c1dee2f2357368b46857e Mon Sep 17 00:00:00 2001 From: Quercitron Date: Mon, 31 Oct 2016 03:01:02 +0300 Subject: [PATCH] * Emrakul, the Promised End - Fix that extra turn is not giving when Emrakul is cast during an opponent's turn (fixes #2492). --- .../mage/cards/e/EmrakulThePromisedEnd.java | 14 +++-- .../single/emn/EmrakulThePromisedEndTest.java | 63 +++++++++++++++++++ .../src/main/java/mage/game/turn/TurnMod.java | 16 +++++ .../main/java/mage/game/turn/TurnMods.java | 10 ++- 4 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/emn/EmrakulThePromisedEndTest.java diff --git a/Mage.Sets/src/mage/cards/e/EmrakulThePromisedEnd.java b/Mage.Sets/src/mage/cards/e/EmrakulThePromisedEnd.java index 175adfd6be..90dd9e87f4 100644 --- a/Mage.Sets/src/mage/cards/e/EmrakulThePromisedEnd.java +++ b/Mage.Sets/src/mage/cards/e/EmrakulThePromisedEnd.java @@ -34,9 +34,9 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CastSourceTriggeredAbility; import mage.abilities.effects.common.cost.CostModificationEffectImpl; -import mage.abilities.effects.common.turn.ControlTargetPlayerNextTurnEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.ProtectionAbility; import mage.abilities.keyword.TrampleAbility; @@ -143,10 +143,10 @@ class EmrakulThePromisedEndCostReductionEffect extends CostModificationEffectImp } } -class EmrakulThePromisedEndGainControlEffect extends ControlTargetPlayerNextTurnEffect { +class EmrakulThePromisedEndGainControlEffect extends OneShotEffect { EmrakulThePromisedEndGainControlEffect() { - super(); + super(Outcome.GainControl); this.staticText = "you gain control of target opponent during that player's next turn. After that turn, that player takes an extra turn"; } @@ -164,8 +164,12 @@ class EmrakulThePromisedEndGainControlEffect extends ControlTargetPlayerNextTurn Player controller = game.getPlayer(source.getControllerId()); Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); if (controller != null && targetPlayer != null) { - game.getState().getTurnMods().add(new TurnMod(targetPlayer.getId(), false)); + TurnMod controlPlayerTurnMod = new TurnMod(targetPlayer.getId(), controller.getId()); + TurnMod extraTurnMod = new TurnMod(targetPlayer.getId(), false); + controlPlayerTurnMod.setSubsequentTurnMod(extraTurnMod); + game.getState().getTurnMods().add(controlPlayerTurnMod); + return true; } - return super.apply(game, source); + return false; } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/emn/EmrakulThePromisedEndTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/emn/EmrakulThePromisedEndTest.java new file mode 100644 index 0000000000..6ab93d4b73 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/emn/EmrakulThePromisedEndTest.java @@ -0,0 +1,63 @@ +package org.mage.test.cards.single.emn; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author Quercitron + */ +public class EmrakulThePromisedEndTest extends CardTestPlayerBase { + + // Test that extra turn is added correctly when Emrakul is cast during an opponent's turn. + @Test + public void testExtraTurn_Turn2() { + addCard(Zone.BATTLEFIELD, playerB, "Island", 20); + // Creature cards you own that aren't on the battlefield have flash. + addCard(Zone.HAND, playerB, "Teferi, Mage of Zhalfir"); + // When you cast Emrakul, you gain control of target opponent during that player's next turn. + // After that turn, that player takes an extra turn. + addCard(Zone.HAND, playerB, "Emrakul, the Promised End"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Teferi, Mage of Zhalfir"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Emrakul, the Promised End"); + + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertActivePlayer(playerB); + } + + @Test + public void testExtraTurn_Turn3() { + addCard(Zone.BATTLEFIELD, playerB, "Island", 20); + addCard(Zone.HAND, playerB, "Teferi, Mage of Zhalfir"); + addCard(Zone.HAND, playerB, "Emrakul, the Promised End"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Teferi, Mage of Zhalfir"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Emrakul, the Promised End"); + + setStopAt(3, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertActivePlayer(playerA); + } + + @Test + public void testExtraTurn_Turn4() { + addCard(Zone.BATTLEFIELD, playerB, "Island", 20); + addCard(Zone.HAND, playerB, "Teferi, Mage of Zhalfir"); + addCard(Zone.HAND, playerB, "Emrakul, the Promised End"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Teferi, Mage of Zhalfir"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Emrakul, the Promised End"); + + setStopAt(4, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertActivePlayer(playerA); + } + +} diff --git a/Mage/src/main/java/mage/game/turn/TurnMod.java b/Mage/src/main/java/mage/game/turn/TurnMod.java index ab06249c29..8ace8f46e9 100644 --- a/Mage/src/main/java/mage/game/turn/TurnMod.java +++ b/Mage/src/main/java/mage/game/turn/TurnMod.java @@ -53,6 +53,11 @@ public class TurnMod implements Serializable { private TurnPhase afterPhase; private PhaseStep afterStep; + // Turn mod that should be applied after current turn mod. + // Implemented only for control player turn mod! + // Added for Emrakul, the Promised End. + private TurnMod subsequentTurnMod; + /** * Used to define if a player skips the next turn or gets an extra turn. * @@ -142,6 +147,9 @@ public class TurnMod implements Serializable { this.skipStep = mod.skipStep; this.afterPhase = mod.afterPhase; this.afterStep = mod.afterStep; + if (mod.subsequentTurnMod != null) { + this.subsequentTurnMod = mod.subsequentTurnMod.copy(); + } } public UUID getPlayerId() { @@ -191,4 +199,12 @@ public class TurnMod implements Serializable { public UUID getId() { return id; } + + public TurnMod getSubsequentTurnMod() { + return subsequentTurnMod; + } + + public void setSubsequentTurnMod(TurnMod subsequentTurnMod) { + this.subsequentTurnMod = subsequentTurnMod; + } } diff --git a/Mage/src/main/java/mage/game/turn/TurnMods.java b/Mage/src/main/java/mage/game/turn/TurnMods.java index ee9baa5b38..947791def9 100644 --- a/Mage/src/main/java/mage/game/turn/TurnMods.java +++ b/Mage/src/main/java/mage/game/turn/TurnMods.java @@ -86,11 +86,11 @@ public class TurnMods extends ArrayList { public UUID controlsTurn(UUID playerId) { ListIterator it = this.listIterator(this.size()); - UUID newControllerId = null; + TurnMod controlPlayerTurnMod = null; while (it.hasPrevious()) { TurnMod turnMod = it.previous(); if (turnMod.getNewControllerId() != null && turnMod.getPlayerId().equals(playerId)) { - newControllerId = turnMod.getNewControllerId(); + controlPlayerTurnMod = turnMod; it.remove(); } } @@ -102,7 +102,11 @@ public class TurnMods extends ArrayList { it.remove(); } } - return newControllerId; + // apply subsequent turn mod + if (controlPlayerTurnMod != null && controlPlayerTurnMod.getSubsequentTurnMod() != null) { + this.add(controlPlayerTurnMod.getSubsequentTurnMod()); + } + return controlPlayerTurnMod != null ? controlPlayerTurnMod.getNewControllerId() : null; } public Step extraStep(UUID playerId, PhaseStep afterStep) {