In resetChatAndPhase() (the rewound() handler), also clear all spectators from both PlayerManager and PlayerListWidget before the replay rebuilds from event 0. The forward replay then re-adds exactly the spectators whose join events fall within the new time range via eventGameStateChanged/eventJoin.

This commit is contained in:
Lukas Brübach 2026-09-07 01:57:07 +02:00
parent 44909f3d6c
commit eaf8351426
5 changed files with 27 additions and 0 deletions

View file

@ -75,6 +75,14 @@ PlayerLogic *PlayerManager::getPlayer(int playerId) const
return player;
}
void PlayerManager::clearSpectators()
{
const QList<int> spectatorIds = spectators.keys();
for (int spectatorId : spectatorIds) {
removeSpectator(spectatorId);
}
}
void PlayerManager::onPlayerConceded(int playerId, bool conceded)
{
// Everything else cares about this

View file

@ -100,6 +100,9 @@ public:
emit spectatorRemoved(spectatorId, spectatorInfo);
}
/** @brief Remove all spectators, emitting the removal signal for each. */
void clearSpectators();
[[nodiscard]] AbstractGame *getGame() const
{
return game;

View file

@ -181,6 +181,17 @@ void PlayerListWidget::removePlayer(int playerId)
delete takeTopLevelItem(indexOfTopLevelItem(player));
}
void PlayerListWidget::clearSpectators()
{
const QList<int> playerIds = players.keys();
for (int playerId : playerIds) {
QTreeWidgetItem *player = players.value(playerId, 0);
if (player && !player->data(1, Qt::UserRole).toBool()) {
removePlayer(playerId);
}
}
}
void PlayerListWidget::setActivePlayer(int playerId)
{
QMapIterator<int, QTreeWidgetItem *> i(players);

View file

@ -66,6 +66,7 @@ public slots:
void addPlayer(const ServerInfo_PlayerProperties &player);
void removePlayer(int playerId);
void updatePlayerProperties(const ServerInfo_PlayerProperties &prop, int playerId = -1);
void clearSpectators();
};
#endif

View file

@ -266,6 +266,10 @@ void TabGame::resetChatAndPhase()
// reset phase markers
game->getGameState()->setCurrentPhase(-1);
// reset spectator state so the replay can rebuild it from the start
game->getPlayerManager()->clearSpectators();
playerListWidget->clearSpectators();
}
void TabGame::emitUserEvent()