mirror of
https://github.com/magefree/mage.git
synced 2026-01-10 04:42:07 -08:00
Fixed (probably) the player1 concedes but other player2 wins. Fixed that if player runs out of timer time or player lose of beeing idle, the match will end correctly.
This commit is contained in:
parent
6d039e4262
commit
473c9e207b
32 changed files with 286 additions and 132 deletions
|
|
@ -13,7 +13,7 @@ public enum TableState {
|
|||
CONSTRUCTING ("Constructing"),
|
||||
FINISHED ("Finished");
|
||||
|
||||
private String text;
|
||||
private final String text;
|
||||
|
||||
TableState(String text) {
|
||||
this.text = text;
|
||||
|
|
|
|||
|
|
@ -122,7 +122,8 @@ public interface Game extends MageItem, Serializable {
|
|||
UUID getActivePlayerId();
|
||||
UUID getPriorityPlayerId();
|
||||
void leave(UUID playerId);
|
||||
boolean isGameOver();
|
||||
boolean gameOver(UUID playerId);
|
||||
boolean hasEnded();
|
||||
Battlefield getBattlefield();
|
||||
SpellStack getStack();
|
||||
Exile getExile();
|
||||
|
|
@ -218,6 +219,8 @@ public interface Game extends MageItem, Serializable {
|
|||
void mulligan(UUID playerId);
|
||||
void endMulligan(UUID playerId);
|
||||
void quit(UUID playerId);
|
||||
void timerTimeout(UUID playerId);
|
||||
void idleTimeout(UUID playerId);
|
||||
void concede(UUID playerId);
|
||||
void undo(UUID playerId);
|
||||
void emptyManaPools();
|
||||
|
|
|
|||
|
|
@ -418,8 +418,26 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts check if game over or if playerId is given
|
||||
* let the player concede.
|
||||
*
|
||||
* @param playerId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean isGameOver() {
|
||||
public synchronized boolean gameOver(UUID playerId) {
|
||||
if (playerId == null) {
|
||||
boolean result = checkIfGameIsOver();
|
||||
return result;
|
||||
} else {
|
||||
leave(playerId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean checkIfGameIsOver() {
|
||||
if (state.isGameOver()) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -447,6 +465,11 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnded() {
|
||||
return endTime != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWinner() {
|
||||
if (winnerId == null) {
|
||||
|
|
@ -546,13 +569,13 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
Player player = getPlayer(players.get());
|
||||
boolean wasPaused = state.isPaused();
|
||||
state.resume();
|
||||
if (!isGameOver()) {
|
||||
if (!gameOver(null)) {
|
||||
fireInformEvent(new StringBuilder("Turn ").append(state.getTurnNum()).toString());
|
||||
if (checkStopOnTurnOption()) {
|
||||
return;
|
||||
}
|
||||
state.getTurn().resumePlay(this, wasPaused);
|
||||
if (!isPaused() && !isGameOver()) {
|
||||
if (!isPaused() && !gameOver(null)) {
|
||||
endOfTurn();
|
||||
player = players.getNext(this);
|
||||
state.setTurnNum(state.getTurnNum() + 1);
|
||||
|
|
@ -562,10 +585,10 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
|
||||
protected void play(UUID nextPlayerId) {
|
||||
if (!isPaused() && !isGameOver()) {
|
||||
if (!isPaused() && !gameOver(null)) {
|
||||
PlayerList players = state.getPlayerList(nextPlayerId);
|
||||
Player player = getPlayer(players.get());
|
||||
while (!isPaused() && !isGameOver()) {
|
||||
while (!isPaused() && !gameOver(null)) {
|
||||
|
||||
if (!playTurn(player)) {
|
||||
break;
|
||||
|
|
@ -583,7 +606,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
player = players.getNext(this);
|
||||
}
|
||||
}
|
||||
if (isGameOver()) {
|
||||
if (gameOver(null)) {
|
||||
winnerId = findWinnersAndLosers();
|
||||
logger.info(new StringBuilder("Game with gameId ").append(this.getId()).append(" ended."));
|
||||
}
|
||||
|
|
@ -597,7 +620,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
state.setActivePlayerId(player.getId());
|
||||
player.becomesActivePlayer();
|
||||
state.getTurn().play(this, player.getId());
|
||||
if (isPaused() || isGameOver()) {
|
||||
if (isPaused() || gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
endOfTurn();
|
||||
|
|
@ -865,9 +888,30 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
@Override
|
||||
public synchronized void quit(UUID playerId) {
|
||||
Player player = state.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
fireInformEvent(player.getName() + " quits the match.");
|
||||
if (player != null) {
|
||||
player.quit(this);
|
||||
}else {
|
||||
logger.error(new StringBuilder("player not found - playerId: ").append(playerId));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void timerTimeout(UUID playerId) {
|
||||
Player player = state.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
player.timerTimeout(this);
|
||||
} else {
|
||||
logger.error(new StringBuilder("player not found - playerId: ").append(playerId));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void idleTimeout(UUID playerId) {
|
||||
Player player = state.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
player.idleTimeout(this);
|
||||
} else {
|
||||
logger.error(new StringBuilder("player not found - playerId: ").append(playerId));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -923,7 +967,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
int bookmark = 0;
|
||||
clearAllBookmarks();
|
||||
try {
|
||||
while (!isPaused() && !isGameOver()) {
|
||||
while (!isPaused() && !gameOver(null)) {
|
||||
if (!resuming) {
|
||||
state.getPlayers().resetPassed();
|
||||
state.getPlayerList().setCurrent(activePlayerId);
|
||||
|
|
@ -933,13 +977,13 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
fireUpdatePlayersEvent();
|
||||
Player player;
|
||||
while (!isPaused() && !isGameOver()) {
|
||||
while (!isPaused() && !gameOver(null)) {
|
||||
try {
|
||||
//if (bookmark == 0)
|
||||
//bookmark = bookmarkState();
|
||||
player = getPlayer(state.getPlayerList().get());
|
||||
state.setPriorityPlayerId(player.getId());
|
||||
while (!player.isPassed() && player.isInGame() && !isPaused() && !isGameOver()) {
|
||||
while (!player.isPassed() && player.isInGame() && !isPaused() && !gameOver(null)) {
|
||||
if (!resuming) {
|
||||
if (checkStateAndTriggered()) {
|
||||
applyEffects();
|
||||
|
|
@ -947,7 +991,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
//resetLKI();
|
||||
applyEffects();
|
||||
saveState(false);
|
||||
if (isPaused() || isGameOver()) {
|
||||
if (isPaused() || gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
// resetPassed should be called if player performs any action
|
||||
|
|
@ -962,7 +1006,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
resetShortLivingLKI();
|
||||
resuming = false;
|
||||
if (isPaused() || isGameOver()) {
|
||||
if (isPaused() || gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
if (allPassed()) {
|
||||
|
|
@ -1164,9 +1208,9 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
public boolean checkStateAndTriggered() {
|
||||
boolean somethingHappened = false;
|
||||
//20091005 - 115.5
|
||||
while (!isPaused() && !this.isGameOver()) {
|
||||
while (!isPaused() && !gameOver(null)) {
|
||||
if (!checkStateBasedActions() ) {
|
||||
if (isPaused() || this.isGameOver() || !checkTriggered()) {
|
||||
if (isPaused() || gameOver(null) || !checkTriggered()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1729,7 +1773,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
return;
|
||||
}
|
||||
player.leave();
|
||||
if (this.isGameOver()) {
|
||||
if (gameOver(null)) {
|
||||
// no need to remove objects if only one player is left so the game is over
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,8 +112,8 @@ public class Table implements Serializable {
|
|||
}
|
||||
|
||||
public void initTournament() {
|
||||
setState(TableState.DUELING);
|
||||
|
||||
setState(TableState.DUELING);
|
||||
tournament.setStepStartTime(new Date());
|
||||
}
|
||||
|
||||
public void endTournament() {
|
||||
|
|
@ -122,10 +122,12 @@ public class Table implements Serializable {
|
|||
|
||||
public void initDraft() {
|
||||
setState(TableState.DRAFTING);
|
||||
tournament.setStepStartTime(new Date());
|
||||
}
|
||||
|
||||
public void construct() {
|
||||
setState(TableState.CONSTRUCTING);
|
||||
tournament.setStepStartTime(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
//20101001 - 508.1d
|
||||
checkAttackRequirements(player, game);
|
||||
player.selectAttackers(game, attackerId);
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
checkAttackRestrictions(player, game);
|
||||
|
|
@ -316,7 +316,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
}
|
||||
while (choose) {
|
||||
blockController.selectBlockers(game, defenderId);
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
if (!this.checkBlockRestrictions(defender, game)) {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ public interface Match {
|
|||
|
||||
UUID getId();
|
||||
String getName();
|
||||
boolean isMatchOver();
|
||||
boolean hasEnded();
|
||||
boolean checkIfMatchEnds();
|
||||
List<MatchPlayer> getPlayers();
|
||||
MatchPlayer getPlayer(UUID playerId);
|
||||
|
||||
|
|
|
|||
|
|
@ -126,20 +126,31 @@ public abstract class MatchImpl implements Match {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatchOver() {
|
||||
public boolean hasEnded() {
|
||||
return endTime != null;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean checkIfMatchEnds() {
|
||||
int activePlayers = 0;
|
||||
for (MatchPlayer player: players) {
|
||||
if (!player.hasQuit()) {
|
||||
MatchPlayer matchWinner = null;
|
||||
for (MatchPlayer matchPlayer: players) {
|
||||
if (!matchPlayer.hasQuit()) {
|
||||
activePlayers++;
|
||||
matchWinner = matchPlayer;
|
||||
}
|
||||
if (player.getWins() >= options.getWinsNeeded()) {
|
||||
if (matchPlayer.getWins() >= options.getWinsNeeded()) {
|
||||
matchPlayer.setMatchWinner(true);
|
||||
endTime = new Date();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (activePlayers < 2) {
|
||||
endTime = new Date();
|
||||
return true;
|
||||
if (matchWinner != null) {
|
||||
matchWinner.setMatchWinner(true);
|
||||
}
|
||||
endTime = new Date();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -200,24 +211,28 @@ public abstract class MatchImpl implements Match {
|
|||
@Override
|
||||
public void endGame() {
|
||||
Game game = getGame();
|
||||
for (MatchPlayer player: this.players) {
|
||||
Player p = game.getPlayer(player.getPlayer().getId());
|
||||
if (p != null) {
|
||||
for (MatchPlayer matchPlayer: this.players) {
|
||||
Player player = game.getPlayer(matchPlayer.getPlayer().getId());
|
||||
if (player != null) {
|
||||
// get the left time from player priority timer
|
||||
if (game.getPriorityTime() > 0) {
|
||||
player.setPriorityTimeLeft(p.getPriorityTimeLeft());
|
||||
matchPlayer.setPriorityTimeLeft(player.getPriorityTimeLeft());
|
||||
}
|
||||
if (p.hasQuit()) {
|
||||
player.setQuit(true);
|
||||
if (player.hasQuit()) {
|
||||
matchPlayer.setQuit(true);
|
||||
}
|
||||
if (p.hasWon()) {
|
||||
player.addWin();
|
||||
if (player.hasTimerTimeout()) {
|
||||
matchPlayer.setTimerTimeout(true);
|
||||
}
|
||||
if (p.hasLost()) {
|
||||
player.addLose();
|
||||
if (player.hasWon()) {
|
||||
matchPlayer.addWin();
|
||||
}
|
||||
if (player.hasLost()) {
|
||||
matchPlayer.addLose();
|
||||
}
|
||||
}
|
||||
}
|
||||
checkIfMatchEnds();
|
||||
game.fireGameEndInfo();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,12 +39,14 @@ import mage.players.Player;
|
|||
public class MatchPlayer {
|
||||
private int wins;
|
||||
private int loses;
|
||||
|
||||
private boolean matchWinner;
|
||||
|
||||
private Deck deck;
|
||||
private Player player;
|
||||
private final String name;
|
||||
|
||||
private boolean quit;
|
||||
private boolean timerTimeout;
|
||||
private boolean doneSideboarding;
|
||||
private int priorityTimeLeft;
|
||||
|
||||
|
|
@ -55,7 +57,9 @@ public class MatchPlayer {
|
|||
this.loses = 0;
|
||||
this.doneSideboarding = true;
|
||||
this.quit = false;
|
||||
this.timerTimeout = false;
|
||||
this.name = player.getName();
|
||||
this.matchWinner = false;
|
||||
}
|
||||
|
||||
public int getPriorityTimeLeft() {
|
||||
|
|
@ -125,7 +129,23 @@ public class MatchPlayer {
|
|||
this.doneSideboarding = true;
|
||||
this.quit = quit;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasTimerTimeout() {
|
||||
return timerTimeout;
|
||||
}
|
||||
|
||||
public void setTimerTimeout(boolean timerTimeout) {
|
||||
this.timerTimeout = timerTimeout;
|
||||
}
|
||||
|
||||
public boolean isMatchWinner() {
|
||||
return matchWinner;
|
||||
}
|
||||
|
||||
public void setMatchWinner(boolean matchWinner) {
|
||||
this.matchWinner = matchWinner;
|
||||
}
|
||||
|
||||
public void cleanUpOnMatchEnd() {
|
||||
// Free resources that are not needed after match end
|
||||
this.deck = null;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public class Round {
|
|||
public boolean isRoundOver() {
|
||||
boolean roundIsOver = true;
|
||||
for (TournamentPairing pair: pairs) {
|
||||
if (pair.getMatch() != null && !pair.getMatch().isMatchOver()) {
|
||||
if (pair.getMatch() != null && !pair.getMatch().hasEnded()) {
|
||||
roundIsOver = false;
|
||||
} else {
|
||||
if (!pair.isAlreadyPublished()) {
|
||||
|
|
|
|||
|
|
@ -78,6 +78,10 @@ public interface Tournament {
|
|||
// tournament times
|
||||
Date getStartTime();
|
||||
Date getEndTime();
|
||||
|
||||
Date getStepStartTime();
|
||||
void setStepStartTime(Date date);
|
||||
|
||||
// tournament type
|
||||
TournamentType getTournamentType();
|
||||
void setTournamentType(TournamentType tournamentType);
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ public abstract class TournamentImpl implements Tournament {
|
|||
|
||||
protected Date startTime;
|
||||
protected Date endTime;
|
||||
protected Date stepStartTime;
|
||||
protected boolean abort;
|
||||
protected String tournamentState;
|
||||
|
||||
|
|
@ -244,7 +245,7 @@ public abstract class TournamentImpl implements Tournament {
|
|||
for (Round round: rounds) {
|
||||
for (TournamentPairing pair: round.getPairs()) {
|
||||
Match match = pair.getMatch();
|
||||
if (match != null && match.isMatchOver()) {
|
||||
if (match != null && match.hasEnded()) {
|
||||
TournamentPlayer tp1 = pair.getPlayer1();
|
||||
TournamentPlayer tp2 = pair.getPlayer2();
|
||||
MatchPlayer mp1 = match.getPlayer(pair.getPlayer1().getPlayer().getId());
|
||||
|
|
@ -302,11 +303,11 @@ public abstract class TournamentImpl implements Tournament {
|
|||
matchResult.append(p2.getPlayer().getName());
|
||||
matchResult.append(" (").append(mp1.getWins());
|
||||
if (mp1.hasQuit()) {
|
||||
matchResult.append("Q");
|
||||
matchResult.append(mp1.hasTimerTimeout()?"T":"Q");
|
||||
}
|
||||
matchResult.append("-").append(mp2.getWins());
|
||||
if (mp2.hasQuit()) {
|
||||
matchResult.append("Q");
|
||||
matchResult.append(mp2.hasTimerTimeout()?"T":"Q");
|
||||
}
|
||||
matchResult.append(") ");
|
||||
return matchResult.toString();
|
||||
|
|
@ -479,4 +480,18 @@ public abstract class TournamentImpl implements Tournament {
|
|||
this.tournamentState = tournamentState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getStepStartTime() {
|
||||
if (stepStartTime != null) {
|
||||
return new Date(stepStartTime.getTime());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStepStartTime(Date stepStartTime) {
|
||||
this.stepStartTime = stepStartTime;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public class TournamentPairing {
|
|||
}
|
||||
|
||||
public void eliminatePlayers() {
|
||||
if (match.isMatchOver()) {
|
||||
if (match.hasEnded()) {
|
||||
MatchPlayer mPlayer1 = match.getPlayer(player1.getPlayer().getId());
|
||||
MatchPlayer mPlayer2 = match.getPlayer(player2.getPlayer().getId());
|
||||
if (mPlayer1.hasQuit() || (!mPlayer2.hasQuit() && mPlayer1.getWins() < match.getWinsNeeded())) {
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
}
|
||||
|
||||
public boolean play(Game game, UUID activePlayerId) {
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
if (beginPhase(game, activePlayerId)) {
|
||||
|
||||
for (Step step: steps) {
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
currentStep = step;
|
||||
|
|
@ -115,7 +115,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
playStep(game);
|
||||
}
|
||||
}
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
count++;
|
||||
|
|
@ -136,7 +136,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
}
|
||||
|
||||
public boolean resumePlay(Game game, PhaseStep stepType, boolean wasPaused) {
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
resumeStep(game, wasPaused);
|
||||
while (it.hasNext()) {
|
||||
step = it.next();
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
currentStep = step;
|
||||
|
|
@ -159,7 +159,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
count++;
|
||||
|
|
@ -194,10 +194,10 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
protected void playStep(Game game) {
|
||||
if (!currentStep.skipStep(game, activePlayerId)) {
|
||||
prePriority(game, activePlayerId);
|
||||
if (!game.isPaused() && !game.isGameOver()) {
|
||||
if (!game.isPaused() && !game.gameOver(null)) {
|
||||
currentStep.priority(game, activePlayerId, false);
|
||||
}
|
||||
if (!game.isPaused() && !game.isGameOver()) {
|
||||
if (!game.isPaused() && !game.gameOver(null)) {
|
||||
postPriority(game, activePlayerId);
|
||||
}
|
||||
}
|
||||
|
|
@ -219,11 +219,11 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
prePriority(game, activePlayerId);
|
||||
}
|
||||
case PRIORITY:
|
||||
if (!game.isPaused() && !game.isGameOver()) {
|
||||
if (!game.isPaused() && !game.gameOver(null)) {
|
||||
currentStep.priority(game, activePlayerId, resuming);
|
||||
}
|
||||
case POST:
|
||||
if (!game.isPaused() && !game.isGameOver()) {
|
||||
if (!game.isPaused() && !game.gameOver(null)) {
|
||||
postPriority(game, activePlayerId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public class Turn implements Serializable {
|
|||
|
||||
private Phase currentPhase;
|
||||
private UUID activePlayerId;
|
||||
private List<Phase> phases = new ArrayList<Phase>();
|
||||
private final List<Phase> phases = new ArrayList<>();
|
||||
private boolean declareAttackersStepStarted = false;
|
||||
|
||||
public Turn() {
|
||||
|
|
@ -109,7 +109,7 @@ public class Turn implements Serializable {
|
|||
|
||||
public void play(Game game, UUID activePlayerId) {
|
||||
this.setDeclareAttackersStepStarted(false);
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ public class Turn implements Serializable {
|
|||
resetCounts();
|
||||
game.getPlayer(activePlayerId).beginTurn(game);
|
||||
for (Phase phase: phases) {
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
currentPhase = phase;
|
||||
|
|
@ -168,7 +168,7 @@ public class Turn implements Serializable {
|
|||
}
|
||||
while (it.hasNext()) {
|
||||
phase = it.next();
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
currentPhase = phase;
|
||||
|
|
|
|||
|
|
@ -129,6 +129,10 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
boolean hasWon();
|
||||
boolean hasQuit();
|
||||
void quit(Game game);
|
||||
boolean hasTimerTimeout();
|
||||
void timerTimeout(Game game);
|
||||
boolean hasIdleTimeout();
|
||||
void idleTimeout(Game game);
|
||||
boolean hasLeft();
|
||||
/**
|
||||
* Player is still active in game (has not left, lost or won the game).
|
||||
|
|
|
|||
|
|
@ -114,7 +114,10 @@ import mage.target.common.TargetDiscard;
|
|||
import mage.watchers.common.BloodthirstWatcher;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* * @param <T>
|
||||
*/
|
||||
public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Serializable {
|
||||
|
||||
private static final transient Logger log = Logger.getLogger(PlayerImpl.class);
|
||||
|
|
@ -160,6 +163,10 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
protected boolean left;
|
||||
// set if the player quits the complete match
|
||||
protected boolean quit;
|
||||
// set if the player lost match because of priority timeout
|
||||
protected boolean timerTimeout;
|
||||
// set if the player lost match because of idle timeout
|
||||
protected boolean idleTimeout;
|
||||
|
||||
protected RangeOfInfluence range;
|
||||
protected Set<UUID> inRange = new HashSet<>();
|
||||
|
|
@ -234,6 +241,8 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
|
||||
this.left = player.left;
|
||||
this.quit = player.quit;
|
||||
this.timerTimeout = player.timerTimeout;
|
||||
this.idleTimeout = player.idleTimeout;
|
||||
this.range = player.range;
|
||||
this.canGainLife = player.canGainLife;
|
||||
this.canLoseLife = player.canLoseLife;
|
||||
|
|
@ -288,6 +297,8 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
|
||||
this.left = player.hasLeft();
|
||||
this.quit = player.hasQuit();
|
||||
this.timerTimeout = player.hasTimerTimeout();
|
||||
this.idleTimeout = player.hasIdleTimeout();
|
||||
this.range = player.getRange();
|
||||
this.canGainLife = player.isCanGainLife();
|
||||
this.canLoseLife = player.isCanLoseLife();
|
||||
|
|
@ -343,7 +354,11 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
this.wins = false;
|
||||
this.loses = false;
|
||||
this.left = false;
|
||||
this.quit = false; // reset is neccessary because in tournament player will be used for each round
|
||||
// reset is neccessary because in tournament player will be used for each round
|
||||
this.quit = false;
|
||||
this.timerTimeout = false;
|
||||
this.idleTimeout = false;
|
||||
|
||||
this.passed = false;
|
||||
this.passedTurn = false;
|
||||
this.passedAllTurns = false;
|
||||
|
|
@ -732,7 +747,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
resetStoredBookmark(game);
|
||||
return true;
|
||||
}
|
||||
if (!game.isGameOver()) { // if player left or game is over no undo is possible - this could lead to wrong winner
|
||||
if (!game.hasEnded()) { // if player left or game is over no undo is possible - this could lead to wrong winner
|
||||
game.restoreState(bookmark);
|
||||
}
|
||||
}
|
||||
|
|
@ -1475,13 +1490,30 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
|
||||
@Override
|
||||
public void quit(Game game) {
|
||||
game.informPlayers(new StringBuilder(getName()).append(" quits the match.").toString());
|
||||
quit = true;
|
||||
this.concede(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timerTimeout(Game game) {
|
||||
game.informPlayers(new StringBuilder(getName()).append(" has run out of time. Loosing the Match.").toString());
|
||||
quit = true;
|
||||
timerTimeout = true;
|
||||
this.concede(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void idleTimeout(Game game) {
|
||||
game.informPlayers(new StringBuilder(getName()).append(" has run out of time. Loosing the Match.").toString());
|
||||
quit = true;
|
||||
idleTimeout = true;
|
||||
this.concede(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void concede(Game game) {
|
||||
game.leave(playerId);
|
||||
game.gameOver(playerId);
|
||||
lost(game);
|
||||
this.left = true;
|
||||
}
|
||||
|
|
@ -2117,6 +2149,16 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
return quit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTimerTimeout() {
|
||||
return timerTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIdleTimeout() {
|
||||
return idleTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReachedNextTurnAfterLeaving(boolean reachedNextTurnAfterLeaving) {
|
||||
this.reachedNextTurnAfterLeaving = reachedNextTurnAfterLeaving;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue