From 03db4ccce6c6b6f9871082fb3e73b968d139428a Mon Sep 17 00:00:00 2001 From: RickyRister <42636155+RickyRister@users.noreply.github.com> Date: Tue, 17 Dec 2024 20:38:22 -0800 Subject: [PATCH] ability to directly attach from other zones (#5250) * add attach and draw arrow actions to more card menus * implement attaching from other zones * disallow attaching from deck * do nothing if target is already attached * add null check --- cockatrice/src/game/board/arrow_item.cpp | 44 +++++++++++++------ cockatrice/src/game/board/arrow_item.h | 2 + cockatrice/src/game/player/player.cpp | 55 ++++++++++++++++++++++++ cockatrice/src/game/player/player.h | 1 + 4 files changed, 89 insertions(+), 13 deletions(-) diff --git a/cockatrice/src/game/board/arrow_item.cpp b/cockatrice/src/game/board/arrow_item.cpp index 430ea6adc..42fb20b5c 100644 --- a/cockatrice/src/game/board/arrow_item.cpp +++ b/cockatrice/src/game/board/arrow_item.cpp @@ -307,25 +307,43 @@ void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } } +void ArrowAttachItem::attachCards(CardItem *startCard, const CardItem *targetCard) +{ + // do nothing if target is already attached to another card + if (targetCard->getAttachedTo()) { + return; + } + + CardZone *startZone = startCard->getZone(); + CardZone *targetZone = targetCard->getZone(); + + // move card onto table first if attaching from some other zone + if (startZone->getName() != "table") { + auto info = startCard->getInfo(); + player->playCardToTable(startCard, false, info ? info->getCipt() : false); + } + + Command_AttachCard cmd; + cmd.set_start_zone("table"); + cmd.set_card_id(startCard->getId()); + cmd.set_target_player_id(targetZone->getPlayer()->getId()); + cmd.set_target_zone(targetZone->getName().toStdString()); + cmd.set_target_card_id(targetCard->getId()); + + player->sendGameCommand(cmd); +} + void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (!startItem) return; if (targetItem && (targetItem != startItem)) { - CardItem *startCard = qgraphicsitem_cast(startItem); - CardZone *startZone = startCard->getZone(); - CardItem *targetCard = qgraphicsitem_cast(targetItem); - CardZone *targetZone = targetCard->getZone(); - - Command_AttachCard cmd; - cmd.set_start_zone(startZone->getName().toStdString()); - cmd.set_card_id(startCard->getId()); - cmd.set_target_player_id(targetZone->getPlayer()->getId()); - cmd.set_target_zone(targetZone->getName().toStdString()); - cmd.set_target_card_id(targetCard->getId()); - - player->sendGameCommand(cmd); + auto startCard = qgraphicsitem_cast(startItem); + auto targetCard = qgraphicsitem_cast(targetItem); + if (startCard && targetCard) { + attachCards(startCard, targetCard); + } } delArrow(); diff --git a/cockatrice/src/game/board/arrow_item.h b/cockatrice/src/game/board/arrow_item.h index 04d4bc207..9ca21d938 100644 --- a/cockatrice/src/game/board/arrow_item.h +++ b/cockatrice/src/game/board/arrow_item.h @@ -88,6 +88,8 @@ class ArrowAttachItem : public ArrowItem private: QList childArrows; + void attachCards(CardItem *startCard, const CardItem *targetCard); + public: ArrowAttachItem(ArrowTarget *_startItem); void addChildArrow(ArrowAttachItem *childArrow); diff --git a/cockatrice/src/game/player/player.cpp b/cockatrice/src/game/player/player.cpp index 869abecb2..876e0f7b5 100644 --- a/cockatrice/src/game/player/player.cpp +++ b/cockatrice/src/game/player/player.cpp @@ -2666,6 +2666,46 @@ void Player::playCard(CardItem *card, bool faceDown, bool tapped) sendGameCommand(cmd); } +/** + * 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, bool tapped) +{ + if (card == nullptr) { + return; + } + + Command_MoveCard cmd; + cmd.set_start_player_id(card->getZone()->getPlayer()->getId()); + cmd.set_start_zone(card->getZone()->getName().toStdString()); + cmd.set_target_player_id(getId()); + CardToMove *cardToMove = cmd.mutable_cards_to_move()->add_card(); + cardToMove->set_card_id(card->getId()); + + CardInfoPtr info = card->getInfo(); + if (!info) { + return; + } + + int tableRow = faceDown ? 2 : info->getTableRow(); + // default instant/sorcery cards to the noncreatures row + if (tableRow > 2) { + tableRow = 1; + } + + QPoint gridPoint = QPoint(-1, TableZone::clampValidTableRow(2 - tableRow)); + cardToMove->set_face_down(faceDown); + if (!faceDown) { + cardToMove->set_pt(info->getPowTough().toStdString()); + } + cardToMove->set_tapped(faceDown ? false : tapped); + cmd.set_target_zone("table"); + cmd.set_x(gridPoint.x()); + cmd.set_y(gridPoint.y()); + sendGameCommand(cmd); +} + void Player::addCard(CardItem *card) { emit newCardAdded(card); @@ -3635,6 +3675,7 @@ void Player::updateCardMenu(const CardItem *card) cardMenu->addSeparator(); } else if (card->getZone()->getName() == "stack") { // Card is on the stack + cardMenu->addAction(aAttach); cardMenu->addAction(aDrawArrow); cardMenu->addSeparator(); cardMenu->addAction(aClone); @@ -3649,12 +3690,17 @@ void Player::updateCardMenu(const CardItem *card) cardMenu->addAction(aSelectAll); cardMenu->addAction(aPlay); cardMenu->addAction(aPlayFacedown); + cardMenu->addSeparator(); cardMenu->addAction(aClone); cardMenu->addMenu(moveMenu); cardMenu->addSeparator(); cardMenu->addAction(aSelectAll); + cardMenu->addSeparator(); + cardMenu->addAction(aAttach); + cardMenu->addAction(aDrawArrow); + addRelatedCardView(card, cardMenu); addRelatedCardActions(card, cardMenu); } else { @@ -3667,8 +3713,17 @@ void Player::updateCardMenu(const CardItem *card) connect(revealMenu, &QMenu::triggered, this, &Player::actReveal); cardMenu->addMenu(moveMenu); + + // actions that are really wonky when done from deck or sideboard + if (card->getZone()->getName() == "hand") { + cardMenu->addSeparator(); + cardMenu->addAction(aAttach); + cardMenu->addAction(aDrawArrow); + } + cardMenu->addSeparator(); cardMenu->addAction(aSelectAll); + addRelatedCardView(card, cardMenu); } } else { diff --git a/cockatrice/src/game/player/player.h b/cockatrice/src/game/player/player.h index 484e509d7..e8d149e42 100644 --- a/cockatrice/src/game/player/player.h +++ b/cockatrice/src/game/player/player.h @@ -390,6 +390,7 @@ public: void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void playCard(CardItem *c, bool faceDown, bool tapped); + void playCardToTable(CardItem *c, bool faceDown, bool tapped); void addCard(CardItem *c); void deleteCard(CardItem *c); void addZone(CardZone *z);