more code for local playing

This commit is contained in:
Max-Wilhelm Bruker 2010-08-14 17:01:14 +02:00
parent f6a340ddf3
commit 5ff099f4bc
15 changed files with 267 additions and 137 deletions

View file

@ -52,15 +52,16 @@ void GameScene::rearrange()
QPointF base; QPointF base;
qreal sceneWidth = 0; qreal sceneWidth = 0;
qreal sceneHeight = 0; qreal sceneHeight = 0;
Player *localPlayer = 0; QList<Player *> localPlayers;
for (int i = 0; i < players.size(); ++i) for (int i = 0; i < players.size(); ++i)
if (!players[i]->getLocal()) if (!players[i]->getLocal())
PlayerProcessor::processPlayer(players[i], sceneWidth, sceneHeight, base, players.size() == 1); PlayerProcessor::processPlayer(players[i], sceneWidth, sceneHeight, base, players.size() == 1);
else else
localPlayer = players[i]; localPlayers.append(players[i]);
if (localPlayer)
PlayerProcessor::processPlayer(localPlayer, sceneWidth, sceneHeight, base, players.size() == 1); for (int i = 0; i < localPlayers.size(); ++i)
PlayerProcessor::processPlayer(localPlayers[i], sceneWidth, sceneHeight, base, players.size() == 1);
playersRect = QRectF(0, 0, sceneWidth, sceneHeight); playersRect = QRectF(0, 0, sceneWidth, sceneHeight);

View file

@ -2,11 +2,11 @@
#include "localserverinterface.h" #include "localserverinterface.h"
#include "protocol.h" #include "protocol.h"
LocalClient::LocalClient(LocalServerInterface *_lsi, QObject *parent) LocalClient::LocalClient(LocalServerInterface *_lsi, const QString &_playerName, QObject *parent)
: AbstractClient(parent), lsi(_lsi) : AbstractClient(parent), lsi(_lsi)
{ {
connect(lsi, SIGNAL(itemToClient(ProtocolItem *)), this, SLOT(itemFromServer(ProtocolItem *))); connect(lsi, SIGNAL(itemToClient(ProtocolItem *)), this, SLOT(itemFromServer(ProtocolItem *)));
sendCommand(new Command_Login("Player", QString())); sendCommand(new Command_Login(_playerName, QString()));
} }
LocalClient::~LocalClient() LocalClient::~LocalClient()

View file

