* Until your next turn effects - fixed that continuous effects of lost/leaved players can be discarded by combat or some cards before next turn starts;

This commit is contained in:
Oleg Agafonov 2019-12-26 07:28:37 +04:00
parent a2e4e55811
commit 2460408da8
14 changed files with 147 additions and 93 deletions

View file

@ -217,7 +217,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
boolean canDelete = false;
Player player = game.getPlayer(startingControllerId);
// discard on start of turn for leave player
// discard on start of turn for leaved player
// 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.

View file

@ -1,7 +1,5 @@
package mage.abilities.effects.common;
import java.io.ObjectStreamException;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.MageSingleton;
@ -20,6 +18,8 @@ import mage.players.PlayerList;
import mage.target.Target;
import mage.target.common.TargetOpponent;
import java.io.ObjectStreamException;
/**
* 1. The controller of the spell or ability chooses an opponent. (This doesn't
* target the opponent.) 2. Each player involved in the clash reveals the top
@ -36,7 +36,7 @@ import mage.target.common.TargetOpponent;
* 7. The clash spell or ability finishes resolving. That usually involves a
* bonus gained by the controller of the clash spell or ability if they won
* the clash. 8. Abilities that triggered during the clash are put on the stack.
*
* <p>
* There are no draws or losses in a clash. Either you win it or you don't. Each
* spell or ability with clash says what happens if you (the controller of that
* spell or ability) win the clash. Typically, if you don't win the clash,
@ -148,7 +148,7 @@ public class ClashEffect extends OneShotEffect implements MageSingleton {
if (cardOpponent != null && current.getId().equals(opponent.getId())) {
topOpponent = current.chooseUse(Outcome.Detriment, "Put " + cardOpponent.getLogName() + " back on top of your library? (otherwise it goes to bottom)", source, game);
}
nextPlayer = playerList.getNext(game);
nextPlayer = playerList.getNext(game, false);
} while (nextPlayer != null && !nextPlayer.getId().equals(game.getActivePlayerId()));
// put the cards back to library
if (cardController != null) {

View file

@ -766,7 +766,7 @@ public abstract class GameImpl implements Game, Serializable {
state.getTurn().resumePlay(this, wasPaused);
if (!isPaused() && !checkIfGameIsOver()) {
endOfTurn();
player = playerList.getNext(this);
player = playerList.getNext(this, true);
state.setTurnNum(state.getTurnNum() + 1);
}
}
@ -791,7 +791,7 @@ public abstract class GameImpl implements Game, Serializable {
if (!playExtraTurns()) {
break;
}
playerByOrder = playerList.getNext(this);
playerByOrder = playerList.getNext(this, true);
state.setPlayerByOrderId(playerByOrder.getId());
}
}
@ -2494,7 +2494,6 @@ public abstract class GameImpl implements Game, Serializable {
perm.removeFromCombat(this, true);
}
toOutside.add(perm);
// it.remove();
} else if (perm.isControlledBy(player.getId())) {
// and any effects which give that player control of any objects or players end
Effects:
@ -2591,7 +2590,7 @@ public abstract class GameImpl implements Game, Serializable {
if (!isActivePlayer(playerId)) {
setMonarchId(null, getActivePlayerId());
} else {
Player nextPlayer = getPlayerList().getNext(this);
Player nextPlayer = getPlayerList().getNext(this, true);
if (nextPlayer != null) {
setMonarchId(null, nextPlayer.getId());
}

View file

@ -1236,7 +1236,7 @@ public class Combat implements Serializable, Copyable<Combat> {
case LEFT:
players = game.getState().getPlayerList(attackingPlayerId);
while (attackingPlayer.isInGame()) {
Player opponent = players.getNext(game);
Player opponent = players.getNext(game, false);
if (attackingPlayer.hasOpponent(opponent.getId(), game)) {
attackablePlayers.add(opponent.getId());
break;

View file

@ -487,10 +487,10 @@ public abstract class PlayerImpl implements Player, Serializable {
inRange.add(playerId);
PlayerList players = game.getState().getPlayerList(playerId);
for (int i = 0; i < range.getRange(); i++) {
Player player = players.getNext(game);
Player player = players.getNext(game, false);
if (player != null) {
while (player.hasLeft()) {
player = players.getNext(game);
player = players.getNext(game, false);
}
inRange.add(player.getId());
}

View file

@ -1,12 +1,11 @@
package mage.players;
import java.util.UUID;
import mage.game.Game;
import mage.util.CircularList;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class PlayerList extends CircularList<UUID> {
@ -23,7 +22,7 @@ public class PlayerList extends CircularList<UUID> {
}
public Player getNextInRange(Player basePlayer, Game game) {
UUID currentPlayerBefore = get();
UUID currentPlayerBefore = this.get();
UUID nextPlayerId = super.getNext();
do {
if (basePlayer.getInRange().contains(nextPlayerId)) {
@ -34,7 +33,10 @@ public class PlayerList extends CircularList<UUID> {
return null;
}
public Player getNext(Game game) {
/**
* checkNextTurnReached - use it turns/priority code only to mark leaved player as "reached next turn end" (need for some continous effects)
*/
public Player getNext(Game game, boolean checkNextTurnReached) {
UUID start = this.get();
if (start == null) {
return null;
@ -42,11 +44,14 @@ public class PlayerList extends CircularList<UUID> {
Player player;
while (true) {
player = game.getPlayer(super.getNext());
if (!player.hasLeft() && !player.hasLost()) {
if (player.isInGame()) {
break;
}
if (!player.hasReachedNextTurnAfterLeaving()) {
player.setReachedNextTurnAfterLeaving(true);
if (checkNextTurnReached) {
if (!player.hasReachedNextTurnAfterLeaving()) {
player.setReachedNextTurnAfterLeaving(true);
}
}
if (player.getId().equals(start)) {
return null;
@ -60,7 +65,7 @@ public class PlayerList extends CircularList<UUID> {
UUID start = this.get();
while (true) {
player = game.getPlayer(super.getPrevious());
if (!player.hasLeft() && !player.hasLost()) {
if (player.isInGame()) {
break;
}
if (player.getId().equals(start)) {