preliminary client-side replay support, works in principle
This commit is contained in:
parent
d50d179b2f
commit
a1bcd9854f
13 changed files with 220 additions and 32 deletions
|
@ -175,7 +175,8 @@ if (NOT QT_QTMULTIMEDIA_FOUND)
|
||||||
endif (NOT QT_QTMULTIMEDIA_FOUND)
|
endif (NOT QT_QTMULTIMEDIA_FOUND)
|
||||||
FIND_PACKAGE(Protobuf REQUIRED)
|
FIND_PACKAGE(Protobuf REQUIRED)
|
||||||
|
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
#set(CMAKE_BUILD_TYPE Release)
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
|
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
|
||||||
|
|
||||||
QT4_WRAP_CPP(cockatrice_HEADERS_MOC ${cockatrice_HEADERS})
|
QT4_WRAP_CPP(cockatrice_HEADERS_MOC ${cockatrice_HEADERS})
|
||||||
|
|
|
@ -56,6 +56,12 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||||
QPushButton *deckPathButton = new QPushButton("...");
|
QPushButton *deckPathButton = new QPushButton("...");
|
||||||
connect(deckPathButton, SIGNAL(clicked()), this, SLOT(deckPathButtonClicked()));
|
connect(deckPathButton, SIGNAL(clicked()), this, SLOT(deckPathButtonClicked()));
|
||||||
|
|
||||||
|
replaysPathLabel = new QLabel;
|
||||||
|
replaysPathEdit = new QLineEdit(settingsCache->getReplaysPath());
|
||||||
|
replaysPathEdit->setReadOnly(true);
|
||||||
|
QPushButton *replaysPathButton = new QPushButton("...");
|
||||||
|
connect(replaysPathButton, SIGNAL(clicked()), this, SLOT(replaysPathButtonClicked()));
|
||||||
|
|
||||||
picsPathLabel = new QLabel;
|
picsPathLabel = new QLabel;
|
||||||
picsPathEdit = new QLineEdit(settingsCache->getPicsPath());
|
picsPathEdit = new QLineEdit(settingsCache->getPicsPath());
|
||||||
picsPathEdit->setReadOnly(true);
|
picsPathEdit->setReadOnly(true);
|
||||||
|
@ -72,12 +78,15 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||||
pathsGrid->addWidget(deckPathLabel, 0, 0);
|
pathsGrid->addWidget(deckPathLabel, 0, 0);
|
||||||
pathsGrid->addWidget(deckPathEdit, 0, 1);
|
pathsGrid->addWidget(deckPathEdit, 0, 1);
|
||||||
pathsGrid->addWidget(deckPathButton, 0, 2);
|
pathsGrid->addWidget(deckPathButton, 0, 2);
|
||||||
pathsGrid->addWidget(picsPathLabel, 1, 0);
|
pathsGrid->addWidget(replaysPathLabel, 1, 0);
|
||||||
pathsGrid->addWidget(picsPathEdit, 1, 1);
|
pathsGrid->addWidget(replaysPathEdit, 1, 1);
|
||||||
pathsGrid->addWidget(picsPathButton, 1, 2);
|
pathsGrid->addWidget(replaysPathButton, 1, 2);
|
||||||
pathsGrid->addWidget(cardDatabasePathLabel, 2, 0);
|
pathsGrid->addWidget(picsPathLabel, 2, 0);
|
||||||
pathsGrid->addWidget(cardDatabasePathEdit, 2, 1);
|
pathsGrid->addWidget(picsPathEdit, 2, 1);
|
||||||
pathsGrid->addWidget(cardDatabasePathButton, 2, 2);
|
pathsGrid->addWidget(picsPathButton, 2, 2);
|
||||||
|
pathsGrid->addWidget(cardDatabasePathLabel, 3, 0);
|
||||||
|
pathsGrid->addWidget(cardDatabasePathEdit, 3, 1);
|
||||||
|
pathsGrid->addWidget(cardDatabasePathButton, 3, 2);
|
||||||
pathsGroupBox = new QGroupBox;
|
pathsGroupBox = new QGroupBox;
|
||||||
pathsGroupBox->setLayout(pathsGrid);
|
pathsGroupBox->setLayout(pathsGrid);
|
||||||
|
|
||||||
|
@ -114,6 +123,16 @@ void GeneralSettingsPage::deckPathButtonClicked()
|
||||||
settingsCache->setDeckPath(path);
|
settingsCache->setDeckPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GeneralSettingsPage::replaysPathButtonClicked()
|
||||||
|
{
|
||||||
|
QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"));
|
||||||
|
if (path.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
replaysPathEdit->setText(path);
|
||||||
|
settingsCache->setReplaysPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
void GeneralSettingsPage::picsPathButtonClicked()
|
void GeneralSettingsPage::picsPathButtonClicked()
|
||||||
{
|
{
|
||||||
QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"));
|
QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"));
|
||||||
|
@ -146,6 +165,7 @@ void GeneralSettingsPage::retranslateUi()
|
||||||
picDownloadCheckBox->setText(tr("Download card pictures on the fly"));
|
picDownloadCheckBox->setText(tr("Download card pictures on the fly"));
|
||||||
pathsGroupBox->setTitle(tr("Paths"));
|
pathsGroupBox->setTitle(tr("Paths"));
|
||||||
deckPathLabel->setText(tr("Decks directory:"));
|
deckPathLabel->setText(tr("Decks directory:"));
|
||||||
|
replaysPathLabel->setText(tr("Replays directory:"));
|
||||||
picsPathLabel->setText(tr("Pictures directory:"));
|
picsPathLabel->setText(tr("Pictures directory:"));
|
||||||
cardDatabasePathLabel->setText(tr("Path to card database:"));
|
cardDatabasePathLabel->setText(tr("Path to card database:"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,22 +28,24 @@ public:
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
private slots:
|
private slots:
|
||||||
void deckPathButtonClicked();
|
void deckPathButtonClicked();
|
||||||
|
void replaysPathButtonClicked();
|
||||||
void picsPathButtonClicked();
|
void picsPathButtonClicked();
|
||||||
void cardDatabasePathButtonClicked();
|
void cardDatabasePathButtonClicked();
|
||||||
void languageBoxChanged(int index);
|
void languageBoxChanged(int index);
|
||||||
signals:
|
signals:
|
||||||
void picsPathChanged(const QString &path);
|
/* void picsPathChanged(const QString &path);
|
||||||
|
void replaysPathChanged(const QString &path);
|
||||||
void cardDatabasePathChanged(const QString &path);
|
void cardDatabasePathChanged(const QString &path);
|
||||||
void changeLanguage(const QString &qmFile);
|
void changeLanguage(const QString &qmFile);
|
||||||
void picDownloadChanged(int state);
|
void picDownloadChanged(int state);
|
||||||
private:
|
*/private:
|
||||||
QStringList findQmFiles();
|
QStringList findQmFiles();
|
||||||
QString languageName(const QString &qmFile);
|
QString languageName(const QString &qmFile);
|
||||||
QLineEdit *deckPathEdit, *picsPathEdit, *cardDatabasePathEdit;
|
QLineEdit *deckPathEdit, *replaysPathEdit, *picsPathEdit, *cardDatabasePathEdit;
|
||||||
QGroupBox *personalGroupBox, *pathsGroupBox;
|
QGroupBox *personalGroupBox, *pathsGroupBox;
|
||||||
QComboBox *languageBox;
|
QComboBox *languageBox;
|
||||||
QCheckBox *picDownloadCheckBox;
|
QCheckBox *picDownloadCheckBox;
|
||||||
QLabel *languageLabel, *deckPathLabel, *picsPathLabel, *cardDatabasePathLabel;
|
QLabel *languageLabel, *deckPathLabel, *replaysPathLabel, *picsPathLabel, *cardDatabasePathLabel;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AppearanceSettingsPage : public AbstractSettingsPage {
|
class AppearanceSettingsPage : public AbstractSettingsPage {
|
||||||
|
|
|
@ -108,6 +108,10 @@ int main(int argc, char *argv[])
|
||||||
QDir().mkpath(dataDir + "/decks");
|
QDir().mkpath(dataDir + "/decks");
|
||||||
settingsCache->setDeckPath(dataDir + "/decks");
|
settingsCache->setDeckPath(dataDir + "/decks");
|
||||||
}
|
}
|
||||||
|
if (!QDir(settingsCache->getReplaysPath()).exists() || settingsCache->getReplaysPath().isEmpty()) {
|
||||||
|
QDir().mkpath(dataDir + "/replays");
|
||||||
|
settingsCache->setReplaysPath(dataDir + "/replays");
|
||||||
|
}
|
||||||
if (!QDir(settingsCache->getPicsPath()).exists() || settingsCache->getPicsPath().isEmpty()) {
|
if (!QDir(settingsCache->getPicsPath()).exists() || settingsCache->getPicsPath().isEmpty()) {
|
||||||
QDir().mkpath(dataDir + "/pics");
|
QDir().mkpath(dataDir + "/pics");
|
||||||
settingsCache->setPicsPath(dataDir + "/pics");
|
settingsCache->setPicsPath(dataDir + "/pics");
|
||||||
|
|
|
@ -29,6 +29,14 @@ void MessageLogWidget::logGameJoined(int gameId)
|
||||||
appendHtml(tr("You have joined game #%1.", "male").arg(gameId));
|
appendHtml(tr("You have joined game #%1.", "male").arg(gameId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessageLogWidget::logReplayStarted(int gameId)
|
||||||
|
{
|
||||||
|
if (female)
|
||||||
|
appendHtml(tr("You are watching a replay of game #%1.", "female").arg(gameId));
|
||||||
|
else
|
||||||
|
appendHtml(tr("You are watching a replay of game #%1.", "male").arg(gameId));
|
||||||
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logJoin(Player *player)
|
void MessageLogWidget::logJoin(Player *player)
|
||||||
{
|
{
|
||||||
soundEngine->cuckoo();
|
soundEngine->cuckoo();
|
||||||
|
|
|
@ -40,6 +40,7 @@ private:
|
||||||
int mulliganNumber;
|
int mulliganNumber;
|
||||||
public slots:
|
public slots:
|
||||||
void logGameJoined(int gameId);
|
void logGameJoined(int gameId);
|
||||||
|
void logReplayStarted(int gameId);
|
||||||
void logJoin(Player *player);
|
void logJoin(Player *player);
|
||||||
void logLeave(Player *player);
|
void logLeave(Player *player);
|
||||||
void logGameClosed();
|
void logGameClosed();
|
||||||
|
|
|
@ -56,8 +56,10 @@ PlayerListWidget::PlayerListWidget(TabSupervisor *_tabSupervisor, AbstractClient
|
||||||
playerIcon = QIcon(":/resources/icon_player.svg");
|
playerIcon = QIcon(":/resources/icon_player.svg");
|
||||||
spectatorIcon = QIcon(":/resources/icon_spectator.svg");
|
spectatorIcon = QIcon(":/resources/icon_spectator.svg");
|
||||||
|
|
||||||
|
if (tabSupervisor) {
|
||||||
itemDelegate = new PlayerListItemDelegate(this);
|
itemDelegate = new PlayerListItemDelegate(this);
|
||||||
setItemDelegate(itemDelegate);
|
setItemDelegate(itemDelegate);
|
||||||
|
}
|
||||||
|
|
||||||
setMinimumHeight(60);
|
setMinimumHeight(60);
|
||||||
setIconSize(QSize(20, 15));
|
setIconSize(QSize(20, 15));
|
||||||
|
|
|
@ -8,6 +8,7 @@ SettingsCache::SettingsCache()
|
||||||
lang = settings->value("personal/lang").toString();
|
lang = settings->value("personal/lang").toString();
|
||||||
|
|
||||||
deckPath = settings->value("paths/decks").toString();
|
deckPath = settings->value("paths/decks").toString();
|
||||||
|
replaysPath = settings->value("paths/replays").toString();
|
||||||
picsPath = settings->value("paths/pics").toString();
|
picsPath = settings->value("paths/pics").toString();
|
||||||
cardDatabasePath = settings->value("paths/carddatabase").toString();
|
cardDatabasePath = settings->value("paths/carddatabase").toString();
|
||||||
|
|
||||||
|
@ -49,6 +50,12 @@ void SettingsCache::setDeckPath(const QString &_deckPath)
|
||||||
settings->setValue("paths/decks", deckPath);
|
settings->setValue("paths/decks", deckPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsCache::setReplaysPath(const QString &_replaysPath)
|
||||||
|
{
|
||||||
|
replaysPath = _replaysPath;
|
||||||
|
settings->setValue("paths/replays", replaysPath);
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsCache::setPicsPath(const QString &_picsPath)
|
void SettingsCache::setPicsPath(const QString &_picsPath)
|
||||||
{
|
{
|
||||||
picsPath = _picsPath;
|
picsPath = _picsPath;
|
||||||
|
|
|
@ -26,7 +26,7 @@ private:
|
||||||
QSettings *settings;
|
QSettings *settings;
|
||||||
|
|
||||||
QString lang;
|
QString lang;
|
||||||
QString deckPath, picsPath, cardDatabasePath;
|
QString deckPath, replaysPath, picsPath, cardDatabasePath;
|
||||||
QString handBgPath, stackBgPath, tableBgPath, playerBgPath, cardBackPicturePath;
|
QString handBgPath, stackBgPath, tableBgPath, playerBgPath, cardBackPicturePath;
|
||||||
bool picDownload;
|
bool picDownload;
|
||||||
bool doubleClickToPlay;
|
bool doubleClickToPlay;
|
||||||
|
@ -45,6 +45,7 @@ public:
|
||||||
SettingsCache();
|
SettingsCache();
|
||||||
QString getLang() const { return lang; }
|
QString getLang() const { return lang; }
|
||||||
QString getDeckPath() const { return deckPath; }
|
QString getDeckPath() const { return deckPath; }
|
||||||
|
QString getReplaysPath() const { return replaysPath; }
|
||||||
QString getPicsPath() const { return picsPath; }
|
QString getPicsPath() const { return picsPath; }
|
||||||
QString getCardDatabasePath() const { return cardDatabasePath; }
|
QString getCardDatabasePath() const { return cardDatabasePath; }
|
||||||
QString getHandBgPath() const { return handBgPath; }
|
QString getHandBgPath() const { return handBgPath; }
|
||||||
|
@ -69,6 +70,7 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
void setLang(const QString &_lang);
|
void setLang(const QString &_lang);
|
||||||
void setDeckPath(const QString &_deckPath);
|
void setDeckPath(const QString &_deckPath);
|
||||||
|
void setReplaysPath(const QString &_replaysPath);
|
||||||
void setPicsPath(const QString &_picsPath);
|
void setPicsPath(const QString &_picsPath);
|
||||||
void setCardDatabasePath(const QString &_cardDatabasePath);
|
void setCardDatabasePath(const QString &_cardDatabasePath);
|
||||||
void setHandBgPath(const QString &_handBgPath);
|
void setHandBgPath(const QString &_handBgPath);
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include <google/protobuf/descriptor.h>
|
#include <google/protobuf/descriptor.h>
|
||||||
#include "pending_command.h"
|
#include "pending_command.h"
|
||||||
|
#include "pb/game_replay.pb.h"
|
||||||
#include "pb/command_concede.pb.h"
|
#include "pb/command_concede.pb.h"
|
||||||
#include "pb/command_deck_select.pb.h"
|
#include "pb/command_deck_select.pb.h"
|
||||||
#include "pb/command_ready_start.pb.h"
|
#include "pb/command_ready_start.pb.h"
|
||||||
|
@ -195,6 +196,85 @@ void DeckViewContainer::setDeck(DeckList *deck)
|
||||||
readyStartButton->setEnabled(true);
|
readyStartButton->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TabGame::TabGame(GameReplay *_replay)
|
||||||
|
: Tab(0),
|
||||||
|
hostId(-1),
|
||||||
|
localPlayerId(-1),
|
||||||
|
spectator(true),
|
||||||
|
spectatorsCanTalk(false),
|
||||||
|
spectatorsSeeEverything(true),
|
||||||
|
gameStateKnown(false),
|
||||||
|
started(false),
|
||||||
|
resuming(false),
|
||||||
|
currentPhase(-1),
|
||||||
|
replay(_replay),
|
||||||
|
currentReplayStep(0)
|
||||||
|
{
|
||||||
|
gameId = replay->game_info().game_id();
|
||||||
|
gameDescription = QString::fromStdString(replay->game_info().description());
|
||||||
|
|
||||||
|
phasesToolbar = new PhasesToolbar;
|
||||||
|
phasesToolbar->hide();
|
||||||
|
|
||||||
|
scene = new GameScene(phasesToolbar, this);
|
||||||
|
gameView = new GameView(scene);
|
||||||
|
gameView->hide();
|
||||||
|
|
||||||
|
cardInfo = new CardInfoWidget(CardInfoWidget::ModeGameTab);
|
||||||
|
playerListWidget = new PlayerListWidget(0, 0, this);
|
||||||
|
playerListWidget->setFocusPolicy(Qt::NoFocus);
|
||||||
|
|
||||||
|
timeElapsedLabel = new QLabel;
|
||||||
|
timeElapsedLabel->setAlignment(Qt::AlignCenter);
|
||||||
|
messageLog = new MessageLogWidget(QString(), false);
|
||||||
|
connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfo, SLOT(setCard(QString)));
|
||||||
|
connect(messageLog, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
|
||||||
|
connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||||
|
sayLabel = 0;
|
||||||
|
|
||||||
|
deckViewContainerLayout = new QVBoxLayout;
|
||||||
|
|
||||||
|
QVBoxLayout *messageLogLayout = new QVBoxLayout;
|
||||||
|
messageLogLayout->addWidget(timeElapsedLabel);
|
||||||
|
messageLogLayout->addWidget(messageLog);
|
||||||
|
|
||||||
|
QWidget *messageLogLayoutWidget = new QWidget;
|
||||||
|
messageLogLayoutWidget->setLayout(messageLogLayout);
|
||||||
|
|
||||||
|
splitter = new QSplitter(Qt::Vertical);
|
||||||
|
splitter->addWidget(cardInfo);
|
||||||
|
splitter->addWidget(playerListWidget);
|
||||||
|
splitter->addWidget(messageLogLayoutWidget);
|
||||||
|
|
||||||
|
mainLayout = new QHBoxLayout;
|
||||||
|
mainLayout->addWidget(gameView, 10);
|
||||||
|
mainLayout->addLayout(deckViewContainerLayout, 10);
|
||||||
|
mainLayout->addWidget(splitter);
|
||||||
|
|
||||||
|
aNextPhase = 0;
|
||||||
|
aNextTurn = 0;
|
||||||
|
aRemoveLocalArrows = 0;
|
||||||
|
aConcede = 0;
|
||||||
|
aLeaveGame = new QAction(this);
|
||||||
|
connect(aLeaveGame, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
|
||||||
|
|
||||||
|
phasesMenu = 0;
|
||||||
|
tabMenu = new QMenu(this);
|
||||||
|
tabMenu->addAction(aLeaveGame);
|
||||||
|
|
||||||
|
retranslateUi();
|
||||||
|
setLayout(mainLayout);
|
||||||
|
|
||||||
|
splitter->restoreState(settingsCache->getTabGameSplitterSizes());
|
||||||
|
|
||||||
|
messageLog->logReplayStarted(gameId);
|
||||||
|
|
||||||
|
gameTimer = new QTimer(this);
|
||||||
|
gameTimer->setInterval(1000);
|
||||||
|
connect(gameTimer, SIGNAL(timeout()), this, SLOT(nextReplayStep()));
|
||||||
|
gameTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, const Event_GameJoined &event)
|
TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, const Event_GameJoined &event)
|
||||||
: Tab(_tabSupervisor),
|
: Tab(_tabSupervisor),
|
||||||
clients(_clients),
|
clients(_clients),
|
||||||
|
@ -205,10 +285,11 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_client
|
||||||
spectator(event.spectator()),
|
spectator(event.spectator()),
|
||||||
spectatorsCanTalk(event.spectators_can_talk()),
|
spectatorsCanTalk(event.spectators_can_talk()),
|
||||||
spectatorsSeeEverything(event.spectators_see_everything()),
|
spectatorsSeeEverything(event.spectators_see_everything()),
|
||||||
gameStateKnown(false),
|
gameStateKnown(true),
|
||||||
started(false),
|
started(false),
|
||||||
resuming(event.resuming()),
|
resuming(event.resuming()),
|
||||||
currentPhase(-1)
|
currentPhase(-1),
|
||||||
|
replay(0)
|
||||||
{
|
{
|
||||||
gameTimer = new QTimer(this);
|
gameTimer = new QTimer(this);
|
||||||
gameTimer->setInterval(1000);
|
gameTimer->setInterval(1000);
|
||||||
|
@ -320,6 +401,7 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_client
|
||||||
|
|
||||||
TabGame::~TabGame()
|
TabGame::~TabGame()
|
||||||
{
|
{
|
||||||
|
delete replay;
|
||||||
settingsCache->setTabGameSplitterSizes(splitter->saveState());
|
settingsCache->setTabGameSplitterSizes(splitter->saveState());
|
||||||
|
|
||||||
QMapIterator<int, Player *> i(players);
|
QMapIterator<int, Player *> i(players);
|
||||||
|
@ -334,22 +416,33 @@ TabGame::~TabGame()
|
||||||
|
|
||||||
void TabGame::retranslateUi()
|
void TabGame::retranslateUi()
|
||||||
{
|
{
|
||||||
|
if (phasesMenu) {
|
||||||
for (int i = 0; i < phaseActions.size(); ++i)
|
for (int i = 0; i < phaseActions.size(); ++i)
|
||||||
phaseActions[i]->setText(phasesToolbar->getLongPhaseName(i));
|
phaseActions[i]->setText(phasesToolbar->getLongPhaseName(i));
|
||||||
phasesMenu->setTitle(tr("&Phases"));
|
phasesMenu->setTitle(tr("&Phases"));
|
||||||
|
}
|
||||||
|
|
||||||
tabMenu->setTitle(tr("&Game"));
|
tabMenu->setTitle(tr("&Game"));
|
||||||
|
if (aNextPhase) {
|
||||||
aNextPhase->setText(tr("Next &phase"));
|
aNextPhase->setText(tr("Next &phase"));
|
||||||
aNextPhase->setShortcut(tr("Ctrl+Space"));
|
aNextPhase->setShortcut(tr("Ctrl+Space"));
|
||||||
|
}
|
||||||
|
if (aNextTurn) {
|
||||||
aNextTurn->setText(tr("Next &turn"));
|
aNextTurn->setText(tr("Next &turn"));
|
||||||
aNextTurn->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Return")) << QKeySequence(tr("Ctrl+Enter")));
|
aNextTurn->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Return")) << QKeySequence(tr("Ctrl+Enter")));
|
||||||
|
}
|
||||||
|
if (aRemoveLocalArrows) {
|
||||||
aRemoveLocalArrows->setText(tr("&Remove all local arrows"));
|
aRemoveLocalArrows->setText(tr("&Remove all local arrows"));
|
||||||
aRemoveLocalArrows->setShortcut(tr("Ctrl+R"));
|
aRemoveLocalArrows->setShortcut(tr("Ctrl+R"));
|
||||||
|
}
|
||||||
|
if (aConcede) {
|
||||||
aConcede->setText(tr("&Concede"));
|
aConcede->setText(tr("&Concede"));
|
||||||
aConcede->setShortcut(tr("F2"));
|
aConcede->setShortcut(tr("F2"));
|
||||||
|
}
|
||||||
aLeaveGame->setText(tr("&Leave game"));
|
aLeaveGame->setText(tr("&Leave game"));
|
||||||
aLeaveGame->setShortcut(tr("Ctrl+Q"));
|
aLeaveGame->setShortcut(tr("Ctrl+Q"));
|
||||||
|
|
||||||
|
if (sayLabel)
|
||||||
sayLabel->setText(tr("&Say:"));
|
sayLabel->setText(tr("&Say:"));
|
||||||
cardInfo->retranslateUi();
|
cardInfo->retranslateUi();
|
||||||
|
|
||||||
|
@ -368,6 +461,17 @@ void TabGame::closeRequest()
|
||||||
actLeaveGame();
|
actLeaveGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabGame::nextReplayStep()
|
||||||
|
{
|
||||||
|
if (replay->event_list_size() <= currentReplayStep) {
|
||||||
|
QMessageBox::information(this, "", "done");
|
||||||
|
gameTimer->stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processGameEventContainer(replay->event_list(currentReplayStep), 0);
|
||||||
|
++currentReplayStep;
|
||||||
|
}
|
||||||
|
|
||||||
void TabGame::incrementGameTime()
|
void TabGame::incrementGameTime()
|
||||||
{
|
{
|
||||||
int seconds = ++secondsElapsed;
|
int seconds = ++secondsElapsed;
|
||||||
|
|
|
@ -49,6 +49,7 @@ class TabGame;
|
||||||
class DeckList;
|
class DeckList;
|
||||||
class QVBoxLayout;
|
class QVBoxLayout;
|
||||||
class QHBoxLayout;
|
class QHBoxLayout;
|
||||||
|
class GameReplay;
|
||||||
class ServerInfo_User;
|
class ServerInfo_User;
|
||||||
class PendingCommand;
|
class PendingCommand;
|
||||||
|
|
||||||
|
@ -107,6 +108,8 @@ private:
|
||||||
QStringList phasesList;
|
QStringList phasesList;
|
||||||
int currentPhase;
|
int currentPhase;
|
||||||
int activePlayer;
|
int activePlayer;
|
||||||
|
GameReplay *replay;
|
||||||
|
int currentReplayStep;
|
||||||
|
|
||||||
QSplitter *splitter;
|
QSplitter *splitter;
|
||||||
CardInfoWidget *cardInfo;
|
CardInfoWidget *cardInfo;
|
||||||
|
@ -155,6 +158,7 @@ signals:
|
||||||
void containerProcessingDone();
|
void containerProcessingDone();
|
||||||
void openMessageDialog(const QString &userName, bool focus);
|
void openMessageDialog(const QString &userName, bool focus);
|
||||||
private slots:
|
private slots:
|
||||||
|
void nextReplayStep();
|
||||||
void incrementGameTime();
|
void incrementGameTime();
|
||||||
void adminLockChanged(bool lock);
|
void adminLockChanged(bool lock);
|
||||||
void newCardAdded(AbstractCardItem *card);
|
void newCardAdded(AbstractCardItem *card);
|
||||||
|
@ -168,6 +172,7 @@ private slots:
|
||||||
void actNextTurn();
|
void actNextTurn();
|
||||||
public:
|
public:
|
||||||
TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, const Event_GameJoined &event);
|
TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, const Event_GameJoined &event);
|
||||||
|
TabGame(GameReplay *replay);
|
||||||
~TabGame();
|
~TabGame();
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
void closeRequest();
|
void closeRequest();
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include <QMenuBar>
|
#include <QMenuBar>
|
||||||
#include <QPixmapCache>
|
#include <QPixmapCache>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "window_main.h"
|
#include "window_main.h"
|
||||||
|
@ -35,7 +37,10 @@
|
||||||
#include "localserver.h"
|
#include "localserver.h"
|
||||||
#include "localserverinterface.h"
|
#include "localserverinterface.h"
|
||||||
#include "localclient.h"
|
#include "localclient.h"
|
||||||
|
#include "settingscache.h"
|
||||||
|
#include "tab_game.h"
|
||||||
|
|
||||||
|
#include "pb/game_replay.pb.h"
|
||||||
#include "pb/room_commands.pb.h"
|
#include "pb/room_commands.pb.h"
|
||||||
#include "pb/event_connection_closed.pb.h"
|
#include "pb/event_connection_closed.pb.h"
|
||||||
#include "pb/event_server_shutdown.pb.h"
|
#include "pb/event_server_shutdown.pb.h"
|
||||||
|
@ -145,6 +150,28 @@ void MainWindow::actSinglePlayer()
|
||||||
mainClient->sendCommand(mainClient->prepareRoomCommand(createCommand, 0));
|
mainClient->sendCommand(mainClient->prepareRoomCommand(createCommand, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::actWatchReplay()
|
||||||
|
{
|
||||||
|
QFileDialog dlg(this, tr("Load replay"));
|
||||||
|
dlg.setDirectory(settingsCache->getReplaysPath());
|
||||||
|
dlg.setNameFilters(QStringList() << QObject::tr("Cockatrice replays (*.cor)"));
|
||||||
|
if (!dlg.exec())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QString fileName = dlg.selectedFiles().at(0);
|
||||||
|
QFile file(fileName);
|
||||||
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
|
return;
|
||||||
|
QByteArray buf = file.readAll();
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
GameReplay *replay = new GameReplay;
|
||||||
|
replay->ParseFromArray(buf.data(), buf.size());
|
||||||
|
|
||||||
|
TabGame *replayWatcher = new TabGame(replay);
|
||||||
|
replayWatcher->show();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::localGameEnded()
|
void MainWindow::localGameEnded()
|
||||||
{
|
{
|
||||||
delete localServer;
|
delete localServer;
|
||||||
|
@ -243,6 +270,7 @@ void MainWindow::retranslateUi()
|
||||||
aConnect->setText(tr("&Connect..."));
|
aConnect->setText(tr("&Connect..."));
|
||||||
aDisconnect->setText(tr("&Disconnect"));
|
aDisconnect->setText(tr("&Disconnect"));
|
||||||
aSinglePlayer->setText(tr("Start &local game..."));
|
aSinglePlayer->setText(tr("Start &local game..."));
|
||||||
|
aWatchReplay->setText(tr("&Watch replay..."));
|
||||||
aDeckEditor->setText(tr("&Deck editor"));
|
aDeckEditor->setText(tr("&Deck editor"));
|
||||||
aFullScreen->setText(tr("&Full screen"));
|
aFullScreen->setText(tr("&Full screen"));
|
||||||
aFullScreen->setShortcut(tr("Ctrl+F"));
|
aFullScreen->setShortcut(tr("Ctrl+F"));
|
||||||
|
@ -266,6 +294,8 @@ void MainWindow::createActions()
|
||||||
connect(aDisconnect, SIGNAL(triggered()), this, SLOT(actDisconnect()));
|
connect(aDisconnect, SIGNAL(triggered()), this, SLOT(actDisconnect()));
|
||||||
aSinglePlayer = new QAction(this);
|
aSinglePlayer = new QAction(this);
|
||||||
connect(aSinglePlayer, SIGNAL(triggered()), this, SLOT(actSinglePlayer()));
|
connect(aSinglePlayer, SIGNAL(triggered()), this, SLOT(actSinglePlayer()));
|
||||||
|
aWatchReplay = new QAction(this);
|
||||||
|
connect(aWatchReplay, SIGNAL(triggered()), this, SLOT(actWatchReplay()));
|
||||||
aDeckEditor = new QAction(this);
|
aDeckEditor = new QAction(this);
|
||||||
connect(aDeckEditor, SIGNAL(triggered()), this, SLOT(actDeckEditor()));
|
connect(aDeckEditor, SIGNAL(triggered()), this, SLOT(actDeckEditor()));
|
||||||
aFullScreen = new QAction(this);
|
aFullScreen = new QAction(this);
|
||||||
|
@ -286,6 +316,7 @@ void MainWindow::createMenus()
|
||||||
cockatriceMenu->addAction(aConnect);
|
cockatriceMenu->addAction(aConnect);
|
||||||
cockatriceMenu->addAction(aDisconnect);
|
cockatriceMenu->addAction(aDisconnect);
|
||||||
cockatriceMenu->addAction(aSinglePlayer);
|
cockatriceMenu->addAction(aSinglePlayer);
|
||||||
|
cockatriceMenu->addAction(aWatchReplay);
|
||||||
cockatriceMenu->addSeparator();
|
cockatriceMenu->addSeparator();
|
||||||
cockatriceMenu->addAction(aDeckEditor);
|
cockatriceMenu->addAction(aDeckEditor);
|
||||||
cockatriceMenu->addSeparator();
|
cockatriceMenu->addSeparator();
|
||||||
|
|
|
@ -47,6 +47,7 @@ private slots:
|
||||||
void actConnect();
|
void actConnect();
|
||||||
void actDisconnect();
|
void actDisconnect();
|
||||||
void actSinglePlayer();
|
void actSinglePlayer();
|
||||||
|
void actWatchReplay();
|
||||||
void actDeckEditor();
|
void actDeckEditor();
|
||||||
void actFullScreen(bool checked);
|
void actFullScreen(bool checked);
|
||||||
void actSettings();
|
void actSettings();
|
||||||
|
@ -60,7 +61,7 @@ private:
|
||||||
void createActions();
|
void createActions();
|
||||||
void createMenus();
|
void createMenus();
|
||||||
QMenu *cockatriceMenu, *tabMenu, *helpMenu;
|
QMenu *cockatriceMenu, *tabMenu, *helpMenu;
|
||||||
QAction *aConnect, *aDisconnect, *aSinglePlayer, *aDeckEditor, *aFullScreen, *aSettings, *aExit,
|
QAction *aConnect, *aDisconnect, *aSinglePlayer, *aWatchReplay, *aDeckEditor, *aFullScreen, *aSettings, *aExit,
|
||||||
*aAbout;
|
*aAbout;
|
||||||
TabSupervisor *tabSupervisor;
|
TabSupervisor *tabSupervisor;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue