diff --git a/cockatrice/src/arrowitem.cpp b/cockatrice/src/arrowitem.cpp index 146b0d1b..cc4c67dc 100644 --- a/cockatrice/src/arrowitem.cpp +++ b/cockatrice/src/arrowitem.cpp @@ -154,7 +154,7 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) QList colliding = scene()->items(endPos); ArrowTarget *cursorItem = 0; - int cursorItemZ = -1; + qreal cursorItemZ = -1; for (int i = colliding.size() - 1; i >= 0; i--) if (qgraphicsitem_cast(colliding.at(i)) || qgraphicsitem_cast(colliding.at(i))) if (colliding.at(i)->zValue() > cursorItemZ) { @@ -243,11 +243,14 @@ void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) QList colliding = scene()->items(endPos); ArrowTarget *cursorItem = 0; + qreal cursorItemZ = -1; for (int i = colliding.size() - 1; i >= 0; i--) - if (qgraphicsitem_cast(colliding.at(i))) { - cursorItem = static_cast(colliding.at(i)); - break; - } + if (qgraphicsitem_cast(colliding.at(i))) + if (colliding.at(i)->zValue() > cursorItemZ) { + cursorItem = static_cast(colliding.at(i)); + cursorItemZ = cursorItem->zValue(); + } + if ((cursorItem != targetItem) && targetItem) targetItem->setBeingPointedAt(false); if (!cursorItem) { diff --git a/cockatrice/src/selectzone.cpp b/cockatrice/src/selectzone.cpp index fcc6017b..f3bafab1 100644 --- a/cockatrice/src/selectzone.cpp +++ b/cockatrice/src/selectzone.cpp @@ -33,6 +33,8 @@ void SelectZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void SelectZone::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) { + scene()->clearSelection(); + selectionOrigin = event->pos(); static_cast(scene())->startRubberBand(event->scenePos()); event->accept(); diff --git a/common/server_cardzone.cpp b/common/server_cardzone.cpp index 0ac064be..2ea5b8fb 100644 --- a/common/server_cardzone.cpp +++ b/common/server_cardzone.cpp @@ -82,11 +82,25 @@ int Server_CardZone::getFreeGridColumn(int x, int y, const QString &cardName) co coordMap.insert(cards[i]->getX(), cards[i]); int resultX = 0; - if (x != -1) { + if (x == -1) { + for (int i = 0; i < cards.size(); ++i) + if ((cards[i]->getName() == cardName) && !(cards[i]->getX() % 3) && (cards[i]->getY() == y)) { + if (!cards[i]->getAttachedCards().isEmpty()) + continue; + if (!coordMap.value(cards[i]->getX() + 1)) + return cards[i]->getX() + 1; + if (!coordMap.value(cards[i]->getX() + 2)) + return cards[i]->getX() + 2; + } + } else if (x == -2) { + } else { x = (x / 3) * 3; if (!coordMap.contains(x)) resultX = x; - else if (!coordMap.contains(x + 1)) + else if (!coordMap.value(x)->getAttachedCards().isEmpty()) { + resultX = x; + x = -1; + } else if (!coordMap.contains(x + 1)) resultX = x + 1; else if (!coordMap.contains(x + 2)) resultX = x + 2; @@ -94,22 +108,35 @@ int Server_CardZone::getFreeGridColumn(int x, int y, const QString &cardName) co resultX = x; x = -1; } - } else - for (int i = 0; i < cards.size(); ++i) - if ((cards[i]->getName() == cardName) && !(cards[i]->getX() % 3) && (cards[i]->getY() == y)) { - if (!coordMap.value(cards[i]->getX() + 1)) - return cards[i]->getX() + 1; - if (!coordMap.value(cards[i]->getX() + 2)) - return cards[i]->getX() + 2; - } + } - if (x == -1) + if (x < 0) while (coordMap.value(resultX)) resultX += 3; return resultX; } +bool Server_CardZone::isColumnStacked(int x, int y) const +{ + QMap coordMap; + for (int i = 0; i < cards.size(); ++i) + if (cards[i]->getY() == y) + coordMap.insert(cards[i]->getX(), cards[i]); + + return coordMap.contains((x / 3) * 3 + 1); +} + +bool Server_CardZone::isColumnEmpty(int x, int y) const +{ + QMap coordMap; + for (int i = 0; i < cards.size(); ++i) + if (cards[i]->getY() == y) + coordMap.insert(cards[i]->getX(), cards[i]); + + return !coordMap.contains((x / 3) * 3); +} + void Server_CardZone::moveCard(CommandContainer *cont, QMap &coordMap, Server_Card *card, int x, int y) { coordMap.remove(card->getX()); diff --git a/common/server_cardzone.h b/common/server_cardzone.h index bfc14353..c27d907a 100644 --- a/common/server_cardzone.h +++ b/common/server_cardzone.h @@ -50,6 +50,8 @@ public: Server_Player *getPlayer() const { return player; } int getFreeGridColumn(int x, int y, const QString &cardName) const; + bool isColumnEmpty(int x, int y) const; + bool isColumnStacked(int x, int y) const; void fixFreeSpaces(CommandContainer *cont, int x, int y); void moveCard(CommandContainer *cont, QMap &coordMap, Server_Card *card, int x, int y); QList cards; diff --git a/common/server_player.cpp b/common/server_player.cpp index 8293edca..92929554 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -217,9 +217,13 @@ ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *st return RespContextError; */ int position = -1; - Server_Card *card = startzone->getCard(_cardId, true, &position); + Server_Card *card = startzone->getCard(_cardId, false, &position); if (!card) return RespNameNotFound; + if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y)) + return RespContextError; + startzone->getCard(_cardId, true); + int oldX = card->getX(), oldY = card->getY(); if (startzone != targetzone) { @@ -246,10 +250,6 @@ ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *st } } - if (startzone->hasCoords()) { - - } - if (card->getDestroyOnZoneChange() && (startzone != targetzone)) { cont->enqueueGameEventPrivate(new Event_DestroyCard(getPlayerId(), startzone->getName(), card->getId()), game->getGameId()); cont->enqueueGameEventPublic(new Event_DestroyCard(getPlayerId(), startzone->getName(), card->getId()), game->getGameId()); diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index ae61a285..475c8b46 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -673,6 +673,9 @@ ResponseCode Server_ProtocolHandler::cmdAttachCard(Command_AttachCard *cmd, Comm for (int i = 0; i < attachedList.size(); ++i) player->unattachCard(cont, attachedList[i]); + if (targetzone->isColumnStacked(targetCard->getX(), targetCard->getY())) + targetPlayer->moveCard(cont, targetzone, targetCard->getId(), targetzone, targetzone->getFreeGridColumn(-2, targetCard->getY(), targetCard->getName()), targetCard->getY(), targetCard->getFaceDown(), false); + card->setParentCard(targetCard); card->setCoords(-1, card->getY()); cont->enqueueGameEventPrivate(new Event_AttachCard(player->getPlayerId(), startzone->getName(), card->getId(), targetPlayer->getPlayerId(), targetzone->getName(), targetCard->getId()), game->getGameId());