* Added optional rollback current turn and up to 3 previous turns to the battlefield menu. All other players have to agree to the rollback to let it happen.

This commit is contained in:
LevelX2 2015-06-07 00:53:08 +02:00
parent 5736efa103
commit 8acf28eed1
38 changed files with 661 additions and 252 deletions

View file

@ -43,6 +43,7 @@ import mage.constants.RangeOfInfluence;
import mage.constants.TableState;
import mage.game.Game;
import mage.game.GameException;
import mage.game.GameOptions;
import mage.game.Seat;
import mage.game.Table;
import mage.game.draft.Draft;
@ -551,7 +552,10 @@ public class TableController {
try {
match.startGame();
table.initGame();
GameManager.getInstance().createGameSession(match.getGame(), userPlayerMap, table.getId(), choosingPlayerId);
GameOptions gameOptions = new GameOptions();
gameOptions.rollbackTurnsAllowed = match.getOptions().isRollbackTurnsAllowed();
match.getGame().setGameOptions(gameOptions);
GameManager.getInstance().createGameSession(match.getGame(), userPlayerMap, table.getId(), choosingPlayerId, gameOptions);
String creator = null;
StringBuilder opponent = new StringBuilder();
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { // no AI players

View file

@ -64,6 +64,7 @@ import mage.constants.PlayerAction;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.GameException;
import mage.game.GameOptions;
import mage.game.Table;
import mage.game.events.Listener;
import mage.game.events.PlayerQueryEvent;
@ -116,15 +117,23 @@ public class GameController implements GameCallback {
private UUID choosingPlayerId;
private Future<?> gameFuture;
private boolean useTimeout = true;
private GameOptions gameOptions;
private UUID userReqestingRollback;
private int turnsToRollback;
private int requestsOpen;
public GameController(Game game, ConcurrentHashMap<UUID, UUID> userPlayerMap, UUID tableId, UUID choosingPlayerId) {
public GameController(Game game, ConcurrentHashMap<UUID, UUID> userPlayerMap, UUID tableId, UUID choosingPlayerId, GameOptions gameOptions) {
gameSessionId = UUID.randomUUID();
this.userPlayerMap = userPlayerMap;
chatId = ChatManager.getInstance().createChatSession("Game " + game.getId());
this.userReqestingRollback = null;
this.game = game;
this.game.setSaveGame(ConfigSettings.getInstance().isSaveGameActivated());
this.tableId = tableId;
this.choosingPlayerId = choosingPlayerId;
this.gameOptions = gameOptions;
for (Player player: game.getPlayers().values()) {
if (!player.isHuman()) {
useTimeout = false; // no timeout for AI players because of beeing idle
@ -474,6 +483,56 @@ public class GameController implements GameCallback {
case UNDO:
game.undo(getPlayerId(userId));
break;
case ROLLBACK_TURNS: // basic request of a player to rollback
if (data instanceof Integer) {
turnsToRollback = (Integer) data;
if (game.canRollbackTurns(turnsToRollback)) {
requestsOpen = requestPermissionToRollback(userId, turnsToRollback);
if (requestsOpen == 0) {
game.rollbackTurns(turnsToRollback);
turnsToRollback = -1;
requestsOpen = -1;
} else {
userReqestingRollback = userId;
}
} else {
UUID playerId = getPlayerId(userId);
if (playerId != null) {
Player player = game.getPlayer(playerId);
if (player != null) {
game.informPlayer(player, "That turn is not available for rollback.");
}
}
}
}
break;
case ADD_PERMISSION_TO_ROLLBACK_TURN:
if (userReqestingRollback != null && requestsOpen > 0 && !userId.equals(userReqestingRollback)) {
requestsOpen--;
if (requestsOpen == 0) {
game.rollbackTurns(turnsToRollback);
turnsToRollback = -1;
userReqestingRollback = null;
requestsOpen = -1;
}
}
break;
case DENY_PERMISSON_TO_ROLLBACK_TURN: // one player has denied - so cancel the request
{
UUID playerId = getPlayerId(userId);
if (playerId != null) {
Player player = game.getPlayer(playerId);
if (player != null) {
if (userReqestingRollback != null && requestsOpen > 0 && !userId.equals(userReqestingRollback)) {
turnsToRollback = -1;
userReqestingRollback = null;
requestsOpen = -1;
game.informPlayers("Rollback request denied by " + player.getLogName());
}
}
}
}
break;
case CONCEDE:
game.concede(getPlayerId(userId));
break;
@ -513,6 +572,23 @@ public class GameController implements GameCallback {
}
}
private int requestPermissionToRollback(UUID userIdRequester, int numberTurns) {
int requests = 0;
for (Player player: game.getState().getPlayers().values()) {
User requestedUser = getUserByPlayerId(player.getId());
if (player.isInGame() && player.isHuman() &&
requestedUser != null &&
!requestedUser.getId().equals(userIdRequester)) {
requests++;
GameSessionPlayer gameSession = gameSessions.get(player.getId());
if (gameSession != null) {
gameSession.requestPermissionToRollbackTurn(userIdRequester, numberTurns);
}
}
}
return requests;
}
private void requestPermissionToSeeHandCards(UUID userIdRequester, UUID userIdGranter) {
Player grantingPlayer = game.getPlayer(userIdGranter);
if (grantingPlayer != null) {

View file

@ -34,6 +34,7 @@ import mage.cards.decks.DeckCardLists;
import mage.constants.ManaType;
import mage.constants.PlayerAction;
import mage.game.Game;
import mage.game.GameOptions;
import mage.view.GameView;
/**
@ -51,8 +52,8 @@ public class GameManager {
private final ConcurrentHashMap<UUID, GameController> gameControllers = new ConcurrentHashMap<>();
public UUID createGameSession(Game game, ConcurrentHashMap<UUID, UUID> userPlayerMap, UUID tableId, UUID choosingPlayerId) {
GameController gameController = new GameController(game, userPlayerMap, tableId, choosingPlayerId);
public UUID createGameSession(Game game, ConcurrentHashMap<UUID, UUID> userPlayerMap, UUID tableId, UUID choosingPlayerId, GameOptions gameOptions) {
GameController gameController = new GameController(game, userPlayerMap, tableId, choosingPlayerId, gameOptions);
gameControllers.put(game.getId(), gameController);
return gameController.getSessionId();
}

View file

@ -170,6 +170,34 @@ public class GameSessionPlayer extends GameSessionWatcher {
}
}
public void requestPermissionToRollbackTurn(UUID requestingUserId, int numberTurns) {
if (!killed) {
User requestingUser = UserManager.getInstance().getUser(requestingUserId);
User requestedUser = UserManager.getInstance().getUser(userId);
if (requestedUser != null && requestingUser != null) {
String message;
switch(numberTurns) {
case 0:
message = "Allow rollback to the start of the current turn?";
break;
case 1:
message = "Allow rollback to the start of the previous turn?";
break;
default:
message = "Allow to rollback "+numberTurns+ " turns?";
}
UserRequestMessage userRequestMessage = new UserRequestMessage(
"Request by " + requestedUser.getName(), message
, PlayerAction.REQUEST_PERMISSION_TO_ROLLBACK_TURN);
userRequestMessage.setRelatedUser(requestingUserId, requestingUser.getName());
userRequestMessage.setGameId(game.getId());
userRequestMessage.setButton1("Accept", PlayerAction.ADD_PERMISSION_TO_ROLLBACK_TURN);
userRequestMessage.setButton2("Deny", PlayerAction.DENY_PERMISSON_TO_ROLLBACK_TURN);
requestedUser.fireCallback(new ClientCallback("userRequestDialog", game.getId(), userRequestMessage));
}
}
}
public void requestPermissionToSeeHandCards(UUID watcherId) {
if (!killed) {
User watcher = UserManager.getInstance().getUser(watcherId);

View file

@ -37,6 +37,7 @@ import org.apache.log4j.Logger;
/**
*
* @author BetaSteward_at_googlemail.com
* @param <T>
*/
public class GameWorker<T> implements Callable {