mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-13 05:20:00 -08:00
[Client] Lay out table and turn order dialog in seat order
This commit is contained in:
parent
00c0b2c96b
commit
6a25a2f15e
4 changed files with 96 additions and 2 deletions
|
|
@ -35,6 +35,7 @@
|
|||
#include <functional>
|
||||
#include <libcockatrice/game/abstract_game.h>
|
||||
#include <libcockatrice/game/board/arrow_data.h>
|
||||
#include <libcockatrice/game/game_state.h>
|
||||
#include <libcockatrice/game/player/player_actions.h>
|
||||
#include <libcockatrice/game/player/player_event_handler.h>
|
||||
#include <libcockatrice/game/player/player_info.h>
|
||||
|
|
@ -432,6 +433,37 @@ QList<PlayerLogic *> GameScene::collectActivePlayers(int &firstPlayerIndex) cons
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lay out the table in seat order rather than id order. Players missing
|
||||
// from the tracked order keep id order at the end.
|
||||
QList<int> seatOrder;
|
||||
for (auto *pgItem : playerViews.values()) {
|
||||
if (PlayerLogic *p = pgItem->getLogic()) {
|
||||
seatOrder = p->getGame()->getGameState()->getSeatOrder();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!seatOrder.isEmpty()) {
|
||||
std::sort(activePlayers.begin(), activePlayers.end(), [&](PlayerLogic *a, PlayerLogic *b) {
|
||||
int indexA = seatOrder.indexOf(a->getPlayerInfo()->getId());
|
||||
int indexB = seatOrder.indexOf(b->getPlayerInfo()->getId());
|
||||
if (indexA == -1) {
|
||||
indexA = seatOrder.size() + a->getPlayerInfo()->getId();
|
||||
}
|
||||
if (indexB == -1) {
|
||||
indexB = seatOrder.size() + b->getPlayerInfo()->getId();
|
||||
}
|
||||
return indexA < indexB;
|
||||
});
|
||||
// Recompute the local-player index after sorting.
|
||||
firstPlayerIndex = 0;
|
||||
for (int i = 0; i < activePlayers.size(); ++i) {
|
||||
if (activePlayers[i]->getPlayerInfo()->getLocal()) {
|
||||
firstPlayerIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return activePlayers;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -638,8 +638,25 @@ void TabGame::actTurnOrder()
|
|||
}
|
||||
|
||||
QStringList playerNames;
|
||||
for (PlayerLogic *player : game->getPlayerManager()->getPlayers()) {
|
||||
playerNames.append(player->getPlayerInfo()->getName());
|
||||
const QList<int> seatOrder = game->getGameState()->getSeatOrder();
|
||||
const auto &players = game->getPlayerManager()->getPlayers();
|
||||
if (!seatOrder.isEmpty()) {
|
||||
for (int playerId : seatOrder) {
|
||||
if (PlayerLogic *player = players.value(playerId, nullptr)) {
|
||||
playerNames.append(player->getPlayerInfo()->getName());
|
||||
}
|
||||
}
|
||||
// Include any players missing from the tracked order rather than dropping them.
|
||||
for (auto it = players.constBegin(); it != players.constEnd(); ++it) {
|
||||
const QString name = it.value()->getPlayerInfo()->getName();
|
||||
if (!playerNames.contains(name)) {
|
||||
playerNames.append(name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (PlayerLogic *player : players) {
|
||||
playerNames.append(player->getPlayerInfo()->getName());
|
||||
}
|
||||
}
|
||||
|
||||
DlgTurnOrder dlg(playerNames, this);
|
||||
|
|
@ -1334,6 +1351,7 @@ void TabGame::createPlayAreaWidget(bool bReplay)
|
|||
scene = new GameScene(phasesToolbar, this);
|
||||
connect(game->getPlayerManager(), &PlayerManager::playerConceded, scene, &GameScene::rearrange);
|
||||
connect(game->getPlayerManager(), &PlayerManager::playerCountChanged, scene, &GameScene::rearrange);
|
||||
connect(game->getGameState(), &GameState::seatOrderChanged, scene, &GameScene::rearrange);
|
||||
connect(scene, &GameScene::arrowDeletionRequested, game->getGameEventHandler(),
|
||||
&GameEventHandler::handleArrowDeletion);
|
||||
connect(game->getGameEventHandler(), &GameEventHandler::arrowDeleted, scene, &GameScene::deleteArrow);
|
||||
|
|
|
|||
|
|
@ -458,6 +458,19 @@ void GameEventHandler::eventGameStateChanged(const Event_GameStateChanged &event
|
|||
|
||||
emit remotePlayersDecksSelected(opponentDecksToDisplay);
|
||||
|
||||
// The server emits player_list in seat order, so record it to lay out the
|
||||
// table by seating rather than by player id.
|
||||
QList<int> seatOrder;
|
||||
for (int i = 0; i < playerListSize; ++i) {
|
||||
const ServerInfo_PlayerProperties &prop = event.player_list(i).properties();
|
||||
if (!prop.spectator()) {
|
||||
seatOrder.append(prop.player_id());
|
||||
}
|
||||
}
|
||||
if (!seatOrder.isEmpty()) {
|
||||
game->getGameState()->setSeatOrder(seatOrder);
|
||||
}
|
||||
|
||||
game->getGameState()->setGameTime(event.seconds_elapsed());
|
||||
|
||||
if (event.game_started() && !game->getGameMetaInfo()->started()) {
|
||||
|
|
@ -670,6 +683,22 @@ void GameEventHandler::eventPlayerOrderChanged(const Event_PlayerOrderChanged &e
|
|||
for (const auto &name : event.player_names()) {
|
||||
playerNames.append(QString::fromStdString(name));
|
||||
}
|
||||
|
||||
// Track the seating by stable player id so the table layout and the turn
|
||||
// order dialog follow the shuffled order instead of id order.
|
||||
QList<int> seatOrder;
|
||||
const auto &players = game->getPlayerManager()->getPlayers();
|
||||
for (const QString &name : playerNames) {
|
||||
for (auto it = players.constBegin(); it != players.constEnd(); ++it) {
|
||||
if (it.value() && it.value()->getPlayerInfo()->getName() == name) {
|
||||
seatOrder.append(it.key());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!seatOrder.isEmpty()) {
|
||||
game->getGameState()->setSeatOrder(seatOrder);
|
||||
}
|
||||
emit logTurnOrderChanged(playerNames, event.randomized());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,6 +112,19 @@ public:
|
|||
return hostId;
|
||||
}
|
||||
|
||||
void setSeatOrder(const QList<int> &order)
|
||||
{
|
||||
if (seatOrder != order) {
|
||||
seatOrder = order;
|
||||
emit seatOrderChanged(seatOrder);
|
||||
}
|
||||
}
|
||||
|
||||
QList<int> getSeatOrder() const
|
||||
{
|
||||
return seatOrder;
|
||||
}
|
||||
|
||||
int getSecondsElapsed() const
|
||||
{
|
||||
return secondsElapsed;
|
||||
|
|
@ -123,6 +136,7 @@ signals:
|
|||
void gameStopped();
|
||||
void activePhaseChanged(int activePhase);
|
||||
void activePlayerChanged(int playerId);
|
||||
void seatOrderChanged(const QList<int> &seatOrder);
|
||||
|
||||
public slots:
|
||||
void incrementGameTime();
|
||||
|
|
@ -142,6 +156,7 @@ private:
|
|||
int currentPhase;
|
||||
int activePlayer;
|
||||
bool gameClosed;
|
||||
QList<int> seatOrder;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_GAME_STATE_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue