experimental card stacking

This commit is contained in:
Max-Wilhelm Bruker 2010-12-14 19:26:40 +01:00
parent 21cc0ed8d6
commit f4962d021e
8 changed files with 291 additions and 212 deletions

View file

@ -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);
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;
y = boxLineWidth + (CARD_HEIGHT + paddingY) * gridPoint.y();
}
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;
int baseX = -1;
qreal oldTempX = 0, tempX = 0;
do {
++resultX;
tempX += gridPointWidth.value(resultY * 1000 + resultX, CARD_WIDTH) + 0.5 * CARD_WIDTH;
++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)

View file

@ -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;

View file

@ -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;
// 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;
QMap<int, Server_Card *> coordMap;
for (int i = 0; i < cards.size(); ++i)
if ((cards[i]->getY() == y) && (cards[i]->getX() == x)) {
occupied = true;
++x;
break;
}
} while (occupied);
if (cards[i]->getY() == y)
coordMap.insert(cards[i]->getX(), cards[i]);
return x;
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]->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)
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)

View file

@ -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();

View file

@ -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)

View file

@ -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);
};

View file

@ -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)

View file

@ -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);