Turn under control reworked:

- game: added support for human games (cards like Emrakul, the Promised End, #12878);
 - game: added support of 720.1. to reset control in the turn beginning instead cleanup step (related to #12115);
 - game: added game logs for priorities in cleanup step;
 - game: fixed game freezes and wrong skip settings usages (related to #12878);
 - gui: added playable and choose-able marks for controlling player's cards and permanents, including switched hands;
 - gui: added controlling player name in all choice dialogs;
 - info: control of computer players is it not yet supported;
This commit is contained in:
Oleg Agafonov 2025-01-07 12:26:30 +04:00
parent 75d241d541
commit c076f4925f
17 changed files with 177 additions and 140 deletions

View file

@ -906,14 +906,14 @@ public class GameController implements GameCallback {
perform(playerId, playerId1 -> getGameSession(playerId1).getMultiAmount(messages, min, max, options));
}
private void informOthers(UUID playerId) {
private void informOthers(UUID waitingPlayerId) {
StringBuilder message = new StringBuilder();
if (game.getStep() != null) {
message.append(game.getTurnStepType().toString()).append(" - ");
}
message.append("Waiting for ").append(game.getPlayer(playerId).getLogName());
message.append("Waiting for ").append(game.getPlayer(waitingPlayerId).getLogName());
for (final Entry<UUID, GameSessionPlayer> entry : getGameSessionsMap().entrySet()) {
if (!entry.getKey().equals(playerId)) {
if (!entry.getKey().equals(waitingPlayerId)) {
entry.getValue().inform(message.toString());
}
}
@ -1030,7 +1030,7 @@ public class GameController implements GameCallback {
// TODO: if watcher disconnects then game freezes with active timer, must be fix for such use case
// same for another player (can be fixed by super-duper connection)
if (informOthers) {
informOthers(playerId);
informOthers(realPlayerController.getId());
}
}

View file

@ -212,13 +212,14 @@ public class GameSessionPlayer extends GameSessionWatcher {
// game view calculation can take some time and can be called from non-game thread,
// so use copy for thread save (protection from ConcurrentModificationException)
Game sourceGame = game.copy();
Player player = sourceGame.getPlayer(playerId); // null for watcher
GameView gameView = new GameView(sourceGame.getState(), sourceGame, playerId, null);
if (player != null) {
if (gameView.getPriorityPlayerName().equals(player.getName())) {
gameView.setCanPlayObjects(player.getPlayableObjects(sourceGame, Zone.ALL));
}
// playable info (if opponent under control then show opponent's playable)
Player player = sourceGame.getPlayer(playerId); // null for watcher
Player priorityPlayer = sourceGame.getPlayer(sourceGame.getPriorityPlayerId());
Player controllingPlayer = priorityPlayer == null ? null : sourceGame.getPlayer(priorityPlayer.getTurnControlledBy());
if (controllingPlayer != null && player == controllingPlayer) {
gameView.setCanPlayObjects(priorityPlayer.getPlayableObjects(sourceGame, Zone.ALL));
}
processControlledPlayers(sourceGame, player, gameView);