Differentiate games and replays.

Took 9 seconds
This commit is contained in:
Lukas Brübach 2025-09-10 14:48:09 +02:00
parent 0e33187388
commit 595eb609ad
29 changed files with 224 additions and 177 deletions

View file

@ -207,6 +207,7 @@ set(cockatrice_SOURCES
src/game/filters/filter_tree.cpp src/game/filters/filter_tree.cpp
src/game/filters/filter_tree_model.cpp src/game/filters/filter_tree_model.cpp
src/game/filters/syntax_help.cpp src/game/filters/syntax_help.cpp
src/game/abstract_game.cpp
src/game/game.cpp src/game/game.cpp
src/game/game_event_handler.cpp src/game/game_event_handler.cpp
src/game/game_meta_info.cpp src/game/game_meta_info.cpp
@ -228,6 +229,7 @@ set(cockatrice_SOURCES
src/game/player/player_manager.cpp src/game/player/player_manager.cpp
src/game/player/player_menu.cpp src/game/player/player_menu.cpp
src/game/player/player_target.cpp src/game/player/player_target.cpp
src/game/replay.cpp
src/game/zones/card_zone.cpp src/game/zones/card_zone.cpp
src/game/zones/hand_zone.cpp src/game/zones/hand_zone.cpp
src/game/zones/pile_zone.cpp src/game/zones/pile_zone.cpp

View file

@ -8,10 +8,12 @@
#include "../../game/cards/card_database_manager.h" #include "../../game/cards/card_database_manager.h"
#include "../../game/deckview/deck_view_container.h" #include "../../game/deckview/deck_view_container.h"
#include "../../game/deckview/tabbed_deck_view_container.h" #include "../../game/deckview/tabbed_deck_view_container.h"
#include "../../game/game.h"
#include "../../game/game_scene.h" #include "../../game/game_scene.h"
#include "../../game/game_view.h" #include "../../game/game_view.h"
#include "../../game/player/player.h" #include "../../game/player/player.h"
#include "../../game/player/player_list_widget.h" #include "../../game/player/player_list_widget.h"
#include "../../game/replay.h"
#include "../../game/zones/card_zone.h" #include "../../game/zones/card_zone.h"
#include "../../main.h" #include "../../main.h"
#include "../../server/abstract_client.h" #include "../../server/abstract_client.h"
@ -49,22 +51,11 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
: Tab(_tabSupervisor), sayLabel(nullptr), sayEdit(nullptr) : Tab(_tabSupervisor), sayLabel(nullptr), sayEdit(nullptr)
{ {
// THIS CTOR IS USED ON REPLAY // THIS CTOR IS USED ON REPLAY
game = new Replay(this, _replay);
/*game->getGameMetaInfo() = new GameMetaInfo();
game->getGameState() =
new GameState(0, -1, _tabSupervisor->getIsLocalGame(), QList<AbstractClient *>(), false, false, -1, false);
connectToGameState();
game->getPlayerManager() = new PlayerManager(this, -1, true, false);
game->getGameEventHandler() = new GameEventHandler(this);*/
connectToGameEventHandler();
createCardInfoDock(true); createCardInfoDock(true);
createPlayerListDock(true); createPlayerListDock(true);
connectPlayerListToGameEventHandler();
createMessageDock(true); createMessageDock(true);
connectMessageLogToGameEventHandler();
createPlayAreaWidget(true); createPlayAreaWidget(true);
createDeckViewContainerWidget(true); createDeckViewContainerWidget(true);
createReplayDock(_replay); createReplayDock(_replay);
@ -81,6 +72,14 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
createReplayMenuItems(); createReplayMenuItems();
createViewMenuItems(); createViewMenuItems();
connectToGameState();
connectToPlayerManager();
connectToGameEventHandler();
connectPlayerListToGameEventHandler();
connectMessageLogToGameEventHandler();
connectMessageLogToPlayerHandler();
retranslateUi(); retranslateUi();
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this, connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
&TabGame::refreshShortcuts); &TabGame::refreshShortcuts);

View file

@ -2,7 +2,7 @@
#define TAB_GAME_H #define TAB_GAME_H
#include "../../client/tearoff_menu.h" #include "../../client/tearoff_menu.h"
#include "../../game/game.h" #include "../../game/abstract_game.h"
#include "../../game/player/player.h" #include "../../game/player/player.h"
#include "../../server/message_log_widget.h" #include "../../server/message_log_widget.h"
#include "../replay_manager.h" #include "../replay_manager.h"
@ -51,7 +51,7 @@ class TabGame : public Tab
{ {
Q_OBJECT Q_OBJECT
private: private:
Game *game; AbstractGame *game;
const UserListProxy *userListProxy; const UserListProxy *userListProxy;
ReplayManager *replayManager; ReplayManager *replayManager;
QStringList gameTypes; QStringList gameTypes;
@ -178,7 +178,7 @@ public:
QString getTabText() const override; QString getTabText() const override;
Game *getGame() const AbstractGame *getGame() const
{ {
return game; return game;
} }

View file

@ -0,0 +1,55 @@
#include "abstract_game.h"
#include "player/player.h"
AbstractGame::AbstractGame(TabGame *_tab)
: tab(_tab)
{
gameMetaInfo = new GameMetaInfo(this);
gameEventHandler = new GameEventHandler(this);
activeCard = nullptr;
}
bool AbstractGame::isHost() const
{
return gameState->getHostId() == playerManager->getLocalPlayerId();
}
AbstractClient *AbstractGame::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 AbstractGame::loadReplay(GameReplay *replay)
{
gameMetaInfo->setFromProto(replay->game_info());
gameMetaInfo->setSpectatorsOmniscient(true);
}
void AbstractGame::setActiveCard(CardItem *card)
{
activeCard = card;
}
CardItem *AbstractGame::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);
}

View file

@ -0,0 +1,68 @@
#ifndef COCKATRICE_ABSTRACT_GAME_H
#define COCKATRICE_ABSTRACT_GAME_H
#include "../../../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 <QObject>
class CardItem;
class TabGame;
class AbstractGame : public QObject
{
Q_OBJECT
public:
explicit AbstractGame(TabGame *tab);
TabGame *tab;
GameMetaInfo *gameMetaInfo;
GameState *gameState;
GameEventHandler *gameEventHandler;
PlayerManager *playerManager;
CardItem *activeCard;
TabGame *getTab() const
{
return tab;
}
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_ABSTRACT_GAME_H

View file

@ -1,5 +1,6 @@
#include "abstract_counter.h" #include "abstract_counter.h"
#include "../../client/tabs/tab_game.h"
#include "../../client/translate_counter_name.h" #include "../../client/translate_counter_name.h"
#include "../../settings/cache_settings.h" #include "../../settings/cache_settings.h"
#include "../player/player.h" #include "../player/player.h"

View file

@ -1,67 +1,20 @@
#include "game.h" #include "game.h"
#include "../client/tabs/tab_game.h"
#include "pb/event_game_joined.pb.h" #include "pb/event_game_joined.pb.h"
Game::Game(TabGame *_tab, Game::Game(TabGame *_tab,
QList<AbstractClient *> &_clients, QList<AbstractClient *> &_clients,
const Event_GameJoined &event, const Event_GameJoined &event,
const QMap<int, QString> &_roomGameTypes) const QMap<int, QString> &_roomGameTypes)
: tab(_tab) : AbstractGame(_tab)
{ {
gameMetaInfo = new GameMetaInfo(this);
gameMetaInfo->setFromProto(event.game_info()); gameMetaInfo->setFromProto(event.game_info());
gameMetaInfo->setRoomGameTypes(_roomGameTypes); gameMetaInfo->setRoomGameTypes(_roomGameTypes);
gameState = new GameState(this, 0, event.host_id(), tab->getTabSupervisor()->getIsLocalGame(), _clients, false, gameState = new GameState(this, 0, event.host_id(), tab->getTabSupervisor()->getIsLocalGame(), _clients, false,
event.resuming(), -1, 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); connect(gameMetaInfo, &GameMetaInfo::startedChanged, gameState, &GameState::onStartedChanged);
playerManager = new PlayerManager(this, event.player_id(), event.judge(), event.spectator());
gameEventHandler = new GameEventHandler(this); gameMetaInfo->setStarted(false);
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);
}

View file

@ -1,18 +1,10 @@
#ifndef COCKATRICE_GAME_H #ifndef COCKATRICE_GAME_H
#define COCKATRICE_GAME_H #define COCKATRICE_GAME_H
#include "../../../common/pb/game_replay.pb.h" #include "abstract_game.h"
#include "game_event_handler.h"
#include "game_meta_info.h"
#include "game_state.h"
#include "player/player_manager.h"
#include <QObject> #include <QObject>
class CardItem; class Game : public AbstractGame
class GameMetaInfo;
class TabGame;
class Game : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -21,52 +13,6 @@ public:
QList<AbstractClient *> &_clients, QList<AbstractClient *> &_clients,
const Event_GameJoined &event, const Event_GameJoined &event,
const QMap<int, QString> &_roomGameTypes); const QMap<int, QString> &_roomGameTypes);
TabGame *tab;
GameMetaInfo *gameMetaInfo;
GameState *gameState;
GameEventHandler *gameEventHandler;
PlayerManager *playerManager;
CardItem *activeCard;
TabGame *getTab() const
{
return tab;
}
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 #endif // COCKATRICE_GAME_H

View file

@ -4,7 +4,7 @@
#include "../server/abstract_client.h" #include "../server/abstract_client.h"
#include "../server/message_log_widget.h" #include "../server/message_log_widget.h"
#include "../server/pending_command.h" #include "../server/pending_command.h"
#include "game.h" #include "abstract_game.h"
#include "get_pb_extension.h" #include "get_pb_extension.h"
#include "pb/command_concede.pb.h" #include "pb/command_concede.pb.h"
#include "pb/command_delete_arrow.pb.h" #include "pb/command_delete_arrow.pb.h"
@ -29,7 +29,7 @@
#include "pb/event_set_active_player.pb.h" #include "pb/event_set_active_player.pb.h"
#include "pb/game_event_container.pb.h" #include "pb/game_event_container.pb.h"
GameEventHandler::GameEventHandler(Game *_game) : QObject(_game), game(_game) GameEventHandler::GameEventHandler(AbstractGame *_game) : QObject(_game), game(_game)
{ {
} }

View file

@ -30,7 +30,7 @@ class Event_Ping;
class Event_GameSay; class Event_GameSay;
class Event_Kicked; class Event_Kicked;
class Event_ReverseTurn; class Event_ReverseTurn;
class Game; class AbstractGame;
class PendingCommand; class PendingCommand;
class Player; class Player;
@ -41,10 +41,10 @@ class GameEventHandler : public QObject
Q_OBJECT Q_OBJECT
private: private:
Game *game; AbstractGame *game;
public: public:
explicit GameEventHandler(Game *_game); explicit GameEventHandler(AbstractGame *_game);
void handleNextTurn(); void handleNextTurn();
void handleReverseTurn(); void handleReverseTurn();

View file

@ -1,7 +1,7 @@
#include "game_meta_info.h" #include "game_meta_info.h"
#include "game.h" #include "abstract_game.h"
GameMetaInfo::GameMetaInfo(Game *_game) : QObject(_game), game(_game) GameMetaInfo::GameMetaInfo(AbstractGame *_game) : QObject(_game), game(_game)
{ {
} }

View file

@ -10,12 +10,12 @@
// This class de-couples the domain object (i.e. the GameMetaInfo) from the network object. // 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. // If the network object changes, only this class needs to be adjusted.
class Game; class AbstractGame;
class GameMetaInfo : public QObject class GameMetaInfo : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit GameMetaInfo(Game *_game); explicit GameMetaInfo(AbstractGame *_game);
QMap<int, QString> roomGameTypes; QMap<int, QString> roomGameTypes;
@ -79,7 +79,7 @@ public:
return roomGameTypes.find(gameInfo_.game_types(index)).value(); return roomGameTypes.find(gameInfo_.game_types(index)).value();
} }
Game *getGame() const AbstractGame *getGame() const
{ {
return game; return game;
} }
@ -105,7 +105,7 @@ signals:
void spectatorsOmniscienceChanged(bool omniscient); void spectatorsOmniscienceChanged(bool omniscient);
private: private:
Game *game; AbstractGame *game;
ServerInfo_Game gameInfo_; ServerInfo_Game gameInfo_;
}; };

