diff --git a/cockatrice/src/tablezone.cpp b/cockatrice/src/tablezone.cpp index 4d52cf93..66482e92 100644 --- a/cockatrice/src/tablezone.cpp +++ b/cockatrice/src/tablezone.cpp @@ -19,7 +19,7 @@ TableZone::TableZone(Player *_p, QGraphicsItem *parent) if (settingsCache->getEconomicalGrid()) height = 2 * boxLineWidth + (int) (11.0 / 3 * CARD_HEIGHT + 2 * paddingY); else - height = 2 * boxLineWidth + 3 * CARD_HEIGHT + 2 * paddingY; + height = 2 * boxLineWidth + 3 * (CARD_HEIGHT + 20) + 2 * paddingY; width = minWidth + 2 * marginX + 2 * boxLineWidth; currentMinimumWidth = minWidth; @@ -52,7 +52,7 @@ void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem */*optio else painter->fillRect(boundingRect(), QBrush(bgPixmap)); painter->setPen(QColor(255, 255, 255, 40)); - qreal separatorY = 2 * (CARD_HEIGHT + paddingY) + boxLineWidth - paddingY / 2; + qreal separatorY = 2 * (CARD_HEIGHT + 20 + paddingY) + boxLineWidth - paddingY / 2; if (isInverted()) separatorY = height - separatorY; painter->drawLine(QPointF(0, separatorY), QPointF(width, separatorY)); @@ -103,13 +103,27 @@ void TableZone::reorganizeCards() QList arrowsToUpdate; // Calculate table grid distortion so that the mapping functions work properly - gridPointWidth.clear(); + QMap gridPointStackCount; for (int i = 0; i < cards.size(); ++i) { - QPoint gridPoint = cards[i]->getGridPos(); + const QPoint &gridPoint = cards[i]->getGridPos(); if (gridPoint.x() == -1) continue; - gridPointWidth.insert(gridPoint.x() + gridPoint.y() * 1000, CARD_WIDTH * (1 + cards[i]->getAttachedCards().size() / 3.0)); + const int key = gridPoint.x() / 3 + gridPoint.y() * 1000; + gridPointStackCount.insert(key, gridPointStackCount.value(key, 0) + 1); + } + gridPointWidth.clear(); + for (int i = 0; i < cards.size(); ++i) { + const QPoint &gridPoint = cards[i]->getGridPos(); + if (gridPoint.x() == -1) + continue; + + const int key = gridPoint.x() / 3 + gridPoint.y() * 1000; + const int stackCount = gridPointStackCount.value(key, 0); + if (stackCount == 1) + gridPointWidth.insert(key, CARD_WIDTH * (1 + cards[i]->getAttachedCards().size() / 3.0)); + else + gridPointWidth.insert(key, CARD_WIDTH * (1 + (stackCount - 1) / 3.0)); } for (int i = 0; i < cards.size(); ++i) { @@ -216,16 +230,12 @@ CardItem *TableZone::getCardFromCoords(const QPointF &point) const QPointF TableZone::mapFromGrid(const QPoint &gridPoint) const { qreal x, y; - if ((gridPoint.y() == 2) && (settingsCache->getEconomicalGrid())) { - x = marginX + (CARD_WIDTH * gridPoint.x() + CARD_WIDTH * (gridPoint.x() / 3)) / 2; - y = boxLineWidth + (CARD_HEIGHT + paddingY) * gridPoint.y() + (gridPoint.x() % 3 * CARD_HEIGHT) / 3; - } else { - x = marginX + 0.5 * CARD_WIDTH * gridPoint.x(); - for (int i = 0; i < gridPoint.x(); ++i) - x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH); - - y = boxLineWidth + (CARD_HEIGHT + paddingY) * gridPoint.y(); - } + x = marginX + (gridPoint.x() % 3) * CARD_WIDTH / 3.0; + for (int i = 0; i < gridPoint.x() / 3; ++i) + x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH) + paddingX; + + y = boxLineWidth + gridPoint.y() * (CARD_HEIGHT + paddingY + 20) + (gridPoint.x() % 3) * 10; + if (isInverted()) y = height - CARD_HEIGHT - y; @@ -238,7 +248,7 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const qreal y = mapPoint.y(); if (isInverted()) y = height - y; - y += paddingY / 2 - boxLineWidth; + y -= boxLineWidth; if (x < 0) x = 0; @@ -249,27 +259,24 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const else if (y > height - CARD_HEIGHT) y = height - CARD_HEIGHT; - int resultY = (int) (y / (CARD_HEIGHT + paddingY)); + int resultY = round(y / (CARD_HEIGHT + paddingY + 20)); - if ((resultY == 2) && (settingsCache->getEconomicalGrid())) - return QPoint( - (int) (x * 2 / CARD_WIDTH - floor(x / (2 * CARD_WIDTH))), - 2 - ); - else { - int resultX = -1; - qreal tempX = 0; - do { - ++resultX; - tempX += gridPointWidth.value(resultY * 1000 + resultX, CARD_WIDTH) + 0.5 * CARD_WIDTH; - } while (tempX < x + 1); - return QPoint(resultX, resultY); - } + int baseX = -1; + qreal oldTempX = 0, tempX = 0; + do { + ++baseX; + oldTempX = tempX; + tempX += gridPointWidth.value(resultY * 1000 + baseX, CARD_WIDTH) + paddingX; + } while (tempX < x + 1); + + qreal xdiff = x - oldTempX; + int resultX = baseX * 3 + qMin((int) floor(xdiff * 3 / CARD_WIDTH), 2); + return QPoint(resultX, resultY); } QPointF TableZone::closestGridPoint(const QPointF &point) { - return mapFromGrid(mapToGrid(point + QPoint(CARD_WIDTH / 2, CARD_HEIGHT / 2))); + return mapFromGrid(mapToGrid(point + QPoint(1, 1))); } void TableZone::setWidth(qreal _width) diff --git a/cockatrice/src/tablezone.h b/cockatrice/src/tablezone.h index 9f9f0650..b881bb81 100644 --- a/cockatrice/src/tablezone.h +++ b/cockatrice/src/tablezone.h @@ -9,7 +9,8 @@ signals: void sizeChanged(); private: static const int boxLineWidth = 10; - static const int paddingY = 20; + static const int paddingX = 20; + static const int paddingY = 10; static const int marginX = 20; static const int minWidth = 15 * CARD_WIDTH / 2; diff --git a/common/server_cardzone.cpp b/common/server_cardzone.cpp index 07a56c15..0ac064be 100644 --- a/common/server_cardzone.cpp +++ b/common/server_cardzone.cpp @@ -19,6 +19,7 @@ ***************************************************************************/ #include "server_cardzone.h" #include "server_card.h" +#include "server_player.h" #include "rng_abstract.h" Server_CardZone::Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ZoneType _type) @@ -73,24 +74,68 @@ Server_Card *Server_CardZone::getCard(int id, bool remove, int *position) } } -int Server_CardZone::getFreeGridColumn(int y) const +int Server_CardZone::getFreeGridColumn(int x, int y, const QString &cardName) const { - int x = 0; + QMap coordMap; + for (int i = 0; i < cards.size(); ++i) + if (cards[i]->getY() == y) + coordMap.insert(cards[i]->getX(), cards[i]); - // Stupid algorithm. For large numbers of cards, it would be more - // efficient to sort the cards by their x value and only need to iterate once. - bool occupied; - do { - occupied = false; + int resultX = 0; + if (x != -1) { + x = (x / 3) * 3; + if (!coordMap.contains(x)) + resultX = x; + else if (!coordMap.contains(x + 1)) + resultX = x + 1; + else if (!coordMap.contains(x + 2)) + resultX = x + 2; + else { + resultX = x; + x = -1; + } + } else for (int i = 0; i < cards.size(); ++i) - if ((cards[i]->getY() == y) && (cards[i]->getX() == x)) { - occupied = true; - ++x; - break; + 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; } - } while (occupied); - return x; + if (x == -1) + while (coordMap.value(resultX)) + resultX += 3; + + return resultX; +} + +void Server_CardZone::moveCard(CommandContainer *cont, QMap &coordMap, Server_Card *card, int x, int y) +{ + coordMap.remove(card->getX()); + player->moveCard(cont, this, card->getId(), this, x, y, card->getFaceDown(), false); + coordMap.insert(x, card); +} + +void Server_CardZone::fixFreeSpaces(CommandContainer *cont, int x, int y) +{ + QMap coordMap; + for (int i = 0; i < cards.size(); ++i) + if (cards[i]->getY() == y) + coordMap.insert(cards[i]->getX(), cards[i]); + + int baseX = (x / 3) * 3; + if (!coordMap.contains(baseX)) { + if (coordMap.contains(baseX + 1)) + moveCard(cont, coordMap, coordMap.value(baseX + 1), baseX, y); + else if (coordMap.contains(baseX + 2)) { + moveCard(cont, coordMap, coordMap.value(baseX + 2), baseX, y); + return; + } else + return; + } + if (!coordMap.contains(baseX + 1) && coordMap.contains(baseX + 2)) + moveCard(cont, coordMap, coordMap.value(baseX + 2), baseX + 1, y); } void Server_CardZone::insertCard(Server_Card *card, int x, int y) diff --git a/common/server_cardzone.h b/common/server_cardzone.h index fa35a728..bfc14353 100644 --- a/common/server_cardzone.h +++ b/common/server_cardzone.h @@ -26,6 +26,8 @@ class Server_Card; class Server_Player; +class Server_Game; +class CommandContainer; class Server_CardZone { private: @@ -47,7 +49,9 @@ public: QString getName() const { return name; } Server_Player *getPlayer() const { return player; } - int getFreeGridColumn(int y) const; + int getFreeGridColumn(int x, int y, const QString &cardName) const; + void fixFreeSpaces(CommandContainer *cont, int x, int y); + void moveCard(CommandContainer *cont, QMap &coordMap, Server_Card *card, int x, int y); QList cards; void insertCard(Server_Card *card, int x, int y); void shuffle(); diff --git a/common/server_player.cpp b/common/server_player.cpp index ebc34b43..8293edca 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -198,6 +198,175 @@ bool Server_Player::deleteCounter(int counterId) return true; } +ResponseCode Server_Player::moveCard(CommandContainer *cont, const QString &_startZone, int _cardId, const QString &_targetZone, int x, int y, bool faceDown, bool tapped) +{ + Server_CardZone *startzone = getZones().value(_startZone); + Server_CardZone *targetzone = getZones().value(_targetZone); + if ((!startzone) || (!targetzone)) + return RespNameNotFound; + + return moveCard(cont, startzone, _cardId, targetzone, x, y, faceDown, tapped); +} + +ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *startzone, int _cardId, Server_CardZone *targetzone, int x, int y, bool faceDown, bool tapped) +{ + // Collision detection +/* if (targetzone->hasCoords()) + for (int i = 0; i < targetzone->cards.size(); ++i) + if ((targetzone->cards[i]->getX() == x) && (targetzone->cards[i]->getY() == y) && (x != -1)) + return RespContextError; +*/ + int position = -1; + Server_Card *card = startzone->getCard(_cardId, true, &position); + if (!card) + return RespNameNotFound; + int oldX = card->getX(), oldY = card->getY(); + + if (startzone != targetzone) { + // Delete all attachment relationships + if (card->getParentCard()) + card->setParentCard(0); + + const QList &attachedCards = card->getAttachedCards(); + for (int i = 0; i < attachedCards.size(); ++i) + attachedCards[i]->getZone()->getPlayer()->unattachCard(cont, attachedCards[i]); + + // Delete all arrows from and to the card + const QList &players = game->getPlayers().values(); + for (int i = 0; i < players.size(); ++i) { + QList arrowsToDelete; + QMapIterator arrowIterator(players[i]->getArrows()); + while (arrowIterator.hasNext()) { + Server_Arrow *arrow = arrowIterator.next().value(); + if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card)) + arrowsToDelete.append(arrow->getId()); + } + for (int j = 0; j < arrowsToDelete.size(); ++j) + players[i]->deleteArrow(arrowsToDelete[j]); + } + } + + 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()); + if (startzone->hasCoords()) + startzone->fixFreeSpaces(cont, oldX, oldY); + card->deleteLater(); + return RespOk; + } + + if (!targetzone->hasCoords()) { + y = 0; + if (x == -1) + x = targetzone->cards.size(); + + card->resetState(); + } else +// if (x == -1) + x = targetzone->getFreeGridColumn(x, y, card->getName()); + + targetzone->insertCard(card, x, y); + + bool targetBeingLookedAt = (targetzone->getType() != HiddenZone) || (targetzone->getCardsBeingLookedAt() > x) || (targetzone->getCardsBeingLookedAt() == -1); + bool sourceBeingLookedAt = (startzone->getType() != HiddenZone) || (startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1); + + bool targetHiddenToPlayer = faceDown || !targetBeingLookedAt; + bool targetHiddenToOthers = faceDown || (targetzone->getType() != PublicZone); + bool sourceHiddenToPlayer = card->getFaceDown() || !sourceBeingLookedAt; + bool sourceHiddenToOthers = card->getFaceDown() || (startzone->getType() != PublicZone); + + QString privateCardName, publicCardName; + if (!(sourceHiddenToPlayer && targetHiddenToPlayer)) + privateCardName = card->getName(); + if (!(sourceHiddenToOthers && targetHiddenToOthers)) + publicCardName = card->getName(); + + int oldCardId = card->getId(); + if (faceDown) + card->setId(newCardId()); + card->setFaceDown(faceDown); + + // The player does not get to see which card he moved if it moves between two parts of hidden zones which + // are not being looked at. + int privateNewCardId = card->getId(); + int privateOldCardId = oldCardId; + if (!targetBeingLookedAt && !sourceBeingLookedAt) { + privateOldCardId = -1; + privateNewCardId = -1; + privateCardName = QString(); + } + int privatePosition = -1; + if (startzone->getType() == HiddenZone) + privatePosition = position; + cont->enqueueGameEventPrivate(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId()); + cont->enqueueGameEventOmniscient(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId()); + + // Other players do not get to see the start and/or target position of the card if the respective + // part of the zone is being looked at. The information is not needed anyway because in hidden zones, + // all cards are equal. + if ( + ((startzone->getType() == HiddenZone) && ((startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1))) + || (startzone->getType() == PublicZone) + ) + position = -1; + if ((targetzone->getType() == HiddenZone) && ((targetzone->getCardsBeingLookedAt() > x) || (targetzone->getCardsBeingLookedAt() == -1))) + x = -1; + + if ((startzone->getType() == PublicZone) || (targetzone->getType() == PublicZone)) + cont->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), oldCardId, publicCardName, startzone->getName(), position, targetzone->getName(), x, y, card->getId(), faceDown), game->getGameId()); + else + cont->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), -1, QString(), startzone->getName(), position, targetzone->getName(), x, y, -1, false), game->getGameId()); + + if (tapped) + setCardAttrHelper(cont, targetzone->getName(), card->getId(), "tapped", "1"); + + if (startzone->hasCoords()) + startzone->fixFreeSpaces(cont, oldX, oldY); + + return RespOk; +} + +void Server_Player::unattachCard(CommandContainer *cont, Server_Card *card) +{ + Server_CardZone *zone = card->getZone(); + + card->setParentCard(0); + cont->enqueueGameEventPrivate(new Event_AttachCard(getPlayerId(), zone->getName(), card->getId(), -1, QString(), -1), game->getGameId()); + cont->enqueueGameEventPublic(new Event_AttachCard(getPlayerId(), zone->getName(), card->getId(), -1, QString(), -1), game->getGameId()); + + moveCard(cont, zone->getName(), card->getId(), zone->getName(), -1, card->getY(), card->getFaceDown(), card->getTapped()); +} + +ResponseCode Server_Player::setCardAttrHelper(CommandContainer *cont, const QString &zoneName, int cardId, const QString &attrName, const QString &attrValue) +{ + Server_CardZone *zone = getZones().value(zoneName); + if (!zone) + return RespNameNotFound; + if (!zone->hasCoords()) + return RespContextError; + + if (cardId == -1) { + QListIterator CardIterator(zone->cards); + while (CardIterator.hasNext()) + if (!CardIterator.next()->setAttribute(attrName, attrValue, true)) + return RespInvalidCommand; + } else { + Server_Card *card = zone->getCard(cardId, false); + if (!card) + return RespNameNotFound; + if (!card->setAttribute(attrName, attrValue, false)) + return RespInvalidCommand; + } + cont->enqueueGameEventPrivate(new Event_SetCardAttr(getPlayerId(), zone->getName(), cardId, attrName, attrValue), game->getGameId()); + cont->enqueueGameEventPublic(new Event_SetCardAttr(getPlayerId(), zone->getName(), cardId, attrName, attrValue), game->getGameId()); + cont->enqueueGameEventOmniscient(new Event_SetCardAttr(getPlayerId(), zone->getName(), cardId, attrName, attrValue), game->getGameId()); + return RespOk; +} + void Server_Player::sendProtocolItem(ProtocolItem *item, bool deleteItem) { if (handler) diff --git a/common/server_player.h b/common/server_player.h index 2381a836..6e17b9c6 100644 --- a/common/server_player.h +++ b/common/server_player.h @@ -5,16 +5,19 @@ #include #include #include +#include "protocol_datastructures.h" class DeckList; class Server_Game; class Server_CardZone; class Server_Counter; class Server_Arrow; +class Server_Card; class Server_ProtocolHandler; class ProtocolItem; class ServerInfo_User; class ServerInfo_PlayerProperties; +class CommandContainer; class Server_Player : public Server_ArrowTarget { Q_OBJECT @@ -71,6 +74,11 @@ public: void clearZones(); void setupZones(); + ResponseCode moveCard(CommandContainer *cont, const QString &_startZone, int _cardId, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped); + ResponseCode moveCard(CommandContainer *cont, Server_CardZone *startzone, int _cardId, Server_CardZone *targetzone, int x, int y, bool faceDown, bool tapped); + void unattachCard(CommandContainer *cont, Server_Card *card); + ResponseCode setCardAttrHelper(CommandContainer *cont, const QString &zone, int cardId, const QString &attrName, const QString &attrValue); + void sendProtocolItem(ProtocolItem *item, bool deleteItem = true); }; diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 18c80565..ae61a285 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -510,7 +510,7 @@ ResponseCode Server_ProtocolHandler::cmdMulligan(Command_Mulligan * /*cmd*/, Com Server_CardZone *hand = player->getZones().value("hand"); while (!hand->cards.isEmpty()) - moveCard(game, player, cont, "hand", hand->cards.first()->getId(), "deck", 0, 0, false, false); + player->moveCard(cont, "hand", hand->cards.first()->getId(), "deck", 0, 0, false, false); player->getZones().value("deck")->shuffle(); cont->enqueueGameEventPrivate(new Event_Shuffle(player->getPlayerId()), game->getGameId()); @@ -565,7 +565,8 @@ ResponseCode Server_ProtocolHandler::cmdDrawCards(Command_DrawCards *cmd, Comman return drawCards(game, player, cont, cmd->getNumber()); } -ResponseCode Server_ProtocolHandler::moveCard(Server_Game *game, Server_Player *player, CommandContainer *cont, const QString &_startZone, int _cardId, const QString &_targetZone, int x, int y, bool faceDown, bool tapped) + +ResponseCode Server_ProtocolHandler::cmdMoveCard(Command_MoveCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { if (player->getSpectator()) return RespFunctionNotAllowed; @@ -573,122 +574,7 @@ ResponseCode Server_ProtocolHandler::moveCard(Server_Game *game, Server_Player * if (!game->getGameStarted()) return RespGameNotStarted; - Server_CardZone *startzone = player->getZones().value(_startZone); - Server_CardZone *targetzone = player->getZones().value(_targetZone); - if ((!startzone) || (!targetzone)) - return RespNameNotFound; - - // Collision detection - if (targetzone->hasCoords()) - for (int i = 0; i < targetzone->cards.size(); ++i) - if ((targetzone->cards[i]->getX() == x) && (targetzone->cards[i]->getY() == y) && (x != -1)) - return RespContextError; - - int position = -1; - Server_Card *card = startzone->getCard(_cardId, true, &position); - if (!card) - return RespNameNotFound; - - if (startzone != targetzone) { - // Delete all attachment relationships - if (card->getParentCard()) - card->setParentCard(0); - - const QList &attachedCards = card->getAttachedCards(); - for (int i = 0; i < attachedCards.size(); ++i) - unattachCard(game, attachedCards[i]->getZone()->getPlayer(), cont, attachedCards[i]); - - // Delete all arrows from and to the card - const QList &players = game->getPlayers().values(); - for (int i = 0; i < players.size(); ++i) { - QList arrowsToDelete; - QMapIterator arrowIterator(players[i]->getArrows()); - while (arrowIterator.hasNext()) { - Server_Arrow *arrow = arrowIterator.next().value(); - if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card)) - arrowsToDelete.append(arrow->getId()); - } - for (int j = 0; j < arrowsToDelete.size(); ++j) - players[i]->deleteArrow(arrowsToDelete[j]); - } - } - - if (card->getDestroyOnZoneChange() && (startzone != targetzone)) { - cont->enqueueGameEventPrivate(new Event_DestroyCard(player->getPlayerId(), startzone->getName(), card->getId()), game->getGameId()); - cont->enqueueGameEventPublic(new Event_DestroyCard(player->getPlayerId(), startzone->getName(), card->getId()), game->getGameId()); - return RespOk; - } - - if (!targetzone->hasCoords()) { - y = 0; - if (x == -1) - x = targetzone->cards.size(); - - card->resetState(); - } else if (x == -1) - x = targetzone->getFreeGridColumn(y); - - targetzone->insertCard(card, x, y); - - bool targetBeingLookedAt = (targetzone->getType() != HiddenZone) || (targetzone->getCardsBeingLookedAt() > x) || (targetzone->getCardsBeingLookedAt() == -1); - bool sourceBeingLookedAt = (startzone->getType() != HiddenZone) || (startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1); - - bool targetHiddenToPlayer = faceDown || !targetBeingLookedAt; - bool targetHiddenToOthers = faceDown || (targetzone->getType() != PublicZone); - bool sourceHiddenToPlayer = card->getFaceDown() || !sourceBeingLookedAt; - bool sourceHiddenToOthers = card->getFaceDown() || (startzone->getType() != PublicZone); - - QString privateCardName, publicCardName; - if (!(sourceHiddenToPlayer && targetHiddenToPlayer)) - privateCardName = card->getName(); - if (!(sourceHiddenToOthers && targetHiddenToOthers)) - publicCardName = card->getName(); - - int oldCardId = card->getId(); - if (faceDown) - card->setId(player->newCardId()); - card->setFaceDown(faceDown); - - // The player does not get to see which card he moved if it moves between two parts of hidden zones which - // are not being looked at. - int privateNewCardId = card->getId(); - int privateOldCardId = oldCardId; - if (!targetBeingLookedAt && !sourceBeingLookedAt) { - privateOldCardId = -1; - privateNewCardId = -1; - privateCardName = QString(); - } - int privatePosition = -1; - if (startzone->getType() == HiddenZone) - privatePosition = position; - cont->enqueueGameEventPrivate(new Event_MoveCard(player->getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId()); - cont->enqueueGameEventOmniscient(new Event_MoveCard(player->getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId()); - - // Other players do not get to see the start and/or target position of the card if the respective - // part of the zone is being looked at. The information is not needed anyway because in hidden zones, - // all cards are equal. - if ( - ((startzone->getType() == HiddenZone) && ((startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1))) - || (startzone->getType() == PublicZone) - ) - position = -1; - if ((targetzone->getType() == HiddenZone) && ((targetzone->getCardsBeingLookedAt() > x) || (targetzone->getCardsBeingLookedAt() == -1))) - x = -1; - - if ((startzone->getType() == PublicZone) || (targetzone->getType() == PublicZone)) - cont->enqueueGameEventPublic(new Event_MoveCard(player->getPlayerId(), oldCardId, publicCardName, startzone->getName(), position, targetzone->getName(), x, y, card->getId(), faceDown), game->getGameId()); - else - cont->enqueueGameEventPublic(new Event_MoveCard(player->getPlayerId(), -1, QString(), startzone->getName(), position, targetzone->getName(), x, y, -1, false), game->getGameId()); - - if (tapped) - setCardAttrHelper(cont, game, player, targetzone->getName(), card->getId(), "tapped", "1"); - - return RespOk; -} - -ResponseCode Server_ProtocolHandler::cmdMoveCard(Command_MoveCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) -{ - return moveCard(game, player, cont, cmd->getStartZone(), cmd->getCardId(), cmd->getTargetZone(), cmd->getX(), cmd->getY(), cmd->getFaceDown(), cmd->getTapped()); + return player->moveCard(cont, cmd->getStartZone(), cmd->getCardId(), cmd->getTargetZone(), cmd->getX(), cmd->getY(), cmd->getFaceDown(), cmd->getTapped()); } ResponseCode Server_ProtocolHandler::cmdFlipCard(Command_FlipCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) @@ -720,17 +606,6 @@ ResponseCode Server_ProtocolHandler::cmdFlipCard(Command_FlipCard *cmd, CommandC return RespOk; } -void Server_ProtocolHandler::unattachCard(Server_Game *game, Server_Player *player, CommandContainer *cont, Server_Card *card) -{ - Server_CardZone *zone = card->getZone(); - - card->setParentCard(0); - cont->enqueueGameEventPrivate(new Event_AttachCard(player->getPlayerId(), zone->getName(), card->getId(), -1, QString(), -1), game->getGameId()); - cont->enqueueGameEventPublic(new Event_AttachCard(player->getPlayerId(), zone->getName(), card->getId(), -1, QString(), -1), game->getGameId()); - - moveCard(game, player, cont, zone->getName(), card->getId(), zone->getName(), -1, card->getY(), card->getFaceDown(), card->getTapped()); -} - ResponseCode Server_ProtocolHandler::cmdAttachCard(Command_AttachCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { if (player->getSpectator()) @@ -796,14 +671,14 @@ ResponseCode Server_ProtocolHandler::cmdAttachCard(Command_AttachCard *cmd, Comm // Unattach all cards attached to the card being attached. const QList &attachedList = card->getAttachedCards(); for (int i = 0; i < attachedList.size(); ++i) - unattachCard(game, player, cont, attachedList[i]); + player->unattachCard(cont, attachedList[i]); 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()); cont->enqueueGameEventPublic(new Event_AttachCard(player->getPlayerId(), startzone->getName(), card->getId(), targetPlayer->getPlayerId(), targetzone->getName(), targetCard->getId()), game->getGameId()); } else - unattachCard(game, player, cont, card); + player->unattachCard(cont, card); return RespOk; } @@ -822,8 +697,8 @@ ResponseCode Server_ProtocolHandler::cmdCreateToken(Command_CreateToken *cmd, Co int x = cmd->getX(); int y = cmd->getY(); - if (zone->hasCoords() && (x == -1)) - x = zone->getFreeGridColumn(y); + if (zone->hasCoords()) + x = zone->getFreeGridColumn(x, y, cmd->getCardName()); if (x < 0) x = 0; if (y < 0) @@ -917,7 +792,7 @@ ResponseCode Server_ProtocolHandler::cmdDeleteArrow(Command_DeleteArrow *cmd, Co return RespOk; } -ResponseCode Server_ProtocolHandler::setCardAttrHelper(CommandContainer *cont, Server_Game *game, Server_Player *player, const QString &zoneName, int cardId, const QString &attrName, const QString &attrValue) +ResponseCode Server_ProtocolHandler::cmdSetCardAttr(Command_SetCardAttr *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { if (player->getSpectator()) return RespFunctionNotAllowed; @@ -925,33 +800,7 @@ ResponseCode Server_ProtocolHandler::setCardAttrHelper(CommandContainer *cont, S if (!game->getGameStarted()) return RespGameNotStarted; - Server_CardZone *zone = player->getZones().value(zoneName); - if (!zone) - return RespNameNotFound; - if (!zone->hasCoords()) - return RespContextError; - - if (cardId == -1) { - QListIterator CardIterator(zone->cards); - while (CardIterator.hasNext()) - if (!CardIterator.next()->setAttribute(attrName, attrValue, true)) - return RespInvalidCommand; - } else { - Server_Card *card = zone->getCard(cardId, false); - if (!card) - return RespNameNotFound; - if (!card->setAttribute(attrName, attrValue, false)) - return RespInvalidCommand; - } - cont->enqueueGameEventPrivate(new Event_SetCardAttr(player->getPlayerId(), zone->getName(), cardId, attrName, attrValue), game->getGameId()); - cont->enqueueGameEventPublic(new Event_SetCardAttr(player->getPlayerId(), zone->getName(), cardId, attrName, attrValue), game->getGameId()); - cont->enqueueGameEventOmniscient(new Event_SetCardAttr(player->getPlayerId(), zone->getName(), cardId, attrName, attrValue), game->getGameId()); - return RespOk; -} - -ResponseCode Server_ProtocolHandler::cmdSetCardAttr(Command_SetCardAttr *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) -{ - return setCardAttrHelper(cont, game, player, cmd->getZone(), cmd->getCardId(), cmd->getAttrName(), cmd->getAttrValue()); + return player->setCardAttrHelper(cont, cmd->getZone(), cmd->getCardId(), cmd->getAttrName(), cmd->getAttrValue()); } ResponseCode Server_ProtocolHandler::cmdSetCardCounter(Command_SetCardCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) diff --git a/common/server_protocolhandler.h b/common/server_protocolhandler.h index d7719259..aa515760 100644 --- a/common/server_protocolhandler.h +++ b/common/server_protocolhandler.h @@ -62,18 +62,14 @@ private: ResponseCode cmdShuffle(Command_Shuffle *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdMulligan(Command_Mulligan *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdRollDie(Command_RollDie *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); - // XXX Maybe the following function and others belong into Server_Player ResponseCode drawCards(Server_Game *game, Server_Player *player, CommandContainer *cont, int number); ResponseCode cmdDrawCards(Command_DrawCards *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); - ResponseCode moveCard(Server_Game *game, Server_Player *player, CommandContainer *cont, const QString &_startZone, int _cardId, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped); ResponseCode cmdMoveCard(Command_MoveCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdFlipCard(Command_FlipCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); - void unattachCard(Server_Game *game, Server_Player *player, CommandContainer *cont, Server_Card *card); ResponseCode cmdAttachCard(Command_AttachCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdCreateToken(Command_CreateToken *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdCreateArrow(Command_CreateArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdDeleteArrow(Command_DeleteArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); - ResponseCode setCardAttrHelper(CommandContainer *cont, Server_Game *game, Server_Player *player, const QString &zone, int cardId, const QString &attrName, const QString &attrValue); ResponseCode cmdSetCardAttr(Command_SetCardAttr *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdSetCardCounter(Command_SetCardCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdIncCardCounter(Command_IncCardCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player);