From c57e138a78afc618f69583a77e1d282e529bdb9f Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Tue, 20 Oct 2009 23:20:07 +0200 Subject: [PATCH] prepareGeometryChange bugfix; more arrows code --- cockatrice/src/arrowitem.cpp | 21 ++++--- cockatrice/src/arrowitem.h | 12 +++- cockatrice/src/client.cpp | 35 +++++++++-- cockatrice/src/client.h | 34 ++++++++++- cockatrice/src/game.cpp | 56 ++++++++++------- cockatrice/src/game.h | 2 + cockatrice/src/player.cpp | 89 +++++++++++++++++++++++++-- cockatrice/src/player.h | 8 +++ cockatrice/src/tablezone.cpp | 1 + servatrice/src/arrow.h | 6 +- servatrice/src/servergame.h | 2 +- servatrice/src/serversocket.cpp | 104 +++++++++++++++++++------------- servatrice/src/serversocket.h | 6 +- 13 files changed, 289 insertions(+), 87 deletions(-) diff --git a/cockatrice/src/arrowitem.cpp b/cockatrice/src/arrowitem.cpp index 054cc5f3..b6346b4e 100644 --- a/cockatrice/src/arrowitem.cpp +++ b/cockatrice/src/arrowitem.cpp @@ -7,8 +7,8 @@ #include #include -ArrowItem::ArrowItem(CardItem *_startItem, CardItem *_targetItem) - : QGraphicsItem(), startItem(_startItem), targetItem(_targetItem) +ArrowItem::ArrowItem(int _id, CardItem *_startItem, CardItem *_targetItem, const QColor &_color) + : QGraphicsItem(), id(_id), startItem(_startItem), targetItem(_targetItem), color(_color), fullColor(true) { setZValue(2000000005); if (startItem && targetItem) @@ -17,7 +17,6 @@ ArrowItem::ArrowItem(CardItem *_startItem, CardItem *_targetItem) void ArrowItem::updatePath() { - color = QColor(255, 0, 0, 200); QPointF endPoint = targetItem->mapToScene(QPointF(targetItem->boundingRect().width() / 2, targetItem->boundingRect().height() / 2)); updatePath(endPoint); } @@ -32,6 +31,7 @@ void ArrowItem::updatePath(const QPointF &endPoint) QLineF line(startPoint, endPoint); qreal lineLength = line.length(); + prepareGeometryChange(); if (lineLength < headLength) path = QPainterPath(); else { @@ -51,12 +51,17 @@ void ArrowItem::updatePath(const QPointF &endPoint) void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { - painter->setBrush(color); + QColor paintColor(color); + if (fullColor) + paintColor.setAlpha(200); + else + paintColor.setAlpha(150); + painter->setBrush(paintColor); painter->drawPath(path); } ArrowDragItem::ArrowDragItem(CardItem *_startItem) - : ArrowItem(_startItem) + : ArrowItem(-1, _startItem) { } @@ -71,10 +76,11 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) if ((cursorItem = qgraphicsitem_cast(colliding.at(i)))) break; if (!cursorItem) { + fullColor = false; targetItem = 0; updatePath(endPos); - color = QColor(190, 0, 0, 150); } else { + fullColor = true; targetItem = cursorItem; updatePath(); } @@ -92,7 +98,8 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/) startItem->getId(), targetZone->getPlayer()->getId(), targetZone->getName(), - targetItem->getId() + targetItem->getId(), + color ); } deleteLater(); diff --git a/cockatrice/src/arrowitem.h b/cockatrice/src/arrowitem.h index 1d8a054e..7850a498 100644 --- a/cockatrice/src/arrowitem.h +++ b/cockatrice/src/arrowitem.h @@ -11,14 +11,22 @@ class ArrowItem : public QObject, public QGraphicsItem { private: QPainterPath path; protected: - QColor color; + int id; CardItem *startItem, *targetItem; + QColor color; + bool fullColor; public: - ArrowItem(CardItem *_startItem = 0, CardItem *_targetItem = 0); + ArrowItem(int id, CardItem *_startItem = 0, CardItem *_targetItem = 0, const QColor &color = Qt::red); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QRectF boundingRect() const { return path.boundingRect(); } void updatePath(); void updatePath(const QPointF &endPoint); + + int getId() const { return id; } + void setStartItem(CardItem *_item) { startItem = _item; } + void setTargetItem(CardItem *_item) { targetItem = _item; } + CardItem *getStartItem() const { return startItem; } + CardItem *getTargetItem() const { return targetItem; } }; class ArrowDragItem : public ArrowItem { diff --git a/cockatrice/src/client.cpp b/cockatrice/src/client.cpp index 3b751c70..e333e574 100644 --- a/cockatrice/src/client.cpp +++ b/cockatrice/src/client.cpp @@ -23,6 +23,7 @@ ServerEventData::ServerEventData(const QString &line) eventHash.insert("move_card", eventMoveCard); eventHash.insert("create_token", eventCreateToken); eventHash.insert("create_arrow", eventCreateArrow); + eventHash.insert("delete_arrow", eventDeleteArrow); eventHash.insert("set_card_attr", eventSetCardAttr); eventHash.insert("add_counter", eventAddCounter); eventHash.insert("set_counter", eventSetCounter); @@ -110,6 +111,7 @@ void PendingCommand_DumpAll::responseReceived(ServerResponse resp) emit zoneListReceived(zoneList); emit cardListReceived(cardList); emit counterListReceived(counterList); + emit arrowListReceived(arrowList); } PendingCommand::responseReceived(resp); } @@ -319,8 +321,7 @@ void Client::readLine() } int cmdid = values.takeFirst().toInt(); PendingCommand *pc = pendingCommands.value(cmdid, 0); - int colorValue = values[3].toInt(); - ServerCounter sc(values[0].toInt(), values[1].toInt(), values[2], QColor(colorValue / 65536, (colorValue % 65536) / 256, colorValue % 256), values[4].toInt(), values[5].toInt()); + ServerCounter sc(values[0].toInt(), values[1].toInt(), values[2], numberToColor(values[3].toInt()), values[4].toInt(), values[5].toInt()); PendingCommand_ListCounters *pcLC = qobject_cast(pc); if (pcLC) @@ -332,6 +333,20 @@ void Client::readLine() else emit protocolError(); } + } else if (prefix == "list_arrows") { + if (values.size() != 10) { + emit protocolError(); + continue; + } + int cmdid = values.takeFirst().toInt(); + PendingCommand *pc = pendingCommands.value(cmdid, 0); + ServerArrow sa(values[0].toInt(), values[1].toInt(), values[2].toInt(), values[3], values[4].toInt(), values[5].toInt(), values[6], values[7].toInt(), numberToColor(values[8].toInt())); + + PendingCommand_DumpAll *pcDA = qobject_cast(pc); + if (pcDA) + pcDA->addArrow(sa); + else + emit protocolError(); } else emit protocolError(); } @@ -498,9 +513,9 @@ PendingCommand *Client::createToken(const QString &zone, const QString &name, co return cmd(QString("create_token|%1|%2|%3|%4|%5").arg(zone).arg(name).arg(powtough).arg(x).arg(y)); } -PendingCommand *Client::createArrow(int startPlayerId, const QString &startZone, int startCardId, int targetPlayerId, const QString &targetPlayerZone, int targetCardId) +PendingCommand *Client::createArrow(int startPlayerId, const QString &startZone, int startCardId, int targetPlayerId, const QString &targetPlayerZone, int targetCardId, const QColor &color) { - return cmd(QString("create_arrow|%1|%2|%3|%4|%5|%6").arg(startPlayerId).arg(startZone).arg(startCardId).arg(targetPlayerId).arg(targetPlayerZone).arg(targetCardId)); + return cmd(QString("create_arrow|%1|%2|%3|%4|%5|%6|%7").arg(startPlayerId).arg(startZone).arg(startCardId).arg(targetPlayerId).arg(targetPlayerZone).arg(targetCardId).arg(colorToNumber(color))); } PendingCommand *Client::setCardAttr(const QString &zone, int cardid, const QString &aname, const QString &avalue) @@ -529,7 +544,7 @@ PendingCommand *Client::incCounter(int counterId, int delta) PendingCommand *Client::addCounter(const QString &counterName, QColor color, int radius, int value) { - return cmd(QString("add_counter|%1|%2|%3|%4").arg(counterName).arg(color.red() * 65536 + color.green() * 256 + color.blue()).arg(radius).arg(value)); + return cmd(QString("add_counter|%1|%2|%3|%4").arg(counterName).arg(colorToNumber(color)).arg(radius).arg(value)); } PendingCommand *Client::setCounter(int counterId, int value) @@ -584,3 +599,13 @@ PendingCommand_DumpAll *Client::dumpAll() cmd("dump_all", pc); return pc; } + +QColor Client::numberToColor(int colorValue) const +{ + return QColor(colorValue / 65536, (colorValue % 65536) / 256, colorValue % 256); +} + +int Client::colorToNumber(const QColor &color) const +{ + return color.red() * 65536 + color.green() * 256 + color.blue(); +} diff --git a/cockatrice/src/client.h b/cockatrice/src/client.h index 4883d57d..0590196f 100644 --- a/cockatrice/src/client.h +++ b/cockatrice/src/client.h @@ -45,6 +45,7 @@ enum ServerEventType { eventMoveCard, eventCreateToken, eventCreateArrow, + eventDeleteArrow, eventSetCardAttr, eventAddCounter, eventSetCounter, @@ -195,6 +196,31 @@ public: int getCount() const { return count; } }; +class ServerArrow { +private: + int id; + int playerId; + int startPlayerId; + QString startZone; + int startCardId; + int targetPlayerId; + QString targetZone; + int targetCardId; + QColor color; +public: + ServerArrow(int _playerId, int _id, int _startPlayerId, const QString &_startZone, int _startCardId, int _targetPlayerId, const QString &_targetZone, int _targetCardId, const QColor &_color) + : id(_id), playerId(_playerId), startPlayerId(_startPlayerId), startZone(_startZone), startCardId(_startCardId), targetPlayerId(_targetPlayerId), targetZone(_targetZone), targetCardId(_targetCardId), color(_color) { } + int getId() const { return id; } + int getPlayerId() const { return playerId; } + int getStartPlayerId() const { return startPlayerId; } + QString getStartZone() const { return startZone; } + int getStartCardId() const { return startCardId; } + int getTargetPlayerId() const { return targetPlayerId; } + QString getTargetZone() const { return targetZone; } + int getTargetCardId() const { return targetCardId; } + QColor getColor() const { return color; } +}; + class PendingCommand : public QObject { Q_OBJECT private: @@ -288,17 +314,20 @@ private: QList zoneList; QList cardList; QList counterList; + QList arrowList; signals: void playerListReceived(QList _playerList); void zoneListReceived(QList _zoneList); void cardListReceived(QList _cardList); void counterListReceived(QList _counterList); + void arrowListReceived(QList _arrowList); public: void responseReceived(ServerResponse resp); void addPlayer(const ServerPlayer &player) { playerList.append(player); } void addZone(const ServerZone &zone) { zoneList.append(zone); } void addCard(const ServerZoneCard &card) { cardList.append(card); } void addCounter(const ServerCounter &counter) { counterList.append(counter); } + void addArrow(const ServerArrow &arrow) { arrowList.append(arrow); } }; class Client : public QObject { @@ -346,6 +375,9 @@ public: void connectToServer(const QString &hostname, unsigned int port, const QString &_playerName, const QString &_password); void disconnectFromServer(); + + QColor numberToColor(int colorValue) const; + int colorToNumber(const QColor &color) const; public slots: PendingCommand *chatListChannels(); PendingCommand_ChatJoinChannel *chatJoinChannel(const QString &name); @@ -364,7 +396,7 @@ public slots: PendingCommand *drawCards(unsigned int number); PendingCommand *moveCard(int cardid, const QString &startzone, const QString &targetzone, int x, int y = 0, bool faceDown = false); PendingCommand *createToken(const QString &zone, const QString &name, const QString &powtough, int x, int y); - PendingCommand *createArrow(int startPlayerId, const QString &startZone, int startCardId, int targetPlayerId, const QString &targetPlayerZone, int targetCardId); + PendingCommand *createArrow(int startPlayerId, const QString &startZone, int startCardId, int targetPlayerId, const QString &targetPlayerZone, int targetCardId, const QColor &color); PendingCommand *setCardAttr(const QString &zone, int cardid, const QString &aname, const QString &avalue); PendingCommand *readyStart(); PendingCommand *incCounter(int counterId, int delta); diff --git a/cockatrice/src/game.cpp b/cockatrice/src/game.cpp index 9f3cbc6e..5f215a0a 100644 --- a/cockatrice/src/game.cpp +++ b/cockatrice/src/game.cpp @@ -137,6 +137,7 @@ Player *Game::addPlayer(int playerId, const QString &playerName, bool local) connect(newPlayer, SIGNAL(logSetCardCounters(Player *, QString, int, int)), this, SIGNAL(logSetCardCounters(Player *, QString, int, int))); connect(newPlayer, SIGNAL(logSetTapped(Player *, QString, bool)), this, SIGNAL(logSetTapped(Player *, QString, bool))); connect(newPlayer, SIGNAL(logSetCounter(Player *, QString, int, int)), this, SIGNAL(logSetCounter(Player *, QString, int, int))); + connect(newPlayer, SIGNAL(logCreateArrow(Player *, Player *, QString, Player *, QString)), this, SIGNAL(logCreateArrow(Player *, Player *, QString, Player *, QString))); connect(newPlayer, SIGNAL(logSetDoesntUntap(Player *, QString, bool)), this, SIGNAL(logSetDoesntUntap(Player *, QString, bool))); players.insert(playerId, newPlayer); @@ -203,6 +204,36 @@ void Game::counterListReceived(QList list) } } +void Game::arrowListReceived(QList list) +{ + QMapIterator i(players); + while (i.hasNext()) + i.next().value()->clearArrows(); + + for (int i = 0; i < list.size(); ++i) { + Player *p = players.value(list[i].getPlayerId(), 0); + if (!p) + continue; + + Player *startPlayer = players.value(list[i].getStartPlayerId(), 0); + Player *targetPlayer = players.value(list[i].getTargetPlayerId(), 0); + if (!startPlayer || !targetPlayer) + continue; + + CardZone *startZone = startPlayer->getZones().value(list[i].getStartZone(), 0); + CardZone *targetZone = targetPlayer->getZones().value(list[i].getTargetZone(), 0); + if (!startZone || !targetZone) + continue; + + CardItem *startCard = startZone->getCard(list[i].getStartCardId(), QString()); + CardItem *targetCard = targetZone->getCard(list[i].getTargetCardId(), QString()); + if (!startCard || !targetCard) + continue; + + p->addArrow(list[i].getId(), startCard, targetCard, list[i].getColor()); + } +} + void Game::playerListReceived(QList playerList) { QStringList nameList; @@ -321,26 +352,8 @@ void Game::gameEvent(const ServerEventData &msg) } break; } - case eventCreateArrow: { - const QStringList &data = msg.getEventData(); - Player *startPlayer = players.value(data[0].toInt(), 0); - Player *targetPlayer = players.value(data[3].toInt(), 0); - if (!startPlayer || !targetPlayer) - break; - CardZone *startZone = startPlayer->getZones().value(data[1], 0); - CardZone *targetZone = targetPlayer->getZones().value(data[4], 0); - if (!startZone || !targetZone) - break; - CardItem *startCard = startZone->getCard(data[2].toInt(), QString()); - CardItem *targetCard = targetZone->getCard(data[5].toInt(), QString()); - if (!startCard || !targetCard) - break; - - emit logCreateArrow(p, startPlayer, startCard->getName(), targetPlayer, targetCard->getName()); - ArrowItem *arrow = new ArrowItem(startCard, targetCard); - scene->addItem(arrow); - break; - } + case eventCreateArrow: + case eventDeleteArrow: case eventCreateToken: case eventSetupZones: case eventSetCardAttr: @@ -512,6 +525,7 @@ void Game::queryGameState() connect(pc, SIGNAL(zoneListReceived(QList)), this, SLOT(zoneListReceived(QList))); connect(pc, SIGNAL(cardListReceived(QList)), this, SLOT(cardListReceived(QList))); connect(pc, SIGNAL(counterListReceived(QList)), this, SLOT(counterListReceived(QList))); + connect(pc, SIGNAL(arrowListReceived(QList)), this, SLOT(arrowListReceived(QList))); } void Game::activePlayerDrawCard() @@ -543,4 +557,4 @@ Player *Game::getActiveLocalPlayer() const return p; } return 0; -} +} \ No newline at end of file diff --git a/cockatrice/src/game.h b/cockatrice/src/game.h index 07d7544c..ced6a399 100644 --- a/cockatrice/src/game.h +++ b/cockatrice/src/game.h @@ -68,6 +68,7 @@ private slots: void cardListReceived(QList list); void zoneListReceived(QList list); void counterListReceived(QList list); + void arrowListReceived(QList list); void readyStart(); signals: @@ -107,6 +108,7 @@ public: void restartGameDialog(); void hoverCardEvent(CardItem *card); Player *addPlayer(int playerId, const QString &playerName, bool local); + const QMap &getPlayers() const { return players; } void queryGameState(); }; diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 05d3ffda..68f0ef53 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -2,6 +2,7 @@ #include "client.h" #include "cardzone.h" #include "counter.h" +#include "arrowitem.h" #include "zoneviewzone.h" #include "zoneviewwidget.h" #include "game.h" @@ -205,6 +206,7 @@ Player::~Player() delete i.next().value(); clearCounters(); + clearArrows(); delete playerMenu; } @@ -428,6 +430,7 @@ void Player::gameEvent(const ServerEventData &event) } clearCounters(); + clearArrows(); CardZone *deck = zones.value("deck"); for (; deck_cards; deck_cards--) @@ -486,11 +489,9 @@ void Player::gameEvent(const ServerEventData &event) break; } - int x = data[5].toInt(); int y = data[6].toInt(); bool facedown = data[7].toInt(); - // XXX Mehr Fehlerbehandlung int logPosition = position; int logX = x; @@ -499,9 +500,11 @@ void Player::gameEvent(const ServerEventData &event) if (x == -1) x = 0; CardItem *card = startZone->takeCard(position, cardId, cardName, startZone != targetZone); - if (!card) // XXX + if (!card) { qDebug("moveCard: card not found"); - + break; + } + card->deleteDragItem(); card->setFaceDown(facedown); @@ -512,6 +515,27 @@ void Player::gameEvent(const ServerEventData &event) targetZone->addCard(card, true, x, y); + // Look at all arrows from and to the card. + // If the card was moved to another zone, delete the arrows, otherwise update them. + QMapIterator playerIterator(static_cast(parent())->getPlayers()); + while (playerIterator.hasNext()) { + Player *p = playerIterator.next().value(); + + QList arrowsToDelete; + QMapIterator arrowIterator(p->getArrows()); + while (arrowIterator.hasNext()) { + ArrowItem *arrow = arrowIterator.next().value(); + if ((arrow->getStartItem() == card) || (arrow->getTargetItem() == card)) { + if (startZone == targetZone) + arrow->updatePath(); + else + arrowsToDelete.append(arrow->getId()); + } + } + for (int i = 0; i < arrowsToDelete.size(); ++i) + p->delArrow(arrowsToDelete[i]); + } + break; } case eventCreateToken: { @@ -582,6 +606,39 @@ void Player::gameEvent(const ServerEventData &event) emit logSetCounter(this, c->getName(), value, oldValue); break; } + case eventCreateArrow: { + if (data.size() != 8) + break; + + const QMap &playerList = static_cast(parent())->getPlayers(); + + Player *startPlayer = playerList.value(data[1].toInt(), 0); + Player *targetPlayer = playerList.value(data[4].toInt(), 0); + if (!startPlayer || !targetPlayer) + return; + + CardZone *startZone = startPlayer->getZones().value(data[2], 0); + CardZone *targetZone = targetPlayer->getZones().value(data[5], 0); + if (!startZone || !targetZone) + return; + + CardItem *startCard = startZone->getCard(data[3].toInt(), QString()); + CardItem *targetCard = targetZone->getCard(data[6].toInt(), QString()); + if (!startCard || !targetCard) + return; + + addArrow(data[0].toInt(), startCard, targetCard, client->numberToColor(data[7].toInt())); + emit logCreateArrow(this, startPlayer, startCard->getName(), targetPlayer, targetCard->getName()); + + break; + } + case eventDeleteArrow: { + if (data.size() != 1) + break; + + delArrow(data[0].toInt()); + break; + } default: qDebug("unhandled player event"); } @@ -666,6 +723,30 @@ void Player::clearCounters() counters.clear(); } +void Player::addArrow(int arrowId, CardItem *startCard, CardItem *targetCard, const QColor &color) +{ + ArrowItem *arrow = new ArrowItem(arrowId, startCard, targetCard, color); + arrows.insert(arrowId, arrow); + scene()->addItem(arrow); +} + +void Player::delArrow(int arrowId) +{ + ArrowItem *a = arrows.value(arrowId, 0); + if (!a) + return; + arrows.remove(arrowId); + delete a; +} + +void Player::clearArrows() +{ + QMapIterator arrowIterator(arrows); + while (arrowIterator.hasNext()) + delete arrowIterator.next().value(); + arrows.clear(); +} + void Player::rearrangeCounters() { qreal marginTop = 50; diff --git a/cockatrice/src/player.h b/cockatrice/src/player.h index 03469bfd..f1779327 100644 --- a/cockatrice/src/player.h +++ b/cockatrice/src/player.h @@ -14,6 +14,7 @@ class QAction; class ZoneViewZone; class Game; class Counter; +class ArrowItem; class CardZone; class TableZone; class HandZone; @@ -32,6 +33,7 @@ signals: void logSetCardCounters(Player *player, QString cardName, int value, int oldValue); void logSetTapped(Player *player, QString cardName, bool tapped); void logSetCounter(Player *player, QString counterName, int value, int oldValue); + void logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard); void logSetDoesntUntap(Player *player, QString cardName, bool doesntUntap); void sizeChanged(); @@ -80,6 +82,7 @@ private: QRectF bRect; QMap counters; + QMap arrows; void rearrangeCounters(); void initSayMenu(); @@ -94,6 +97,10 @@ public: void addCounter(int counterId, const QString &name, QColor color, int radius, int value); void delCounter(int counterId); void clearCounters(); + + void addArrow(int arrowId, CardItem *startCard, CardItem *targetCard, const QColor &color); + void delArrow(int arrowId); + void clearArrows(); Client *client; void addZone(CardZone *z); @@ -105,6 +112,7 @@ public: QString getName() const { return name; } bool getLocal() const { return local; } const QMap &getZones() const { return zones; } + const QMap &getArrows() const { return arrows; } TableZone *getTable() const { return table; } void gameEvent(const ServerEventData &event); CardDatabase *getDb() const { return db; } diff --git a/cockatrice/src/tablezone.cpp b/cockatrice/src/tablezone.cpp index 535d541d..619b0a45 100644 --- a/cockatrice/src/tablezone.cpp +++ b/cockatrice/src/tablezone.cpp @@ -109,6 +109,7 @@ void TableZone::resizeToContents() xMax = minWidth; int newWidth = xMax + 2 * marginX; if (newWidth != width) { + prepareGeometryChange(); width = newWidth; emit sizeChanged(); } diff --git a/servatrice/src/arrow.h b/servatrice/src/arrow.h index 9b5c7e8c..65d34b40 100644 --- a/servatrice/src/arrow.h +++ b/servatrice/src/arrow.h @@ -5,11 +5,13 @@ class Card; class Arrow { private: + int id; Card *startCard, *targetCard; int color; public: - Arrow(Card *_startCard, Card *_targetCard, int _color) - : startCard(_startCard), targetCard(_targetCard), color(_color) { } + Arrow(int _id, Card *_startCard, Card *_targetCard, int _color) + : id(_id), startCard(_startCard), targetCard(_targetCard), color(_color) { } + int getId() const { return id; } Card *getStartCard() const { return startCard; } Card *getTargetCard() const { return targetCard; } int getColor() const { return color; } diff --git a/servatrice/src/servergame.h b/servatrice/src/servergame.h index 7ba666ff..23bca6c4 100644 --- a/servatrice/src/servergame.h +++ b/servatrice/src/servergame.h @@ -49,13 +49,13 @@ public: bool getGameStarted() const { return gameStarted; } int getPlayerCount() const { return players.size(); } const QList &getPlayers() const { return players; } + ServerSocket *getPlayer(int playerId); int getGameId() const { return gameId; } QString getDescription() const { return description; } QString getPassword() const { return password; } int getMaxPlayers() const { return maxPlayers; } bool getSpectatorsAllowed() const { return spectatorsAllowed; } QString getGameListLine() const; - ServerSocket *getPlayer(int playerId); ReturnMessage::ReturnCode checkJoin(const QString &_password, bool spectator); void addPlayer(ServerSocket *player, bool spectator); void removePlayer(ServerSocket *player); diff --git a/servatrice/src/serversocket.cpp b/servatrice/src/serversocket.cpp index d6fcf33f..9d3e0aef 100644 --- a/servatrice/src/serversocket.cpp +++ b/servatrice/src/serversocket.cpp @@ -93,11 +93,6 @@ ServerSocket::ServerSocket(Server *_server, QObject *parent) << QVariant::Int << QVariant::Int, &ServerSocket::cmdCreateArrow)); commandHash.insert("delete_arrow", CommandProperties(true, true, true, false, QList() - << QVariant::Int - << QVariant::String - << QVariant::Int - << QVariant::Int - << QVariant::String << QVariant::Int, &ServerSocket::cmdDeleteArrow)); commandHash.insert("set_card_attr", CommandProperties(true, true, true, false, QList() << QVariant::String @@ -173,6 +168,18 @@ int ServerSocket::newCounterId() const return id + 1; } +int ServerSocket::newArrowId() const +{ + int id = 0; + QMapIterator i(arrows); + while (i.hasNext()) { + Arrow *a = i.next().value(); + if (a->getId() > id) + id = a->getId(); + } + return id + 1; +} + PlayerZone *ServerSocket::getZone(const QString &name) const { QListIterator ZoneIterator(zones); @@ -233,8 +240,9 @@ void ServerSocket::clearZones() delete counterIterator.next().value(); counters.clear(); - for (int i = 0; i < arrows.size(); i++) - delete arrows.at(i); + QMapIterator arrowIterator(arrows); + while (arrowIterator.hasNext()) + delete arrowIterator.next().value(); arrows.clear(); } @@ -248,6 +256,16 @@ void ServerSocket::leaveGame() clearZones(); } +bool ServerSocket::deleteArrow(int arrowId) +{ + Arrow *arrow = arrows.value(arrowId, 0); + if (!arrow) + return false; + arrows.remove(arrowId); + delete arrow; + return true; +} + void ServerSocket::readClient() { while (canReadLine()) { @@ -556,6 +574,23 @@ ReturnMessage::ReturnCode ServerSocket::cmdMoveCard(const QList ¶m .arg(targetzone->getName()) .arg(x) .arg(y), this); + + // If the card was moved to another zone, delete all arrows from and to the card + if (startzone != targetzone) { + const QList &players = game->getPlayers(); + for (int i = 0; i < players.size(); ++i) { + QList arrowsToDelete; + QMapIterator arrowIterator(players[i]->getArrows()); + while (arrowIterator.hasNext()) { + Arrow *arrow = arrowIterator.next().value(); + if ((arrow->getStartCard() == card) || (arrow->getTargetCard() == card)) + arrowsToDelete.append(arrow->getId()); + } + for (int j = 0; j < arrowsToDelete.size(); ++j) + players[i]->deleteArrow(arrowsToDelete[j]); + } + } + return ReturnMessage::ReturnOk; } @@ -597,13 +632,18 @@ ReturnMessage::ReturnCode ServerSocket::cmdCreateArrow(const QList &pa Card *targetCard = targetZone->getCard(params[5].toInt(), false); if (!startCard || !targetCard || (startCard == targetCard)) return ReturnMessage::ReturnContextError; - for (int i = 0; i < arrows.size(); ++i) - if ((arrows[i]->getStartCard() == startCard) && (arrows[i]->getTargetCard() == targetCard)) + QMapIterator arrowIterator(arrows); + while (arrowIterator.hasNext()) { + Arrow *temp = arrowIterator.next().value(); + if ((temp->getStartCard() == startCard) && (temp->getTargetCard() == targetCard)) return ReturnMessage::ReturnContextError; + } int color = params[6].toInt(); - arrows.append(new Arrow(startCard, targetCard, color)); - emit broadcastEvent(QString("create_arrow|%1|%2|%3|%4|%5|%6|%7") + Arrow *arrow = new Arrow(newArrowId(), startCard, targetCard, color); + arrows.insert(arrow->getId(), arrow); + emit broadcastEvent(QString("create_arrow|%1|%2|%3|%4|%5|%6|%7|%8") + .arg(arrow->getId()) .arg(startPlayer->getPlayerId()) .arg(startZone->getName()) .arg(startCard->getId()) @@ -617,34 +657,11 @@ ReturnMessage::ReturnCode ServerSocket::cmdCreateArrow(const QList &pa ReturnMessage::ReturnCode ServerSocket::cmdDeleteArrow(const QList ¶ms) { - ServerSocket *startPlayer = game->getPlayer(params[0].toInt()); - ServerSocket *targetPlayer = game->getPlayer(params[3].toInt()); - if (!startPlayer || !targetPlayer) - return ReturnMessage::ReturnContextError; - PlayerZone *startZone = startPlayer->getZone(params[1].toString()); - PlayerZone *targetZone = targetPlayer->getZone(params[4].toString()); - if (!startZone || !targetZone) - return ReturnMessage::ReturnContextError; - Card *startCard = startZone->getCard(params[2].toInt(), false); - Card *targetCard = targetZone->getCard(params[5].toInt(), false); - - Arrow *arrow = 0; - for (int i = 0; i < arrows.size(); ++i) - if ((arrows[i]->getStartCard() == startCard) && (arrows[i]->getTargetCard() == targetCard)) { - arrow = arrows.takeAt(i); - break; - } - if (!arrow) + int arrowId = params[0].toInt(); + if (!deleteArrow(arrowId)) return ReturnMessage::ReturnContextError; - emit broadcastEvent(QString("delete_arrow|%1|%2|%3|%4|%5|%6") - .arg(startPlayer->getPlayerId()) - .arg(startZone->getName()) - .arg(startCard->getId()) - .arg(targetPlayer->getPlayerId()) - .arg(targetZone->getName()) - .arg(targetCard->getId()), this - ); + emit broadcastEvent(QString("delete_arrow|%1").arg(arrowId), this); return ReturnMessage::ReturnOk; } @@ -866,15 +883,18 @@ ReturnMessage::ReturnCode ServerSocket::cmdSetActivePhase(const QList QStringList ServerSocket::listArrowsHelper(ServerSocket *player) { QStringList result; - const QList &arrowList = player->getArrows(); - for (int i = 0; i < arrowList.size(); ++i) { - Card *startCard = arrowList[i]->getStartCard(); - Card *targetCard = arrowList[i]->getTargetCard(); + QMapIterator arrowIterator(player->getArrows()); + while (arrowIterator.hasNext()) { + Arrow *arrow = arrowIterator.next().value(); + + Card *startCard = arrow->getStartCard(); + Card *targetCard = arrow->getTargetCard(); PlayerZone *startZone = startCard->getZone(); PlayerZone *targetZone = targetCard->getZone(); ServerSocket *startPlayer = startZone->getPlayer(); ServerSocket *targetPlayer = targetZone->getPlayer(); - result << QString("%1|%2|%3|%4|%5|%6|%7").arg(startPlayer->getPlayerName()).arg(startZone->getName()).arg(startCard->getId()).arg(targetPlayer->getPlayerName()).arg(targetZone->getName()).arg(targetCard->getId()).arg(arrowList[i]->getColor()); + + result << QString("%1|%2|%3|%4|%5|%6|%7|%8|%9").arg(player->getPlayerId()).arg(arrow->getId()).arg(startPlayer->getPlayerId()).arg(startZone->getName()).arg(startCard->getId()).arg(targetPlayer->getPlayerId()).arg(targetZone->getName()).arg(targetCard->getId()).arg(arrow->getColor()); } return result; } diff --git a/servatrice/src/serversocket.h b/servatrice/src/serversocket.h index d2fefed5..8b06047b 100644 --- a/servatrice/src/serversocket.h +++ b/servatrice/src/serversocket.h @@ -115,13 +115,14 @@ private: QList SideboardList; QList zones; QMap counters; - QList arrows; + QMap arrows; int playerId; QString playerName; bool spectator; int nextCardId; int newCardId(); int newCounterId() const; + int newArrowId() const; PlayerZone *getZone(const QString &name) const; void clearZones(); bool parseCommand(QString line); @@ -149,7 +150,8 @@ public: bool getAcceptsChatChannelListChanges() const { return acceptsChatChannelListChanges; } const QList &getZones() const { return zones; } const QMap &getCounters() const { return counters; } - const QList &getArrows() const { return arrows; } + const QMap &getArrows() const { return arrows; } + bool deleteArrow(int arrowId); void setupZones(); };