experimental card stacking
This commit is contained in:
parent
21cc0ed8d6
commit
f4962d021e
8 changed files with 291 additions and 212 deletions
|
@ -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<ArrowItem *> arrowsToUpdate;
|
||||
|
||||
// Calculate table grid distortion so that the mapping functions work properly
|
||||
gridPointWidth.clear();
|
||||
QMap<int, int> 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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<int, Server_Card *> 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<int, Server_Card *> &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<int, Server_Card *> 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)
|
||||
|
|
|
@ -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<int, Server_Card *> &coordMap, Server_Card *card, int x, int y);
|
||||
QList<Server_Card *> cards;
|
||||
void insertCard(Server_Card *card, int x, int y);
|
||||
void shuffle();
|
||||
|
|
|
@ -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<Server_Card *> &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<Server_Player *> &players = game->getPlayers().values();
|
||||
for (int i = 0; i < players.size(); ++i) {
|
||||
QList<int> arrowsToDelete;
|
||||
QMapIterator<int, Server_Arrow *> 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<Server_Card *> 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)
|
||||
|
|
|
@ -5,16 +5,19 @@
|
|||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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<Server_Card *> &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<Server_Player *> &players = game->getPlayers().values();
|
||||
for (int i = 0; i < players.size(); ++i) {
|
||||
QList<int> arrowsToDelete;
|
||||
QMapIterator<int, Server_Arrow *> 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<Server_Card *> &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<Server_Card *> 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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue