game timer: Add chess-style buffer time option (#10598)

* UI Changes

* Add new buffer time options

* Main functionality

* Final implementation

Also added player UI for when they are using their buffer time (timer turns green)
This commit is contained in:
Alexander Novotny 2023-07-28 22:05:21 -04:00 committed by GitHub
parent b7543af939
commit 519b3988be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 273 additions and 16 deletions

View file

@ -0,0 +1,41 @@
package mage.constants;
/**
* The time a player receives whenever the timer starts. This ticks down before their normal time,
* and refreshes to full every time the timer starts, creating a sort of buffer. Similar to how to
* chess clocks work.
*
* Based off of MatchTimeLimit
*
* @author alexander-novo
*/
public enum MatchBufferTime {
NONE(0, "None"),
SEC__05(5, "5 Seconds"),
SEC__10(10, "10 Seconds"),
SEC__15(15, "15 Seconds"),
SEC__20(20, "20 Seconds"),
SEC__25(25, "25 Seconds"),
SEC__30(30, "30 Seconds");
private final int matchSeconds;
private final String name;
MatchBufferTime(int matchSeconds, String name) {
this.matchSeconds = matchSeconds;
this.name = name;
}
public int getBufferTime() {
return matchSeconds;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}

View file

@ -529,6 +529,10 @@ public interface Game extends MageItem, Serializable, Copyable<Game> {
void setPriorityTime(int priorityTime);
int getBufferTime();
void setBufferTime(int bufferTime);
UUID getStartingPlayerId();
void setStartingPlayerId(UUID startingPlayerId);

View file

@ -143,7 +143,8 @@ public abstract class GameImpl implements Game {
private boolean scopeRelevant = false; // replacement effects: used to indicate that currently applied replacement effects have to check for scope relevance (614.12 13/01/18)
private boolean saveGame = false; // replay code, not done
private int priorityTime; // match time limit
private int priorityTime; // Match time limit (per player). Set at the start of the match and only goes down.
private int bufferTime; // Buffer time before priority time starts going down. Buffer time is refreshed every time the timer starts.
private final int startingLife;
private final int startingHandSize;
private final int minimumDeckSize;
@ -253,6 +254,7 @@ public abstract class GameImpl implements Game {
this.scopeRelevant = game.scopeRelevant;
this.saveGame = game.saveGame;
this.priorityTime = game.priorityTime;
this.bufferTime = game.bufferTime;
this.startingLife = game.startingLife;
this.startingHandSize = game.startingHandSize;
this.minimumDeckSize = game.minimumDeckSize;
@ -3645,6 +3647,16 @@ public abstract class GameImpl implements Game {
this.priorityTime = priorityTime;
}
@Override
public int getBufferTime() {
return bufferTime;
}
@Override
public void setBufferTime(int bufferTime) {
this.bufferTime = bufferTime;
}
@Override
public UUID getStartingPlayerId() {
return startingPlayerId;

View file

@ -201,9 +201,11 @@ public abstract class MatchImpl implements Match {
// set the priority time left for the match
if (games.isEmpty()) { // first game full time
matchPlayer.getPlayer().setPriorityTimeLeft(options.getPriorityTime());
matchPlayer.getPlayer().setBufferTimeLeft(options.getBufferTime());
} else {
if (matchPlayer.getPriorityTimeLeft() > 0) {
matchPlayer.getPlayer().setPriorityTimeLeft(matchPlayer.getPriorityTimeLeft());
matchPlayer.getPlayer().setBufferTimeLeft(options.getBufferTime());
}
}
} else {
@ -213,6 +215,7 @@ public abstract class MatchImpl implements Match {
}
}
game.setPriorityTime(options.getPriorityTime());
game.setBufferTime(options.getBufferTime());
}
protected void shufflePlayers() {

View file

@ -1,6 +1,7 @@
package mage.game.match;
import mage.constants.MatchBufferTime;
import mage.constants.MatchTimeLimit;
import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence;
@ -48,6 +49,7 @@ public class MatchOptions implements Serializable {
* Time each player has during the game to play using his\her priority.
*/
protected MatchTimeLimit matchTimeLimit; // 0 = no priorityTime handling
protected MatchBufferTime matchBufferTime; // Amount of time each player gets before their normal time limit counts down. Refreshes each time the normal timer is invoked.
protected MulliganType mulliganType;
/*public MatchOptions(String name, String gameType) {
@ -160,6 +162,21 @@ public class MatchOptions implements Serializable {
this.matchTimeLimit = matchTimeLimit;
}
public int getBufferTime() {
if (matchBufferTime == null) {
return MatchBufferTime.NONE.getBufferTime();
}
return matchBufferTime.getBufferTime();
}
public MatchBufferTime getMatchBufferTime() {
return this.matchBufferTime;
}
public void setMatchBufferTime(MatchBufferTime matchBufferTime) {
this.matchBufferTime = matchBufferTime;
}
public String getPassword() {
return password;
}

View file

@ -854,6 +854,20 @@ public interface Player extends MageItem, Copyable<Player> {
*/
int getPriorityTimeLeft();
/**
* Set seconds left before priority time starts ticking down.
*
* @param timeLeft
*/
void setBufferTimeLeft(int timeLeft);
/**
* Returns seconds left before priority time starts ticking down.
*
* @return
*/
int getBufferTimeLeft();
void setReachedNextTurnAfterLeaving(boolean reachedNextTurnAfterLeaving);
boolean hasReachedNextTurnAfterLeaving();

View file

@ -119,6 +119,7 @@ public abstract class PlayerImpl implements Player, Serializable {
protected int turns;
protected int storedBookmark = -1;
protected int priorityTimeLeft = Integer.MAX_VALUE;
protected int bufferTimeLeft = 0;
// conceded or connection lost game
protected boolean left;
@ -275,6 +276,7 @@ public abstract class PlayerImpl implements Player, Serializable {
this.justActivatedType = player.justActivatedType;
this.priorityTimeLeft = player.getPriorityTimeLeft();
this.bufferTimeLeft = player.getBufferTimeLeft();
this.reachedNextTurnAfterLeaving = player.reachedNextTurnAfterLeaving;
this.castSourceIdWithAlternateMana.addAll(player.getCastSourceIdWithAlternateMana());
@ -4454,6 +4456,16 @@ public abstract class PlayerImpl implements Player, Serializable {
return priorityTimeLeft;
}
@Override
public void setBufferTimeLeft(int timeLeft) {
bufferTimeLeft = timeLeft;
}
@Override
public int getBufferTimeLeft() {
return bufferTimeLeft;
}
@Override
public boolean hasQuit() {
return quit;