From 5c8d1f3cff31e4ec82fe415ade1b1c80d2f2398c Mon Sep 17 00:00:00 2001 From: RickyRister <42636155+RickyRister@users.noreply.github.com> Date: Sun, 16 Feb 2025 14:02:45 -0800 Subject: [PATCH] Make AttachTo tokens work from non-table zones (#5629) * move card to play before creating attached token * leave comment * hardcode createCard target zone to table To get attached token from graveyard/exile to work --- cockatrice/src/game/player/player.cpp | 14 +++++++++++--- cockatrice/src/game/player/player.h | 2 +- common/server_player.cpp | 3 +++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/cockatrice/src/game/player/player.cpp b/cockatrice/src/game/player/player.cpp index 71a9a0a3f..22b4f99fc 100644 --- a/cockatrice/src/game/player/player.cpp +++ b/cockatrice/src/game/player/player.cpp @@ -1930,7 +1930,15 @@ bool Player::createRelatedFromRelation(const CardItem *sourceCard, const CardRel createCard(sourceCard, dbName, CardRelation::DoesNotAttach, persistent); } } else { - createCard(sourceCard, dbName, cardRelation->getAttachType(), persistent); + auto attachType = cardRelation->getAttachType(); + + // move card onto table first if attaching from some other zone + // we only do this for AttachTo because cross-zone TransformInto is already handled server-side + if (attachType == CardRelation::AttachTo && sourceCard->getZone()->getName() != "table") { + playCardToTable(sourceCard, false); + } + + createCard(sourceCard, dbName, attachType, persistent); } return true; } @@ -1973,7 +1981,7 @@ void Player::createCard(const CardItem *sourceCard, cmd.set_annotation(""); } cmd.set_destroy_on_zone_change(!persistent); - cmd.set_target_zone(sourceCard->getZone()->getName().toStdString()); + cmd.set_target_zone("table"); // we currently only support creating tokens on the table cmd.set_x(gridPoint.x()); cmd.set_y(gridPoint.y()); @@ -2754,7 +2762,7 @@ void Player::playCard(CardItem *card, bool faceDown) * Like {@link Player::playCard}, but forces the card to be played to the table zone. * Cards with tablerow 3 (the stack) will be played to tablerow 1 (the noncreatures row). */ -void Player::playCardToTable(CardItem *card, bool faceDown) +void Player::playCardToTable(const CardItem *card, bool faceDown) { if (card == nullptr) { return; diff --git a/cockatrice/src/game/player/player.h b/cockatrice/src/game/player/player.h index 5404cdd96..b4b4a35b9 100644 --- a/cockatrice/src/game/player/player.h +++ b/cockatrice/src/game/player/player.h @@ -402,7 +402,7 @@ public: void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void playCard(CardItem *c, bool faceDown); - void playCardToTable(CardItem *c, bool faceDown); + void playCardToTable(const CardItem *c, bool faceDown); void addCard(CardItem *c); void deleteCard(CardItem *c); void addZone(CardZone *z); diff --git a/common/server_player.cpp b/common/server_player.cpp index 74d4b751a..60ebfa3c0 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -1358,6 +1358,9 @@ Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & return Response::RespNameNotFound; } } + + // prevent attaching from non-table zones + // (attaching from non-table zones is handled client-side by moving the card to table zone first) if (!startzone->hasCoords()) { return Response::RespContextError; }