mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-11 00:24:47 -07:00
Click to hide revealed cards; MultiMove function
This commit is contained in:
parent
f07bb38e4a
commit
9c527fb5aa
28 changed files with 424 additions and 284 deletions
|
|
@ -27,6 +27,7 @@ void ProtocolItem::initializeHash()
|
|||
registerSerializableItem("player_ping", ServerInfo_PlayerPing::newItem);
|
||||
registerSerializableItem("file", DeckList_File::newItem);
|
||||
registerSerializableItem("directory", DeckList_Directory::newItem);
|
||||
registerSerializableItem("card_id", CardId::newItem);
|
||||
|
||||
registerSerializableItem("containercmd", CommandContainer::newItem);
|
||||
registerSerializableItem("containergame_event", GameEventContainer::newItem);
|
||||
|
|
@ -34,6 +35,7 @@ void ProtocolItem::initializeHash()
|
|||
registerSerializableItem("cmddeck_upload", Command_DeckUpload::newItem);
|
||||
registerSerializableItem("cmddeck_select", Command_DeckSelect::newItem);
|
||||
registerSerializableItem("cmdset_sideboard_plan", Command_SetSideboardPlan::newItem);
|
||||
registerSerializableItem("cmdmove_card", Command_MoveCard::newItem);
|
||||
|
||||
registerSerializableItem("resp", ProtocolResponse::newItem);
|
||||
ProtocolResponse::initializeHash();
|
||||
|
|
@ -198,6 +200,21 @@ QList<MoveCardToZone *> Command_SetSideboardPlan::getMoveList() const
|
|||
return typecastItemList<MoveCardToZone *>();
|
||||
}
|
||||
|
||||
Command_MoveCard::Command_MoveCard(int _gameId, const QString &_startZone, const QList<CardId *> &_cardIds, int _targetPlayerId, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped)
|
||||
: GameCommand("move_card", _gameId)
|
||||
{
|
||||
insertItem(new SerializableItem_String("start_zone", _startZone));
|
||||
insertItem(new SerializableItem_Int("target_player_id", _targetPlayerId));
|
||||
insertItem(new SerializableItem_String("target_zone", _targetZone));
|
||||
insertItem(new SerializableItem_Int("x", _x));
|
||||
insertItem(new SerializableItem_Int("y", _y));
|
||||
insertItem(new SerializableItem_Bool("face_down", _faceDown));
|
||||
insertItem(new SerializableItem_Bool("tapped", _tapped));
|
||||
|
||||
for (int i = 0; i < _cardIds.size(); ++i)
|
||||
itemList.append(_cardIds[i]);
|
||||
}
|
||||
|
||||
QHash<QString, ResponseCode> ProtocolResponse::responseHash;
|
||||
|
||||
ProtocolResponse::ProtocolResponse(int _cmdId, ResponseCode _responseCode, const QString &_itemName)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ enum ItemId {
|
|||
ItemId_Command_DeckUpload = ItemId_Other + 100,
|
||||
ItemId_Command_DeckSelect = ItemId_Other + 101,
|
||||
ItemId_Command_SetSideboardPlan = ItemId_Other + 102,
|
||||
ItemId_Command_MoveCard = ItemId_Other + 103,
|
||||
ItemId_Event_ListRooms = ItemId_Other + 200,
|
||||
ItemId_Event_JoinRoom = ItemId_Other + 201,
|
||||
ItemId_Event_ListGames = ItemId_Other + 203,
|
||||
|
|
@ -189,6 +190,22 @@ public:
|
|||
QList<MoveCardToZone *> getMoveList() const;
|
||||
};
|
||||
|
||||
class Command_MoveCard : public GameCommand {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Command_MoveCard(int _gameId = -1, const QString &_startZone = QString(), const QList<CardId *> &_cardIds = QList<CardId *>(), int _targetPlayerId = -1, const QString &_targetZone = QString(), int _x = -1, int _y = -1, bool _faceDown = false, bool _tapped = false);
|
||||
QString getStartZone() const { return static_cast<SerializableItem_String *>(itemMap.value("start_zone"))->getData(); }
|
||||
QList<CardId *> getCardIds() const { return typecastItemList<CardId *>(); }
|
||||
int getTargetPlayerId() const { return static_cast<SerializableItem_Int *>(itemMap.value("target_player_id"))->getData(); }
|
||||
QString getTargetZone() const { return static_cast<SerializableItem_String *>(itemMap.value("target_zone"))->getData(); }
|
||||
int getX() const { return static_cast<SerializableItem_Int *>(itemMap.value("x"))->getData(); }
|
||||
int getY() const { return static_cast<SerializableItem_Int *>(itemMap.value("y"))->getData(); }
|
||||
bool getFaceDown() const { return static_cast<SerializableItem_Bool *>(itemMap.value("face_down"))->getData(); }
|
||||
bool getTapped() const { return static_cast<SerializableItem_Bool *>(itemMap.value("tapped"))->getData(); }
|
||||
static SerializableItem *newItem() { return new Command_MoveCard; }
|
||||
int getItemId() const { return ItemId_Command_MoveCard; }
|
||||
};
|
||||
|
||||
// -----------------
|
||||
// --- RESPONSES ---
|
||||
// -----------------
|
||||
|
|
|
|||
|
|
@ -20,6 +20,12 @@ enum ResponseCode { RespNothing, RespOk, RespInvalidCommand, RespInvalidData, Re
|
|||
// list index, whereas cards in any other zone are referenced by their ids.
|
||||
enum ZoneType { PrivateZone, PublicZone, HiddenZone };
|
||||
|
||||
class CardId : public SerializableItem_Int {
|
||||
public:
|
||||
CardId(int _cardId = -1) : SerializableItem_Int("card_id", _cardId) { }
|
||||
static SerializableItem *newItem() { return new CardId; }
|
||||
};
|
||||
|
||||
class ServerInfo_User : public SerializableItem_Map {
|
||||
public:
|
||||
enum UserLevelFlags {
|
||||
|
|
|
|||
|
|
@ -21,53 +21,52 @@ ItemId_Command_Shuffle = 1019,
|
|||
ItemId_Command_Mulligan = 1020,
|
||||
ItemId_Command_RollDie = 1021,
|
||||
ItemId_Command_DrawCards = 1022,
|
||||
ItemId_Command_MoveCard = 1023,
|
||||
ItemId_Command_FlipCard = 1024,
|
||||
ItemId_Command_AttachCard = 1025,
|
||||
ItemId_Command_CreateToken = 1026,
|
||||
ItemId_Command_CreateArrow = 1027,
|
||||
ItemId_Command_DeleteArrow = 1028,
|
||||
ItemId_Command_SetCardAttr = 1029,
|
||||
ItemId_Command_SetCardCounter = 1030,
|
||||
ItemId_Command_IncCardCounter = 1031,
|
||||
ItemId_Command_ReadyStart = 1032,
|
||||
ItemId_Command_Concede = 1033,
|
||||
ItemId_Command_IncCounter = 1034,
|
||||
ItemId_Command_CreateCounter = 1035,
|
||||
ItemId_Command_SetCounter = 1036,
|
||||
ItemId_Command_DelCounter = 1037,
|
||||
ItemId_Command_NextTurn = 1038,
|
||||
ItemId_Command_SetActivePhase = 1039,
|
||||
ItemId_Command_DumpZone = 1040,
|
||||
ItemId_Command_StopDumpZone = 1041,
|
||||
ItemId_Command_RevealCards = 1042,
|
||||
ItemId_Event_Say = 1043,
|
||||
ItemId_Event_Leave = 1044,
|
||||
ItemId_Event_GameClosed = 1045,
|
||||
ItemId_Event_Shuffle = 1046,
|
||||
ItemId_Event_RollDie = 1047,
|
||||
ItemId_Event_MoveCard = 1048,
|
||||
ItemId_Event_FlipCard = 1049,
|
||||
ItemId_Event_DestroyCard = 1050,
|
||||
ItemId_Event_AttachCard = 1051,
|
||||
ItemId_Event_CreateToken = 1052,
|
||||
ItemId_Event_DeleteArrow = 1053,
|
||||
ItemId_Event_SetCardAttr = 1054,
|
||||
ItemId_Event_SetCardCounter = 1055,
|
||||
ItemId_Event_SetCounter = 1056,
|
||||
ItemId_Event_DelCounter = 1057,
|
||||
ItemId_Event_SetActivePlayer = 1058,
|
||||
ItemId_Event_SetActivePhase = 1059,
|
||||
ItemId_Event_DumpZone = 1060,
|
||||
ItemId_Event_StopDumpZone = 1061,
|
||||
ItemId_Event_ServerMessage = 1062,
|
||||
ItemId_Event_Message = 1063,
|
||||
ItemId_Event_GameJoined = 1064,
|
||||
ItemId_Event_UserLeft = 1065,
|
||||
ItemId_Event_LeaveRoom = 1066,
|
||||
ItemId_Event_RoomSay = 1067,
|
||||
ItemId_Context_ReadyStart = 1068,
|
||||
ItemId_Context_Concede = 1069,
|
||||
ItemId_Context_DeckSelect = 1070,
|
||||
ItemId_Other = 1071
|
||||
ItemId_Command_FlipCard = 1023,
|
||||
ItemId_Command_AttachCard = 1024,
|
||||
ItemId_Command_CreateToken = 1025,
|
||||
ItemId_Command_CreateArrow = 1026,
|
||||
ItemId_Command_DeleteArrow = 1027,
|
||||
ItemId_Command_SetCardAttr = 1028,
|
||||
ItemId_Command_SetCardCounter = 1029,
|
||||
ItemId_Command_IncCardCounter = 1030,
|
||||
ItemId_Command_ReadyStart = 1031,
|
||||
ItemId_Command_Concede = 1032,
|
||||
ItemId_Command_IncCounter = 1033,
|
||||
ItemId_Command_CreateCounter = 1034,
|
||||
ItemId_Command_SetCounter = 1035,
|
||||
ItemId_Command_DelCounter = 1036,
|
||||
ItemId_Command_NextTurn = 1037,
|
||||
ItemId_Command_SetActivePhase = 1038,
|
||||
ItemId_Command_DumpZone = 1039,
|
||||
ItemId_Command_StopDumpZone = 1040,
|
||||
ItemId_Command_RevealCards = 1041,
|
||||
ItemId_Event_Say = 1042,
|
||||
ItemId_Event_Leave = 1043,
|
||||
ItemId_Event_GameClosed = 1044,
|
||||
ItemId_Event_Shuffle = 1045,
|
||||
ItemId_Event_RollDie = 1046,
|
||||
ItemId_Event_MoveCard = 1047,
|
||||
ItemId_Event_FlipCard = 1048,
|
||||
ItemId_Event_DestroyCard = 1049,
|
||||
ItemId_Event_AttachCard = 1050,
|
||||
ItemId_Event_CreateToken = 1051,
|
||||
ItemId_Event_DeleteArrow = 1052,
|
||||
ItemId_Event_SetCardAttr = 1053,
|
||||
ItemId_Event_SetCardCounter = 1054,
|
||||
ItemId_Event_SetCounter = 1055,
|
||||
ItemId_Event_DelCounter = 1056,
|
||||
ItemId_Event_SetActivePlayer = 1057,
|
||||
ItemId_Event_SetActivePhase = 1058,
|
||||
ItemId_Event_DumpZone = 1059,
|
||||
ItemId_Event_StopDumpZone = 1060,
|
||||
ItemId_Event_ServerMessage = 1061,
|
||||
ItemId_Event_Message = 1062,
|
||||
ItemId_Event_GameJoined = 1063,
|
||||
ItemId_Event_UserLeft = 1064,
|
||||
ItemId_Event_LeaveRoom = 1065,
|
||||
ItemId_Event_RoomSay = 1066,
|
||||
ItemId_Context_ReadyStart = 1067,
|
||||
ItemId_Context_Concede = 1068,
|
||||
ItemId_Context_DeckSelect = 1069,
|
||||
ItemId_Other = 1070
|
||||
};
|
||||
|
|
|
|||
|
|
@ -114,18 +114,6 @@ Command_DrawCards::Command_DrawCards(int _gameId, int _number)
|
|||
{
|
||||
insertItem(new SerializableItem_Int("number", _number));
|
||||
}
|
||||
Command_MoveCard::Command_MoveCard(int _gameId, const QString &_startZone, int _cardId, int _targetPlayerId, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped)
|
||||
: GameCommand("move_card", _gameId)
|
||||
{
|
||||
insertItem(new SerializableItem_String("start_zone", _startZone));
|
||||
insertItem(new SerializableItem_Int("card_id", _cardId));
|
||||
insertItem(new SerializableItem_Int("target_player_id", _targetPlayerId));
|
||||
insertItem(new SerializableItem_String("target_zone", _targetZone));
|
||||
insertItem(new SerializableItem_Int("x", _x));
|
||||
insertItem(new SerializableItem_Int("y", _y));
|
||||
insertItem(new SerializableItem_Bool("face_down", _faceDown));
|
||||
insertItem(new SerializableItem_Bool("tapped", _tapped));
|
||||
}
|
||||
Command_FlipCard::Command_FlipCard(int _gameId, const QString &_zone, int _cardId, bool _faceDown)
|
||||
: GameCommand("flip_card", _gameId)
|
||||
{
|
||||
|
|
@ -461,7 +449,6 @@ void ProtocolItem::initializeHashAuto()
|
|||
itemNameHash.insert("cmdmulligan", Command_Mulligan::newItem);
|
||||
itemNameHash.insert("cmdroll_die", Command_RollDie::newItem);
|
||||
itemNameHash.insert("cmddraw_cards", Command_DrawCards::newItem);
|
||||
itemNameHash.insert("cmdmove_card", Command_MoveCard::newItem);
|
||||
itemNameHash.insert("cmdflip_card", Command_FlipCard::newItem);
|
||||
itemNameHash.insert("cmdattach_card", Command_AttachCard::newItem);
|
||||
itemNameHash.insert("cmdcreate_token", Command_CreateToken::newItem);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
2:mulligan
|
||||
2:roll_die:i,sides
|
||||
2:draw_cards:i,number
|
||||
2:move_card:s,start_zone:i,card_id:i,target_player_id:s,target_zone:i,x:i,y:b,face_down:b,tapped
|
||||
2:flip_card:s,zone:i,card_id:b,face_down
|
||||
2:attach_card:s,start_zone:i,card_id:i,target_player_id:s,target_zone:i,target_card_id
|
||||
2:create_token:s,zone:s,card_name:s,color:s,pt:s,annotation:b,destroy:i,x:i,y
|
||||
|
|
|
|||
|
|
@ -182,21 +182,6 @@ public:
|
|||
static SerializableItem *newItem() { return new Command_DrawCards; }
|
||||
int getItemId() const { return ItemId_Command_DrawCards; }
|
||||
};
|
||||
class Command_MoveCard : public GameCommand {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Command_MoveCard(int _gameId = -1, const QString &_startZone = QString(), int _cardId = -1, int _targetPlayerId = -1, const QString &_targetZone = QString(), int _x = -1, int _y = -1, bool _faceDown = false, bool _tapped = false);
|
||||
QString getStartZone() const { return static_cast<SerializableItem_String *>(itemMap.value("start_zone"))->getData(); };
|
||||
int getCardId() const { return static_cast<SerializableItem_Int *>(itemMap.value("card_id"))->getData(); };
|
||||
int getTargetPlayerId() const { return static_cast<SerializableItem_Int *>(itemMap.value("target_player_id"))->getData(); };
|
||||
QString getTargetZone() const { return static_cast<SerializableItem_String *>(itemMap.value("target_zone"))->getData(); };
|
||||
int getX() const { return static_cast<SerializableItem_Int *>(itemMap.value("x"))->getData(); };
|
||||
int getY() const { return static_cast<SerializableItem_Int *>(itemMap.value("y"))->getData(); };
|
||||
bool getFaceDown() const { return static_cast<SerializableItem_Bool *>(itemMap.value("face_down"))->getData(); };
|
||||
bool getTapped() const { return static_cast<SerializableItem_Bool *>(itemMap.value("tapped"))->getData(); };
|
||||
static SerializableItem *newItem() { return new Command_MoveCard; }
|
||||
int getItemId() const { return ItemId_Command_MoveCard; }
|
||||
};
|
||||
class Command_FlipCard : public GameCommand {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
#include "server_card.h"
|
||||
#include "server_player.h"
|
||||
#include "rng_abstract.h"
|
||||
#include <QSet>
|
||||
#include <QDebug>
|
||||
|
||||
Server_CardZone::Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ZoneType _type)
|
||||
: player(_player), name(_name), has_coords(_has_coords), type(_type), cardsBeingLookedAt(0)
|
||||
|
|
@ -29,7 +31,7 @@ Server_CardZone::Server_CardZone(Server_Player *_player, const QString &_name, b
|
|||
|
||||
Server_CardZone::~Server_CardZone()
|
||||
{
|
||||
qDebug(QString("Server_CardZone destructor: %1").arg(name).toLatin1());
|
||||
qDebug() << "Server_CardZone destructor:" << name;
|
||||
clear();
|
||||
}
|
||||
|
||||
|
|
@ -41,6 +43,13 @@ void Server_CardZone::shuffle()
|
|||
cards = temp;
|
||||
}
|
||||
|
||||
int Server_CardZone::removeCard(Server_Card *card)
|
||||
{
|
||||
int index = cards.indexOf(card);
|
||||
cards.removeAt(index);
|
||||
return index;
|
||||
}
|
||||
|
||||
Server_Card *Server_CardZone::getCard(int id, bool remove, int *position)
|
||||
{
|
||||
if (type != HiddenZone) {
|
||||
|
|
@ -146,29 +155,37 @@ bool Server_CardZone::isColumnEmpty(int x, int y) const
|
|||
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);
|
||||
player->moveCard(cont, this, QList<int>() << card->getId(), this, x, y, card->getFaceDown(), false);
|
||||
coordMap.insert(x, card);
|
||||
}
|
||||
|
||||
void Server_CardZone::fixFreeSpaces(CommandContainer *cont, int x, int y)
|
||||
void Server_CardZone::fixFreeSpaces(CommandContainer *cont)
|
||||
{
|
||||
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;
|
||||
QSet<int> placesToLook;
|
||||
for (int i = 0; i < cards.size(); ++i) {
|
||||
coordMap.insert(cards[i]->getY() * 10000 + cards[i]->getX(), cards[i]);
|
||||
placesToLook.insert(cards[i]->getY() * 10000 + (cards[i]->getX() / 3) * 3);
|
||||
}
|
||||
|
||||
QSetIterator<int> placeIterator(placesToLook);
|
||||
while (placeIterator.hasNext()) {
|
||||
int foo = placeIterator.next();
|
||||
int y = foo / 10000;
|
||||
int baseX = foo - y * 10000;
|
||||
|
||||
if (!coordMap.contains(y * 10000 + baseX)) {
|
||||
if (coordMap.contains(y * 10000 + baseX + 1))
|
||||
moveCard(cont, coordMap, coordMap.value(y * 10000 + baseX + 1), baseX, y);
|
||||
else if (coordMap.contains(baseX + 2)) {
|
||||
moveCard(cont, coordMap, coordMap.value(y * 10000 + baseX + 2), baseX, y);
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
}
|
||||
if (!coordMap.contains(y * 10000 + baseX + 1) && coordMap.contains(y * 10000 + baseX + 2))
|
||||
moveCard(cont, coordMap, coordMap.value(y * 10000 + baseX + 2), baseX + 1, y);
|
||||
}
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ public:
|
|||
Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ZoneType _type);
|
||||
~Server_CardZone();
|
||||
|
||||
int removeCard(Server_Card *card);
|
||||
Server_Card *getCard(int id, bool remove, int *position = NULL);
|
||||
|
||||
int getCardsBeingLookedAt() const { return cardsBeingLookedAt; }
|
||||
|
|
@ -52,7 +53,7 @@ public:
|
|||
int getFreeGridColumn(int x, int y, const QString &cardName) const;
|
||||
bool isColumnEmpty(int x, int y) const;
|
||||
bool isColumnStacked(int x, int y) const;
|
||||
void fixFreeSpaces(CommandContainer *cont, int x, int y);
|
||||
void fixFreeSpaces(CommandContainer *cont);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "protocol.h"
|
||||
#include "protocol_items.h"
|
||||
#include "decklist.h"
|
||||
#include <QDebug>
|
||||
|
||||
Server_Player::Server_Player(Server_Game *_game, int _playerId, ServerInfo_User *_userInfo, bool _spectator, Server_ProtocolHandler *_handler)
|
||||
: game(_game), handler(_handler), userInfo(new ServerInfo_User(_userInfo)), deck(0), playerId(_playerId), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false), deckId(-2)
|
||||
|
|
@ -198,7 +199,7 @@ bool Server_Player::deleteCounter(int counterId)
|
|||
return true;
|
||||
}
|
||||
|
||||
ResponseCode Server_Player::moveCard(CommandContainer *cont, const QString &_startZone, int _cardId, int targetPlayerId, const QString &_targetZone, int x, int y, bool faceDown, bool tapped)
|
||||
ResponseCode Server_Player::moveCard(CommandContainer *cont, const QString &_startZone, const QList<int> &_cardIds, int targetPlayerId, const QString &_targetZone, int x, int y, bool faceDown, bool tapped)
|
||||
{
|
||||
Server_CardZone *startzone = getZones().value(_startZone);
|
||||
Server_Player *targetPlayer = game->getPlayers().value(targetPlayerId);
|
||||
|
|
@ -208,128 +209,168 @@ ResponseCode Server_Player::moveCard(CommandContainer *cont, const QString &_sta
|
|||
if ((!startzone) || (!targetzone))
|
||||
return RespNameNotFound;
|
||||
|
||||
return moveCard(cont, startzone, _cardId, targetzone, x, y, faceDown, tapped);
|
||||
return moveCard(cont, startzone, _cardIds, 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)
|
||||
class Server_Player::MoveCardCompareFunctor {
|
||||
private:
|
||||
int x;
|
||||
public:
|
||||
MoveCardCompareFunctor(int _x) : x(_x) { }
|
||||
inline bool operator()(QPair<Server_Card *, int> a, QPair<Server_Card *, int> b)
|
||||
{
|
||||
if (a.second < x) {
|
||||
if (b.second >= x)
|
||||
return false;
|
||||
else
|
||||
return (a.second > b.second);
|
||||
} else {
|
||||
if (b.second < x)
|
||||
return true;
|
||||
else
|
||||
return (a.second < b.second);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *startzone, const QList<int> &_cardIds, Server_CardZone *targetzone, int x, int y, bool faceDown, bool tapped)
|
||||
{
|
||||
// Disallow controller change between different zones.
|
||||
if ((startzone->getName() != targetzone->getName()) && (startzone->getPlayer() != targetzone->getPlayer()))
|
||||
return RespContextError;
|
||||
|
||||
int position = -1;
|
||||
Server_Card *card = startzone->getCard(_cardId, false, &position);
|
||||
if (!card)
|
||||
return RespNameNotFound;
|
||||
if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y))
|
||||
return RespContextError;
|
||||
startzone->getCard(_cardId, true);
|
||||
if (!targetzone->hasCoords() && (x == -1))
|
||||
x = targetzone->cards.size();
|
||||
|
||||
int oldX = card->getX(), oldY = card->getY();
|
||||
|
||||
// Attachment relationships can be retained when moving a card onto the opponent's table
|
||||
if (startzone->getName() != targetzone->getName()) {
|
||||
// Delete all attachment relationships
|
||||
if (card->getParentCard())
|
||||
card->setParentCard(0);
|
||||
|
||||
// Make a copy of the list because the original one gets modified during the loop
|
||||
QList<Server_Card *> attachedCards = card->getAttachedCards();
|
||||
for (int i = 0; i < attachedCards.size(); ++i)
|
||||
attachedCards[i]->getZone()->getPlayer()->unattachCard(cont, attachedCards[i]);
|
||||
QList<QPair<Server_Card *, int> > cardsToMove;
|
||||
for (int i = 0; i < _cardIds.size(); ++i) {
|
||||
int position;
|
||||
Server_Card *card = startzone->getCard(_cardIds[i], false, &position);
|
||||
if (!card)
|
||||
return RespNameNotFound;
|
||||
if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y))
|
||||
return RespContextError;
|
||||
cardsToMove.append(QPair<Server_Card *, int>(card, position));
|
||||
}
|
||||
|
||||
if (startzone != targetzone) {
|
||||
// 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());
|
||||
MoveCardCompareFunctor cmp(startzone == targetzone ? -1 : x);
|
||||
qSort(cardsToMove.begin(), cardsToMove.end(), cmp);
|
||||
|
||||
bool secondHalf = false;
|
||||
int xIndex = -1;
|
||||
for (int cardIndex = 0; cardIndex < cardsToMove.size(); ++cardIndex) {
|
||||
Server_Card *card = cardsToMove[cardIndex].first;
|
||||
int originalPosition = cardsToMove[cardIndex].second;
|
||||
int position = startzone->removeCard(card);
|
||||
if ((startzone == targetzone) && !startzone->hasCoords()) {
|
||||
if (!secondHalf && (originalPosition < x)) {
|
||||
xIndex = -1;
|
||||
secondHalf = true;
|
||||
} else if (secondHalf)
|
||||
--xIndex;
|
||||
else
|
||||
++xIndex;
|
||||
} else
|
||||
++xIndex;
|
||||
int newX = x + xIndex;
|
||||
|
||||
// Attachment relationships can be retained when moving a card onto the opponent's table
|
||||
if (startzone->getName() != targetzone->getName()) {
|
||||
// Delete all attachment relationships
|
||||
if (card->getParentCard())
|
||||
card->setParentCard(0);
|
||||
|
||||
// Make a copy of the list because the original one gets modified during the loop
|
||||
QList<Server_Card *> attachedCards = card->getAttachedCards();
|
||||
for (int i = 0; i < attachedCards.size(); ++i)
|
||||
attachedCards[i]->getZone()->getPlayer()->unattachCard(cont, attachedCards[i]);
|
||||
}
|
||||
|
||||
if (startzone != targetzone) {
|
||||
// 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]);
|
||||
}
|
||||
for (int j = 0; j < arrowsToDelete.size(); ++j)
|
||||
players[i]->deleteArrow(arrowsToDelete[j]);
|
||||
}
|
||||
|
||||
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());
|
||||
card->deleteLater();
|
||||
} else {
|
||||
if (!targetzone->hasCoords()) {
|
||||
y = 0;
|
||||
card->resetState();
|
||||
} else
|
||||
newX = targetzone->getFreeGridColumn(newX, y, card->getName());
|
||||
|
||||
targetzone->insertCard(card, newX, y);
|
||||
|
||||
bool targetBeingLookedAt = (targetzone->getType() != HiddenZone) || (targetzone->getCardsBeingLookedAt() > newX) || (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->getPlayer()->getPlayerId(), targetzone->getName(), newX, y, privateNewCardId, faceDown), game->getGameId());
|
||||
cont->enqueueGameEventOmniscient(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), newX, 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() > newX) || (targetzone->getCardsBeingLookedAt() == -1)))
|
||||
newX = -1;
|
||||
|
||||
if ((startzone->getType() == PublicZone) || (targetzone->getType() == PublicZone))
|
||||
cont->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), oldCardId, publicCardName, startzone->getName(), position, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), newX, y, card->getId(), faceDown), game->getGameId());
|
||||
else
|
||||
cont->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), -1, QString(), startzone->getName(), position, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), newX, y, -1, false), game->getGameId());
|
||||
|
||||
if (tapped)
|
||||
setCardAttrHelper(cont, targetzone->getName(), card->getId(), "tapped", "1");
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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->getPlayer()->getPlayerId(), targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId());
|
||||
cont->enqueueGameEventOmniscient(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getPlayer()->getPlayerId(), 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->getPlayer()->getPlayerId(), targetzone->getName(), x, y, card->getId(), faceDown), game->getGameId());
|
||||
else
|
||||
cont->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), -1, QString(), startzone->getName(), position, targetzone->getPlayer()->getPlayerId(), 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);
|
||||
startzone->fixFreeSpaces(cont);
|
||||
|
||||
return RespOk;
|
||||
}
|
||||
|
|
@ -342,7 +383,7 @@ void Server_Player::unattachCard(CommandContainer *cont, Server_Card *card)
|
|||
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, card->getId(), zone, -1, card->getY(), card->getFaceDown(), card->getTapped());
|
||||
moveCard(cont, zone, QList<int>() << card->getId(), zone, -1, card->getY(), card->getFaceDown(), card->getTapped());
|
||||
}
|
||||
|
||||
ResponseCode Server_Player::setCardAttrHelper(CommandContainer *cont, const QString &zoneName, int cardId, const QString &attrName, const QString &attrValue)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ class CommandContainer;
|
|||
class Server_Player : public Server_ArrowTarget {
|
||||
Q_OBJECT
|
||||
private:
|
||||
class MoveCardCompareFunctor;
|
||||
Server_Game *game;
|
||||
Server_ProtocolHandler *handler;
|
||||
ServerInfo_User *userInfo;
|
||||
|
|
@ -74,8 +75,8 @@ public:
|
|||
void clearZones();
|
||||
void setupZones();
|
||||
|
||||
ResponseCode moveCard(CommandContainer *cont, const QString &_startZone, int _cardId, int _targetPlayer, 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);
|
||||
ResponseCode moveCard(CommandContainer *cont, const QString &_startZone, const QList<int> &_cardId, int _targetPlayer, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped);
|
||||
ResponseCode moveCard(CommandContainer *cont, Server_CardZone *startzone, const QList<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);
|
||||
|
||||
|
|
|
|||
|
|
@ -483,7 +483,7 @@ ResponseCode Server_ProtocolHandler::cmdMulligan(Command_Mulligan * /*cmd*/, Com
|
|||
|
||||
Server_CardZone *deck = player->getZones().value("deck");
|
||||
while (!hand->cards.isEmpty())
|
||||
player->moveCard(cont, hand, hand->cards.first()->getId(), deck, 0, 0, false, false);
|
||||
player->moveCard(cont, hand, QList<int>() << hand->cards.first()->getId(), deck, 0, 0, false, false);
|
||||
|
||||
deck->shuffle();
|
||||
cont->enqueueGameEventPrivate(new Event_Shuffle(player->getPlayerId()), game->getGameId());
|
||||
|
|
@ -545,8 +545,13 @@ ResponseCode Server_ProtocolHandler::cmdMoveCard(Command_MoveCard *cmd, CommandC
|
|||
|
||||
if (!game->getGameStarted())
|
||||
return RespGameNotStarted;
|
||||
|
||||
return player->moveCard(cont, cmd->getStartZone(), cmd->getCardId(), cmd->getTargetPlayerId(), cmd->getTargetZone(), cmd->getX(), cmd->getY(), cmd->getFaceDown(), cmd->getTapped());
|
||||
|
||||
QList<int> cardIds;
|
||||
const QList<CardId *> &temp = cmd->getCardIds();
|
||||
for (int i = 0; i < temp.size(); ++i)
|
||||
cardIds.append(temp[i]->getData());
|
||||
|
||||
return player->moveCard(cont, cmd->getStartZone(), cardIds, cmd->getTargetPlayerId(), 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)
|
||||
|
|
@ -646,7 +651,7 @@ ResponseCode Server_ProtocolHandler::cmdAttachCard(Command_AttachCard *cmd, Comm
|
|||
player->unattachCard(cont, attachedList[i]);
|
||||
|
||||
if (targetzone->isColumnStacked(targetCard->getX(), targetCard->getY()))
|
||||
targetPlayer->moveCard(cont, targetzone, targetCard->getId(), targetzone, targetzone->getFreeGridColumn(-2, targetCard->getY(), targetCard->getName()), targetCard->getY(), targetCard->getFaceDown(), false);
|
||||
targetPlayer->moveCard(cont, targetzone, QList<int>() << targetCard->getId(), targetzone, targetzone->getFreeGridColumn(-2, targetCard->getY(), targetCard->getName()), targetCard->getY(), targetCard->getFaceDown(), false);
|
||||
|
||||
card->setParentCard(targetCard);
|
||||
card->setCoords(-1, card->getY());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue