Merge pull request #2533 from magefree/issue-2492-emrakul-extra-turn

* Emrakul, the Promised End - Fix that extra turn is not giving when …
This commit is contained in:
LevelX2 2016-10-31 07:36:11 +01:00 committed by GitHub
commit de28ea797e
4 changed files with 95 additions and 8 deletions

View file

@ -34,9 +34,9 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility; import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CastSourceTriggeredAbility; import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.effects.common.turn.ControlTargetPlayerNextTurnEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.ProtectionAbility; import mage.abilities.keyword.ProtectionAbility;
import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TrampleAbility;
@ -143,10 +143,10 @@ class EmrakulThePromisedEndCostReductionEffect extends CostModificationEffectImp
} }
} }
class EmrakulThePromisedEndGainControlEffect extends ControlTargetPlayerNextTurnEffect { class EmrakulThePromisedEndGainControlEffect extends OneShotEffect {
EmrakulThePromisedEndGainControlEffect() { 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"; 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 controller = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (controller != null && targetPlayer != null) { 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;
} }
} }

View file

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

View file

@ -53,6 +53,11 @@ public class TurnMod implements Serializable {
private TurnPhase afterPhase; private TurnPhase afterPhase;
private PhaseStep afterStep; 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. * 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.skipStep = mod.skipStep;
this.afterPhase = mod.afterPhase; this.afterPhase = mod.afterPhase;
this.afterStep = mod.afterStep; this.afterStep = mod.afterStep;
if (mod.subsequentTurnMod != null) {
this.subsequentTurnMod = mod.subsequentTurnMod.copy();
}
} }
public UUID getPlayerId() { public UUID getPlayerId() {
@ -191,4 +199,12 @@ public class TurnMod implements Serializable {
public UUID getId() { public UUID getId() {
return id; return id;
} }
public TurnMod getSubsequentTurnMod() {
return subsequentTurnMod;
}
public void setSubsequentTurnMod(TurnMod subsequentTurnMod) {
this.subsequentTurnMod = subsequentTurnMod;
}
} }

View file

@ -86,11 +86,11 @@ public class TurnMods extends ArrayList<TurnMod> {
public UUID controlsTurn(UUID playerId) { public UUID controlsTurn(UUID playerId) {
ListIterator<TurnMod> it = this.listIterator(this.size()); ListIterator<TurnMod> it = this.listIterator(this.size());
UUID newControllerId = null; TurnMod controlPlayerTurnMod = null;
while (it.hasPrevious()) { while (it.hasPrevious()) {
TurnMod turnMod = it.previous(); TurnMod turnMod = it.previous();
if (turnMod.getNewControllerId() != null && turnMod.getPlayerId().equals(playerId)) { if (turnMod.getNewControllerId() != null && turnMod.getPlayerId().equals(playerId)) {
newControllerId = turnMod.getNewControllerId(); controlPlayerTurnMod = turnMod;
it.remove(); it.remove();
} }
} }
@ -102,7 +102,11 @@ public class TurnMods extends ArrayList<TurnMod> {
it.remove(); 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) { public Step extraStep(UUID playerId, PhaseStep afterStep) {