From 9ba19464739fe85ad79356cdd280aef90abb2b7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Wed, 4 Nov 2026 08:52:00 +0100 Subject: [PATCH] [Client] Address the seat-order review comments - Give the game setup checkboxes a row of their own so they no longer collide in the create-game dialog - Rename DlgTurnOrder::randomize() to isRandomizeRequested() - Document what the ids in GameState::seatOrder mean - Keep "Set turn order..." in sync with the game: hidden for non-hosts and once the game has started, re-shown when the game ends or hosting moves to the local player (new GameState::hostChanged signal) --- .../widgets/dialogs/dlg_create_game.cpp | 6 ++--- .../widgets/dialogs/dlg_turn_order.h | 2 +- .../src/interface/widgets/tabs/tab_game.cpp | 22 +++++++++++++++---- .../src/interface/widgets/tabs/tab_game.h | 1 + .../libcockatrice/game/game_state.h | 7 ++++++ 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp index 15d086c26..ada4237f7 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp @@ -123,10 +123,10 @@ void DlgCreateGame::sharedCtor() auto *gameSetupOptionsLayout = new QGridLayout; gameSetupOptionsLayout->addWidget(startingLifeTotalLabel, 0, 0); gameSetupOptionsLayout->addWidget(startingLifeTotalEdit, 0, 1); - gameSetupOptionsLayout->addWidget(shareDecklistsOnLoadCheckBox, 1, 0); - gameSetupOptionsLayout->addWidget(shufflePlayersCheckBox, 1, 1); + gameSetupOptionsLayout->addWidget(shareDecklistsOnLoadCheckBox, 1, 0, 1, 2); + gameSetupOptionsLayout->addWidget(shufflePlayersCheckBox, 2, 0, 1, 2); if (room && room->getUserInfo()->user_level() & ServerInfo_User::IsJudge) { - gameSetupOptionsLayout->addWidget(createGameAsJudgeCheckBox, 2, 0); + gameSetupOptionsLayout->addWidget(createGameAsJudgeCheckBox, 3, 0, 1, 2); } else { createGameAsJudgeCheckBox->setChecked(false); createGameAsJudgeCheckBox->setHidden(true); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_turn_order.h b/cockatrice/src/interface/widgets/dialogs/dlg_turn_order.h index 8b47bd5fe..2670d9336 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_turn_order.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_turn_order.h @@ -38,7 +38,7 @@ public: void retranslateUi(); - [[nodiscard]] bool randomize() const + [[nodiscard]] bool isRandomizeRequested() const { return randomizeRequested; } diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.cpp b/cockatrice/src/interface/widgets/tabs/tab_game.cpp index bfd31923d..7270e001a 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_game.cpp @@ -192,6 +192,7 @@ void TabGame::connectToGameState() { connect(game->getGameState(), &GameState::gameStarted, this, &TabGame::startGame); connect(game->getGameState(), &GameState::gameStopped, this, &TabGame::stopGame); + connect(game->getGameState(), &GameState::hostChanged, this, &TabGame::updateTurnOrderAction); connect(game->getGameState(), &GameState::activePhaseChanged, this, &TabGame::setActivePhase); connect(game->getGameState(), &GameState::activePlayerChanged, this, &TabGame::setActivePlayer); } @@ -664,7 +665,20 @@ void TabGame::actTurnOrder() return; } - game->getGameEventHandler()->handleSetPlayerOrder(dlg.order(), dlg.randomize()); + game->getGameEventHandler()->handleSetPlayerOrder(dlg.order(), dlg.isRandomizeRequested()); +} + +/** + * Shows the turn order action only when it can actually change anything: the + * player must be host and the game must not have started yet. Called whenever + * either condition may have changed (game start/stop, host change). + */ +void TabGame::updateTurnOrderAction() +{ + if (aTurnOrder == nullptr) { + return; + } + aTurnOrder->setVisible(game->isHost() && !game->getGameMetaInfo()->started()); } /** @@ -995,6 +1009,7 @@ void TabGame::startGame(bool _resuming) aConcede->setText(tr("&Concede")); aConcede->setEnabled(true); } + updateTurnOrderAction(); } void TabGame::stopGame() @@ -1017,6 +1032,7 @@ void TabGame::stopGame() aConcede->setText(tr("&Concede")); aConcede->setEnabled(false); } + updateTurnOrderAction(); } void TabGame::closeGame() @@ -1143,9 +1159,7 @@ void TabGame::createMenuItems() connect(aReverseTurn, &QAction::triggered, game->getGameEventHandler(), &GameEventHandler::handleReverseTurn); aTurnOrder = new QAction(this); connect(aTurnOrder, &QAction::triggered, this, &TabGame::actTurnOrder); - if (!game->isHost() || game->getGameMetaInfo()->started()) { - aTurnOrder->setVisible(false); - } + updateTurnOrderAction(); aRemoveLocalArrows = new QAction(this); connect(aRemoveLocalArrows, &QAction::triggered, this, &TabGame::actRemoveLocalArrows); aRotateViewCW = new QAction(this); diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.h b/cockatrice/src/interface/widgets/tabs/tab_game.h index 7d044ec28..7e9452caf 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.h +++ b/cockatrice/src/interface/widgets/tabs/tab_game.h @@ -164,6 +164,7 @@ private slots: void actConcede(); void actCopyGameLink(); void actTurnOrder(); + void updateTurnOrderAction(); void actRemoveLocalArrows(); void actRotateViewCW(); void actRotateViewCCW(); diff --git a/libcockatrice_game/libcockatrice/game/game_state.h b/libcockatrice_game/libcockatrice/game/game_state.h index 7d3941cb7..4d02019ce 100644 --- a/libcockatrice_game/libcockatrice/game/game_state.h +++ b/libcockatrice_game/libcockatrice/game/game_state.h @@ -33,7 +33,11 @@ public: void setHostId(int _hostId) { + if (hostId == _hostId) { + return; + } hostId = _hostId; + emit hostChanged(hostId); } QList getClients() const @@ -136,6 +140,7 @@ signals: void gameStopped(); void activePhaseChanged(int activePhase); void activePlayerChanged(int playerId); + void hostChanged(int hostId); void seatOrderChanged(const QList &seatOrder); public slots: @@ -156,6 +161,8 @@ private: int currentPhase; int activePlayer; bool gameClosed; + //! Player ids in seating (turn) order, first to play first. Empty until the + //! server sends an order, in which case players are laid out in id order. QList seatOrder; };