diff --git a/cockatrice/src/deckview.cpp b/cockatrice/src/deckview.cpp index 5f34e0dc..1790bb25 100644 --- a/cockatrice/src/deckview.cpp +++ b/cockatrice/src/deckview.cpp @@ -64,6 +64,11 @@ DeckViewCard::DeckViewCard(const QString &_name, const QString &_originZone, QGr { } +DeckViewCard::~DeckViewCard() +{ + delete dragItem; +} + void DeckViewCard::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { AbstractCardItem::paint(painter, option, widget); @@ -85,6 +90,9 @@ void DeckViewCard::mouseMoveEvent(QGraphicsSceneMouseEvent *event) if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < 2 * QApplication::startDragDistance()) return; + if (static_cast(scene())->getLocked()) + return; + delete dragItem; dragItem = new DeckViewCardDragItem(this, event->pos()); scene()->addItem(dragItem); @@ -185,7 +193,7 @@ void DeckViewCardContainer::setWidth(qreal _width) } DeckViewScene::DeckViewScene(QObject *parent) - : QGraphicsScene(parent), deck(0) + : QGraphicsScene(parent), locked(false), deck(0) { } diff --git a/cockatrice/src/deckview.h b/cockatrice/src/deckview.h index 55365136..987a2290 100644 --- a/cockatrice/src/deckview.h +++ b/cockatrice/src/deckview.h @@ -21,6 +21,7 @@ private: DeckViewCardDragItem *dragItem; public: DeckViewCard(const QString &_name = QString(), const QString &_originZone = QString(), QGraphicsItem *parent = 0); + ~DeckViewCard(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); const QString &getOriginZone() const { return originZone; } protected: @@ -65,6 +66,7 @@ signals: void newCardAdded(AbstractCardItem *card); void sideboardPlanChanged(); private: + bool locked; DeckList *deck; QMap cardContainers; void rebuildTree(); @@ -73,6 +75,8 @@ private: public: DeckViewScene(QObject *parent = 0); ~DeckViewScene(); + void setLocked(bool _locked) { locked = _locked; } + bool getLocked() const { return locked; } void setDeck(DeckList *_deck); void updateContents(); QList getSideboardPlan() const; @@ -92,6 +96,7 @@ signals: public: DeckView(QWidget *parent = 0); void setDeck(DeckList *_deck); + void setLocked(bool _locked) { deckViewScene->setLocked(_locked); } QList getSideboardPlan() const { return deckViewScene->getSideboardPlan(); } }; diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp index 443782c8..ffa7b35d 100644 --- a/cockatrice/src/messagelogwidget.cpp +++ b/cockatrice/src/messagelogwidget.cpp @@ -92,6 +92,11 @@ void MessageLogWidget::logReadyStart(Player *player) append(tr("%1 is ready to start the game.").arg(sanitizeHtml(player->getName()))); } +void MessageLogWidget::logNotReadyStart(Player *player) +{ + append(tr("%1 is not ready to start the game any more.").arg(sanitizeHtml(player->getName()))); +} + void MessageLogWidget::logConcede(Player *player) { append(tr("%1 has conceded the game.").arg(sanitizeHtml(player->getName()))); diff --git a/cockatrice/src/messagelogwidget.h b/cockatrice/src/messagelogwidget.h index f8ba59d2..90557d04 100644 --- a/cockatrice/src/messagelogwidget.h +++ b/cockatrice/src/messagelogwidget.h @@ -30,6 +30,7 @@ public slots: void logLeaveSpectator(QString name); void logDeckSelect(Player *player, int deckId); void logReadyStart(Player *player); + void logNotReadyStart(Player *player); void logConcede(Player *player); void logGameStart(); void logSay(Player *player, QString message); diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp index 127c2158..3bc71242 100644 --- a/cockatrice/src/tab_game.cpp +++ b/cockatrice/src/tab_game.cpp @@ -19,6 +19,29 @@ #include "arrowitem.h" #include "main.h" +ReadyStartButton::ReadyStartButton(QWidget *parent) + : QPushButton(parent), readyStart(false) +{ +} + +void ReadyStartButton::paintEvent(QPaintEvent *event) +{ + QPushButton::paintEvent(event); + + QPainter painter(this); + if (readyStart) + painter.setPen(QPen(Qt::green, 3)); + else + painter.setPen(QPen(Qt::red, 3)); + painter.drawRect(1.5, 1.5, width() - 3, height() - 3); +} + +void ReadyStartButton::setReadyStart(bool _readyStart) +{ + readyStart = _readyStart; + update(); +} + TabGame::TabGame(Client *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming) : Tab(), client(_client), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1) { @@ -28,7 +51,7 @@ TabGame::TabGame(Client *_client, int _gameId, const QString &_gameDescription, loadLocalButton = new QPushButton; loadRemoteButton = new QPushButton; - readyStartButton = new QPushButton; + readyStartButton = new ReadyStartButton; readyStartButton->setEnabled(false); QHBoxLayout *buttonHBox = new QHBoxLayout; @@ -142,7 +165,7 @@ void TabGame::retranslateUi() loadLocalButton->setText(tr("Load &local deck")); loadRemoteButton->setText(tr("Load d&eck from server")); - readyStartButton->setText(tr("S&tart game")); + readyStartButton->setText(tr("Ready to s&tart")); sayLabel->setText(tr("&Say:")); cardInfo->retranslateUi(); @@ -360,7 +383,18 @@ void TabGame::eventPlayerPropertiesChanged(Event_PlayerPropertiesChanged *event, return; playerListWidget->updatePlayerProperties(event->getProperties()); if (context) switch (context->getItemId()) { - case ItemId_Context_ReadyStart: messageLog->logReadyStart(player); break; + case ItemId_Context_ReadyStart: { + bool ready = event->getProperties()->getReadyStart(); + if (player->getLocal()) { + readyStartButton->setReadyStart(ready); + deckView->setLocked(ready); + } + if (ready) + messageLog->logReadyStart(player); + else + messageLog->logNotReadyStart(player); + break; + } case ItemId_Context_Concede: messageLog->logConcede(player); break; case ItemId_Context_DeckSelect: messageLog->logDeckSelect(player, static_cast(context)->getDeckId()); break; default: ; @@ -498,7 +532,7 @@ void TabGame::deckSelectFinished(ProtocolResponse *r) void TabGame::readyStart() { - client->sendCommand(new Command_ReadyStart(gameId)); + client->sendCommand(new Command_ReadyStart(gameId, !readyStartButton->getReadyStart())); } void TabGame::newCardAdded(AbstractCardItem *card) diff --git a/cockatrice/src/tab_game.h b/cockatrice/src/tab_game.h index c9c6991f..24d33448 100644 --- a/cockatrice/src/tab_game.h +++ b/cockatrice/src/tab_game.h @@ -2,6 +2,7 @@ #define TAB_GAME_H #include +#include #include "tab.h" class Client; @@ -39,6 +40,18 @@ class CardZone; class AbstractCardItem; class CardItem; +class ReadyStartButton : public QPushButton { + Q_OBJECT +private: + bool readyStart; +public: + ReadyStartButton(QWidget *parent = 0); + bool getReadyStart() const { return readyStart; } + void setReadyStart(bool _readyStart); +protected: + void paintEvent(QPaintEvent *event); +}; + class TabGame : public Tab { Q_OBJECT private: @@ -54,7 +67,8 @@ private: bool resuming; int currentPhase; - QPushButton *loadLocalButton, *loadRemoteButton, *readyStartButton; + QPushButton *loadLocalButton, *loadRemoteButton; + ReadyStartButton *readyStartButton; CardInfoWidget *cardInfo; PlayerListWidget *playerListWidget; MessageLogWidget *messageLog; diff --git a/common/protocol.h b/common/protocol.h index 5e1af53b..edf51c03 100644 --- a/common/protocol.h +++ b/common/protocol.h @@ -47,7 +47,7 @@ class ProtocolItem : public SerializableItem_Map { private: static void initializeHashAuto(); public: - static const int protocolVersion = 6; + static const int protocolVersion = 7; static void initializeHash(); virtual int getItemId() const = 0; ProtocolItem(const QString &_itemType, const QString &_itemSubType); diff --git a/common/protocol_items.cpp b/common/protocol_items.cpp index d0ed4cfa..7f681569 100644 --- a/common/protocol_items.cpp +++ b/common/protocol_items.cpp @@ -147,9 +147,10 @@ Command_SetCardAttr::Command_SetCardAttr(int _gameId, const QString &_zone, int insertItem(new SerializableItem_String("attr_name", _attrName)); insertItem(new SerializableItem_String("attr_value", _attrValue)); } -Command_ReadyStart::Command_ReadyStart(int _gameId) +Command_ReadyStart::Command_ReadyStart(int _gameId, bool _ready) : GameCommand("ready_start", _gameId) { + insertItem(new SerializableItem_Bool("ready", _ready)); } Command_Concede::Command_Concede(int _gameId) : GameCommand("concede", _gameId) diff --git a/common/protocol_items.dat b/common/protocol_items.dat index 1ff77468..0f511799 100644 --- a/common/protocol_items.dat +++ b/common/protocol_items.dat @@ -23,7 +23,7 @@ 2:create_arrow:i,start_player_id:s,start_zone:i,start_card_id:i,target_player_id:s,target_zone:i,target_card_id:c,color 2:delete_arrow:i,arrow_id 2:set_card_attr:s,zone:i,card_id:s,attr_name:s,attr_value -2:ready_start +2:ready_start:b,ready 2:concede 2:inc_counter:i,counter_id:i,delta 2:create_counter:s,counter_name:c,color:i,radius:i,value diff --git a/common/protocol_items.h b/common/protocol_items.h index feb67947..43d8afd4 100644 --- a/common/protocol_items.h +++ b/common/protocol_items.h @@ -227,7 +227,8 @@ public: class Command_ReadyStart : public GameCommand { Q_OBJECT public: - Command_ReadyStart(int _gameId = -1); + Command_ReadyStart(int _gameId = -1, bool _ready = false); + bool getReady() const { return static_cast(itemMap.value("ready"))->getData(); }; static SerializableItem *newItem() { return new Command_ReadyStart; } int getItemId() const { return ItemId_Command_ReadyStart; } }; diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 5ae69afe..0d549591 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -365,6 +365,8 @@ ResponseCode Server_ProtocolHandler::cmdSetSideboardPlan(Command_SetSideboardPla { if (player->getSpectator()) return RespFunctionNotAllowed; + if (player->getReadyStart()) + return RespContextError; DeckList *deck = player->getDeck(); if (!deck) @@ -385,7 +387,7 @@ ResponseCode Server_ProtocolHandler::cmdConcede(Command_Concede * /*cmd*/, Comma return RespOk; } -ResponseCode Server_ProtocolHandler::cmdReadyStart(Command_ReadyStart * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player *player) +ResponseCode Server_ProtocolHandler::cmdReadyStart(Command_ReadyStart *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { if (player->getSpectator()) return RespFunctionNotAllowed; @@ -393,7 +395,10 @@ ResponseCode Server_ProtocolHandler::cmdReadyStart(Command_ReadyStart * /*cmd*/, if (!player->getDeck()) return RespContextError; - player->setReadyStart(true); + if (player->getReadyStart() == cmd->getReady()) + return RespContextError; + + player->setReadyStart(cmd->getReady()); game->sendGameEvent(new Event_PlayerPropertiesChanged(player->getProperties()), new Context_ReadyStart); game->startGameIfReady(); return RespOk; diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index 94b72ad4..5a3c427c 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -135,4 +135,4 @@ AuthenticationResult Servatrice::checkUserPassword(const QString &user, const QS return UnknownUser; } -const QString Servatrice::versionString = "Servatrice 0.20100526"; +const QString Servatrice::versionString = "Servatrice 0.20100603";