View file

@ -1,6 +1,7 @@
#include "game_state.h" #include "game_state.h"
#include "abstract_game.h"
GameState::GameState(Game *_game, GameState::GameState(AbstractGame *_game,
int _secondsElapsed, int _secondsElapsed,
int _hostId, int _hostId,
bool _isLocalGame, bool _isLocalGame,

View file

@ -1,13 +1,13 @@
#ifndef COCKATRICE_GAME_STATE_H #ifndef COCKATRICE_GAME_STATE_H
#define COCKATRICE_GAME_STATE_H #define COCKATRICE_GAME_STATE_H
#include "../client/tabs/tab_game.h"
#include "../server/abstract_client.h" #include "../server/abstract_client.h"
#include "pb/serverinfo_game.pb.h" #include "pb/serverinfo_game.pb.h"
#include "pb/serverinfo_playerproperties.pb.h"
#include <QObject> #include <QObject>
#include <QTimer>
class AbstractGame;
class ServerInfo_PlayerProperties; class ServerInfo_PlayerProperties;
class ServerInfo_User; class ServerInfo_User;
@ -16,7 +16,7 @@ class GameState : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit GameState(Game *_game, explicit GameState(AbstractGame *_game,
int secondsElapsed, int secondsElapsed,
int hostId, int hostId,
bool isLocalGame, bool isLocalGame,
@ -132,7 +132,7 @@ public slots:
void setGameTime(int _secondsElapsed); void setGameTime(int _secondsElapsed);
private: private:
Game *game; AbstractGame *game;
QTimer *gameTimer; QTimer *gameTimer;
int secondsElapsed; int secondsElapsed;
QMap<int, QString> roomGameTypes; QMap<int, QString> roomGameTypes;

View file

@ -29,7 +29,7 @@
#include <QPainter> #include <QPainter>
#include <QtConcurrent> #include <QtConcurrent>
Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, Game *_parent) Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, AbstractGame *_parent)
: QObject(_parent), game(_parent), playerInfo(new PlayerInfo(info, _id, _local, _judge)), : QObject(_parent), game(_parent), playerInfo(new PlayerInfo(info, _id, _local, _judge)),
playerEventHandler(new PlayerEventHandler(this)), playerActions(new PlayerActions(this)), active(false), playerEventHandler(new PlayerEventHandler(this)), playerActions(new PlayerActions(this)), active(false),
conceded(false), deck(nullptr), zoneId(0), dialogSemaphore(false) conceded(false), deck(nullptr), zoneId(0), dialogSemaphore(false)

View file

@ -6,7 +6,6 @@
#include "../board/abstract_graphics_item.h" #include "../board/abstract_graphics_item.h"
#include "../cards/card_info.h" #include "../cards/card_info.h"
#include "../filters/filter_string.h" #include "../filters/filter_string.h"
#include "../game.h"
#include "pb/card_attributes.pb.h" #include "pb/card_attributes.pb.h"
#include "pb/game_event.pb.h" #include "pb/game_event.pb.h"
#include "player_actions.h" #include "player_actions.h"
@ -33,6 +32,7 @@ class Message;
} // namespace google } // namespace google
class AbstractCardItem; class AbstractCardItem;
class AbstractCounter; class AbstractCounter;
class AbstractGame;
class ArrowItem; class ArrowItem;
class ArrowTarget; class ArrowTarget;
class CardDatabase; class CardDatabase;
@ -74,7 +74,7 @@ public slots:
void setActive(bool _active); void setActive(bool _active);
public: public:
Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, Game *_parent); Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, AbstractGame *_parent);
~Player() override; ~Player() override;
void initializeZones(); void initializeZones();
@ -94,7 +94,7 @@ public:
return active; return active;
} }
Game *getGame() const AbstractGame *getGame() const
{ {
return game; return game;
} }
@ -224,7 +224,7 @@ public:
void setZoneId(int _zoneId); void setZoneId(int _zoneId);
private: private:
Game *game; AbstractGame *game;
PlayerInfo *playerInfo; PlayerInfo *playerInfo;
PlayerEventHandler *playerEventHandler; PlayerEventHandler *playerEventHandler;
PlayerActions *playerActions; PlayerActions *playerActions;

