From b478026f6c2f5b04111f1be5686d4bed8dbfbbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Tue, 9 Sep 2025 21:29:34 +0200 Subject: [PATCH] Do to-do's Took 3 hours 32 minutes --- cockatrice/CMakeLists.txt | 1 + .../client/network/replay_timeline_widget.cpp | 2 + .../client/network/replay_timeline_widget.h | 2 +- cockatrice/src/client/replay_manager.cpp | 6 +- cockatrice/src/client/replay_manager.h | 1 + cockatrice/src/client/tabs/tab_game.cpp | 304 ++++++++---------- cockatrice/src/client/tabs/tab_game.h | 49 +-- cockatrice/src/client/tabs/tab_supervisor.cpp | 5 +- .../src/game/board/abstract_counter.cpp | 7 +- cockatrice/src/game/board/abstract_counter.h | 4 +- .../src/game/board/abstract_graphics_item.h | 6 +- cockatrice/src/game/board/card_item.cpp | 11 +- cockatrice/src/game/board/counter_general.cpp | 6 +- cockatrice/src/game/board/counter_general.h | 3 +- .../src/game/deckview/deck_view_container.cpp | 22 +- cockatrice/src/game/game.cpp | 63 ++++ cockatrice/src/game/game.h | 62 ++++ cockatrice/src/game/game_event_handler.cpp | 86 ++--- cockatrice/src/game/game_event_handler.h | 18 +- cockatrice/src/game/game_meta_info.cpp | 6 + cockatrice/src/game/game_meta_info.h | 11 +- cockatrice/src/game/game_scene.cpp | 4 +- cockatrice/src/game/game_state.cpp | 8 +- cockatrice/src/game/game_state.h | 39 +-- cockatrice/src/game/player/player.cpp | 33 +- cockatrice/src/game/player/player.h | 19 +- cockatrice/src/game/player/player_actions.cpp | 47 ++- .../src/game/player/player_graphics_item.cpp | 2 +- cockatrice/src/game/player/player_info.cpp | 13 +- cockatrice/src/game/player/player_info.h | 7 - .../src/game/player/player_list_widget.cpp | 4 +- .../src/game/player/player_list_widget.h | 6 +- cockatrice/src/game/player/player_manager.cpp | 79 ++++- cockatrice/src/game/player/player_manager.h | 101 +++--- cockatrice/src/game/player/player_menu.cpp | 17 +- cockatrice/src/game/player/player_target.cpp | 12 +- cockatrice/src/game/player/player_target.h | 10 +- cockatrice/src/game/zones/card_zone.cpp | 1 + .../src/game/zones/logic/card_zone_logic.h | 1 + cockatrice/src/server/chat_view/chat_view.cpp | 2 +- cockatrice/src/server/chat_view/chat_view.h | 6 +- cockatrice/src/server/message_log_widget.cpp | 19 +- cockatrice/src/server/message_log_widget.h | 13 +- .../src/server/user/user_context_menu.cpp | 2 +- .../src/server/user/user_context_menu.h | 6 +- 45 files changed, 620 insertions(+), 506 deletions(-) create mode 100644 cockatrice/src/game/game.cpp create mode 100644 cockatrice/src/game/game.h diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 32e409fb4..98bea18f8 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -207,6 +207,7 @@ set(cockatrice_SOURCES src/game/filters/filter_tree.cpp src/game/filters/filter_tree_model.cpp src/game/filters/syntax_help.cpp + src/game/game.cpp src/game/game_event_handler.cpp src/game/game_meta_info.cpp src/game/game_scene.cpp diff --git a/cockatrice/src/client/network/replay_timeline_widget.cpp b/cockatrice/src/client/network/replay_timeline_widget.cpp index d1a44835c..1f258bf68 100644 --- a/cockatrice/src/client/network/replay_timeline_widget.cpp +++ b/cockatrice/src/client/network/replay_timeline_widget.cpp @@ -1,5 +1,7 @@ #include "replay_timeline_widget.h" +#include "../../settings/cache_settings.h" + #include #include #include diff --git a/cockatrice/src/client/network/replay_timeline_widget.h b/cockatrice/src/client/network/replay_timeline_widget.h index 2483c8123..1ff995826 100644 --- a/cockatrice/src/client/network/replay_timeline_widget.h +++ b/cockatrice/src/client/network/replay_timeline_widget.h @@ -1,7 +1,7 @@ #ifndef REPLAY_TIMELINE_WIDGET #define REPLAY_TIMELINE_WIDGET -#include "../../game/player/player.h" +#include "../../game/player/event_processing_options.h" #include #include diff --git a/cockatrice/src/client/replay_manager.cpp b/cockatrice/src/client/replay_manager.cpp index debdd1657..1890d3308 100644 --- a/cockatrice/src/client/replay_manager.cpp +++ b/cockatrice/src/client/replay_manager.cpp @@ -11,7 +11,7 @@ ReplayManager::ReplayManager(TabGame *parent, GameReplay *_replay) aReplaySkipBackwardBig(nullptr) { if (replay) { - game->loadReplay(replay); + game->getGame()->loadReplay(replay); // Create list: event number -> time [ms] // Distribute simultaneous events evenly across 1 second. @@ -95,8 +95,8 @@ ReplayManager::ReplayManager(TabGame *parent, GameReplay *_replay) void ReplayManager::replayNextEvent(EventProcessingOptions options) { - game->getGameEventHandler()->processGameEventContainer(replay->event_list(timelineWidget->getCurrentEvent()), - nullptr, options); + game->getGame()->getGameEventHandler()->processGameEventContainer( + replay->event_list(timelineWidget->getCurrentEvent()), nullptr, options); } void ReplayManager::replayFinished() diff --git a/cockatrice/src/client/replay_manager.h b/cockatrice/src/client/replay_manager.h index 8fd3d123c..4c5f0ea38 100644 --- a/cockatrice/src/client/replay_manager.h +++ b/cockatrice/src/client/replay_manager.h @@ -2,6 +2,7 @@ #define REPLAY_MANAGER_H #include "network/replay_timeline_widget.h" #include "pb/game_replay.pb.h" +#include "tabs/tab_game.h" #include diff --git a/cockatrice/src/client/tabs/tab_game.cpp b/cockatrice/src/client/tabs/tab_game.cpp index 9197d5841..e4478a9bb 100644 --- a/cockatrice/src/client/tabs/tab_game.cpp +++ b/cockatrice/src/client/tabs/tab_game.cpp @@ -46,18 +46,18 @@ #include TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay) - : Tab(_tabSupervisor), activeCard(nullptr), sayLabel(nullptr), sayEdit(nullptr) + : Tab(_tabSupervisor), sayLabel(nullptr), sayEdit(nullptr) { // THIS CTOR IS USED ON REPLAY - gameMetaInfo = new GameMetaInfo(); - gameState = + /*game->getGameMetaInfo() = new GameMetaInfo(); + game->getGameState() = new GameState(0, -1, _tabSupervisor->getIsLocalGame(), QList(), false, false, -1, false); connectToGameState(); - playerManager = new PlayerManager(this, -1, true, false); + game->getPlayerManager() = new PlayerManager(this, -1, true, false); - gameEventHandler = new GameEventHandler(this); + game->getGameEventHandler() = new GameEventHandler(this);*/ connectToGameEventHandler(); createCardInfoDock(true); @@ -85,7 +85,7 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay) connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this, &TabGame::refreshShortcuts); refreshShortcuts(); - messageLog->logReplayStarted(gameMetaInfo->gameId()); + messageLog->logReplayStarted(game->getGameMetaInfo()->gameId()); QTimer::singleShot(0, this, &TabGame::loadLayout); } @@ -94,32 +94,14 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList &_clients, const Event_GameJoined &event, const QMap &_roomGameTypes) - : Tab(_tabSupervisor), userListProxy(_tabSupervisor->getUserListManager()), activeCard(nullptr) + : Tab(_tabSupervisor), userListProxy(_tabSupervisor->getUserListManager()) { - - gameMetaInfo = new GameMetaInfo(); - gameMetaInfo->setFromProto(event.game_info()); - gameMetaInfo->setRoomGameTypes(_roomGameTypes); - gameState = new GameState(0, event.host_id(), _tabSupervisor->getIsLocalGame(), _clients, false, event.resuming(), - -1, false); - connectToGameState(); - - playerManager = new PlayerManager(this, event.player_id(), event.spectator(), event.judge()); - connectToPlayerManager(); - // THIS CTOR IS USED ON GAMES - gameMetaInfo->setStarted(false); - - connect(gameMetaInfo, &GameMetaInfo::startedChanged, gameState, &GameState::onStartedChanged); - - gameEventHandler = new GameEventHandler(this); - connectToGameEventHandler(); + game = new Game(_clients, event, _roomGameTypes); createCardInfoDock(); createPlayerListDock(); - connectPlayerListToGameEventHandler(); createMessageDock(); - connectMessageLogToGameEventHandler(); createPlayAreaWidget(); createDeckViewContainerWidget(); createReplayDock(nullptr); @@ -137,102 +119,117 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, createMenuItems(); createViewMenuItems(); + + connectToGameState(); + connectToPlayerManager(); + connectToGameEventHandler(); + connectPlayerListToGameEventHandler(); + connectMessageLogToGameEventHandler(); + connectMessageLogToPlayerHandler(); + retranslateUi(); connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this, &TabGame::refreshShortcuts); refreshShortcuts(); // append game to rooms game list for others to see - for (int i = gameMetaInfo->gameTypesSize() - 1; i >= 0; i--) - gameTypes.append(gameMetaInfo->findRoomGameType(i)); + for (int i = game->getGameMetaInfo()->gameTypesSize() - 1; i >= 0; i--) + gameTypes.append(game->getGameMetaInfo()->findRoomGameType(i)); QTimer::singleShot(0, this, &TabGame::loadLayout); } void TabGame::connectToGameState() { - connect(gameState, &GameState::playerAdded, this, &TabGame::addPlayer); - connect(gameState, &GameState::gameStarted, this, &TabGame::startGame); - connect(gameState, &GameState::activePhaseChanged, this, &TabGame::setActivePhase); - connect(gameState, &GameState::activePlayerChanged, this, &TabGame::setActivePlayer); + connect(game->getGameState(), &GameState::gameStarted, this, &TabGame::startGame); + connect(game->getGameState(), &GameState::activePhaseChanged, this, &TabGame::setActivePhase); + connect(game->getGameState(), &GameState::activePlayerChanged, this, &TabGame::setActivePlayer); } void TabGame::connectToPlayerManager() { - connect(playerManager, &PlayerManager::playerAdded, this, &TabGame::addPlayer); + connect(game->getPlayerManager(), &PlayerManager::playerAdded, this, &TabGame::addPlayer); + // update menu text when player concedes so that "concede" gets updated to "unconcede" + connect(game->getPlayerManager(), &PlayerManager::playerConceded, this, &TabGame::retranslateUi); } void TabGame::connectToGameEventHandler() { - connect(this, &TabGame::gameLeft, gameEventHandler, &GameEventHandler::handleGameLeft); - connect(gameEventHandler, &GameEventHandler::gameStopped, this, &TabGame::stopGame); - connect(gameEventHandler, &GameEventHandler::gameClosed, this, &TabGame::closeGame); - connect(gameEventHandler, &GameEventHandler::localPlayerReadyStateChanged, this, + connect(this, &TabGame::gameLeft, game->getGameEventHandler(), &GameEventHandler::handleGameLeft); + connect(game->getGameEventHandler(), &GameEventHandler::emitUserEvent, this, &TabGame::emitUserEvent); + connect(game->getGameEventHandler(), &GameEventHandler::gameStopped, this, &TabGame::stopGame); + connect(game->getGameEventHandler(), &GameEventHandler::gameClosed, this, &TabGame::closeGame); + connect(game->getGameEventHandler(), &GameEventHandler::localPlayerReadyStateChanged, this, &TabGame::processLocalPlayerReadyStateChanged); - connect(gameEventHandler, &GameEventHandler::localPlayerSideboardLocked, this, + connect(game->getGameEventHandler(), &GameEventHandler::localPlayerSideboardLocked, this, &TabGame::processLocalPlayerSideboardLocked); - connect(gameEventHandler, &GameEventHandler::localPlayerDeckSelected, this, &TabGame::processLocalPlayerDeckSelect); + connect(game->getGameEventHandler(), &GameEventHandler::localPlayerDeckSelected, this, + &TabGame::processLocalPlayerDeckSelect); } void TabGame::connectMessageLogToGameEventHandler() { - // connect(gameEventHandler, &GameEventHandler:: , messageLog, &MessageLogWidget::); - connect(gameEventHandler, &GameEventHandler::gameFlooded, messageLog, &MessageLogWidget::logGameFlooded); - connect(gameEventHandler, &GameEventHandler::containerProcessingStarted, messageLog, + // connect(game->getGameEventHandler(), &GameEventHandler:: , messageLog, &MessageLogWidget::); + connect(game->getGameEventHandler(), &GameEventHandler::gameFlooded, messageLog, &MessageLogWidget::logGameFlooded); + connect(game->getGameEventHandler(), &GameEventHandler::containerProcessingStarted, messageLog, &MessageLogWidget::containerProcessingStarted); - connect(gameEventHandler, &GameEventHandler::containerProcessingDone, messageLog, + connect(game->getGameEventHandler(), &GameEventHandler::containerProcessingDone, messageLog, &MessageLogWidget::containerProcessingDone); - connect(gameEventHandler, &GameEventHandler::setContextJudgeName, messageLog, + connect(game->getGameEventHandler(), &GameEventHandler::setContextJudgeName, messageLog, &MessageLogWidget::setContextJudgeName); - connect(gameEventHandler, &GameEventHandler::logSpectatorSay, messageLog, &MessageLogWidget::logSpectatorSay); + connect(game->getGameEventHandler(), &GameEventHandler::logSpectatorSay, messageLog, + &MessageLogWidget::logSpectatorSay); - connect(gameEventHandler, &GameEventHandler::logJoinPlayer, messageLog, &MessageLogWidget::logJoin); - connect(gameEventHandler, &GameEventHandler::logJoinSpectator, messageLog, &MessageLogWidget::logJoinSpectator); - connect(gameEventHandler, &GameEventHandler::logLeave, messageLog, &MessageLogWidget::logLeave); - connect(gameEventHandler, &GameEventHandler::logKicked, messageLog, &MessageLogWidget::logKicked); - connect(gameEventHandler, &GameEventHandler::logConnectionStateChanged, messageLog, + connect(game->getGameEventHandler(), &GameEventHandler::logJoinPlayer, messageLog, &MessageLogWidget::logJoin); + connect(game->getGameEventHandler(), &GameEventHandler::logJoinSpectator, messageLog, + &MessageLogWidget::logJoinSpectator); + connect(game->getGameEventHandler(), &GameEventHandler::logLeave, messageLog, &MessageLogWidget::logLeave); + connect(game->getGameEventHandler(), &GameEventHandler::logKicked, messageLog, &MessageLogWidget::logKicked); + connect(game->getGameEventHandler(), &GameEventHandler::logConnectionStateChanged, messageLog, &MessageLogWidget::logConnectionStateChanged); - connect(gameEventHandler, &GameEventHandler::logDeckSelect, messageLog, &MessageLogWidget::logDeckSelect); - connect(gameEventHandler, &GameEventHandler::logSideboardLockSet, messageLog, + connect(game->getGameEventHandler(), &GameEventHandler::logDeckSelect, messageLog, + &MessageLogWidget::logDeckSelect); + connect(game->getGameEventHandler(), &GameEventHandler::logSideboardLockSet, messageLog, &MessageLogWidget::logSetSideboardLock); - connect(gameEventHandler, &GameEventHandler::logReadyStart, messageLog, &MessageLogWidget::logReadyStart); - connect(gameEventHandler, &GameEventHandler::logNotReadyStart, messageLog, &MessageLogWidget::logNotReadyStart); - connect(gameEventHandler, &GameEventHandler::logGameStart, messageLog, &MessageLogWidget::logGameStart); + connect(game->getGameEventHandler(), &GameEventHandler::logReadyStart, messageLog, + &MessageLogWidget::logReadyStart); + connect(game->getGameEventHandler(), &GameEventHandler::logNotReadyStart, messageLog, + &MessageLogWidget::logNotReadyStart); + connect(game->getGameEventHandler(), &GameEventHandler::logGameStart, messageLog, &MessageLogWidget::logGameStart); - connect(gameEventHandler, &GameEventHandler::playerConceded, messageLog, &MessageLogWidget::logConcede); - connect(gameEventHandler, &GameEventHandler::playerUnconceded, messageLog, &MessageLogWidget::logUnconcede); - - connect(gameEventHandler, &GameEventHandler::logActivePlayer, messageLog, &MessageLogWidget::logSetActivePlayer); - connect(gameEventHandler, &GameEventHandler::logActivePhaseChanged, messageLog, + connect(game->getGameEventHandler(), &GameEventHandler::logActivePlayer, messageLog, + &MessageLogWidget::logSetActivePlayer); + connect(game->getGameEventHandler(), &GameEventHandler::logActivePhaseChanged, messageLog, &MessageLogWidget::logSetActivePhase); - connect(gameEventHandler, &GameEventHandler::logTurnReversed, messageLog, &MessageLogWidget::logReverseTurn); + connect(game->getGameEventHandler(), &GameEventHandler::logTurnReversed, messageLog, + &MessageLogWidget::logReverseTurn); - connect(gameEventHandler, &GameEventHandler::logGameClosed, messageLog, &MessageLogWidget::logGameClosed); + connect(game->getGameEventHandler(), &GameEventHandler::logGameClosed, messageLog, + &MessageLogWidget::logGameClosed); +} + +void TabGame::connectMessageLogToPlayerHandler() +{ + connect(game->getPlayerManager(), &PlayerManager::playerConceded, messageLog, &MessageLogWidget::logConcede); + connect(game->getPlayerManager(), &PlayerManager::playerUnconceded, messageLog, &MessageLogWidget::logUnconcede); } void TabGame::connectPlayerListToGameEventHandler() { - connect(gameEventHandler, &GameEventHandler::playerJoined, playerListWidget, &PlayerListWidget::addPlayer); - connect(gameEventHandler, &GameEventHandler::playerLeft, playerListWidget, &PlayerListWidget::removePlayer); - connect(gameEventHandler, &GameEventHandler::spectatorJoined, playerListWidget, &PlayerListWidget::addPlayer); - connect(gameEventHandler, &GameEventHandler::spectatorLeft, playerListWidget, &PlayerListWidget::removePlayer); - connect(gameEventHandler, &GameEventHandler::playerPropertiesChanged, playerListWidget, + connect(game->getGameEventHandler(), &GameEventHandler::playerJoined, playerListWidget, + &PlayerListWidget::addPlayer); + connect(game->getGameEventHandler(), &GameEventHandler::playerLeft, playerListWidget, + &PlayerListWidget::removePlayer); + connect(game->getGameEventHandler(), &GameEventHandler::spectatorJoined, playerListWidget, + &PlayerListWidget::addPlayer); + connect(game->getGameEventHandler(), &GameEventHandler::spectatorLeft, playerListWidget, + &PlayerListWidget::removePlayer); + connect(game->getGameEventHandler(), &GameEventHandler::playerPropertiesChanged, playerListWidget, &PlayerListWidget::updatePlayerProperties); } -bool TabGame::isHost() const -{ - return gameState->getHostId() == playerManager->getLocalPlayerId(); -} - -void TabGame::loadReplay(GameReplay *replay) -{ - gameMetaInfo->setFromProto(replay->game_info()); - gameMetaInfo->setSpectatorsOmniscient(true); -} - void TabGame::addMentionTag(const QString &value) { sayEdit->insert(value + " "); @@ -251,12 +248,12 @@ void TabGame::resetChatAndPhase() messageLog->clearChat(); // reset phase markers - gameState->setCurrentPhase(-1); + game->getGameState()->setCurrentPhase(-1); } void TabGame::emitUserEvent() { - bool globalEvent = !playerManager->isSpectator() || SettingsCache::instance().getSpectatorNotificationsEnabled(); + bool globalEvent = !game->getPlayerManager()->isSpectator() || SettingsCache::instance().getSpectatorNotificationsEnabled(); emit userEvent(globalEvent); updatePlayerListDockTitle(); } @@ -268,9 +265,9 @@ TabGame::~TabGame() void TabGame::updatePlayerListDockTitle() { - QString tabText = - " | " + (replayManager->replay ? tr("Replay") : tr("Game")) + " #" + QString::number(gameMetaInfo->gameId()); - QString userCountInfo = QString(" %1/%2").arg(playerManager->getPlayerCount()).arg(gameMetaInfo->maxPlayers()); + QString tabText = " | " + (replayManager->replay ? tr("Replay") : tr("Game")) + " #" + + QString::number(game->getGameMetaInfo()->gameId()); + QString userCountInfo = QString(" %1/%2").arg(game->getPlayerManager()->getPlayerCount()).arg(game->getGameMetaInfo()->maxPlayers()); playerListDock->setWindowTitle(tr("Player List") + userCountInfo + (playerListDock->isWindow() ? tabText : QString())); } @@ -278,7 +275,7 @@ void TabGame::updatePlayerListDockTitle() void TabGame::retranslateUi() { QString tabText = - " | " + (replayManager->replay ? tr("Replay") : tr("Game")) + " #" + QString::number(gameMetaInfo->gameId()); + " | " + (replayManager->replay ? tr("Replay") : tr("Game")) + " #" + QString::number(game->getGameMetaInfo()->gameId()); updatePlayerListDockTitle(); cardInfoDock->setWindowTitle(tr("Card Info") + (cardInfoDock->isWindow() ? tabText : QString())); @@ -317,7 +314,7 @@ void TabGame::retranslateUi() if (aGameInfo) aGameInfo->setText(tr("Game &information")); if (aConcede) { - if (playerManager->isMainPlayerConceded()) { + if (game->getPlayerManager()->isMainPlayerConceded()) { aConcede->setText(tr("Un&concede")); } else { aConcede->setText(tr("&Concede")); @@ -364,7 +361,7 @@ void TabGame::retranslateUi() cardInfoFrameWidget->retranslateUi(); - QMapIterator i(playerManager->getPlayers()); + QMapIterator i(game->getPlayerManager()->getPlayers()); while (i.hasNext()) i.next().value()->retranslateUi(); @@ -478,35 +475,34 @@ void TabGame::updateTimeElapsedLabel(const QString newTime) void TabGame::adminLockChanged(bool lock) { - bool v = !(playerManager->isSpectator() && !gameMetaInfo->spectatorsCanChat() && lock); + bool v = !(game->getPlayerManager()->isSpectator() && !game->getGameMetaInfo()->spectatorsCanChat() && lock); sayLabel->setVisible(v); sayEdit->setVisible(v); } void TabGame::actGameInfo() { - DlgCreateGame dlg(gameMetaInfo->proto(), gameMetaInfo->getRoomGameTypes(), this); + DlgCreateGame dlg(game->getGameMetaInfo()->proto(), game->getGameMetaInfo()->getRoomGameTypes(), this); dlg.exec(); } void TabGame::actConcede() { - Player *player = playerManager->getActiveLocalPlayer(gameState->getActivePlayer()); + Player *player = game->getPlayerManager()->getActiveLocalPlayer(game->getGameState()->getActivePlayer()); if (player == nullptr) return; - if (!player->getPlayerInfo()->getConceded()) { + if (!player->getConceded()) { if (QMessageBox::question(this, tr("Concede"), tr("Are you sure you want to concede this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) return; - - emit playerConceded(); + player->setConceded(true); } else { if (QMessageBox::question(this, tr("Unconcede"), tr("You have already conceded. Do you want to return to this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) return; - emit playerUnconceded(); + player->setConceded(false); } } @@ -517,8 +513,8 @@ void TabGame::actConcede() */ bool TabGame::leaveGame() { - if (!gameState->isGameClosed()) { - if (!playerManager->isSpectator()) { + if (!game->getGameState()->isGameClosed()) { + if (!game->getPlayerManager()->isSpectator()) { tabSupervisor->setCurrentWidget(this); if (QMessageBox::question(this, tr("Leave game"), tr("Are you sure you want to leave this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) @@ -566,7 +562,7 @@ void TabGame::removePlayerFromAutoCompleteList(QString playerName) void TabGame::removeSpectator(int spectatorId, ServerInfo_User spectator) { Q_UNUSED(spectator); - QString playerName = "@" + gameState->getSpectatorName(spectatorId); + QString playerName = "@" + game->getPlayerManager()->getSpectatorName(spectatorId); removePlayerFromAutoCompleteList(playerName); } @@ -578,7 +574,7 @@ void TabGame::actPhaseAction() void TabGame::actNextPhase() { - int phase = gameState->getCurrentPhase(); + int phase = game->getGameState()->getCurrentPhase(); if (++phase >= phasesToolbar->phaseCount()) phase = 0; @@ -587,7 +583,7 @@ void TabGame::actNextPhase() void TabGame::actNextPhaseAction() { - int phase = gameState->getCurrentPhase() + 1; + int phase = game->getGameState()->getCurrentPhase() + 1; if (phase >= phasesToolbar->phaseCount()) { phase = 0; } @@ -603,7 +599,7 @@ void TabGame::actNextPhaseAction() void TabGame::actRemoveLocalArrows() { - QMapIterator playerIterator(playerManager->getPlayers()); + QMapIterator playerIterator(game->getPlayerManager()->getPlayers()); while (playerIterator.hasNext()) { Player *player = playerIterator.next().value(); if (!player->getPlayerInfo()->getLocal()) @@ -635,7 +631,7 @@ void TabGame::actCompleterChanged() void TabGame::notifyPlayerJoin(QString playerName) { if (trayIcon) { - QString gameId(QString::number(gameMetaInfo->gameId())); + QString gameId(QString::number(game->getGameMetaInfo()->gameId())); trayIcon->showMessage(tr("A player has joined game #%1").arg(gameId), tr("%1 has joined the game").arg(playerName)); } @@ -671,7 +667,8 @@ Player *TabGame::addPlayer(Player *newPlayer) messageLog->connectToPlayerEventHandler(newPlayer->getPlayerEventHandler()); - if (playerManager->isLocalPlayer(newPlayer->getPlayerInfo()->getId()) && !playerManager->isSpectator()) { + if (game->getGameState()->getIsLocalGame() || + (game->getPlayerManager()->isLocalPlayer(newPlayer->getPlayerInfo()->getId()) && !game->getPlayerManager()->isSpectator())) { addLocalPlayer(newPlayer, newPlayer->getPlayerInfo()->getId()); } @@ -679,17 +676,12 @@ Player *TabGame::addPlayer(Player *newPlayer) createZoneForPlayer(newPlayer, newPlayer->getPlayerInfo()->getId()); - // update menu text when player concedes so that "concede" gets updated to "unconcede" - // TODO: Hook this back up - // connect(newPlayer, &Player::playerCountChanged, this, &TabGame::retranslateUi); - - emit playerAdded(newPlayer); return newPlayer; } void TabGame::addLocalPlayer(Player *newPlayer, int playerId) { - if (gameState->getClients().size() == 1) { + if (game->getGameState()->getClients().size() == 1) { newPlayer->getPlayerMenu()->setShortcutsActive(); } @@ -765,12 +757,12 @@ void TabGame::processLocalPlayerReadyStateChanged(int playerId, bool ready) void TabGame::createZoneForPlayer(Player *newPlayer, int playerId) { - if (!gameState->getSpectators().contains(playerId)) { + if (!game->getPlayerManager()->getSpectators().contains(playerId)) { // Loop for each player, the idea is to have one assigned zone for each non-spectator player - for (int i = 1; i <= playerManager->getPlayerCount(); ++i) { + for (int i = 1; i <= game->getPlayerManager()->getPlayerCount(); ++i) { bool aPlayerHasThisZone = false; - for (auto &player : playerManager->getPlayers()) { + for (auto &player : game->getPlayerManager()->getPlayers()) { if (player->getPlayerInfo()->getZoneId() == i) { aPlayerHasThisZone = true; break; @@ -784,23 +776,9 @@ void TabGame::createZoneForPlayer(Player *newPlayer, int playerId) } } -AbstractClient *TabGame::getClientForPlayer(int playerId) const -{ - if (gameState->getClients().size() > 1) { - if (playerId == -1) { - playerId = playerManager->getActiveLocalPlayer(gameState->getActivePlayer())->getPlayerInfo()->getId(); - } - - return gameState->getClients().at(playerId); - } else if (gameState->getClients().isEmpty()) - return nullptr; - else - return gameState->getClients().first(); -} - void TabGame::startGame(bool _resuming) { - gameState->setCurrentPhase(-1); + game->getGameState()->setCurrentPhase(-1); QMapIterator i(deckViewContainers); while (i.hasNext()) { @@ -813,13 +791,13 @@ void TabGame::startGame(bool _resuming) mainWidget->setCurrentWidget(gamePlayAreaWidget); if (!_resuming) { - QMapIterator playerIterator(playerManager->getPlayers()); + QMapIterator playerIterator(game->getPlayerManager()->getPlayers()); while (playerIterator.hasNext()) playerIterator.next().value()->setGameStarted(); } - playerListWidget->setGameStarted(true, gameState->isResuming()); - gameMetaInfo->setStarted(true); + playerListWidget->setGameStarted(true, game->getGameState()->isResuming()); + game->getGameMetaInfo()->setStarted(true); static_cast(gameView->scene())->rearrange(); } @@ -847,27 +825,27 @@ void TabGame::closeGame() Player *TabGame::setActivePlayer(int id) { - Player *player = playerManager->getPlayer(id); + Player *player = game->getPlayerManager()->getPlayer(id); if (!player) return nullptr; playerListWidget->setActivePlayer(id); - QMapIterator i(playerManager->getPlayers()); + QMapIterator i(game->getPlayerManager()->getPlayers()); while (i.hasNext()) { i.next(); if (i.value() == player) { i.value()->setActive(true); - if (gameState->getClients().size() > 1) { + if (game->getGameState()->getClients().size() > 1) { i.value()->getPlayerMenu()->setShortcutsActive(); } } else { i.value()->setActive(false); - if (gameState->getClients().size() > 1) { + if (game->getGameState()->getClients().size() > 1) { i.value()->getPlayerMenu()->setShortcutsInactive(); } } } - gameState->setCurrentPhase(-1); + game->getGameState()->setCurrentPhase(-1); emitUserEvent(); return player; } @@ -886,19 +864,6 @@ void TabGame::newCardAdded(AbstractCardItem *card) connect(card, &AbstractCardItem::cardShiftClicked, this, &TabGame::linkCardToChat); } -CardItem *TabGame::getCard(int playerId, const QString &zoneName, int cardId) const -{ - Player *player = playerManager->getPlayer(playerId); - if (!player) - return nullptr; - - CardZoneLogic *zone = player->getZones().value(zoneName, 0); - if (!zone) - return nullptr; - - return zone->getCard(cardId); -} - QString TabGame::getTabText() const { QString gameTypeInfo; @@ -908,8 +873,8 @@ QString TabGame::getTabText() const gameTypeInfo.append("..."); } - QString gameDesc(gameMetaInfo->description()); - QString gameId(QString::number(gameMetaInfo->gameId())); + QString gameDesc(game->getGameMetaInfo()->description()); + QString gameId(QString::number(game->getGameMetaInfo()->gameId())); QString tabText; if (replayManager->replay) @@ -929,11 +894,6 @@ QString TabGame::getTabText() const return tabText; } -void TabGame::setActiveCard(CardItem *card) -{ - activeCard = card; -} - /** * @param menu The menu to set. Pass in nullptr to set the menu to empty. */ @@ -954,17 +914,17 @@ void TabGame::createMenuItems() { aNextPhase = new QAction(this); connect(aNextPhase, &QAction::triggered, this, &TabGame::actNextPhase); - connect(this, &TabGame::phaseChanged, gameEventHandler, &GameEventHandler::handleActivePhaseChanged); + connect(this, &TabGame::phaseChanged, game->getGameEventHandler(), &GameEventHandler::handleActivePhaseChanged); aNextPhaseAction = new QAction(this); connect(aNextPhaseAction, &QAction::triggered, this, &TabGame::actNextPhaseAction); - connect(this, &TabGame::turnAdvanced, gameEventHandler, &GameEventHandler::handleNextTurn); + connect(this, &TabGame::turnAdvanced, game->getGameEventHandler(), &GameEventHandler::handleNextTurn); aNextTurn = new QAction(this); - connect(aNextTurn, &QAction::triggered, gameEventHandler, &GameEventHandler::handleNextTurn); + connect(aNextTurn, &QAction::triggered, game->getGameEventHandler(), &GameEventHandler::handleNextTurn); aReverseTurn = new QAction(this); - connect(aReverseTurn, &QAction::triggered, gameEventHandler, &GameEventHandler::handleReverseTurn); + connect(aReverseTurn, &QAction::triggered, game->getGameEventHandler(), &GameEventHandler::handleReverseTurn); aRemoveLocalArrows = new QAction(this); connect(aRemoveLocalArrows, &QAction::triggered, this, &TabGame::actRemoveLocalArrows); - connect(this, &TabGame::arrowDeletionRequested, gameEventHandler, &GameEventHandler::handleArrowDeletion); + connect(this, &TabGame::arrowDeletionRequested, game->getGameEventHandler(), &GameEventHandler::handleArrowDeletion); aRotateViewCW = new QAction(this); connect(aRotateViewCW, &QAction::triggered, this, &TabGame::actRotateViewCW); aRotateViewCCW = new QAction(this); @@ -973,8 +933,10 @@ void TabGame::createMenuItems() connect(aGameInfo, &QAction::triggered, this, &TabGame::actGameInfo); aConcede = new QAction(this); connect(aConcede, &QAction::triggered, this, &TabGame::actConcede); - connect(this, &TabGame::playerConceded, gameEventHandler, &GameEventHandler::handlePlayerConceded); - connect(this, &TabGame::playerUnconceded, gameEventHandler, &GameEventHandler::handlePlayerUnconceded); + connect(game->getPlayerManager(), &PlayerManager::activeLocalPlayerConceded, game->getGameEventHandler(), + &GameEventHandler::handleActiveLocalPlayerConceded); + connect(game->getPlayerManager(), &PlayerManager::activeLocalPlayerUnconceded, game->getGameEventHandler(), + &GameEventHandler::handleActiveLocalPlayerUnconceded); aLeaveGame = new QAction(this); connect(aLeaveGame, &QAction::triggered, this, &TabGame::closeRequest); aFocusChat = new QAction(this); @@ -1209,9 +1171,11 @@ void TabGame::createPlayAreaWidget(bool bReplay) { phasesToolbar = new PhasesToolbar; if (!bReplay) - connect(phasesToolbar, &PhasesToolbar::sendGameCommand, gameEventHandler, + connect(phasesToolbar, &PhasesToolbar::sendGameCommand, game->getGameEventHandler(), qOverload(&GameEventHandler::sendGameCommand)); scene = new GameScene(phasesToolbar, this); + connect(game->getPlayerManager(), &PlayerManager::playerConceded, scene, &GameScene::rearrange); + connect(game->getPlayerManager(), &PlayerManager::playerCountChanged, scene, &GameScene::rearrange); gameView = new GameView(scene); auto gamePlayAreaVBox = new QVBoxLayout; @@ -1282,9 +1246,9 @@ void TabGame::createCardInfoDock(bool bReplay) void TabGame::createPlayerListDock(bool bReplay) { if (bReplay) { - playerListWidget = new PlayerListWidget(nullptr, nullptr, this); + playerListWidget = new PlayerListWidget(nullptr, nullptr, game); } else { - playerListWidget = new PlayerListWidget(tabSupervisor, gameState->getClients().first(), this); + playerListWidget = new PlayerListWidget(tabSupervisor, game->getGameState()->getClients().first(), game); connect(playerListWidget, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool))); } @@ -1310,14 +1274,14 @@ void TabGame::createMessageDock(bool bReplay) if (!bReplay) { timeElapsedLabel = new QLabel; timeElapsedLabel->setAlignment(Qt::AlignCenter); - connect(gameState, &GameState::updateTimeElapsedLabel, this, &TabGame::updateTimeElapsedLabel); - gameState->startGameTimer(); + connect(game->getGameState(), &GameState::updateTimeElapsedLabel, this, &TabGame::updateTimeElapsedLabel); + game->getGameState()->startGameTimer(); messageLogLayout->addWidget(timeElapsedLabel); } // message log - messageLog = new MessageLogWidget(tabSupervisor, this); + messageLog = new MessageLogWidget(tabSupervisor, game); connect(messageLog, &MessageLogWidget::cardNameHovered, cardInfoFrameWidget, qOverload(&CardInfoFrameWidget::setCard)); connect(messageLog, &MessageLogWidget::showCardInfoPopup, this, &TabGame::showCardInfoPopup); @@ -1338,7 +1302,7 @@ void TabGame::createMessageDock(bool bReplay) sayEdit = new LineEditCompleter; sayEdit->setMaxLength(MAX_TEXT_LENGTH); sayLabel->setBuddy(sayEdit); - connect(this, &TabGame::chatMessageSent, gameEventHandler, &GameEventHandler::handleChatMessageSent); + connect(this, &TabGame::chatMessageSent, game->getGameEventHandler(), &GameEventHandler::handleChatMessageSent); completer = new QCompleter(autocompleteUserList, sayEdit); completer->setCaseSensitivity(Qt::CaseInsensitive); completer->setMaxVisibleItems(5); @@ -1347,14 +1311,14 @@ void TabGame::createMessageDock(bool bReplay) sayEdit->setCompleter(completer); actCompleterChanged(); - if (playerManager->isSpectator()) { + if (game->getPlayerManager()->isSpectator()) { /* Spectators can only talk if: * (a) the game creator allows it * (b) the spectator is a moderator/administrator * (c) the spectator is a judge */ - bool isModOrJudge = !tabSupervisor->getAdminLocked() || playerManager->isJudge(); - if (!isModOrJudge && !gameMetaInfo->spectatorsCanChat()) { + bool isModOrJudge = !tabSupervisor->getAdminLocked() || game->getPlayerManager()->isJudge(); + if (!isModOrJudge && !game->getGameMetaInfo()->spectatorsCanChat()) { sayLabel->hide(); sayEdit->hide(); } diff --git a/cockatrice/src/client/tabs/tab_game.h b/cockatrice/src/client/tabs/tab_game.h index 0ac952d84..c3677772e 100644 --- a/cockatrice/src/client/tabs/tab_game.h +++ b/cockatrice/src/client/tabs/tab_game.h @@ -2,11 +2,9 @@ #define TAB_GAME_H #include "../../client/tearoff_menu.h" -#include "../../game/game_event_handler.h" -#include "../../game/game_meta_info.h" -#include "../../game/game_state.h" +#include "../../game/game.h" #include "../../game/player/player.h" -#include "../../game/player/player_manager.h" +#include "../../server/message_log_widget.h" #include "../replay_manager.h" #include "../ui/widgets/visual_deck_storage/visual_deck_storage_widget.h" #include "pb/event_leave.pb.h" @@ -53,12 +51,8 @@ class TabGame : public Tab { Q_OBJECT private: - GameMetaInfo *gameMetaInfo; - GameState *gameState; - GameEventHandler *gameEventHandler; - PlayerManager *playerManager; + Game *game; const UserListProxy *userListProxy; - CardItem *activeCard; ReplayManager *replayManager; QStringList gameTypes; QCompleter *completer; @@ -116,16 +110,12 @@ private: void createReplayDock(GameReplay *replay); signals: void gameClosing(TabGame *tab); - void playerAdded(Player *player); - void playerRemoved(Player *player); void containerProcessingStarted(const GameEventContext &context); void containerProcessingDone(); void openMessageDialog(const QString &userName, bool focus); void openDeckEditor(const DeckLoader *deck); void notIdle(); - void playerConceded(); - void playerUnconceded(); void phaseChanged(int phase); void gameLeft(); void chatMessageSent(QString chatMessage); @@ -178,46 +168,19 @@ public: void connectToPlayerManager(); void connectToGameEventHandler(); void connectMessageLogToGameEventHandler(); + void connectMessageLogToPlayerHandler(); void connectPlayerListToGameEventHandler(); - void loadReplay(GameReplay *replay); TabGame(TabSupervisor *_tabSupervisor, GameReplay *replay); ~TabGame() override; void retranslateUi() override; void updatePlayerListDockTitle(); bool closeRequest() override; - GameMetaInfo *getGameMetaInfo() - { - return gameMetaInfo; - } - - GameState *getGameState() const - { - return gameState; - } - - GameEventHandler *getGameEventHandler() const - { - return gameEventHandler; - } - - PlayerManager *getPlayerManager() const - { - return playerManager; - } - - bool isHost() const; - - CardItem *getCard(int playerId, const QString &zoneName, int cardId) const; - QString getTabText() const override; - AbstractClient *getClientForPlayer(int playerId) const; - - void setActiveCard(CardItem *card); - CardItem *getActiveCard() const + Game *getGame() const { - return activeCard; + return game; } public slots: diff --git a/cockatrice/src/client/tabs/tab_supervisor.cpp b/cockatrice/src/client/tabs/tab_supervisor.cpp index 2b7215375..9e834071c 100644 --- a/cockatrice/src/client/tabs/tab_supervisor.cpp +++ b/cockatrice/src/client/tabs/tab_supervisor.cpp @@ -707,7 +707,7 @@ void TabSupervisor::gameLeft(TabGame *tab) if (tab == currentWidget()) emit setMenu(); - gameTabs.remove(tab->getGameMetaInfo()->gameId()); + gameTabs.remove(tab->getGame()->getGameMetaInfo()->gameId()); removeTab(indexOf(tab)); if (!localClients.isEmpty()) @@ -916,7 +916,8 @@ void TabSupervisor::processGameEventContainer(const GameEventContainer &cont) { TabGame *tab = gameTabs.value(cont.game_id()); if (tab) - tab->getGameEventHandler()->processGameEventContainer(cont, qobject_cast(sender()), {}); + tab->getGame()->getGameEventHandler()->processGameEventContainer(cont, qobject_cast(sender()), + {}); else qCInfo(TabSupervisorLog) << "gameEvent: invalid gameId" << cont.game_id(); } diff --git a/cockatrice/src/game/board/abstract_counter.cpp b/cockatrice/src/game/board/abstract_counter.cpp index 6b05c9443..2da571df5 100644 --- a/cockatrice/src/game/board/abstract_counter.cpp +++ b/cockatrice/src/game/board/abstract_counter.cpp @@ -22,11 +22,10 @@ AbstractCounter::AbstractCounter(Player *_player, bool _shownInCounterArea, int _value, bool _useNameForShortcut, - QGraphicsItem *parent, - QWidget *_game) + QGraphicsItem *parent) : QGraphicsItem(parent), player(_player), id(_id), name(_name), value(_value), useNameForShortcut(_useNameForShortcut), hovered(false), aDec(nullptr), aInc(nullptr), dialogSemaphore(false), - deleteAfterDialog(false), shownInCounterArea(_shownInCounterArea), game(_game) + deleteAfterDialog(false), shownInCounterArea(_shownInCounterArea) { setAcceptHoverEvents(true); @@ -173,7 +172,7 @@ void AbstractCounter::incrementCounter() void AbstractCounter::setCounter() { dialogSemaphore = true; - AbstractCounterDialog dialog(name, QString::number(value), game); + AbstractCounterDialog dialog(name, QString::number(value) /*, game */); const int ok = dialog.exec(); if (deleteAfterDialog) { diff --git a/cockatrice/src/game/board/abstract_counter.h b/cockatrice/src/game/board/abstract_counter.h index 8f2ee2691..4c9ae064a 100644 --- a/cockatrice/src/game/board/abstract_counter.h +++ b/cockatrice/src/game/board/abstract_counter.h @@ -34,7 +34,6 @@ private: bool dialogSemaphore, deleteAfterDialog; bool shownInCounterArea; bool shortcutActive; - QWidget *game; private slots: void refreshShortcuts(); @@ -48,8 +47,7 @@ public: bool _shownInCounterArea, int _value, bool _useNameForShortcut = false, - QGraphicsItem *parent = nullptr, - QWidget *game = nullptr); + QGraphicsItem *parent = nullptr); ~AbstractCounter() override; void retranslateUi(); diff --git a/cockatrice/src/game/board/abstract_graphics_item.h b/cockatrice/src/game/board/abstract_graphics_item.h index 35872adbc..eaa0b881a 100644 --- a/cockatrice/src/game/board/abstract_graphics_item.h +++ b/cockatrice/src/game/board/abstract_graphics_item.h @@ -6,15 +6,15 @@ /** * Parent class of all objects that appear in a game. */ -class AbstractGraphicsItem : public QObject, public QGraphicsItem +class AbstractGraphicsItem : public QGraphicsObject { Q_OBJECT - Q_INTERFACES(QGraphicsItem) + protected: void paintNumberEllipse(int number, int radius, const QColor &color, int position, int count, QPainter *painter); public: - explicit AbstractGraphicsItem(QGraphicsItem *parent = nullptr) : QGraphicsItem(parent) + explicit AbstractGraphicsItem(QGraphicsItem *parent = nullptr) : QGraphicsObject(parent) { } }; diff --git a/cockatrice/src/game/board/card_item.cpp b/cockatrice/src/game/board/card_item.cpp index dcb003a91..50108d09f 100644 --- a/cockatrice/src/game/board/card_item.cpp +++ b/cockatrice/src/game/board/card_item.cpp @@ -260,13 +260,15 @@ void CardItem::deleteDragItem() void CardItem::drawArrow(const QColor &arrowColor) { - if (static_cast(owner->parent())->getPlayerManager()->isSpectator()) + if (static_cast(owner->parent())->getGame()->getPlayerManager()->isSpectator()) return; Player *arrowOwner = static_cast(owner->parent()) - ->getPlayerManager() - ->getActiveLocalPlayer(static_cast(owner->parent())->getGameState()->getActivePlayer()); + ->getGame() + ->getPlayerManager() + ->getActiveLocalPlayer( + static_cast(owner->parent())->getGame()->getGameState()->getActivePlayer()); ArrowDragItem *arrow = new ArrowDragItem(arrowOwner, this, arrowColor); scene()->addItem(arrow); arrow->grabMouse(); @@ -286,7 +288,7 @@ void CardItem::drawArrow(const QColor &arrowColor) void CardItem::drawAttachArrow() { - if (static_cast(owner->parent())->getPlayerManager()->isSpectator()) + if (static_cast(owner->parent())->getGame()->getPlayerManager()->isSpectator()) return; auto *arrow = new ArrowAttachItem(this); @@ -474,6 +476,7 @@ QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value) owner->getGame()->setActiveCard(this); owner->getPlayerMenu()->updateCardMenu(this); } else if (owner->getGameScene()->selectedItems().isEmpty()) { + owner->getGame()->setActiveCard(nullptr); owner->getPlayerMenu()->updateCardMenu(nullptr); } diff --git a/cockatrice/src/game/board/counter_general.cpp b/cockatrice/src/game/board/counter_general.cpp index 3089dc3f1..6bd94cbee 100644 --- a/cockatrice/src/game/board/counter_general.cpp +++ b/cockatrice/src/game/board/counter_general.cpp @@ -12,10 +12,8 @@ GeneralCounter::GeneralCounter(Player *_player, int _radius, int _value, bool useNameForShortcut, - QGraphicsItem *parent, - QWidget *game) - : AbstractCounter(_player, _id, _name, true, _value, useNameForShortcut, parent, game), color(_color), - radius(_radius) + QGraphicsItem *parent) + : AbstractCounter(_player, _id, _name, true, _value, useNameForShortcut, parent), color(_color), radius(_radius) { setCacheMode(DeviceCoordinateCache); } diff --git a/cockatrice/src/game/board/counter_general.h b/cockatrice/src/game/board/counter_general.h index 0bee9c824..dcf93c72c 100644 --- a/cockatrice/src/game/board/counter_general.h +++ b/cockatrice/src/game/board/counter_general.h @@ -18,8 +18,7 @@ public: int _radius, int _value, bool useNameForShortcut = false, - QGraphicsItem *parent = nullptr, - QWidget *game = nullptr); + QGraphicsItem *parent = nullptr); QRectF boundingRect() const override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; }; diff --git a/cockatrice/src/game/deckview/deck_view_container.cpp b/cockatrice/src/game/deckview/deck_view_container.cpp index 2c5b6b625..f09ecb638 100644 --- a/cockatrice/src/game/deckview/deck_view_container.cpp +++ b/cockatrice/src/game/deckview/deck_view_container.cpp @@ -157,7 +157,7 @@ void DeckViewContainer::switchToDeckSelectView() deckViewLayout->update(); setVisibility(loadLocalButton, true); - setVisibility(loadRemoteButton, !parentGame->getGameState()->getIsLocalGame()); + setVisibility(loadRemoteButton, !parentGame->getGame()->getGameState()->getIsLocalGame()); setVisibility(loadFromClipboardButton, true); setVisibility(loadFromWebsiteButton, true); setVisibility(unloadDeckButton, false); @@ -190,7 +190,7 @@ void DeckViewContainer::switchToDeckLoadedView() setVisibility(readyStartButton, true); setVisibility(sideboardLockButton, true); - if (parentGame->isHost()) { + if (parentGame->getGame()->isHost()) { setVisibility(forceStartGameButton, true); } } @@ -287,20 +287,20 @@ void DeckViewContainer::loadDeckFromDeckLoader(const DeckLoader *deck) Command_DeckSelect cmd; cmd.set_deck(deckString.toStdString()); - PendingCommand *pend = parentGame->getGameEventHandler()->prepareGameCommand(cmd); + PendingCommand *pend = parentGame->getGame()->getGameEventHandler()->prepareGameCommand(cmd); connect(pend, &PendingCommand::finished, this, &DeckViewContainer::deckSelectFinished); - parentGame->getGameEventHandler()->sendGameCommand(pend, playerId); + parentGame->getGame()->getGameEventHandler()->sendGameCommand(pend, playerId); } void DeckViewContainer::loadRemoteDeck() { - DlgLoadRemoteDeck dlg(parentGame->getClientForPlayer(playerId), this); + DlgLoadRemoteDeck dlg(parentGame->getGame()->getClientForPlayer(playerId), this); if (dlg.exec()) { Command_DeckSelect cmd; cmd.set_deck_id(dlg.getDeckId()); - PendingCommand *pend = parentGame->getGameEventHandler()->prepareGameCommand(cmd); + PendingCommand *pend = parentGame->getGame()->getGameEventHandler()->prepareGameCommand(cmd); connect(pend, &PendingCommand::finished, this, &DeckViewContainer::deckSelectFinished); - parentGame->getGameEventHandler()->sendGameCommand(pend, playerId); + parentGame->getGame()->getGameEventHandler()->sendGameCommand(pend, playerId); } } @@ -354,7 +354,7 @@ void DeckViewContainer::forceStart() Command_ReadyStart cmd; cmd.set_force_start(true); cmd.set_ready(true); - parentGame->getGameEventHandler()->sendGameCommand(cmd, playerId); + parentGame->getGame()->getGameEventHandler()->sendGameCommand(cmd, playerId); } void DeckViewContainer::sideboardLockButtonClicked() @@ -362,7 +362,7 @@ void DeckViewContainer::sideboardLockButtonClicked() Command_SetSideboardLock cmd; cmd.set_locked(sideboardLockButton->getState()); - parentGame->getGameEventHandler()->sendGameCommand(cmd, playerId); + parentGame->getGame()->getGameEventHandler()->sendGameCommand(cmd, playerId); } void DeckViewContainer::sideboardPlanChanged() @@ -371,7 +371,7 @@ void DeckViewContainer::sideboardPlanChanged() const QList &newPlan = deckView->getSideboardPlan(); for (const auto &i : newPlan) cmd.add_move_list()->CopyFrom(i); - parentGame->getGameEventHandler()->sendGameCommand(cmd, playerId); + parentGame->getGame()->getGameEventHandler()->sendGameCommand(cmd, playerId); } /** @@ -381,7 +381,7 @@ void DeckViewContainer::sendReadyStartCommand(bool ready) { Command_ReadyStart cmd; cmd.set_ready(ready); - parentGame->getGameEventHandler()->sendGameCommand(cmd, playerId); + parentGame->getGame()->getGameEventHandler()->sendGameCommand(cmd, playerId); } /** diff --git a/cockatrice/src/game/game.cpp b/cockatrice/src/game/game.cpp new file mode 100644 index 000000000..ad919940b --- /dev/null +++ b/cockatrice/src/game/game.cpp @@ -0,0 +1,63 @@ +#include "game.h" + +#include "pb/event_game_joined.pb.h" + +Game::Game(QList &_clients, const Event_GameJoined &event, const QMap &_roomGameTypes) +{ + gameMetaInfo = new GameMetaInfo(this); + gameMetaInfo->setFromProto(event.game_info()); + gameMetaInfo->setRoomGameTypes(_roomGameTypes); + gameState = new GameState(this, 0, event.host_id(), /* _tabSupervisor->getIsLocalGame() */ true, _clients, false, + event.resuming(), -1, false); + playerManager = new PlayerManager(this, event.player_id(), event.spectator(), event.judge()); + gameMetaInfo->setStarted(false); + + connect(gameMetaInfo, &GameMetaInfo::startedChanged, gameState, &GameState::onStartedChanged); + + gameEventHandler = new GameEventHandler(this); + + activeCard = nullptr; +} + +bool Game::isHost() const +{ + return gameState->getHostId() == playerManager->getLocalPlayerId(); +} + +AbstractClient *Game::getClientForPlayer(int playerId) const +{ + if (gameState->getClients().size() > 1) { + if (playerId == -1) { + playerId = playerManager->getActiveLocalPlayer(gameState->getActivePlayer())->getPlayerInfo()->getId(); + } + + return gameState->getClients().at(playerId); + } else if (gameState->getClients().isEmpty()) + return nullptr; + else + return gameState->getClients().first(); +} + +void Game::loadReplay(GameReplay *replay) +{ + gameMetaInfo->setFromProto(replay->game_info()); + gameMetaInfo->setSpectatorsOmniscient(true); +} + +void Game::setActiveCard(CardItem *card) +{ + activeCard = card; +} + +CardItem *Game::getCard(int playerId, const QString &zoneName, int cardId) const +{ + Player *player = playerManager->getPlayer(playerId); + if (!player) + return nullptr; + + CardZoneLogic *zone = player->getZones().value(zoneName, 0); + if (!zone) + return nullptr; + + return zone->getCard(cardId); +} diff --git a/cockatrice/src/game/game.h b/cockatrice/src/game/game.h new file mode 100644 index 000000000..835b602d9 --- /dev/null +++ b/cockatrice/src/game/game.h @@ -0,0 +1,62 @@ +#ifndef COCKATRICE_GAME_H +#define COCKATRICE_GAME_H + +#include "../../../cmake-build-debug/common/pb/game_replay.pb.h" +#include "game_event_handler.h" +#include "game_meta_info.h" +#include "game_state.h" +#include "player/player_manager.h" + +#include + +class CardItem; +class GameMetaInfo; +class Game : public QObject +{ + Q_OBJECT + +public: + Game(QList &_clients, const Event_GameJoined &event, const QMap &_roomGameTypes); + + GameMetaInfo *gameMetaInfo; + GameState *gameState; + GameEventHandler *gameEventHandler; + PlayerManager *playerManager; + CardItem *activeCard; + + GameMetaInfo *getGameMetaInfo() + { + return gameMetaInfo; + } + + GameState *getGameState() const + { + return gameState; + } + + GameEventHandler *getGameEventHandler() const + { + return gameEventHandler; + } + + PlayerManager *getPlayerManager() const + { + return playerManager; + } + + bool isHost() const; + + AbstractClient *getClientForPlayer(int playerId) const; + + void loadReplay(GameReplay *replay); + + CardItem *getCard(int playerId, const QString &zoneName, int cardId) const; + + void setActiveCard(CardItem *card); + CardItem *getActiveCard() const + { + return activeCard; + } +}; + +#endif // COCKATRICE_GAME_H diff --git a/cockatrice/src/game/game_event_handler.cpp b/cockatrice/src/game/game_event_handler.cpp index 80602f1ec..b6866ebd2 100644 --- a/cockatrice/src/game/game_event_handler.cpp +++ b/cockatrice/src/game/game_event_handler.cpp @@ -4,6 +4,7 @@ #include "../server/abstract_client.h" #include "../server/message_log_widget.h" #include "../server/pending_command.h" +#include "game.h" #include "get_pb_extension.h" #include "pb/command_concede.pb.h" #include "pb/command_delete_arrow.pb.h" @@ -28,7 +29,7 @@ #include "pb/event_set_active_player.pb.h" #include "pb/game_event_container.pb.h" -GameEventHandler::GameEventHandler(TabGame *_game) : game(_game), gameState(_game->getGameState()) +GameEventHandler::GameEventHandler(Game *_game) : QObject(_game), game(_game) { } @@ -98,12 +99,13 @@ void GameEventHandler::processGameEventContainer(const GameEventContainer &cont, Player *judgep = game->getPlayerManager()->getPlayers().value(id, nullptr); if (judgep) { emit setContextJudgeName(judgep->getPlayerInfo()->getName()); - } else if (gameState->getSpectators().contains(id)) { - emit setContextJudgeName(QString::fromStdString(gameState->getSpectators().value(id).name())); + } else if (game->getPlayerManager()->getSpectators().contains(id)) { + emit setContextJudgeName( + QString::fromStdString(game->getPlayerManager()->getSpectators().value(id).name())); } } - if (gameState->getSpectators().contains(playerId)) { + if (game->getPlayerManager()->getSpectators().contains(playerId)) { switch (eventType) { case GameEvent::GAME_SAY: eventSpectatorSay(event.GetExtension(Event_GameSay::ext), playerId, context); @@ -115,8 +117,8 @@ void GameEventHandler::processGameEventContainer(const GameEventContainer &cont, break; } } else { - if ((gameState->getClients().size() > 1) && (playerId != -1)) - if (gameState->getClients().at(playerId) != client) + if ((game->getGameState()->getClients().size() > 1) && (playerId != -1)) + if (game->getGameState()->getClients().at(playerId) != client) continue; switch (eventType) { @@ -169,7 +171,7 @@ void GameEventHandler::processGameEventContainer(const GameEventContainer &cont, break; } player->getPlayerEventHandler()->processGameEvent(eventType, event, context, options); - game->emitUserEvent(); + emitUserEvent(); } } } @@ -187,12 +189,12 @@ void GameEventHandler::handleReverseTurn() sendGameCommand(Command_ReverseTurn()); } -void GameEventHandler::handlePlayerConceded() +void GameEventHandler::handleActiveLocalPlayerConceded() { sendGameCommand(Command_Concede()); } -void GameEventHandler::handlePlayerUnconceded() +void GameEventHandler::handleActiveLocalPlayerUnconceded() { sendGameCommand(Command_Unconcede()); } @@ -227,7 +229,7 @@ void GameEventHandler::eventSpectatorSay(const Event_GameSay &event, int eventPlayerId, const GameEventContext & /*context*/) { - const ServerInfo_User &userInfo = gameState->getSpectators().value(eventPlayerId); + const ServerInfo_User &userInfo = game->getPlayerManager()->getSpectators().value(eventPlayerId); emit logSpectatorSay(userInfo, QString::fromStdString(event.message())); } @@ -235,13 +237,13 @@ void GameEventHandler::eventSpectatorLeave(const Event_Leave &event, int eventPlayerId, const GameEventContext & /*context*/) { - emit logSpectatorLeave(gameState->getSpectatorName(eventPlayerId), getLeaveReason(event.reason())); + emit logSpectatorLeave(game->getPlayerManager()->getSpectatorName(eventPlayerId), getLeaveReason(event.reason())); emit spectatorLeft(eventPlayerId); - gameState->removeSpectator(eventPlayerId); + game->getPlayerManager()->removeSpectator(eventPlayerId); - game->emitUserEvent(); + emitUserEvent(); } void GameEventHandler::eventGameStateChanged(const Event_GameStateChanged &event, @@ -257,13 +259,13 @@ void GameEventHandler::eventGameStateChanged(const Event_GameStateChanged &event const ServerInfo_PlayerProperties &prop = playerInfo.properties(); const int playerId = prop.player_id(); QString playerName = "@" + QString::fromStdString(prop.user_info().name()); - game->addPlayerToAutoCompleteList(playerName); + emit addPlayerToAutoCompleteList(playerName); if (prop.spectator()) { - gameState->addSpectator(playerId, prop); + game->getPlayerManager()->addSpectator(playerId, prop); } else { Player *player = game->getPlayerManager()->getPlayers().value(playerId, 0); if (!player) { - player = game->getPlayerManager()->addPlayer(playerId, prop.user_info(), game); + player = game->getPlayerManager()->addPlayer(playerId, prop.user_info()); emit playerJoined(prop); emit logJoinPlayer(player); } @@ -285,23 +287,23 @@ void GameEventHandler::eventGameStateChanged(const Event_GameStateChanged &event emit remotePlayersDecksSelected(opponentDecksToDisplay); - gameState->setGameTime(event.seconds_elapsed()); + game->getGameState()->setGameTime(event.seconds_elapsed()); if (event.game_started() && !game->getGameMetaInfo()->started()) { - gameState->setResuming(!gameState->isGameStateKnown()); + game->getGameState()->setResuming(!game->getGameState()->isGameStateKnown()); game->getGameMetaInfo()->setStarted(event.game_started()); - if (gameState->isGameStateKnown()) + if (game->getGameState()->isGameStateKnown()) emit logGameStart(); - gameState->setActivePlayer(event.active_player_id()); - gameState->setCurrentPhase(event.active_phase()); + game->getGameState()->setActivePlayer(event.active_player_id()); + game->getGameState()->setCurrentPhase(event.active_phase()); } else if (!event.game_started() && game->getGameMetaInfo()->started()) { - gameState->setCurrentPhase(-1); - gameState->setActivePlayer(-1); + game->getGameState()->setCurrentPhase(-1); + game->getGameState()->setActivePlayer(-1); game->getGameMetaInfo()->setStarted(false); emit gameStopped(); } - gameState->setGameStateKnown(true); - game->emitUserEvent(); + game->getGameState()->setGameStateKnown(true); + emitUserEvent(); } void GameEventHandler::processCardAttachmentsForPlayers(const Event_GameStateChanged &event) @@ -342,8 +344,7 @@ void GameEventHandler::eventPlayerPropertiesChanged(const Event_PlayerProperties break; } case GameEventContext::CONCEDE: { - emit playerConceded(player); - player->getPlayerInfo()->setConceded(true); + player->setConceded(true); QMapIterator playerIterator(game->getPlayerManager()->getPlayers()); while (playerIterator.hasNext()) @@ -352,8 +353,7 @@ void GameEventHandler::eventPlayerPropertiesChanged(const Event_PlayerProperties break; } case GameEventContext::UNCONCEDE: { - emit playerUnconceded(player); - player->getPlayerInfo()->setConceded(false); + player->setConceded(false); QMapIterator playerIterator(game->getPlayerManager()->getPlayers()); while (playerIterator.hasNext()) @@ -391,22 +391,22 @@ void GameEventHandler::eventJoin(const Event_Join &event, int /*eventPlayerId*/, const ServerInfo_PlayerProperties &playerInfo = event.player_properties(); const int playerId = playerInfo.player_id(); QString playerName = QString::fromStdString(playerInfo.user_info().name()); - game->addPlayerToAutoCompleteList(playerName); + emit addPlayerToAutoCompleteList(playerName); if (game->getPlayerManager()->getPlayers().contains(playerId)) return; if (playerInfo.spectator()) { - gameState->addSpectator(playerId, playerInfo); + game->getPlayerManager()->addSpectator(playerId, playerInfo); emit logJoinSpectator(playerName); emit spectatorJoined(playerInfo); } else { - Player *newPlayer = game->getPlayerManager()->addPlayer(playerId, playerInfo.user_info(), game); + Player *newPlayer = game->getPlayerManager()->addPlayer(playerId, playerInfo.user_info()); emit logJoinPlayer(newPlayer); emit playerJoined(playerInfo); } - game->emitUserEvent(); + emitUserEvent(); } QString GameEventHandler::getLeaveReason(Event_Leave::LeaveReason reason) @@ -447,7 +447,7 @@ void GameEventHandler::eventLeave(const Event_Leave &event, int eventPlayerId, c while (playerIterator.hasNext()) playerIterator.next().value()->updateZones(); - game->emitUserEvent(); + emitUserEvent(); } void GameEventHandler::eventKicked(const Event_Kicked & /*event*/, @@ -460,7 +460,7 @@ void GameEventHandler::eventKicked(const Event_Kicked & /*event*/, emit playerKicked(); - game->emitUserEvent(); + emitUserEvent(); } void GameEventHandler::eventReverseTurn(const Event_ReverseTurn &event, @@ -478,7 +478,7 @@ void GameEventHandler::eventGameHostChanged(const Event_GameHostChanged & /*even int eventPlayerId, const GameEventContext & /*context*/) { - gameState->setHostId(eventPlayerId); + game->getGameState()->setHostId(eventPlayerId); } void GameEventHandler::eventGameClosed(const Event_GameClosed & /*event*/, @@ -486,22 +486,22 @@ void GameEventHandler::eventGameClosed(const Event_GameClosed & /*event*/, const GameEventContext & /*context*/) { game->getGameMetaInfo()->setStarted(false); - gameState->setGameClosed(true); + game->getGameState()->setGameClosed(true); emit gameClosed(); emit logGameClosed(); - game->emitUserEvent(); + emitUserEvent(); } void GameEventHandler::eventSetActivePlayer(const Event_SetActivePlayer &event, int /*eventPlayerId*/, const GameEventContext & /*context*/) { - gameState->setActivePlayer(event.active_player_id()); + game->getGameState()->setActivePlayer(event.active_player_id()); Player *player = game->getPlayerManager()->getPlayer(event.active_player_id()); if (!player) return; emit logActivePlayer(player); - game->emitUserEvent(); + emitUserEvent(); } void GameEventHandler::eventSetActivePhase(const Event_SetActivePhase &event, @@ -509,9 +509,9 @@ void GameEventHandler::eventSetActivePhase(const Event_SetActivePhase &event, const GameEventContext & /*context*/) { const int phase = event.phase(); - if (gameState->getCurrentPhase() != phase) { + if (game->getGameState()->getCurrentPhase() != phase) { emit logActivePhaseChanged(phase); } - gameState->setCurrentPhase(phase); - game->emitUserEvent(); + game->getGameState()->setCurrentPhase(phase); + emitUserEvent(); } \ No newline at end of file diff --git a/cockatrice/src/game/game_event_handler.h b/cockatrice/src/game/game_event_handler.h index 97b657339..e7c46dc19 100644 --- a/cockatrice/src/game/game_event_handler.h +++ b/cockatrice/src/game/game_event_handler.h @@ -3,12 +3,11 @@ #include "pb/event_leave.pb.h" #include "pb/serverinfo_player.pb.h" -#include "player/player.h" +#include "player/event_processing_options.h" #include class AbstractClient; -class TabGame; class Response; class GameEventContainer; class GameEventContext; @@ -30,24 +29,25 @@ class Event_Ping; class Event_GameSay; class Event_Kicked; class Event_ReverseTurn; +class Game; class PendingCommand; +class Player; class GameEventHandler : public QObject { Q_OBJECT private: - TabGame *game; - GameState *gameState; + Game *game; public: - GameEventHandler(TabGame *game); + explicit GameEventHandler(Game *_game); void handleNextTurn(); void handleReverseTurn(); - void handlePlayerConceded(); - void handlePlayerUnconceded(); + void handleActiveLocalPlayerConceded(); + void handleActiveLocalPlayerUnconceded(); void handleActivePhaseChanged(int phase); void handleGameLeft(); void handleChatMessageSent(const QString &chatMessage); @@ -84,6 +84,8 @@ public slots: void sendGameCommand(const ::google::protobuf::Message &command, int playerId = -1); signals: + void emitUserEvent(); + void addPlayerToAutoCompleteList(QString playerName); void localPlayerDeckSelected(Player *localPlayer, int playerId, ServerInfo_Player playerInfo); void remotePlayerDeckSelected(QString deckList, int playerId, QString playerName); void remotePlayersDecksSelected(QVector>> opponentDecks); @@ -106,8 +108,6 @@ signals: void logGameStart(); void logReadyStart(Player *player); void logNotReadyStart(Player *player); - void playerConceded(Player *player); - void playerUnconceded(Player *player); void logDeckSelect(Player *player, QString deckHash, int sideboardSize); void logSideboardLockSet(Player *player, bool sideboardLocked); void logConnectionStateChanged(Player *player, bool connected); diff --git a/cockatrice/src/game/game_meta_info.cpp b/cockatrice/src/game/game_meta_info.cpp index 90a6cbeab..face4cf76 100644 --- a/cockatrice/src/game/game_meta_info.cpp +++ b/cockatrice/src/game/game_meta_info.cpp @@ -1 +1,7 @@ #include "game_meta_info.h" + +#include "game.h" + +GameMetaInfo::GameMetaInfo(Game *_game) : QObject(_game), game(_game) +{ +} diff --git a/cockatrice/src/game/game_meta_info.h b/cockatrice/src/game/game_meta_info.h index 08600423e..642c3c55a 100644 --- a/cockatrice/src/game/game_meta_info.h +++ b/cockatrice/src/game/game_meta_info.h @@ -10,13 +10,12 @@ // This class de-couples the domain object (i.e. the GameMetaInfo) from the network object. // If the network object changes, only this class needs to be adjusted. +class Game; class GameMetaInfo : public QObject { Q_OBJECT public: - explicit GameMetaInfo(QObject *parent = nullptr) : QObject(parent) - { - } + explicit GameMetaInfo(Game *_game); QMap roomGameTypes; @@ -80,6 +79,11 @@ public: return roomGameTypes.find(gameInfo_.game_types(index)).value(); } + Game *getGame() const + { + return game; + } + public slots: void setStarted(bool s) { @@ -101,6 +105,7 @@ signals: void spectatorsOmniscienceChanged(bool omniscient); private: + Game *game; ServerInfo_Game gameInfo_; }; diff --git a/cockatrice/src/game/game_scene.cpp b/cockatrice/src/game/game_scene.cpp index b09aaffc6..1494661d7 100644 --- a/cockatrice/src/game/game_scene.cpp +++ b/cockatrice/src/game/game_scene.cpp @@ -51,8 +51,6 @@ void GameScene::addPlayer(Player *player) players << player->getGraphicsItem(); addItem(player->getGraphicsItem()); connect(player->getGraphicsItem(), &PlayerGraphicsItem::sizeChanged, this, &GameScene::rearrange); - // TODO: game scene really shouldn't cue off of this - // connect(player, &Player::playerCountChanged, this, &GameScene::rearrange); } void GameScene::removePlayer(Player *player) @@ -85,7 +83,7 @@ void GameScene::rearrange() QListIterator playersIter(players); while (playersIter.hasNext()) { Player *p = playersIter.next()->getPlayer(); - if (p && !p->getPlayerInfo()->getConceded()) { + if (p && !p->getConceded()) { playersPlaying.append(p); if (!firstPlayerFound && (p->getPlayerInfo()->getLocal())) { firstPlayerIndex = playersPlaying.size() - 1; diff --git a/cockatrice/src/game/game_state.cpp b/cockatrice/src/game/game_state.cpp index 6dfab76a1..c71fe3ad0 100644 --- a/cockatrice/src/game/game_state.cpp +++ b/cockatrice/src/game/game_state.cpp @@ -1,6 +1,7 @@ #include "game_state.h" -GameState::GameState(int _secondsElapsed, +GameState::GameState(Game *_game, + int _secondsElapsed, int _hostId, bool _isLocalGame, const QList _clients, @@ -8,8 +9,9 @@ GameState::GameState(int _secondsElapsed, bool _resuming, int _currentPhase, bool _gameClosed) - : secondsElapsed(_secondsElapsed), hostId(_hostId), isLocalGame(_isLocalGame), clients(_clients), - gameStateKnown(_gameStateKnown), resuming(_resuming), currentPhase(_currentPhase), gameClosed(_gameClosed) + : QObject(_game), game(_game), secondsElapsed(_secondsElapsed), hostId(_hostId), isLocalGame(_isLocalGame), + clients(_clients), gameStateKnown(_gameStateKnown), resuming(_resuming), currentPhase(_currentPhase), + gameClosed(_gameClosed) { } diff --git a/cockatrice/src/game/game_state.h b/cockatrice/src/game/game_state.h index 12cf82cb1..095c74a7f 100644 --- a/cockatrice/src/game/game_state.h +++ b/cockatrice/src/game/game_state.h @@ -16,7 +16,8 @@ class GameState : public QObject Q_OBJECT public: - explicit GameState(int secondsElapsed, + explicit GameState(Game *_game, + int secondsElapsed, int hostId, bool isLocalGame, QList clients, @@ -25,36 +26,6 @@ public: int currentPhase, bool gameClosed); - const QMap &getSpectators() const - { - return spectators; - } - - ServerInfo_User getSpectator(int playerId) const - { - return spectators.value(playerId); - } - - QString getSpectatorName(int spectatorId) const - { - return QString::fromStdString(spectators.value(spectatorId).name()); - } - - void addSpectator(int spectatorId, const ServerInfo_PlayerProperties &prop) - { - if (!spectators.contains(spectatorId)) { - spectators.insert(spectatorId, prop.user_info()); - emit spectatorAdded(prop); - } - } - - void removeSpectator(int spectatorId) - { - ServerInfo_User spectatorInfo = spectators.value(spectatorId); - spectators.remove(spectatorId); - emit spectatorRemoved(spectatorId, spectatorInfo); - } - void setHostId(int _hostId) { hostId = _hostId; @@ -151,10 +122,6 @@ public: signals: void updateTimeElapsedLabel(QString newTime); - void playerAdded(Player *player); - void playerRemoved(Player *player); - void spectatorAdded(ServerInfo_PlayerProperties spectator); - void spectatorRemoved(int spectatorId, ServerInfo_User spectator); void gameStarted(bool resuming); void gameStopped(); void activePhaseChanged(int activePhase); @@ -165,12 +132,12 @@ public slots: void setGameTime(int _secondsElapsed); private: + Game *game; QTimer *gameTimer; int secondsElapsed; QMap roomGameTypes; int hostId; const bool isLocalGame; - QMap spectators; QList clients; bool gameStateKnown; bool resuming; diff --git a/cockatrice/src/game/player/player.cpp b/cockatrice/src/game/player/player.cpp index 4896f2413..0323a0092 100644 --- a/cockatrice/src/game/player/player.cpp +++ b/cockatrice/src/game/player/player.cpp @@ -29,10 +29,10 @@ #include #include -Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, TabGame *_parent) +Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, Game *_parent) : QObject(_parent), game(_parent), playerInfo(new PlayerInfo(info, _id, _local, _judge)), playerEventHandler(new PlayerEventHandler(this)), playerActions(new PlayerActions(this)), active(false), - deck(nullptr), dialogSemaphore(false) + conceded(false), deck(nullptr), dialogSemaphore(false) { initializeZones(); @@ -44,7 +44,7 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T connect(this, &Player::deckChanged, playerMenu, &PlayerMenu::enableOpenInDeckEditorAction); connect(this, &Player::deckChanged, playerMenu, &PlayerMenu::populatePredefinedTokensMenu); - connect(this, &Player::openDeckEditor, game, &TabGame::openDeckEditor); + // connect(this, &Player::openDeckEditor, game, &TabGame::openDeckEditor); } void Player::initializeZones() @@ -55,7 +55,6 @@ void Player::initializeZones() addZone(new PileZoneLogic(this, "sb", false, false, false, this)); addZone(new TableZoneLogic(this, "table", true, false, true, this)); addZone(new StackZoneLogic(this, "stack", true, false, true, this)); - // TODO: Contentsknown is probably not true for other players addZone(new HandZoneLogic(this, "hand", false, false, true, this)); } @@ -97,6 +96,19 @@ void Player::clear() clearCounters(); } +void Player::setConceded(bool _conceded) +{ + if (conceded != _conceded) { + conceded = _conceded; + + getGraphicsItem()->setVisible(!conceded); + if (conceded) { + clear(); + } + emit concededChanged(getPlayerInfo()->getId(), conceded); + } +} + void Player::processPlayerInfo(const ServerInfo_Player &info) { static QSet builtinZones{/* PileZones */ @@ -160,8 +172,7 @@ void Player::processPlayerInfo(const ServerInfo_Player &info) // Non-builtin zones are hidden by default and can't be interacted // with, except through menus. - // TODO: worry about this (later) - // zone->setVisible(false); + emit zone->setGraphicsVisibility(false); emit addViewCustomZoneActionToCustomZoneMenu(zoneName); @@ -193,7 +204,7 @@ void Player::processPlayerInfo(const ServerInfo_Player &info) addCounter(info.counter_list(i)); } - playerInfo->setConceded(info.properties().conceded()); + setConceded(info.properties().conceded()); } void Player::processCardAttachment(const ServerInfo_Player &info) @@ -268,7 +279,7 @@ AbstractCounter *Player::addCounter(int counterId, const QString &name, QColor c if (name == "life") { ctr = getGraphicsItem()->getPlayerTarget()->addCounter(counterId, name, value); } else { - ctr = new GeneralCounter(this, counterId, name, color, radius, value, true, graphicsItem, game); + ctr = new GeneralCounter(this, counterId, name, color, radius, value, true, graphicsItem); } counters.insert(counterId, ctr); @@ -387,8 +398,8 @@ ArrowItem *Player::addArrow(int arrowId, CardItem *startCard, ArrowTarget *targe { auto *arrow = new ArrowItem(this, arrowId, startCard, targetItem, color); arrows.insert(arrowId, arrow); - // TODO: consider this in the graphics item - // scene()->addItem(arrow); + + getGameScene()->addItem(arrow); return arrow; } @@ -467,5 +478,5 @@ void Player::setGameStarted() if (playerInfo->local) { emit resetTopCardMenuActions(); } - playerInfo->setConceded(false); + setConceded(false); } diff --git a/cockatrice/src/game/player/player.h b/cockatrice/src/game/player/player.h index 77e6ea6ee..058e2c252 100644 --- a/cockatrice/src/game/player/player.h +++ b/cockatrice/src/game/player/player.h @@ -6,6 +6,7 @@ #include "../board/abstract_graphics_item.h" #include "../cards/card_info.h" #include "../filters/filter_string.h" +#include "../game.h" #include "pb/card_attributes.pb.h" #include "pb/game_event.pb.h" #include "player_actions.h" @@ -63,7 +64,8 @@ signals: void deckChanged(); void newCardAdded(AbstractCardItem *card); void rearrangeCounters(); - void activeChanged(bool _active); + void activeChanged(bool active); + void concededChanged(int playerId, bool conceded); void clearCustomZonesMenu(); void addViewCustomZoneActionToCustomZoneMenu(QString zoneName); void resetTopCardMenuActions(); @@ -72,7 +74,7 @@ public slots: void setActive(bool _active); public: - Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, TabGame *_parent); + Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, Game *_parent); ~Player() override; void retranslateUi(); @@ -93,7 +95,7 @@ public: return active; } - TabGame *getGame() const + Game *getGame() const { return game; } @@ -202,6 +204,12 @@ public: return arrows; } + void setConceded(bool _conceded); + bool getConceded() const + { + return conceded; + } + void setGameStarted(); void setDialogSemaphore(const bool _active) @@ -210,7 +218,7 @@ public: } private: - TabGame *game; + Game *game; PlayerInfo *playerInfo; PlayerEventHandler *playerEventHandler; PlayerActions *playerActions; @@ -218,6 +226,7 @@ private: PlayerGraphicsItem *graphicsItem; bool active; + bool conceded; DeckLoader *deck; @@ -237,7 +246,7 @@ class AnnotationDialog : public QInputDialog void keyPressEvent(QKeyEvent *e) override; public: - explicit AnnotationDialog(QWidget *parent) : QInputDialog(parent) + explicit AnnotationDialog(QWidget *parent = nullptr) : QInputDialog(parent) { } }; diff --git a/cockatrice/src/game/player/player_actions.cpp b/cockatrice/src/game/player/player_actions.cpp index 637e739cf..d743f9aae 100644 --- a/cockatrice/src/game/player/player_actions.cpp +++ b/cockatrice/src/game/player/player_actions.cpp @@ -146,7 +146,8 @@ void PlayerActions::actViewTopCards() { int deckSize = player->getDeckZone()->getCards().size(); bool ok; - int number = QInputDialog::getInt(player->getGame(), tr("View top cards of library"), + // TODO: Signal this + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("View top cards of library"), tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberTopCards, 1, deckSize, 1, &ok); if (ok) { @@ -159,7 +160,7 @@ void PlayerActions::actViewBottomCards() { int deckSize = player->getDeckZone()->getCards().size(); bool ok; - int number = QInputDialog::getInt(player->getGame(), tr("View bottom cards of library"), + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("View bottom cards of library"), tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberBottomCards, 1, deckSize, 1, &ok); if (ok) { @@ -232,7 +233,7 @@ void PlayerActions::actShuffleTop() } bool ok; - int number = QInputDialog::getInt(player->getGame(), tr("Shuffle top cards of library"), + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Shuffle top cards of library"), tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberTopCards, 1, maxCards, 1, &ok); if (!ok) { @@ -261,7 +262,7 @@ void PlayerActions::actShuffleBottom() } bool ok; - int number = QInputDialog::getInt(player->getGame(), tr("Shuffle bottom cards of library"), + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Shuffle bottom cards of library"), tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1, maxCards, 1, &ok); if (!ok) { @@ -295,7 +296,7 @@ void PlayerActions::actMulligan() int handSize = player->getHandZone()->getCards().size(); int deckSize = player->getDeckZone()->getCards().size() + handSize; // hand is shuffled back into the deck bool ok; - int number = QInputDialog::getInt(player->getGame(), tr("Draw hand"), + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Draw hand"), tr("Number of cards: (max. %1)").arg(deckSize) + '\n' + tr("0 and lower are in comparison to current hand size"), startSize, -handSize, deckSize, 1, &ok); @@ -321,9 +322,8 @@ void PlayerActions::actDrawCards() { int deckSize = player->getDeckZone()->getCards().size(); bool ok; - int number = - QInputDialog::getInt(player->getGame(), tr("Draw cards"), tr("Number of cards: (max. %1)").arg(deckSize), - defaultNumberTopCards, 1, deckSize, 1, &ok); + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Draw cards"), + tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberTopCards, 1, deckSize, 1, &ok); if (ok) { defaultNumberTopCards = number; Command_DrawCards cmd; @@ -393,7 +393,7 @@ void PlayerActions::actMoveTopCardsToGrave() } bool ok; - int number = QInputDialog::getInt(player->getGame(), tr("Move top cards to grave"), + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Move top cards to grave"), tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberTopCards, 1, maxCards, 1, &ok); if (!ok) { @@ -425,7 +425,7 @@ void PlayerActions::actMoveTopCardsToExile() } bool ok; - int number = QInputDialog::getInt(player->getGame(), tr("Move top cards to exile"), + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Move top cards to exile"), tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberTopCards, 1, maxCards, 1, &ok); if (!ok) { @@ -453,7 +453,7 @@ void PlayerActions::actMoveTopCardsUntil() { stopMoveTopCardsUntil(); - DlgMoveTopCardsUntil dlg(player->getGame(), movingCardsUntilExprs, movingCardsUntilNumberOfHits, + DlgMoveTopCardsUntil dlg(/* player->getGame() */ nullptr, movingCardsUntilExprs, movingCardsUntilNumberOfHits, movingCardsUntilAutoPlay); if (!dlg.exec()) { return; @@ -597,7 +597,7 @@ void PlayerActions::actMoveBottomCardsToGrave() } bool ok; - int number = QInputDialog::getInt(player->getGame(), tr("Move bottom cards to grave"), + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Move bottom cards to grave"), tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1, maxCards, 1, &ok); if (!ok) { @@ -629,7 +629,7 @@ void PlayerActions::actMoveBottomCardsToExile() } bool ok; - int number = QInputDialog::getInt(player->getGame(), tr("Move bottom cards to exile"), + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Move bottom cards to exile"), tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1, maxCards, 1, &ok); if (!ok) { @@ -746,9 +746,8 @@ void PlayerActions::actDrawBottomCards() } bool ok; - int number = - QInputDialog::getInt(player->getGame(), tr("Draw bottom cards"), tr("Number of cards: (max. %1)").arg(maxCards), - defaultNumberBottomCards, 1, maxCards, 1, &ok); + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Draw bottom cards"), + tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1, maxCards, 1, &ok); if (!ok) { return; } else if (number > maxCards) { @@ -820,7 +819,7 @@ void PlayerActions::actUntapAll() void PlayerActions::actRollDie() { - DlgRollDice dlg(player->getGame()); + DlgRollDice dlg(/* player->getGame() */ nullptr); if (!dlg.exec()) { return; } @@ -833,7 +832,7 @@ void PlayerActions::actRollDie() void PlayerActions::actCreateToken() { - DlgCreateToken dlg(player->getPlayerMenu()->getPredefinedTokens(), player->getGame()); + DlgCreateToken dlg(player->getPlayerMenu()->getPredefinedTokens(), /* player->getGame() */ nullptr); if (!dlg.exec()) { return; } @@ -1021,7 +1020,7 @@ bool PlayerActions::createRelatedFromRelation(const CardItem *sourceCard, const if (cardRelation->getIsVariable()) { bool ok; player->setDialogSemaphore(true); - int count = QInputDialog::getInt(player->getGame(), tr("Create tokens"), tr("Number:"), + int count = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Create tokens"), tr("Number:"), cardRelation->getDefaultCount(), 1, MAX_TOKENS_PER_DIALOG, 1, &ok); player->setDialogSemaphore(false); if (!ok) { @@ -1187,7 +1186,7 @@ void PlayerActions::actMoveCardXCardsFromTop() int deckSize = player->getDeckZone()->getCards().size() + 1; // add the card to move to the deck bool ok; int number = - QInputDialog::getInt(player->getGame(), tr("Place card X cards from top of library"), + QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Place card X cards from top of library"), tr("Which position should this card be placed:") + "\n" + tr("(max. %1)").arg(deckSize), defaultNumberTopCardsToPlaceBelow, 1, deckSize, 1, &ok); number -= 1; // indexes start at 0 @@ -1347,7 +1346,7 @@ void PlayerActions::actSetPT() } bool ok; player->setDialogSemaphore(true); - QString pt = getTextWithMax(player->getGame(), tr("Change power/toughness"), tr("Change stats to:"), + QString pt = getTextWithMax(/* player->getGame() */ nullptr, tr("Change power/toughness"), tr("Change stats to:"), QLineEdit::Normal, oldPT, &ok); player->setDialogSemaphore(false); if (player->clearCardsToDelete() || !ok) { @@ -1465,7 +1464,7 @@ void PlayerActions::actSetAnnotation() } player->setDialogSemaphore(true); - AnnotationDialog *dialog = new AnnotationDialog(player->getGame()); + AnnotationDialog *dialog = new AnnotationDialog(/* player->getGame() */); dialog->setOptions(QInputDialog::UsePlainTextEditForTextInput); dialog->setWindowTitle(tr("Set annotation")); dialog->setLabelText(tr("Please enter the new annotation:")); @@ -1561,8 +1560,8 @@ void PlayerActions::actCardCounterTrigger() auto *card = static_cast(player->getGameScene()->selectedItems().first()); oldValue = card->getCounters().value(counterId, 0); } - int number = QInputDialog::getInt(player->getGame(), tr("Set counters"), tr("Number:"), oldValue, 0, - MAX_COUNTERS_ON_CARD, 1, &ok); + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Set counters"), tr("Number:"), + oldValue, 0, MAX_COUNTERS_ON_CARD, 1, &ok); player->setDialogSemaphore(false); if (player->clearCardsToDelete() || !ok) { return; diff --git a/cockatrice/src/game/player/player_graphics_item.cpp b/cockatrice/src/game/player/player_graphics_item.cpp index ce36157df..d1c278e8d 100644 --- a/cockatrice/src/game/player/player_graphics_item.cpp +++ b/cockatrice/src/game/player/player_graphics_item.cpp @@ -13,7 +13,7 @@ PlayerGraphicsItem::PlayerGraphicsItem(Player *_player) : player(_player) playerArea = new PlayerArea(this); - playerTarget = new PlayerTarget(player, playerArea, player->getGame()); + playerTarget = new PlayerTarget(player, playerArea); qreal avatarMargin = (counterAreaWidth + CARD_HEIGHT + 15 - playerTarget->boundingRect().width()) / 2.0; playerTarget->setPos(QPointF(avatarMargin, avatarMargin)); diff --git a/cockatrice/src/game/player/player_info.cpp b/cockatrice/src/game/player/player_info.cpp index e2cf67757..389b90d37 100644 --- a/cockatrice/src/game/player/player_info.cpp +++ b/cockatrice/src/game/player/player_info.cpp @@ -1,23 +1,12 @@ #include "player_info.h" PlayerInfo::PlayerInfo(const ServerInfo_User &info, int _id, bool _local, bool _judge) - : id(_id), local(_local), judge(_judge), handVisible(false), conceded(false), zoneId(0) + : id(_id), local(_local), judge(_judge), handVisible(false), zoneId(0) { userInfo = new ServerInfo_User; userInfo->CopyFrom(info); } -void PlayerInfo::setConceded(bool _conceded) -{ - conceded = _conceded; - // TODO: deal with this - /*setVisible(!conceded); - if (conceded) { - clear(); - } - emit playerCountChanged();*/ -} - void PlayerInfo::setZoneId(int _zoneId) { // TODO: deal with this diff --git a/cockatrice/src/game/player/player_info.h b/cockatrice/src/game/player/player_info.h index 09a6ca481..610a76d7b 100644 --- a/cockatrice/src/game/player/player_info.h +++ b/cockatrice/src/game/player/player_info.h @@ -22,7 +22,6 @@ public: bool local; bool judge; bool handVisible; - bool conceded; int zoneId; int getZoneId() const @@ -32,12 +31,6 @@ public: void setZoneId(int _zoneId); - void setConceded(bool _conceded); - bool getConceded() const - { - return conceded; - } - int getId() const { return id; diff --git a/cockatrice/src/game/player/player_list_widget.cpp b/cockatrice/src/game/player/player_list_widget.cpp index dc7489dce..e2e329603 100644 --- a/cockatrice/src/game/player/player_list_widget.cpp +++ b/cockatrice/src/game/player/player_list_widget.cpp @@ -55,9 +55,7 @@ bool PlayerListTWI::operator<(const QTreeWidgetItem &other) const } PlayerListWidget::PlayerListWidget(TabSupervisor *_tabSupervisor, - AbstractClient *_client, - TabGame *_game, - QWidget *parent) + AbstractClient *_client, Game *_game, QWidget *parent) : QTreeWidget(parent), tabSupervisor(_tabSupervisor), client(_client), game(_game), gameStarted(false) { readyIcon = QPixmap("theme:icons/ready_start"); diff --git a/cockatrice/src/game/player/player_list_widget.h b/cockatrice/src/game/player/player_list_widget.h index 4cef51998..8b70db27a 100644 --- a/cockatrice/src/game/player/player_list_widget.h +++ b/cockatrice/src/game/player/player_list_widget.h @@ -11,7 +11,7 @@ class ServerInfo_PlayerProperties; class TabSupervisor; class AbstractClient; -class TabGame; +class Game; class UserContextMenu; class PlayerListItemDelegate : public QStyledItemDelegate @@ -39,7 +39,7 @@ private: QMap players; TabSupervisor *tabSupervisor; AbstractClient *client; - TabGame *game; + Game *game; UserContextMenu *userContextMenu; QIcon readyIcon, notReadyIcon, concededIcon, playerIcon, judgeIcon, spectatorIcon, lockIcon; bool gameStarted; @@ -47,7 +47,7 @@ signals: void openMessageDialog(const QString &userName, bool focus); public: - PlayerListWidget(TabSupervisor *_tabSupervisor, AbstractClient *_client, TabGame *_game, QWidget *parent = nullptr); + PlayerListWidget(TabSupervisor *_tabSupervisor, AbstractClient *_client, Game *_game, QWidget *parent = nullptr); void retranslateUi(); void setActivePlayer(int playerId); void setGameStarted(bool _gameStarted, bool resuming); diff --git a/cockatrice/src/game/player/player_manager.cpp b/cockatrice/src/game/player/player_manager.cpp index 4e6460de3..35ed32382 100644 --- a/cockatrice/src/game/player/player_manager.cpp +++ b/cockatrice/src/game/player/player_manager.cpp @@ -1,7 +1,80 @@ #include "player_manager.h" -PlayerManager::PlayerManager(QObject *parent, int _localPlayerId, bool _localPlayerIsJudge, bool localPlayerIsSpectator) - : QObject(parent), localPlayerId(_localPlayerId), localPlayerIsJudge(_localPlayerIsJudge), - localPlayerIsSpectator(localPlayerIsSpectator) +#include "../game.h" +#include "player.h" + +PlayerManager::PlayerManager(Game *_game, int _localPlayerId, bool _localPlayerIsJudge, bool localPlayerIsSpectator) + : QObject(_game), game(_game), players(QMap()), localPlayerId(_localPlayerId), + localPlayerIsJudge(_localPlayerIsJudge), localPlayerIsSpectator(localPlayerIsSpectator) { +} + +bool PlayerManager::isMainPlayerConceded() const +{ + Player *player = players.value(localPlayerId, nullptr); + return player && player->getConceded(); +} + +Player *PlayerManager::getActiveLocalPlayer(int activePlayer) const +{ + Player *active = players.value(activePlayer, 0); + if (active) + if (active->getPlayerInfo()->getLocal()) + return active; + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Player *temp = playerIterator.next().value(); + if (temp->getPlayerInfo()->getLocal()) + return temp; + } + + return nullptr; +} + +Player *PlayerManager::addPlayer(int playerId, const ServerInfo_User &info) +{ + auto *newPlayer = new Player(info, playerId, isLocalPlayer(playerId), isJudge(), getGame()); + connect(newPlayer, &Player::concededChanged, this, &PlayerManager::playerConceded); + players.insert(playerId, newPlayer); + emit playerAdded(newPlayer); + emit playerCountChanged(); + return newPlayer; +} + +void PlayerManager::removePlayer(int playerId) +{ + Player *player = getPlayer(playerId); + if (!player) { + return; + } + players.remove(playerId); + emit playerCountChanged(); + emit playerRemoved(player); +} + +Player *PlayerManager::getPlayer(int playerId) const +{ + Player *player = players.value(playerId, 0); + if (!player) + return nullptr; + return player; +} + +void PlayerManager::onPlayerConceded(int playerId, bool conceded) +{ + // GameEventHandler cares about this for sending the concede/unconcede commands + if (playerId == getActiveLocalPlayer(playerId)->getPlayerInfo()->getId()) { + if (conceded) { + emit activeLocalPlayerConceded(); + } else { + emit activeLocalPlayerUnconceded(); + } + } + // Everything else cares about this + if (conceded) { + emit playerConceded(playerId); + } else { + emit playerUnconceded(playerId); + } } \ No newline at end of file diff --git a/cockatrice/src/game/player/player_manager.h b/cockatrice/src/game/player/player_manager.h index c3fc89220..c72dece6d 100644 --- a/cockatrice/src/game/player/player_manager.h +++ b/cockatrice/src/game/player/player_manager.h @@ -1,21 +1,26 @@ #ifndef COCKATRICE_PLAYER_MANAGER_H #define COCKATRICE_PLAYER_MANAGER_H -#include "player.h" +#include "pb/serverinfo_playerproperties.pb.h" +#include #include +class Game; +class Player; class PlayerManager : public QObject { Q_OBJECT public: - PlayerManager(QObject *parent, int _localPlayerId, bool _localPlayerIsJudge, bool localPlayerIsSpectator); + PlayerManager(Game *_game, int _localPlayerId, bool _localPlayerIsJudge, bool localPlayerIsSpectator); + Game *game; QMap players; int localPlayerId; bool localPlayerIsJudge; bool localPlayerIsSpectator; + QMap spectators; bool isSpectator() const { @@ -42,66 +47,68 @@ public: return players.size(); } - Player *getActiveLocalPlayer(int activePlayer) const - { - Player *active = players.value(activePlayer, 0); - if (active) - if (active->getPlayerInfo()->getLocal()) - return active; + Player *getActiveLocalPlayer(int activePlayer) const; - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Player *temp = playerIterator.next().value(); - if (temp->getPlayerInfo()->getLocal()) - return temp; - } + Player *addPlayer(int playerId, const ServerInfo_User &info); - return nullptr; - } + void removePlayer(int playerId); - Player *addPlayer(int playerId, const ServerInfo_User &info, TabGame *game) - { - auto *newPlayer = new Player(info, playerId, isLocalPlayer(playerId), isJudge(), game); - players.insert(playerId, newPlayer); - emit playerAdded(newPlayer); - emit playerCountChanged(); - return newPlayer; - } + Player *getPlayer(int playerId) const; - void removePlayer(int playerId) - { - Player *player = getPlayer(playerId); - if (!player) { - return; - } - players.remove(playerId); - emit playerCountChanged(); - emit playerRemoved(player); - } + void onPlayerConceded(int playerId, bool conceded); - Player *getPlayer(int playerId) const - { - Player *player = players.value(playerId, 0); - if (!player) - return nullptr; - return player; - } - - [[nodiscard]] bool isMainPlayerConceded() const - { - Player *player = players.value(localPlayerId, nullptr); - return player && player->getPlayerInfo()->getConceded(); - } + [[nodiscard]] bool isMainPlayerConceded() const; [[nodiscard]] bool isLocalPlayer(int playerId) const { return playerId == getLocalPlayerId(); } + const QMap &getSpectators() const + { + return spectators; + } + + ServerInfo_User getSpectator(int playerId) const + { + return spectators.value(playerId); + } + + QString getSpectatorName(int spectatorId) const + { + return QString::fromStdString(spectators.value(spectatorId).name()); + } + + void addSpectator(int spectatorId, const ServerInfo_PlayerProperties &prop) + { + if (!spectators.contains(spectatorId)) { + spectators.insert(spectatorId, prop.user_info()); + emit spectatorAdded(prop); + } + } + + void removeSpectator(int spectatorId) + { + ServerInfo_User spectatorInfo = spectators.value(spectatorId); + spectators.remove(spectatorId); + emit spectatorRemoved(spectatorId, spectatorInfo); + } + + Game *getGame() const + { + return game; + } + signals: void playerAdded(Player *player); void playerRemoved(Player *player); + void activeLocalPlayerConceded(); + void activeLocalPlayerUnconceded(); + void playerConceded(int playerId); + void playerUnconceded(int playerId); void playerCountChanged(); + void spectatorAdded(ServerInfo_PlayerProperties spectator); + void spectatorRemoved(int spectatorId, ServerInfo_User spectator); }; #endif // COCKATRICE_PLAYER_MANAGER_H diff --git a/cockatrice/src/game/player/player_menu.cpp b/cockatrice/src/game/player/player_menu.cpp index b01bc5e81..03a55ab90 100644 --- a/cockatrice/src/game/player/player_menu.cpp +++ b/cockatrice/src/game/player/player_menu.cpp @@ -14,9 +14,8 @@ PlayerMenu::PlayerMenu(Player *_player) : player(_player) { if (player->getPlayerInfo()->local || player->getPlayerInfo()->judge) { - // TODO - // connect(_parent, &TabGame::playerAdded, this, &Player::addPlayer); - // connect(_parent, &TabGame::playerRemoved, this, &Player::removePlayer); + connect(player->getGame()->getPlayerManager(), &PlayerManager::playerAdded, this, &PlayerMenu::addPlayer); + connect(player->getGame()->getPlayerManager(), &PlayerManager::playerRemoved, this, &PlayerMenu::removePlayer); } const QList &players = player->getGame()->getPlayerManager()->getPlayers().values(); @@ -520,7 +519,8 @@ void PlayerMenu::playerListActionTriggered() } else if (menu == mRevealTopCard) { int deckSize = player->getDeckZone()->getCards().size(); bool ok; - int number = QInputDialog::getInt(player->getGame(), tr("Reveal top cards of library"), + // TODO: Correctly parent this + int number = QInputDialog::getInt(/* player->getGame() */ nullptr, tr("Reveal top cards of library"), tr("Number of cards: (max. %1)").arg(deckSize), /* defaultNumberTopCards */ 1, 1, deckSize, 1, &ok); if (ok) { @@ -821,8 +821,10 @@ void PlayerMenu::addRelatedCardView(const CardItem *card, QMenu *cardMenu) QString relatedCardName = relatedCard->getName(); CardRef cardRef = {relatedCardName, exactCard.getPrinting().getUuid()}; QAction *viewCard = viewRelatedCards->addAction(relatedCardName); - connect(viewCard, &QAction::triggered, player->getGame(), - [this, cardRef] { player->getGame()->viewCardInfo(cardRef); }); + Q_UNUSED(viewCard); + // TODO: Signal this + /*connect(viewCard, &QAction::triggered, player->getGame(), + [this, cardRef] { player->getGame()->viewCardInfo(cardRef); });*/ } } @@ -1200,7 +1202,8 @@ void PlayerMenu::setShortcutsActive() if (!player->getGame()->getGameState()->getIsLocalGame()) { // unattach action is only active in card menu if the active card is attached. // make unattach shortcut always active so that it consistently works when multiple cards are selected. - player->getGame()->addAction(aUnattach); + // TODO: Signal this + // player->getGame()->addAction(aUnattach); } } diff --git a/cockatrice/src/game/player/player_target.cpp b/cockatrice/src/game/player/player_target.cpp index c43b9a653..9e1b6bc46 100644 --- a/cockatrice/src/game/player/player_target.cpp +++ b/cockatrice/src/game/player/player_target.cpp @@ -12,10 +12,8 @@ PlayerCounter::PlayerCounter(Player *_player, int _id, const QString &_name, - int _value, - QGraphicsItem *parent, - QWidget *game) - : AbstractCounter(_player, _id, _name, false, _value, false, parent, game) + int _value, QGraphicsItem *parent) + : AbstractCounter(_player, _id, _name, false, _value, false, parent) { } @@ -52,8 +50,8 @@ void PlayerCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem * /* painter->drawText(translatedRect, Qt::AlignCenter, QString::number(value)); } -PlayerTarget::PlayerTarget(Player *_owner, QGraphicsItem *parentItem, QWidget *_game) - : ArrowTarget(_owner, parentItem), playerCounter(nullptr), game(_game) +PlayerTarget::PlayerTarget(Player *_owner, QGraphicsItem *parentItem) + : ArrowTarget(_owner, parentItem), playerCounter(nullptr) { setCacheMode(DeviceCoordinateCache); @@ -160,7 +158,7 @@ AbstractCounter *PlayerTarget::addCounter(int _counterId, const QString &_name, playerCounter->delCounter(); } - playerCounter = new PlayerCounter(owner, _counterId, _name, _value, this, game); + playerCounter = new PlayerCounter(owner, _counterId, _name, _value, this); playerCounter->setPos(boundingRect().width() - playerCounter->boundingRect().width(), boundingRect().height() - playerCounter->boundingRect().height()); connect(playerCounter, &PlayerCounter::destroyed, this, &PlayerTarget::counterDeleted); diff --git a/cockatrice/src/game/player/player_target.h b/cockatrice/src/game/player/player_target.h index f5da77f31..7c6f61020 100644 --- a/cockatrice/src/game/player/player_target.h +++ b/cockatrice/src/game/player/player_target.h @@ -14,12 +14,7 @@ class PlayerCounter : public AbstractCounter { Q_OBJECT public: - PlayerCounter(Player *_player, - int _id, - const QString &_name, - int _value, - QGraphicsItem *parent = nullptr, - QWidget *game = nullptr); + PlayerCounter(Player *_player, int _id, const QString &_name, int _value, QGraphicsItem *parent = nullptr); QRectF boundingRect() const override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; }; @@ -30,7 +25,6 @@ class PlayerTarget : public ArrowTarget private: QPixmap fullPixmap; PlayerCounter *playerCounter; - QWidget *game; public slots: void counterDeleted(); @@ -44,7 +38,7 @@ public: return Type; } - explicit PlayerTarget(Player *_player = nullptr, QGraphicsItem *parentItem = nullptr, QWidget *_game = nullptr); + explicit PlayerTarget(Player *_player = nullptr, QGraphicsItem *parentItem = nullptr); ~PlayerTarget() override; QRectF boundingRect() const override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; diff --git a/cockatrice/src/game/zones/card_zone.cpp b/cockatrice/src/game/zones/card_zone.cpp index 1bcccb1fd..0c189cd2b 100644 --- a/cockatrice/src/game/zones/card_zone.cpp +++ b/cockatrice/src/game/zones/card_zone.cpp @@ -11,6 +11,7 @@ CardZone::CardZone(CardZoneLogic *_logic, QGraphicsItem *parent) { connect(logic, &CardZoneLogic::retranslateUi, this, &CardZone::retranslateUi); connect(logic, &CardZoneLogic::cardAdded, this, &CardZone::onCardAdded); + connect(logic, &CardZoneLogic::setGraphicsVisibility, this, [this](bool v) { this->setVisible(v); }); connect(logic, &CardZoneLogic::updateGraphics, this, [this]() { update(); }); connect(logic, &CardZoneLogic::reorganizeCards, this, &CardZone::reorganizeCards); } diff --git a/cockatrice/src/game/zones/logic/card_zone_logic.h b/cockatrice/src/game/zones/logic/card_zone_logic.h index a810bd6da..07fbbceef 100644 --- a/cockatrice/src/game/zones/logic/card_zone_logic.h +++ b/cockatrice/src/game/zones/logic/card_zone_logic.h @@ -25,6 +25,7 @@ signals: void cardCountChanged(); void reorganizeCards(); void updateGraphics(); + void setGraphicsVisibility(bool visible); void retranslateUi(); public: diff --git a/cockatrice/src/server/chat_view/chat_view.cpp b/cockatrice/src/server/chat_view/chat_view.cpp index 069797926..105be5913 100644 --- a/cockatrice/src/server/chat_view/chat_view.cpp +++ b/cockatrice/src/server/chat_view/chat_view.cpp @@ -23,7 +23,7 @@ UserMessagePosition::UserMessagePosition(QTextCursor &cursor) relativePosition = cursor.position() - block.position(); } -ChatView::ChatView(TabSupervisor *_tabSupervisor, TabGame *_game, bool _showTimestamps, QWidget *parent) +ChatView::ChatView(TabSupervisor *_tabSupervisor, Game *_game, bool _showTimestamps, QWidget *parent) : QTextBrowser(parent), tabSupervisor(_tabSupervisor), game(_game), userListProxy(_tabSupervisor->getUserListManager()), evenNumber(true), showTimestamps(_showTimestamps), hoveredItemType(HoveredNothing) diff --git a/cockatrice/src/server/chat_view/chat_view.h b/cockatrice/src/server/chat_view/chat_view.h index 02e73b789..7ba3db9b8 100644 --- a/cockatrice/src/server/chat_view/chat_view.h +++ b/cockatrice/src/server/chat_view/chat_view.h @@ -16,7 +16,7 @@ class QTextTable; class QMouseEvent; class UserContextMenu; class UserListProxy; -class TabGame; +class Game; class UserMessagePosition { @@ -34,7 +34,7 @@ class ChatView : public QTextBrowser Q_OBJECT protected: TabSupervisor *const tabSupervisor; - TabGame *const game; + Game *const game; private: enum HoveredItemType @@ -83,7 +83,7 @@ private slots: void actMessageClicked(); public: - ChatView(TabSupervisor *_tabSupervisor, TabGame *_game, bool _showTimestamps, QWidget *parent = nullptr); + ChatView(TabSupervisor *_tabSupervisor, Game *_game, bool _showTimestamps, QWidget *parent = nullptr); void retranslateUi(); void appendHtml(const QString &html); void virtual appendHtmlServerMessage(const QString &html, diff --git a/cockatrice/src/server/message_log_widget.cpp b/cockatrice/src/server/message_log_widget.cpp index f6bd4d923..b84454383 100644 --- a/cockatrice/src/server/message_log_widget.cpp +++ b/cockatrice/src/server/message_log_widget.cpp @@ -1,6 +1,7 @@ #include "message_log_widget.h" #include "../client/sound_engine.h" +#include "../client/tabs/tab_game.h" #include "../client/translate_counter_name.h" #include "../game/board/card_item.h" #include "../game/phase.h" @@ -141,18 +142,22 @@ void MessageLogWidget::logAttachCard(Player *player, QString cardName, Player *t .arg(cardLink(std::move(targetCardName)))); } -void MessageLogWidget::logConcede(Player *player) +void MessageLogWidget::logConcede(int playerId) { soundEngine->playSound("player_concede"); - appendHtmlServerMessage(tr("%1 has conceded the game.").arg(sanitizeHtml(player->getPlayerInfo()->getName())), - true); + appendHtmlServerMessage( + tr("%1 has conceded the game.") + .arg(sanitizeHtml(game->getPlayerManager()->getPlayer(playerId)->getPlayerInfo()->getName())), + true); } -void MessageLogWidget::logUnconcede(Player *player) +void MessageLogWidget::logUnconcede(int playerId) { soundEngine->playSound("player_concede"); - appendHtmlServerMessage(tr("%1 has unconceded the game.").arg(sanitizeHtml(player->getPlayerInfo()->getName())), - true); + appendHtmlServerMessage( + tr("%1 has unconceded the game.") + .arg(sanitizeHtml(game->getPlayerManager()->getPlayer(playerId)->getPlayerInfo()->getName())), + true); } void MessageLogWidget::logConnectionStateChanged(Player *player, bool connectionState) @@ -834,7 +839,7 @@ void MessageLogWidget::connectToPlayerEventHandler(PlayerEventHandler *playerEve // &PlayerEventHandler::logAlwaysLookAtTopCard, this, &MessageLogWidget::logAlwaysLookAtTopCard); } -MessageLogWidget::MessageLogWidget(TabSupervisor *_tabSupervisor, TabGame *_game, QWidget *parent) +MessageLogWidget::MessageLogWidget(TabSupervisor *_tabSupervisor, Game *_game, QWidget *parent) : ChatView(_tabSupervisor, _game, true, parent), currentContext(MessageContext_None) { } diff --git a/cockatrice/src/server/message_log_widget.h b/cockatrice/src/server/message_log_widget.h index 98f4ce557..84f7fe070 100644 --- a/cockatrice/src/server/message_log_widget.h +++ b/cockatrice/src/server/message_log_widget.h @@ -8,6 +8,7 @@ class Player; class PlayerEventHandler; class CardZone; +class Game; class GameEventContext; class CardItem; @@ -27,14 +28,18 @@ private: static QPair getFromStr(CardZone *zone, QString cardName, int position, bool ownerChange); +public: + void connectToPlayerEventHandler(PlayerEventHandler *player); + MessageLogWidget(TabSupervisor *_tabSupervisor, Game *_game, QWidget *parent = nullptr); + public slots: void containerProcessingDone(); void containerProcessingStarted(const GameEventContext &context); void logAlwaysRevealTopCard(Player *player, CardZone *zone, bool reveal); void logAlwaysLookAtTopCard(Player *player, CardZone *zone, bool reveal); void logAttachCard(Player *player, QString cardName, Player *targetPlayer, QString targetCardName); - void logConcede(Player *player); - void logUnconcede(Player *player); + void logConcede(int playerId); + void logUnconcede(int playerId); void logConnectionStateChanged(Player *player, bool connectionState); void logCreateArrow(Player *player, Player *startPlayer, @@ -89,10 +94,6 @@ public slots: void appendHtmlServerMessage(const QString &html, bool optionalIsBold = false, QString optionalFontColor = QString()) override; - -public: - void connectToPlayerEventHandler(PlayerEventHandler *player); - MessageLogWidget(TabSupervisor *_tabSupervisor, TabGame *_game, QWidget *parent = nullptr); }; #endif diff --git a/cockatrice/src/server/user/user_context_menu.cpp b/cockatrice/src/server/user/user_context_menu.cpp index 26e774bf5..0a514f557 100644 --- a/cockatrice/src/server/user/user_context_menu.cpp +++ b/cockatrice/src/server/user/user_context_menu.cpp @@ -29,7 +29,7 @@ #include #include -UserContextMenu::UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *parent, TabGame *_game) +UserContextMenu::UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *parent, Game *_game) : QObject(parent), client(_tabSupervisor->getClient()), tabSupervisor(_tabSupervisor), userListProxy(_tabSupervisor->getUserListManager()), game(_game) { diff --git a/cockatrice/src/server/user/user_context_menu.h b/cockatrice/src/server/user/user_context_menu.h index 66c8d28a2..a00862d6a 100644 --- a/cockatrice/src/server/user/user_context_menu.h +++ b/cockatrice/src/server/user/user_context_menu.h @@ -14,7 +14,7 @@ class QMenu; class QPoint; class Response; class ServerInfo_User; -class TabGame; +class Game; class TabSupervisor; class UserContextMenu : public QObject @@ -24,7 +24,7 @@ private: AbstractClient *client; TabSupervisor *tabSupervisor; const UserListProxy *userListProxy; - TabGame *game; + Game *game; QAction *aUserName; QAction *aDetails; @@ -54,7 +54,7 @@ private slots: void gamesOfUserReceived(const Response &resp, const CommandContainer &commandContainer); public: - UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *_parent, TabGame *_game = 0); + UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *_parent, Game *_game = 0); void retranslateUi(); void showContextMenu(const QPoint &pos, const QString &userName,