diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp index b08495bad..00561bef2 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp @@ -198,6 +198,35 @@ shouldDestroyOnMove(const Server_Card *card, const Server_CardZone *startZone, c return true; } +/** + * @brief Determines whether the moved card should be face-down + */ +static bool +shouldBeFaceDown(const MoveCardStruct &cardStruct, const Server_CardZone *startZone, const Server_CardZone *targetZone) +{ + if (!targetZone) { + return false; + } + + // being face-down only makes sense for public zones + if (targetZone->getType() != ServerInfo_Zone::PublicZone) { + return false; + } + + // face-down property in proto takes precedence + if (cardStruct.cardToMove->has_face_down()) { + return cardStruct.cardToMove->face_down(); + } + + // Default to keep face-down the same if zone didn't change. + // Compare using zone names because face-down is maintained when changing controllers. + if (startZone && startZone->getName() == targetZone->getName()) { + return cardStruct.card->getFaceDown(); + } + + return false; +} + Response::ResponseCode Server_AbstractPlayer::moveCard(GameEventStorage &ges, Server_CardZone *startzone, const QList &_cards, @@ -257,10 +286,7 @@ Response::ResponseCode Server_AbstractPlayer::moveCard(GameEventStorage &ges, for (auto cardStruct : cardsToMove) { Server_Card *card = cardStruct.card; - const CardToMove *thisCardProperties = cardStruct.cardToMove; int originalPosition = cardStruct.position; - bool faceDown = targetzone->hasCoords() && - (thisCardProperties->has_face_down() ? thisCardProperties->face_down() : card->getFaceDown()); bool sourceBeingLookedAt; int position = startzone->removeCard(card, sourceBeingLookedAt); @@ -315,6 +341,8 @@ Response::ResponseCode Server_AbstractPlayer::moveCard(GameEventStorage &ges, ++xIndex; int newX = isReversed ? targetzone->getCards().size() - xCoord + xIndex : xCoord + xIndex; + bool faceDown = shouldBeFaceDown(cardStruct, startzone, targetzone); + if (targetzone->hasCoords()) { newX = targetzone->getFreeGridColumn(newX, yCoord, card->getName(), faceDown); } else { diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/command_move_card.proto b/libcockatrice_protocol/libcockatrice/protocol/pb/command_move_card.proto index 6e9301d27..a5b96da2e 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pb/command_move_card.proto +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/command_move_card.proto @@ -6,7 +6,9 @@ message CardToMove { // Id of the card in its current zone optional sint32 card_id = 1 [default = -1]; - // Places the card face down, hiding its name + // If true, places the card face down, hiding its name. + // If false, forcibly turns the card face up. + // If not set, defers the resulting face down state to the server. optional bool face_down = 2; // When moving add this value to the power/toughness field of the card