View file

@ -54,7 +54,7 @@ bool PlayerListTWI::operator<(const QTreeWidgetItem &other) const
return data(4, Qt::UserRole + 1).toInt() < other.data(4, Qt::UserRole + 1).toInt(); return data(4, Qt::UserRole + 1).toInt() < other.data(4, Qt::UserRole + 1).toInt();
} }
PlayerListWidget::PlayerListWidget(TabSupervisor *_tabSupervisor, AbstractClient *_client, Game *_game, QWidget *parent) PlayerListWidget::PlayerListWidget(TabSupervisor *_tabSupervisor, AbstractClient *_client, AbstractGame *_game, QWidget *parent)
: QTreeWidget(parent), tabSupervisor(_tabSupervisor), client(_client), game(_game), gameStarted(false) : QTreeWidget(parent), tabSupervisor(_tabSupervisor), client(_client), game(_game), gameStarted(false)
{ {
readyIcon = QPixmap("theme:icons/ready_start"); readyIcon = QPixmap("theme:icons/ready_start");

View file

@ -11,7 +11,7 @@
class ServerInfo_PlayerProperties; class ServerInfo_PlayerProperties;
class TabSupervisor; class TabSupervisor;
class AbstractClient; class AbstractClient;
class Game; class AbstractGame;
class UserContextMenu; class UserContextMenu;
class PlayerListItemDelegate : public QStyledItemDelegate class PlayerListItemDelegate : public QStyledItemDelegate
@ -39,7 +39,7 @@ private:
QMap<int, QTreeWidgetItem *> players; QMap<int, QTreeWidgetItem *> players;
TabSupervisor *tabSupervisor; TabSupervisor *tabSupervisor;
AbstractClient *client; AbstractClient *client;
Game *game; AbstractGame *game;
UserContextMenu *userContextMenu; UserContextMenu *userContextMenu;
QIcon readyIcon, notReadyIcon, concededIcon, playerIcon, judgeIcon, spectatorIcon, lockIcon; QIcon readyIcon, notReadyIcon, concededIcon, playerIcon, judgeIcon, spectatorIcon, lockIcon;
bool gameStarted; bool gameStarted;
@ -47,7 +47,7 @@ signals:
void openMessageDialog(const QString &userName, bool focus); void openMessageDialog(const QString &userName, bool focus);
public: public:
PlayerListWidget(TabSupervisor *_tabSupervisor, AbstractClient *_client, Game *_game, QWidget *parent = nullptr); PlayerListWidget(TabSupervisor *_tabSupervisor, AbstractClient *_client, AbstractGame *_game, QWidget *parent = nullptr);
void retranslateUi(); void retranslateUi();
void setActivePlayer(int playerId); void setActivePlayer(int playerId);
void setGameStarted(bool _gameStarted, bool resuming); void setGameStarted(bool _gameStarted, bool resuming);

View file

@ -1,9 +1,9 @@
#include "player_manager.h" #include "player_manager.h"
#include "../game.h" #include "../abstract_game.h"
#include "player.h" #include "player.h"
PlayerManager::PlayerManager(Game *_game, int _localPlayerId, bool _localPlayerIsJudge, bool localPlayerIsSpectator) PlayerManager::PlayerManager(AbstractGame *_game, int _localPlayerId, bool _localPlayerIsJudge, bool localPlayerIsSpectator)
: QObject(_game), game(_game), players(QMap<int, Player *>()), localPlayerId(_localPlayerId), : QObject(_game), game(_game), players(QMap<int, Player *>()), localPlayerId(_localPlayerId),
localPlayerIsJudge(_localPlayerIsJudge), localPlayerIsSpectator(localPlayerIsSpectator) localPlayerIsJudge(_localPlayerIsJudge), localPlayerIsSpectator(localPlayerIsSpectator)
{ {

View file

@ -6,16 +6,16 @@
#include <QMap> #include <QMap>
#include <QObject> #include <QObject>
class Game; class AbstractGame;
class Player; class Player;
class PlayerManager : public QObject class PlayerManager : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
PlayerManager(Game *_game, int _localPlayerId, bool _localPlayerIsJudge, bool localPlayerIsSpectator); PlayerManager(AbstractGame *_game, int _localPlayerId, bool _localPlayerIsJudge, bool localPlayerIsSpectator);
Game *game; AbstractGame *game;
QMap<int, Player *> players; QMap<int, Player *> players;
int localPlayerId; int localPlayerId;
bool localPlayerIsJudge; bool localPlayerIsJudge;
@ -94,7 +94,7 @@ public:
emit spectatorRemoved(spectatorId, spectatorInfo); emit spectatorRemoved(spectatorId, spectatorInfo);
} }
Game *getGame() const AbstractGame *getGame() const
{ {
return game; return game;
} }

View file

@ -370,7 +370,8 @@ PlayerMenu::PlayerMenu(Player *_player) : player(_player)
retranslateUi(); retranslateUi();
} }
void PlayerMenu::setMenusForGraphicItems(){ void PlayerMenu::setMenusForGraphicItems()
{
player->getGraphicsItem()->getTableZoneGraphicsItem()->setMenu(playerMenu); player->getGraphicsItem()->getTableZoneGraphicsItem()->setMenu(playerMenu);
player->getGraphicsItem()->getGraveyardZoneGraphicsItem()->setMenu(graveMenu, aViewGraveyard); player->getGraphicsItem()->getGraveyardZoneGraphicsItem()->setMenu(graveMenu, aViewGraveyard);
player->getGraphicsItem()->getRfgZoneGraphicsItem()->setMenu(rfgMenu, aViewRfg); player->getGraphicsItem()->getRfgZoneGraphicsItem()->setMenu(rfgMenu, aViewRfg);

View file

@ -0,0 +1,12 @@
#include "replay.h"
#include "../client/tabs/tab_game.h"
Replay::Replay(TabGame *_tab, GameReplay *_replay) : AbstractGame(_tab)
{
gameState = new GameState(this, 0, -1, tab->getTabSupervisor()->getIsLocalGame(), {}, false,
false, -1, false);
connect(gameMetaInfo, &GameMetaInfo::startedChanged, gameState, &GameState::onStartedChanged);
playerManager = new PlayerManager(this, -1, false, true);
loadReplay(_replay);
}

View file

@ -0,0 +1,13 @@
#ifndef COCKATRICE_REPLAY_H
#define COCKATRICE_REPLAY_H
#include "abstract_game.h"
class Replay : public AbstractGame {
Q_OBJECT
public:
explicit Replay(TabGame *_tab, GameReplay *_replay);
};
#endif // COCKATRICE_REPLAY_H

View file

@ -23,7 +23,7 @@ UserMessagePosition::UserMessagePosition(QTextCursor &cursor)
relativePosition = cursor.position() - block.position(); relativePosition = cursor.position() - block.position();
} }
ChatView::ChatView(TabSupervisor *_tabSupervisor, Game *_game, bool _showTimestamps, QWidget *parent) ChatView::ChatView(TabSupervisor *_tabSupervisor, AbstractGame *_game, bool _showTimestamps, QWidget *parent)
: QTextBrowser(parent), tabSupervisor(_tabSupervisor), game(_game), : QTextBrowser(parent), tabSupervisor(_tabSupervisor), game(_game),
userListProxy(_tabSupervisor->getUserListManager()), evenNumber(true), showTimestamps(_showTimestamps), userListProxy(_tabSupervisor->getUserListManager()), evenNumber(true), showTimestamps(_showTimestamps),
hoveredItemType(HoveredNothing) hoveredItemType(HoveredNothing)