@ -10,7 +10,7 @@ class LocalClient : public AbstractClient {
private: private:
LocalServerInterface *lsi; LocalServerInterface *lsi;
public: public:
LocalClient(LocalServerInterface *_lsi, QObject *parent = 0); LocalClient(LocalServerInterface *_lsi, const QString &_playerName, QObject *parent = 0);
~LocalClient(); ~LocalClient();
void sendCommandContainer(CommandContainer *cont); void sendCommandContainer(CommandContainer *cont);

View file

@ -1,5 +1,4 @@
#include "player.h" #include "player.h"
#include "abstractclient.h"
#include "cardzone.h" #include "cardzone.h"
#include "playertarget.h" #include "playertarget.h"
#include "counter.h" #include "counter.h"
@ -21,8 +20,8 @@
#include <QMenu> #include <QMenu>
#include <QDebug> #include <QDebug>
Player::Player(const QString &_name, int _id, bool _local, AbstractClient *_client, TabGame *_parent) Player::Player(const QString &_name, int _id, bool _local, TabGame *_parent)
: QObject(_parent), defaultNumberTopCards(3), lastTokenDestroy(true), name(_name), id(_id), active(false), local(_local), mirrored(false), client(_client) : QObject(_parent), defaultNumberTopCards(3), lastTokenDestroy(true), name(_name), id(_id), active(false), local(_local), mirrored(false)
{ {
setCacheMode(DeviceCoordinateCache); setCacheMode(DeviceCoordinateCache);
@ -977,12 +976,12 @@ void Player::rearrangeCounters()
void Player::sendGameCommand(GameCommand *command) void Player::sendGameCommand(GameCommand *command)
{ {
static_cast<TabGame *>(parent())->sendGameCommand(command); static_cast<TabGame *>(parent())->sendGameCommand(command, id);
} }
void Player::sendCommandContainer(CommandContainer *cont) void Player::sendCommandContainer(CommandContainer *cont)
{ {
static_cast<TabGame *>(parent())->sendCommandContainer(cont); static_cast<TabGame *>(parent())->sendCommandContainer(cont, id);
} }
void Player::cardMenuAction() void Player::cardMenuAction()

View file

@ -6,7 +6,6 @@
#include <QMap> #include <QMap>
#include "carditem.h" #include "carditem.h"
class AbstractClient;
class CardDatabase; class CardDatabase;
class QMenu; class QMenu;
class QAction; class QAction;
@ -171,8 +170,7 @@ public:
void clearArrows(); void clearArrows();
PlayerTarget *getPlayerTarget() const { return playerTarget; } PlayerTarget *getPlayerTarget() const { return playerTarget; }
AbstractClient *client; Player(const QString &_name, int _id, bool _local, TabGame *_parent);
Player(const QString &_name, int _id, bool _local, AbstractClient *_client, TabGame *_parent);
~Player(); ~Player();
void retranslateUi(); void retranslateUi();
QMenu *getPlayerMenu() const { return playerMenu; } QMenu *getPlayerMenu() const { return playerMenu; }

View file

@ -42,32 +42,123 @@ void ReadyStartButton::setReadyStart(bool _readyStart)
update(); update();
} }
TabGame::TabGame(AbstractClient *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming) DeckViewContainer::DeckViewContainer(AbstractClient *_client, TabGame *parent)
: Tab(), client(_client), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1) : QWidget(parent), client(_client)
{ {
scene = new GameScene(this);
gameView = new GameView(scene);
gameView->hide();
loadLocalButton = new QPushButton; loadLocalButton = new QPushButton;
loadRemoteButton = new QPushButton; loadRemoteButton = new QPushButton;
readyStartButton = new ReadyStartButton; readyStartButton = new ReadyStartButton;
readyStartButton->setEnabled(false); readyStartButton->setEnabled(false);
connect(loadLocalButton, SIGNAL(clicked()), this, SLOT(loadLocalDeck()));
connect(loadRemoteButton, SIGNAL(clicked()), this, SLOT(loadRemoteDeck()));
connect(readyStartButton, SIGNAL(clicked()), this, SLOT(readyStart()));
QHBoxLayout *buttonHBox = new QHBoxLayout; QHBoxLayout *buttonHBox = new QHBoxLayout;
buttonHBox->addWidget(loadLocalButton); buttonHBox->addWidget(loadLocalButton);
buttonHBox->addWidget(loadRemoteButton); buttonHBox->addWidget(loadRemoteButton);
buttonHBox->addWidget(readyStartButton); buttonHBox->addWidget(readyStartButton);
buttonHBox->addStretch(); buttonHBox->addStretch();
deckView = new DeckView; deckView = new DeckView;
connect(deckView, SIGNAL(newCardAdded(AbstractCardItem *)), this, SLOT(newCardAdded(AbstractCardItem *))); connect(deckView, SIGNAL(newCardAdded(AbstractCardItem *)), this, SIGNAL(newCardAdded(AbstractCardItem *)));
connect(deckView, SIGNAL(sideboardPlanChanged()), this, SLOT(sideboardPlanChanged())); connect(deckView, SIGNAL(sideboardPlanChanged()), this, SLOT(sideboardPlanChanged()));
QVBoxLayout *deckViewLayout = new QVBoxLayout; QVBoxLayout *deckViewLayout = new QVBoxLayout;
deckViewLayout->addLayout(buttonHBox); deckViewLayout->addLayout(buttonHBox);
deckViewLayout->addWidget(deckView); deckViewLayout->addWidget(deckView);
deckViewContainer = new QWidget; setLayout(deckViewLayout);
deckViewContainer->setLayout(deckViewLayout);
retranslateUi();
}
void DeckViewContainer::retranslateUi()
{
loadLocalButton->setText(tr("Load &local deck"));
loadRemoteButton->setText(tr("Load d&eck from server"));
readyStartButton->setText(tr("Ready to s&tart"));
}
void DeckViewContainer::setButtonsVisible(bool _visible)
{
loadLocalButton->setVisible(_visible);
loadRemoteButton->setVisible(_visible);
readyStartButton->setVisible(_visible);
}
void DeckViewContainer::loadLocalDeck()
{
QFileDialog dialog(this, tr("Load deck"));
QSettings settings;
dialog.setDirectory(settings.value("paths/decks").toString());
dialog.setNameFilters(DeckList::fileNameFilters);
if (!dialog.exec())
return;
QString fileName = dialog.selectedFiles().at(0);
DeckList::FileFormat fmt = DeckList::getFormatFromNameFilter(dialog.selectedNameFilter());
DeckList *deck = new DeckList;
if (!deck->loadFromFile(fileName, fmt)) {
delete deck;
// Error message
return;
}
Command_DeckSelect *cmd = new Command_DeckSelect(static_cast<TabGame *>(parent())->getGameId(), deck, -1);
connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(deckSelectFinished(ProtocolResponse *)));
client->sendCommand(cmd);
}
void DeckViewContainer::loadRemoteDeck()
{
DlgLoadRemoteDeck dlg(client);
if (dlg.exec()) {
Command_DeckSelect *cmd = new Command_DeckSelect(static_cast<TabGame *>(parent())->getGameId(), 0, dlg.getDeckId());
connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(deckSelectFinished(ProtocolResponse *)));
client->sendCommand(cmd);
}
}
void DeckViewContainer::deckSelectFinished(ProtocolResponse *r)
{
Response_DeckDownload *resp = qobject_cast<Response_DeckDownload *>(r);
if (!resp)
return;
Deck_PictureCacher::cachePictures(resp->getDeck(), this);
deckView->setDeck(new DeckList(resp->getDeck()));
readyStartButton->setEnabled(true);
}
void DeckViewContainer::readyStart()
{
client->sendCommand(new Command_ReadyStart(static_cast<TabGame *>(parent())->getGameId(), !readyStartButton->getReadyStart()));
}
void DeckViewContainer::sideboardPlanChanged()
{
QList<MoveCardToZone *> newPlan = deckView->getSideboardPlan();
client->sendCommand(new Command_SetSideboardPlan(static_cast<TabGame *>(parent())->getGameId(), newPlan));
}
void DeckViewContainer::setReadyStart(bool ready)
{
readyStartButton->setReadyStart(ready);
deckView->setLocked(ready);
}
void DeckViewContainer::setDeck(DeckList *deck)
{
deckView->setDeck(deck);
readyStartButton->setEnabled(true);
}
TabGame::TabGame(QList<AbstractClient *> &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming)
: Tab(), clients(_clients), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1)
{
scene = new GameScene(this);
gameView = new GameView(scene);
gameView->hide();
cardInfo = new CardInfoWidget; cardInfo = new CardInfoWidget;
playerListWidget = new PlayerListWidget; playerListWidget = new PlayerListWidget;
playerListWidget->setFocusPolicy(Qt::NoFocus); playerListWidget->setFocusPolicy(Qt::NoFocus);
@ -79,10 +170,12 @@ TabGame::TabGame(AbstractClient *_client, int _gameId, const QString &_gameDescr
QHBoxLayout *hLayout = new QHBoxLayout; QHBoxLayout *hLayout = new QHBoxLayout;
hLayout->addWidget(sayLabel); hLayout->addWidget(sayLabel);
hLayout->addWidget(sayEdit); hLayout->addWidget(sayEdit);
deckViewContainerLayout = new QVBoxLayout;
phasesToolbar = new PhasesToolbar; phasesToolbar = new PhasesToolbar;
phasesToolbar->hide(); phasesToolbar->hide();
connect(phasesToolbar, SIGNAL(sendGameCommand(GameCommand *)), this, SLOT(sendGameCommand(GameCommand *))); connect(phasesToolbar, SIGNAL(sendGameCommand(GameCommand *, int)), this, SLOT(sendGameCommand(GameCommand *, int)));
QVBoxLayout *verticalLayout = new QVBoxLayout; QVBoxLayout *verticalLayout = new QVBoxLayout;
verticalLayout->addWidget(cardInfo); verticalLayout->addWidget(cardInfo);
@ -90,26 +183,17 @@ TabGame::TabGame(AbstractClient *_client, int _gameId, const QString &_gameDescr
verticalLayout->addWidget(messageLog, 3); verticalLayout->addWidget(messageLog, 3);
verticalLayout->addLayout(hLayout); verticalLayout->addLayout(hLayout);
QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout = new QHBoxLayout;
mainLayout->addWidget(phasesToolbar); mainLayout->addWidget(phasesToolbar);
mainLayout->addWidget(gameView, 10); mainLayout->addWidget(gameView, 10);
mainLayout->addWidget(deckViewContainer, 10); mainLayout->addLayout(deckViewContainerLayout, 10);
mainLayout->addLayout(verticalLayout); mainLayout->addLayout(verticalLayout);
if (spectator) { if (spectator && !spectatorsCanTalk) {
if (!spectatorsCanTalk) { sayLabel->hide();
sayLabel->hide(); sayEdit->hide();
sayEdit->hide();
}
loadLocalButton->hide();
loadRemoteButton->hide();
readyStartButton->hide();
} }
connect(loadLocalButton, SIGNAL(clicked()), this, SLOT(loadLocalDeck()));
connect(loadRemoteButton, SIGNAL(clicked()), this, SLOT(loadRemoteDeck()));
connect(readyStartButton, SIGNAL(clicked()), this, SLOT(readyStart()));
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(actSay())); connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(actSay()));
// Menu actions // Menu actions
@ -147,6 +231,8 @@ TabGame::~TabGame()
delete i.next().value(); delete i.next().value();
players.clear(); players.clear();
delete deckViewContainerLayout;
emit gameClosing(this); emit gameClosing(this);
} }
@ -163,15 +249,15 @@ void TabGame::retranslateUi()
aConcede->setShortcut(tr("F2")); aConcede->setShortcut(tr("F2"));
aLeaveGame->setText(tr("&Leave game")); aLeaveGame->setText(tr("&Leave game"));
loadLocalButton->setText(tr("Load &local deck"));
loadRemoteButton->setText(tr("Load d&eck from server"));
readyStartButton->setText(tr("Ready to s&tart"));
sayLabel->setText(tr("&Say:")); sayLabel->setText(tr("&Say:"));
cardInfo->retranslateUi(); cardInfo->retranslateUi();
QMapIterator<int, Player *> i(players); QMapIterator<int, Player *> i(players);
while (i.hasNext()) while (i.hasNext())
i.next().value()->retranslateUi(); i.next().value()->retranslateUi();
QMapIterator<int, DeckViewContainer *> j(deckViewContainers);
while (j.hasNext())
j.next().value()->retranslateUi();
scene->retranslateUi(); scene->retranslateUi();
} }
@ -181,7 +267,7 @@ void TabGame::actConcede()
if (QMessageBox::question(this, tr("Concede"), tr("Are you sure you want to concede this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) 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; return;
sendGameCommand(new Command_Concede); sendGameCommand(new Command_Concede, getActiveLocalPlayer()->getId());
} }
void TabGame::actLeaveGame() void TabGame::actLeaveGame()
@ -189,14 +275,14 @@ void TabGame::actLeaveGame()
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) 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)
return; return;
sendGameCommand(new Command_LeaveGame); sendGameCommand(new Command_LeaveGame, getActiveLocalPlayer()->getId());
deleteLater(); deleteLater();
} }
void TabGame::actSay() void TabGame::actSay()
{ {
if (!sayEdit->text().isEmpty()) { if (!sayEdit->text().isEmpty()) {
sendGameCommand(new Command_Say(-1, sayEdit->text())); sendGameCommand(new Command_Say(-1, sayEdit->text()), getActiveLocalPlayer()->getId());
sayEdit->clear(); sayEdit->clear();
} }
} }
@ -206,12 +292,12 @@ void TabGame::actNextPhase()
int phase = currentPhase; int phase = currentPhase;
if (++phase >= phasesToolbar->phaseCount()) if (++phase >= phasesToolbar->phaseCount())
phase = 0; phase = 0;
sendGameCommand(new Command_SetActivePhase(-1, phase)); sendGameCommand(new Command_SetActivePhase(-1, phase), getActiveLocalPlayer()->getId());
} }
void TabGame::actNextTurn() void TabGame::actNextTurn()
{ {
sendGameCommand(new Command_NextTurn); sendGameCommand(new Command_NextTurn, getActiveLocalPlayer()->getId());
} }
void TabGame::actRemoveLocalArrows() void TabGame::actRemoveLocalArrows()
@ -224,18 +310,31 @@ void TabGame::actRemoveLocalArrows()
QMapIterator<int, ArrowItem *> arrowIterator(player->getArrows()); QMapIterator<int, ArrowItem *> arrowIterator(player->getArrows());
while (arrowIterator.hasNext()) { while (arrowIterator.hasNext()) {
ArrowItem *a = arrowIterator.next().value(); ArrowItem *a = arrowIterator.next().value();
sendGameCommand(new Command_DeleteArrow(-1, a->getId())); sendGameCommand(new Command_DeleteArrow(-1, a->getId()), getActiveLocalPlayer()->getId());
} }
} }
} }
Player *TabGame::addPlayer(int playerId, const QString &playerName) Player *TabGame::addPlayer(int playerId, const QString &playerName)
{ {
Player *newPlayer = new Player(playerName, playerId, playerId == localPlayerId, client, this); bool local = ((clients.size() > 1) || (playerId == localPlayerId));
Player *newPlayer = new Player(playerName, playerId, local, this);
scene->addPlayer(newPlayer); scene->addPlayer(newPlayer);
connect(newPlayer, SIGNAL(newCardAdded(AbstractCardItem *)), this, SLOT(newCardAdded(AbstractCardItem *))); connect(newPlayer, SIGNAL(newCardAdded(AbstractCardItem *)), this, SLOT(newCardAdded(AbstractCardItem *)));
messageLog->connectToPlayer(newPlayer); messageLog->connectToPlayer(newPlayer);
if (local && !spectator) {
AbstractClient *client;
if (clients.size() > 1)
client = clients.at(playerId);
else
client = clients.first();
DeckViewContainer *deckView = new DeckViewContainer(client, this);
connect(deckView, SIGNAL(newCardAdded(AbstractCardItem *)), this, SLOT(newCardAdded(AbstractCardItem *)));
deckViewContainers.insert(playerId, deckView);
deckViewContainerLayout->addWidget(deckView);
}
tabMenu->insertMenu(playersSeparator, newPlayer->getPlayerMenu()); tabMenu->insertMenu(playersSeparator, newPlayer->getPlayerMenu());
@ -283,13 +382,19 @@ void TabGame::processGameEventContainer(GameEventContainer *cont)
} }
} }
void TabGame::sendGameCommand(GameCommand *command) void TabGame::sendGameCommand(GameCommand *command, int playerId)
{ {
command->setGameId(gameId); command->setGameId(gameId);
AbstractClient *client;
if (clients.size() > 1)
client = clients.at(playerId);
else
client = clients.first();
client->sendCommand(command); client->sendCommand(command);
} }
void TabGame::sendCommandContainer(CommandContainer *cont) void TabGame::sendCommandContainer(CommandContainer *cont, int playerId)
{ {
const QList<Command *> &cmdList = cont->getCommandList(); const QList<Command *> &cmdList = cont->getCommandList();
for (int i = 0; i < cmdList.size(); ++i) { for (int i = 0; i < cmdList.size(); ++i) {
@ -297,6 +402,12 @@ void TabGame::sendCommandContainer(CommandContainer *cont)
if (cmd) if (cmd)
cmd->setGameId(gameId); cmd->setGameId(gameId);
} }
AbstractClient *client;
if (clients.size() > 1)
client = clients.at(playerId);
else
client = clients.first();
client->sendCommandContainer(cont); client->sendCommandContainer(cont);
} }
@ -304,11 +415,16 @@ void TabGame::startGame()
{ {
currentPhase = -1; currentPhase = -1;
readyStartButton->setReadyStart(false); QMapIterator<int, DeckViewContainer *> i(deckViewContainers);
deckView->setLocked(false); while (i.hasNext()) {
i.next();
i.value()->setReadyStart(false);
i.value()->hide();
}
mainLayout->removeItem(deckViewContainerLayout);
playerListWidget->setGameStarted(true); playerListWidget->setGameStarted(true);
started = true; started = true;
deckViewContainer->hide();
gameView->show(); gameView->show();
phasesToolbar->show(); phasesToolbar->show();
} }
@ -318,12 +434,18 @@ void TabGame::stopGame()
currentPhase = -1; currentPhase = -1;
activePlayer = -1; activePlayer = -1;
QMapIterator<int, DeckViewContainer *> i(deckViewContainers);
while (i.hasNext()) {
i.next();
i.value()->show();
}
mainLayout->insertLayout(2, deckViewContainerLayout, 10);
playerListWidget->setActivePlayer(-1); playerListWidget->setActivePlayer(-1);
playerListWidget->setGameStarted(false); playerListWidget->setGameStarted(false);
started = false; started = false;
gameView->hide(); gameView->hide();
phasesToolbar->hide(); phasesToolbar->hide();
deckViewContainer->show();
} }
void TabGame::eventSpectatorSay(Event_Say *event, GameEventContext * /*context*/) void TabGame::eventSpectatorSay(Event_Say *event, GameEventContext * /*context*/)
@ -361,8 +483,7 @@ void TabGame::eventGameStateChanged(Event_GameStateChanged *event, GameEventCont
player->processPlayerInfo(pl); player->processPlayerInfo(pl);
if (player->getLocal() && pl->getDeck()) { if (player->getLocal() && pl->getDeck()) {
Deck_PictureCacher::cachePictures(pl->getDeck(), this); Deck_PictureCacher::cachePictures(pl->getDeck(), this);
deckView->setDeck(new DeckList(pl->getDeck())); deckViewContainers.value(player->getId())->setDeck(new DeckList(pl->getDeck()));
readyStartButton->setEnabled(true);
} }
} }
} }
@ -398,10 +519,8 @@ void TabGame::eventPlayerPropertiesChanged(Event_PlayerPropertiesChanged *event,
if (context) switch (context->getItemId()) { if (context) switch (context->getItemId()) {
case ItemId_Context_ReadyStart: { case ItemId_Context_ReadyStart: {
bool ready = event->getProperties()->getReadyStart(); bool ready = event->getProperties()->getReadyStart();
if (player->getLocal()) { if (player->getLocal())
readyStartButton->setReadyStart(ready); deckViewContainers.value(player->getId())->setReadyStart(ready);
deckView->setLocked(ready);
}
if (ready) if (ready)
messageLog->logReadyStart(player); messageLog->logReadyStart(player);
else else
@ -500,66 +619,11 @@ void TabGame::eventPing(Event_Ping *event, GameEventContext * /*context*/)
playerListWidget->updatePing(pingList[i]->getPlayerId(), pingList[i]->getPingTime()); playerListWidget->updatePing(pingList[i]->getPlayerId(), pingList[i]->getPingTime());
} }
void TabGame::loadLocalDeck()
{
QFileDialog dialog(this, tr("Load deck"));
QSettings settings;
dialog.setDirectory(settings.value("paths/decks").toString());
dialog.setNameFilters(DeckList::fileNameFilters);
if (!dialog.exec())
return;
QString fileName = dialog.selectedFiles().at(0);
DeckList::FileFormat fmt = DeckList::getFormatFromNameFilter(dialog.selectedNameFilter());
DeckList *deck = new DeckList;
if (!deck->loadFromFile(fileName, fmt)) {
delete deck;
// Error message
return;
}
Command_DeckSelect *cmd = new Command_DeckSelect(gameId, deck, -1);
connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(deckSelectFinished(ProtocolResponse *)));
client->sendCommand(cmd);
}
void TabGame::loadRemoteDeck()
{
DlgLoadRemoteDeck dlg(client);
if (dlg.exec()) {
Command_DeckSelect *cmd = new Command_DeckSelect(gameId, 0, dlg.getDeckId());
connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(deckSelectFinished(ProtocolResponse *)));
client->sendCommand(cmd);
}
}
void TabGame::deckSelectFinished(ProtocolResponse *r)
{
Response_DeckDownload *resp = qobject_cast<Response_DeckDownload *>(r);
if (!resp)
return;
Deck_PictureCacher::cachePictures(resp->getDeck(), this);
deckView->setDeck(new DeckList(resp->getDeck()));
readyStartButton->setEnabled(true);
}
void TabGame::readyStart()
{
client->sendCommand(new Command_ReadyStart(gameId, !readyStartButton->getReadyStart()));
}
void TabGame::newCardAdded(AbstractCardItem *card) void TabGame::newCardAdded(AbstractCardItem *card)
{ {
connect(card, SIGNAL(hovered(AbstractCardItem *)), cardInfo, SLOT(setCard(AbstractCardItem *))); connect(card, SIGNAL(hovered(AbstractCardItem *)), cardInfo, SLOT(setCard(AbstractCardItem *)));
} }
void TabGame::sideboardPlanChanged()
{
QList<MoveCardToZone *> newPlan = deckView->getSideboardPlan();
client->sendCommand(new Command_SetSideboardPlan(gameId, newPlan));
}
CardItem *TabGame::getCard(int playerId, const QString &zoneName, int cardId) const CardItem *TabGame::getCard(int playerId, const QString &zoneName, int cardId) const
{ {
Player *player = players.value(playerId, 0); Player *player = players.value(playerId, 0);

View file

@ -39,6 +39,10 @@ class Player;
class CardZone; class CardZone;
class AbstractCardItem; class AbstractCardItem;
class CardItem; class CardItem;
class TabGame;
class DeckList;
class QVBoxLayout;
class QHBoxLayout;
class ReadyStartButton : public QPushButton { class ReadyStartButton : public QPushButton {
Q_OBJECT Q_OBJECT
@ -52,10 +56,33 @@ protected:
void paintEvent(QPaintEvent *event); void paintEvent(QPaintEvent *event);
}; };
class DeckViewContainer : public QWidget {
Q_OBJECT
private:
QPushButton *loadLocalButton, *loadRemoteButton;
ReadyStartButton *readyStartButton;
DeckView *deckView;
AbstractClient *client;
private slots:
void loadLocalDeck();
void loadRemoteDeck();
void readyStart();
void deckSelectFinished(ProtocolResponse *r);
void sideboardPlanChanged();
signals:
void newCardAdded(AbstractCardItem *card);
public:
DeckViewContainer(AbstractClient *_client, TabGame *parent = 0);
void retranslateUi();
void setButtonsVisible(bool _visible);
void setReadyStart(bool ready);
void setDeck(DeckList *deck);
};
class TabGame : public Tab { class TabGame : public Tab {
Q_OBJECT Q_OBJECT
private: private:
AbstractClient *client; QList<AbstractClient *> clients;
int gameId; int gameId;
QString gameDescription; QString gameDescription;
int localPlayerId; int localPlayerId;
@ -68,8 +95,6 @@ private:
int currentPhase; int currentPhase;
int activePlayer; int activePlayer;
QPushButton *loadLocalButton, *loadRemoteButton;
ReadyStartButton *readyStartButton;
CardInfoWidget *cardInfo; CardInfoWidget *cardInfo;
PlayerListWidget *playerListWidget; PlayerListWidget *playerListWidget;
MessageLogWidget *messageLog; MessageLogWidget *messageLog;
@ -78,8 +103,9 @@ private:
PhasesToolbar *phasesToolbar; PhasesToolbar *phasesToolbar;
GameScene *scene; GameScene *scene;
GameView *gameView; GameView *gameView;
DeckView *deckView; QMap<int, DeckViewContainer *> deckViewContainers;
QWidget *deckViewContainer; QVBoxLayout *deckViewContainerLayout;
QHBoxLayout *mainLayout;
ZoneViewLayout *zoneLayout; ZoneViewLayout *zoneLayout;
QAction *playersSeparator; QAction *playersSeparator;
QMenu *playersMenu; QMenu *playersMenu;
@ -106,12 +132,7 @@ private:
signals: signals:
void gameClosing(TabGame *tab); void gameClosing(TabGame *tab);
private slots: private slots:
void loadLocalDeck();
void loadRemoteDeck();
void readyStart();
void deckSelectFinished(ProtocolResponse *r);
void newCardAdded(AbstractCardItem *card); void newCardAdded(AbstractCardItem *card);
void sideboardPlanChanged();
void actConcede(); void actConcede();
void actLeaveGame(); void actLeaveGame();
@ -120,7 +141,7 @@ private slots:
void actNextPhase(); void actNextPhase();
void actNextTurn(); void actNextTurn();
public: public:
TabGame(AbstractClient *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming); TabGame(QList<AbstractClient *> &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming);
~TabGame(); ~TabGame();
void retranslateUi(); void retranslateUi();
const QMap<int, Player *> &getPlayers() const { return players; } const QMap<int, Player *> &getPlayers() const { return players; }
@ -134,8 +155,8 @@ public:
void processGameEventContainer(GameEventContainer *cont); void processGameEventContainer(GameEventContainer *cont);
public slots: public slots:
void sendGameCommand(GameCommand *command); void sendGameCommand(GameCommand *command, int playerId);
void sendCommandContainer(CommandContainer *cont); void sendCommandContainer(CommandContainer *cont, int playerId);
}; };
#endif #endif

View file

@ -68,6 +68,14 @@ void TabSupervisor::start(AbstractClient *_client)
retranslateUi(); retranslateUi();
} }
void TabSupervisor::startLocal(const QList<AbstractClient *> &_clients)
{
localClients = _clients;
for (int i = 0; i < localClients.size(); ++i)
connect(localClients[i], SIGNAL(gameEventContainerReceived(GameEventContainer *)), this, SLOT(processGameEventContainer(GameEventContainer *)));
connect(localClients.first(), SIGNAL(gameJoinedEventReceived(Event_GameJoined *)), this, SLOT(localGameJoined(Event_GameJoined *)));
}
void TabSupervisor::stop() void TabSupervisor::stop()
{ {
if (!client) if (!client)
@ -104,13 +112,28 @@ void TabSupervisor::updatePingTime(int value, int max)
void TabSupervisor::gameJoined(Event_GameJoined *event) void TabSupervisor::gameJoined(Event_GameJoined *event)
{ {
TabGame *tab = new TabGame(client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); TabGame *tab = new TabGame(QList<AbstractClient *>() << client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming());
connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *))); connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *)));
myAddTab(tab); myAddTab(tab);
gameTabs.insert(event->getGameId(), tab); gameTabs.insert(event->getGameId(), tab);
setCurrentWidget(tab); setCurrentWidget(tab);
} }
void TabSupervisor::localGameJoined(Event_GameJoined *event)
{
TabGame *tab = new TabGame(localClients, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming());
connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *)));
myAddTab(tab);
gameTabs.insert(event->getGameId(), tab);
setCurrentWidget(tab);
for (int i = 1; i < localClients.size(); ++i) {
qDebug("JOINING");
Command_JoinGame *cmd = new Command_JoinGame(event->getGameId());
localClients[i]->sendCommand(cmd);
}
}
void TabSupervisor::gameLeft(TabGame *tab) void TabSupervisor::gameLeft(TabGame *tab)
{ {
emit setMenu(0); emit setMenu(0);

View file

@ -20,6 +20,7 @@ class TabSupervisor : public QTabWidget {
private: private:
QIcon *tabChangedIcon; QIcon *tabChangedIcon;
AbstractClient *client; AbstractClient *client;
QList<AbstractClient *> localClients;
TabServer *tabServer; TabServer *tabServer;
TabDeckStorage *tabDeckStorage; TabDeckStorage *tabDeckStorage;
QMap<QString, TabChatChannel *> chatChannelTabs; QMap<QString, TabChatChannel *> chatChannelTabs;
@ -30,6 +31,7 @@ public:
~TabSupervisor(); ~TabSupervisor();
void retranslateUi(); void retranslateUi();
void start(AbstractClient *_client); void start(AbstractClient *_client);
void startLocal(const QList<AbstractClient *> &_clients);
void stop(); void stop();
int getGameCount() const { return gameTabs.size(); } int getGameCount() const { return gameTabs.size(); }
signals: signals:
@ -38,6 +40,7 @@ private slots:
void updateCurrent(int index); void updateCurrent(int index);
void updatePingTime(int value, int max); void updatePingTime(int value, int max);
void gameJoined(Event_GameJoined *event); void gameJoined(Event_GameJoined *event);
void localGameJoined(Event_GameJoined *event);
void gameLeft(TabGame *tab); void gameLeft(TabGame *tab);
void addChatChannelTab(const QString &channelName); void addChatChannelTab(const QString &channelName);
void chatChannelLeft(TabChatChannel *tab); void chatChannelLeft(TabChatChannel *tab);

View file

@ -80,11 +80,25 @@ void MainWindow::actDisconnect()
void MainWindow::actSinglePlayer() void MainWindow::actSinglePlayer()
{ {
bool ok;
int numberPlayers = QInputDialog::getInt(this, tr("Number of players"), tr("Please enter the number of players."), 2, 1, 8, 1, &ok);
if (!ok)
return;
LocalServer *ls = new LocalServer(this); LocalServer *ls = new LocalServer(this);
LocalServerInterface *mainLsi = ls->newConnection(); LocalServerInterface *mainLsi = ls->newConnection();
LocalClient *mainClient = new LocalClient(mainLsi, this); LocalClient *mainClient = new LocalClient(mainLsi, tr("Player %1").arg(1), this);
tabSupervisor->start(mainClient); localClients.append(mainClient);
for (int i = 0; i < numberPlayers - 1; ++i) {
LocalServerInterface *slaveLsi = ls->newConnection();
LocalClient *slaveClient = new LocalClient(slaveLsi, tr("Player %1").arg(i + 2), this);
localClients.append(slaveClient);
}
tabSupervisor->startLocal(localClients);
Command_CreateGame *createCommand = new Command_CreateGame(QString(), QString(), numberPlayers, false, false, false, false);
mainClient->sendCommand(createCommand);
} }
void MainWindow::actDeckEditor() void MainWindow::actDeckEditor()

View file

@ -26,6 +26,7 @@
class TabSupervisor; class TabSupervisor;
class RemoteClient; class RemoteClient;
class LocalClient;
class MainWindow : public QMainWindow { class MainWindow : public QMainWindow {
Q_OBJECT Q_OBJECT
@ -55,6 +56,7 @@ private:
TabSupervisor *tabSupervisor; TabSupervisor *tabSupervisor;
RemoteClient *client; RemoteClient *client;
QList<AbstractClient *> localClients;
public: public:
MainWindow(QWidget *parent = 0); MainWindow(QWidget *parent = 0);
protected: protected:

View file

@ -14,6 +14,8 @@ enum AuthenticationResult { PasswordWrong = 0, PasswordRight = 1, UnknownUser =
class Server : public QObject class Server : public QObject
{ {
Q_OBJECT Q_OBJECT
signals:
void pingClockTimeout();
private slots: private slots:
void gameClosing(); void gameClosing();
void broadcastChannelUpdate(); void broadcastChannelUpdate();

View file

@ -12,14 +12,11 @@
#include "server_player.h" #include "server_player.h"
#include "decklist.h" #include "decklist.h"
#include <QDateTime> #include <QDateTime>
#include <QTimer>
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent) Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent)
: QObject(parent), server(_server), authState(PasswordWrong), acceptsGameListChanges(false), lastCommandTime(QDateTime::currentDateTime()) : QObject(parent), server(_server), authState(PasswordWrong), acceptsGameListChanges(false), lastCommandTime(QDateTime::currentDateTime())
{ {
pingClock = new QTimer(this); connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
connect(pingClock, SIGNAL(timeout()), this, SLOT(pingClockTimeout()));
pingClock->start(1000);
} }
Server_ProtocolHandler::~Server_ProtocolHandler() Server_ProtocolHandler::~Server_ProtocolHandler()
@ -332,7 +329,7 @@ ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandC
Server_Game *g = server->getGame(cmd->getGameId()); Server_Game *g = server->getGame(cmd->getGameId());
if (!g) if (!g)
return RespNameNotFound; return RespNameNotFound;
ResponseCode result = g->checkJoin(cmd->getPassword(), cmd->getSpectator()); ResponseCode result = g->checkJoin(cmd->getPassword(), cmd->getSpectator());
if (result == RespOk) { if (result == RespOk) {
Server_Player *player = g->addPlayer(this, cmd->getSpectator()); Server_Player *player = g->addPlayer(this, cmd->getSpectator());

View file

@ -27,6 +27,10 @@
Servatrice::Servatrice(QObject *parent) Servatrice::Servatrice(QObject *parent)
: Server(parent) : Server(parent)
{ {
pingClock = new QTimer(this);
connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout()));
pingClock->start(1000);
ProtocolItem::initializeHash(); ProtocolItem::initializeHash();
settings = new QSettings("servatrice.ini", QSettings::IniFormat, this); settings = new QSettings("servatrice.ini", QSettings::IniFormat, this);

View file

@ -26,6 +26,7 @@
class QSqlDatabase; class QSqlDatabase;
class QSettings; class QSettings;
class QSqlQuery; class QSqlQuery;
class QTimer;
class Servatrice : public Server class Servatrice : public Server
{ {
@ -44,6 +45,7 @@ public:
int getMaxGameInactivityTime() const { return maxGameInactivityTime; } int getMaxGameInactivityTime() const { return maxGameInactivityTime; }
int getMaxPlayerInactivityTime() const { return maxPlayerInactivityTime; } int getMaxPlayerInactivityTime() const { return maxPlayerInactivityTime; }
private: private:
QTimer *pingClock;
QTcpServer *tcpServer; QTcpServer *tcpServer;
QString loginMessage; QString loginMessage;
QSettings *settings; QSettings *settings;