* Detain effect - Fixed that detained permanents stayed detained until end of game if the controller of the detain effect left/lost the game before detain effect did end (fixes #304).

This commit is contained in:
LevelX2 2013-08-28 15:11:17 +02:00
parent c14302df8a
commit d7b7f6c234
5 changed files with 36 additions and 10 deletions

View file

@ -114,7 +114,7 @@ class DetainAllRestrictionEffect extends RestrictionEffect<DetainAllRestrictionE
public boolean isInactive(Ability source, Game game) { public boolean isInactive(Ability source, Game game) {
if (game.getPhase().getStep().getType() == PhaseStep.UNTAP && game.getStep().getStepPart() == Step.StepPart.PRE) if (game.getPhase().getStep().getType() == PhaseStep.UNTAP && game.getStep().getStepPart() == Step.StepPart.PRE)
{ {
if (game.getActivePlayerId().equals(source.getControllerId())) { if (game.getActivePlayerId().equals(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) {
for(FixedTarget fixedTarget :this.detainedObjects) { for(FixedTarget fixedTarget :this.detainedObjects) {
Permanent permanent = game.getPermanent(fixedTarget.getFirst(game, source)); Permanent permanent = game.getPermanent(fixedTarget.getFirst(game, source));
if (permanent != null) { if (permanent != null) {
@ -158,4 +158,4 @@ class DetainAllRestrictionEffect extends RestrictionEffect<DetainAllRestrictionE
return new DetainAllRestrictionEffect(this); return new DetainAllRestrictionEffect(this);
} }
} }

View file

@ -29,7 +29,6 @@
package mage.abilities.effects.common; package mage.abilities.effects.common;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -152,7 +151,7 @@ class DetainRestrictionEffect extends RestrictionEffect<DetainRestrictionEffect>
public boolean isInactive(Ability source, Game game) { public boolean isInactive(Ability source, Game game) {
if (game.getPhase().getStep().getType() == PhaseStep.UNTAP && game.getStep().getStepPart() == Step.StepPart.PRE) if (game.getPhase().getStep().getType() == PhaseStep.UNTAP && game.getStep().getStepPart() == Step.StepPart.PRE)
{ {
if (game.getActivePlayerId().equals(source.getControllerId())) { if (game.getActivePlayerId().equals(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) {
for(UUID targetId :this.getTargetPointer().getTargets(game, source)) { for(UUID targetId :this.getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(targetId); Permanent permanent = game.getPermanent(targetId);
if (permanent != null) { if (permanent != null) {

View file

@ -315,4 +315,7 @@ public interface Player extends MageItem, Copyable<Player> {
* @return * @return
*/ */
int getPriorityTimeLeft(); int getPriorityTimeLeft();
void setReachedNextTurnAfterLeaving(boolean reachedNextTurnAfterLeaving);
boolean hasReachedNextTurnAfterLeaving();
} }

View file

@ -29,7 +29,6 @@
package mage.players; package mage.players;
import java.io.Serializable; import java.io.Serializable;
import java.security.InvalidParameterException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -110,7 +109,6 @@ import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetDiscard; import mage.target.common.TargetDiscard;
import mage.watchers.common.BloodthirstWatcher; import mage.watchers.common.BloodthirstWatcher;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.omg.CORBA.DynAnyPackage.Invalid;
public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Serializable { public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Serializable {
@ -170,6 +168,11 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
protected List<UUID> attachments = new ArrayList<UUID>(); protected List<UUID> attachments = new ArrayList<UUID>();
protected boolean topCardRevealed = false; protected boolean topCardRevealed = false;
// 800.4i When a player leaves the game, any continuous effects with durations that last until that player's next turn
// or until a specific point in that turn will last until that turn would have begun.
// They neither expire immediately nor last indefinitely.
protected boolean reachedNextTurnAfterLeaving = false;
protected UserData userData; protected UserData userData;
@ -241,6 +244,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
this.passedTurn = player.passedTurn; this.passedTurn = player.passedTurn;
this.passedAllTurns = player.passedAllTurns; this.passedAllTurns = player.passedAllTurns;
this.priorityTimeLeft = player.getPriorityTimeLeft(); this.priorityTimeLeft = player.getPriorityTimeLeft();
this.reachedNextTurnAfterLeaving = player.reachedNextTurnAfterLeaving;
} }
@Override @Override
@ -288,6 +292,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
this.turnController = player.getTurnControlledBy(); this.turnController = player.getTurnControlledBy();
this.passed = player.isPassed(); this.passed = player.isPassed();
this.priorityTimeLeft = player.getPriorityTimeLeft(); this.priorityTimeLeft = player.getPriorityTimeLeft();
this.reachedNextTurnAfterLeaving = player.hasReachedNextTurnAfterLeaving();
} }
@Override @Override
@ -326,7 +331,9 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
this.canLoseLife = true; this.canLoseLife = true;
this.topCardRevealed = false; this.topCardRevealed = false;
this.setLife(game.getLife(), game); this.setLife(game.getLife(), game);
this.setReachedNextTurnAfterLeaving(false);
game.getState().getWatchers().add(new BloodthirstWatcher(playerId)); game.getState().getWatchers().add(new BloodthirstWatcher(playerId));
} }
@Override @Override
@ -2004,4 +2011,14 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
return quit; return quit;
} }
@Override
public void setReachedNextTurnAfterLeaving(boolean reachedNextTurnAfterLeaving) {
this.reachedNextTurnAfterLeaving = reachedNextTurnAfterLeaving;
}
@Override
public boolean hasReachedNextTurnAfterLeaving() {
return reachedNextTurnAfterLeaving;
}
} }

View file

@ -49,10 +49,15 @@ public class PlayerList extends CircularList<UUID> {
UUID start = this.get(); UUID start = this.get();
while (true) { while (true) {
player = game.getPlayer(super.getNext()); player = game.getPlayer(super.getNext());
if (!player.hasLeft() && !player.hasLost()) if (!player.hasLeft() && !player.hasLost()) {
if (!player.hasReachedNextTurnAfterLeaving()) {
player.setReachedNextTurnAfterLeaving(true);
}
break; break;
if (player.getId().equals(start)) }
if (player.getId().equals(start)) {
return null; return null;
}
} }
return player; return player;
} }
@ -62,10 +67,12 @@ public class PlayerList extends CircularList<UUID> {
UUID start = this.get(); UUID start = this.get();
while (true) { while (true) {
player = game.getPlayer(super.getPrevious()); player = game.getPlayer(super.getPrevious());
if (!player.hasLeft() && !player.hasLost()) if (!player.hasLeft() && !player.hasLost()) {
break; break;
if (player.getId().equals(start)) }
if (player.getId().equals(start)) {
return null; return null;
}
} }
return player; return player;
} }