View file

@ -12,11 +12,11 @@
#include <QTextCursor> #include <QTextCursor>
#include <QTextFragment> #include <QTextFragment>
class AbstractGame;
class QTextTable; class QTextTable;
class QMouseEvent; class QMouseEvent;
class UserContextMenu; class UserContextMenu;
class UserListProxy; class UserListProxy;
class Game;
class UserMessagePosition class UserMessagePosition
{ {
@ -34,7 +34,7 @@ class ChatView : public QTextBrowser
Q_OBJECT Q_OBJECT
protected: protected:
TabSupervisor *const tabSupervisor; TabSupervisor *const tabSupervisor;
Game *const game; AbstractGame *const game;
private: private:
enum HoveredItemType enum HoveredItemType
@ -83,7 +83,7 @@ private slots:
void actMessageClicked(); void actMessageClicked();
public: public:
ChatView(TabSupervisor *_tabSupervisor, Game *_game, bool _showTimestamps, QWidget *parent = nullptr); ChatView(TabSupervisor *_tabSupervisor, AbstractGame *_game, bool _showTimestamps, QWidget *parent = nullptr);
void retranslateUi(); void retranslateUi();
void appendHtml(const QString &html); void appendHtml(const QString &html);
void virtual appendHtmlServerMessage(const QString &html, void virtual appendHtmlServerMessage(const QString &html,

View file

@ -58,8 +58,7 @@ MessageLogWidget::getFromStr(CardZoneLogic *zone, QString cardName, int position
cardNameContainsStartZone = true; cardNameContainsStartZone = true;
} else { } else {
if (ownerChange) { if (ownerChange) {
fromStr = tr(" from the top of %1's library") fromStr = tr(" from the top of %1's library").arg(zone->getPlayer()->getPlayerInfo()->getName());
.arg(zone->getPlayer()->getPlayerInfo()->getName());
} else { } else {
fromStr = tr(" from the top of their library"); fromStr = tr(" from the top of their library");
} }
@ -67,16 +66,14 @@ MessageLogWidget::getFromStr(CardZoneLogic *zone, QString cardName, int position
} else if (position >= zone->getCards().size() - 1) { } else if (position >= zone->getCards().size() - 1) {
if (cardName.isEmpty()) { if (cardName.isEmpty()) {
if (ownerChange) { if (ownerChange) {
cardName = tr("the bottom card of %1's library") cardName = tr("the bottom card of %1's library").arg(zone->getPlayer()->getPlayerInfo()->getName());
.arg(zone->getPlayer()->getPlayerInfo()->getName());
} else { } else {
cardName = tr("the bottom card of their library"); cardName = tr("the bottom card of their library");
} }
cardNameContainsStartZone = true; cardNameContainsStartZone = true;
} else { } else {
if (ownerChange) { if (ownerChange) {
fromStr = tr(" from the bottom of %1's library") fromStr = tr(" from the bottom of %1's library").arg(zone->getPlayer()->getPlayerInfo()->getName());
.arg(zone->getPlayer()->getPlayerInfo()->getName());
} else { } else {
fromStr = tr(" from the bottom of their library"); fromStr = tr(" from the bottom of their library");
} }
@ -375,10 +372,9 @@ void MessageLogWidget::logDrawCards(Player *player, int number, bool deckIsEmpty
void MessageLogWidget::logDumpZone(Player *player, CardZoneLogic *zone, int numberCards, bool isReversed) void MessageLogWidget::logDumpZone(Player *player, CardZoneLogic *zone, int numberCards, bool isReversed)
{ {
if (numberCards == -1) { if (numberCards == -1) {
appendHtmlServerMessage( appendHtmlServerMessage(tr("%1 is looking at %2.")
tr("%1 is looking at %2.") .arg(sanitizeHtml(player->getPlayerInfo()->getName()))
.arg(sanitizeHtml(player->getPlayerInfo()->getName())) .arg(zone->getTranslatedName(zone->getPlayer() == player, CaseLookAtZone)));
.arg(zone->getTranslatedName(zone->getPlayer() == player, CaseLookAtZone)));
} else { } else {
appendHtmlServerMessage( appendHtmlServerMessage(
tr("%1 is looking at the %4 %3 card(s) %2.", "top card for singular, top %3 cards for plural", numberCards) tr("%1 is looking at the %4 %3 card(s) %2.", "top card for singular, top %3 cards for plural", numberCards)
@ -840,7 +836,7 @@ void MessageLogWidget::connectToPlayerEventHandler(PlayerEventHandler *playerEve
&MessageLogWidget::logAlwaysLookAtTopCard); &MessageLogWidget::logAlwaysLookAtTopCard);
} }
MessageLogWidget::MessageLogWidget(TabSupervisor *_tabSupervisor, Game *_game, QWidget *parent) MessageLogWidget::MessageLogWidget(TabSupervisor *_tabSupervisor, AbstractGame *_game, QWidget *parent)
: ChatView(_tabSupervisor, _game, true, parent), currentContext(MessageContext_None) : ChatView(_tabSupervisor, _game, true, parent), currentContext(MessageContext_None)
{ {
} }

View file

@ -6,11 +6,11 @@
#include "chat_view/chat_view.h" #include "chat_view/chat_view.h"
#include "user_level.h" #include "user_level.h"
class AbstractGame;
class CardItem;
class GameEventContext;
class Player; class Player;
class PlayerEventHandler; class PlayerEventHandler;
class Game;
class GameEventContext;
class CardItem;
class MessageLogWidget : public ChatView class MessageLogWidget : public ChatView
{ {
@ -30,7 +30,7 @@ private:
public: public:
void connectToPlayerEventHandler(PlayerEventHandler *player); void connectToPlayerEventHandler(PlayerEventHandler *player);
MessageLogWidget(TabSupervisor *_tabSupervisor, Game *_game, QWidget *parent = nullptr); MessageLogWidget(TabSupervisor *_tabSupervisor, AbstractGame *_game, QWidget *parent = nullptr);
public slots: public slots:
void containerProcessingDone(); void containerProcessingDone();

View file

@ -29,7 +29,7 @@
#include <QtGui> #include <QtGui>
#include <QtWidgets> #include <QtWidgets>
UserContextMenu::UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *parent, Game *_game) UserContextMenu::UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *parent, AbstractGame *_game)
: QObject(parent), client(_tabSupervisor->getClient()), tabSupervisor(_tabSupervisor), : QObject(parent), client(_tabSupervisor->getClient()), tabSupervisor(_tabSupervisor),
userListProxy(_tabSupervisor->getUserListManager()), game(_game) userListProxy(_tabSupervisor->getUserListManager()), game(_game)
{ {

View file

@ -5,6 +5,7 @@
#include <QObject> #include <QObject>
class AbstractGame;
class UserListProxy; class UserListProxy;
class AbstractClient; class AbstractClient;
class ChatView; class ChatView;
@ -14,7 +15,6 @@ class QMenu;
class QPoint; class QPoint;
class Response; class Response;
class ServerInfo_User; class ServerInfo_User;
class Game;
class TabSupervisor; class TabSupervisor;
class UserContextMenu : public QObject class UserContextMenu : public QObject
@ -24,7 +24,7 @@ private:
AbstractClient *client; AbstractClient *client;
TabSupervisor *tabSupervisor; TabSupervisor *tabSupervisor;
const UserListProxy *userListProxy; const UserListProxy *userListProxy;
Game *game; AbstractGame *game;
QAction *aUserName; QAction *aUserName;
QAction *aDetails; QAction *aDetails;
@ -54,7 +54,7 @@ private slots:
void gamesOfUserReceived(const Response &resp, const CommandContainer &commandContainer); void gamesOfUserReceived(const Response &resp, const CommandContainer &commandContainer);
public: public:
UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *_parent, Game *_game = 0); UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *_parent, AbstractGame *_game = 0);
void retranslateUi(); void retranslateUi();
void showContextMenu(const QPoint &pos, void showContextMenu(const QPoint &pos,
const QString &userName, const QString &userName,