From 651b898ee17bc2db7ec0d523f5b75530aaa3ab43 Mon Sep 17 00:00:00 2001 From: DawnFire42 Date: Sat, 14 Mar 2026 18:42:21 -0400 Subject: [PATCH] feat: add 'Move to Table' contextual menu action Adds a 'Table' option to the 'Move to' right-click menu that places each card in its correct table row based on card type, rather than requiring drag-and-drop. Uses per-card iteration so creatures, lands, and noncreatures each land in their proper row. Contrary to the Play option, instants and sorceries also go to the table, covering for what the play option doesn't do. --- .../src/client/settings/shortcuts_settings.h | 6 ++--- .../src/game/player/card_menu_action_type.h | 5 +++- cockatrice/src/game/player/menu/move_menu.cpp | 7 +++++ cockatrice/src/game/player/menu/move_menu.h | 1 + cockatrice/src/game/player/player_actions.cpp | 27 +++++++++++++++++++ 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/cockatrice/src/client/settings/shortcuts_settings.h b/cockatrice/src/client/settings/shortcuts_settings.h index 47332b8c4..76b9df727 100644 --- a/cockatrice/src/client/settings/shortcuts_settings.h +++ b/cockatrice/src/client/settings/shortcuts_settings.h @@ -563,9 +563,9 @@ private: {"Player/aPlayFacedown", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Battlefield, Face Down"), parseSequenceString(""), ShortcutGroup::Move_selected)}, - {"Player/aPlay", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Battlefield"), - parseSequenceString(""), - ShortcutGroup::Move_selected)}, + {"Player/aMoveToTable", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Battlefield"), + parseSequenceString(""), + ShortcutGroup::Move_selected)}, {"Player/aViewHand", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Hand"), parseSequenceString(""), ShortcutGroup::View)}, {"Player/aViewGraveyard", diff --git a/cockatrice/src/game/player/card_menu_action_type.h b/cockatrice/src/game/player/card_menu_action_type.h index aec6d6397..1b63674fa 100644 --- a/cockatrice/src/game/player/card_menu_action_type.h +++ b/cockatrice/src/game/player/card_menu_action_type.h @@ -9,17 +9,20 @@ enum CardMenuActionType { + // Per-card attribute actions (must be <= cmClone for cardMenuAction() dispatch) cmTap, cmUntap, cmDoesntUntap, cmFlip, cmPeek, cmClone, + // Move actions (must be > cmClone for cardMenuAction() dispatch) cmMoveToTopLibrary, cmMoveToBottomLibrary, cmMoveToHand, cmMoveToGraveyard, - cmMoveToExile + cmMoveToExile, + cmMoveToTable }; #endif // COCKATRICE_CARD_MENU_ACTION_TYPE_H diff --git a/cockatrice/src/game/player/menu/move_menu.cpp b/cockatrice/src/game/player/menu/move_menu.cpp index d27e16009..736d2fcc2 100644 --- a/cockatrice/src/game/player/menu/move_menu.cpp +++ b/cockatrice/src/game/player/menu/move_menu.cpp @@ -17,6 +17,8 @@ MoveMenu::MoveMenu(Player *player) : QMenu(tr("Move to")) aMoveToGraveyard->setData(cmMoveToGraveyard); aMoveToExile = new QAction(this); aMoveToExile->setData(cmMoveToExile); + aMoveToTable = new QAction(this); + aMoveToTable->setData(cmMoveToTable); connect(aMoveToTopLibrary, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); connect(aMoveToBottomLibrary, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); @@ -25,11 +27,14 @@ MoveMenu::MoveMenu(Player *player) : QMenu(tr("Move to")) connect(aMoveToHand, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); connect(aMoveToGraveyard, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); connect(aMoveToExile, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); + connect(aMoveToTable, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); addAction(aMoveToTopLibrary); addAction(aMoveToXfromTopOfLibrary); addAction(aMoveToBottomLibrary); addSeparator(); + addAction(aMoveToTable); + addSeparator(); addAction(aMoveToHand); addSeparator(); addAction(aMoveToGraveyard); @@ -50,6 +55,7 @@ void MoveMenu::setShortcutsActive() aMoveToHand->setShortcuts(shortcuts.getShortcut("Player/aMoveToHand")); aMoveToGraveyard->setShortcuts(shortcuts.getShortcut("Player/aMoveToGraveyard")); aMoveToExile->setShortcuts(shortcuts.getShortcut("Player/aMoveToExile")); + aMoveToTable->setShortcuts(shortcuts.getShortcut("Player/aMoveToTable")); } void MoveMenu::retranslateUi() @@ -59,5 +65,6 @@ void MoveMenu::retranslateUi() aMoveToBottomLibrary->setText(tr("&Bottom of library in random order")); aMoveToHand->setText(tr("&Hand")); aMoveToGraveyard->setText(tr("&Graveyard")); + aMoveToTable->setText(tr("T&able")); aMoveToExile->setText(tr("&Exile")); } \ No newline at end of file diff --git a/cockatrice/src/game/player/menu/move_menu.h b/cockatrice/src/game/player/menu/move_menu.h index 5bf657fa4..dc39cb6a5 100644 --- a/cockatrice/src/game/player/menu/move_menu.h +++ b/cockatrice/src/game/player/menu/move_menu.h @@ -23,6 +23,7 @@ public: QAction *aMoveToBottomLibrary = nullptr; QAction *aMoveToHand = nullptr; + QAction *aMoveToTable = nullptr; QAction *aMoveToGraveyard = nullptr; QAction *aMoveToExile = nullptr; }; diff --git a/cockatrice/src/game/player/player_actions.cpp b/cockatrice/src/game/player/player_actions.cpp index ee8a7b1fc..2a0061c77 100644 --- a/cockatrice/src/game/player/player_actions.cpp +++ b/cockatrice/src/game/player/player_actions.cpp @@ -1926,6 +1926,33 @@ void PlayerActions::cardMenuAction() commandList.append(cmd); break; } + case cmMoveToTable: { + for (const auto &card : cardList) { + auto *cmd = new Command_MoveCard; + cmd->set_start_player_id(startPlayerId); + cmd->set_start_zone(startZone.toStdString()); + cmd->set_target_player_id(player->getPlayerInfo()->getId()); + cmd->set_target_zone(ZoneNames::TABLE); + cmd->set_x(-1); + + CardToMove *ctm = cmd->mutable_cards_to_move()->add_card(); + ctm->set_card_id(card->getId()); + ctm->set_face_down(false); + + int tableRow = 0; + ExactCard exactCard = card->getCard(); + if (exactCard) { + const CardInfo &info = exactCard.getInfo(); + tableRow = info.getUiAttributes().tableRow; + ctm->set_pt(info.getPowTough().toStdString()); + ctm->set_tapped(info.getUiAttributes().cipt); + } + + cmd->set_y(TableZone::tableRowToGridY(tableRow)); + commandList.append(cmd); + } + break; + } default: break; }