mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-08 19:13:25 -08:00
Route random hand reveals through PlayerActions
Keep command creation, dispatch and response handling in the game action layer. HandMenu requests the typed operation and presents the count and failure dialogs. Show the chosen recipient, distinguish the count action from the immediate single-card reveal, and use the game window as parent.
This commit is contained in:
parent
ccdee18db2
commit
afe9bf77af
5 changed files with 59 additions and 28 deletions
|
|
@ -6,6 +6,8 @@
|
||||||
#include "../player_graphics_item.h"
|
#include "../player_graphics_item.h"
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
#include <QGraphicsScene>
|
||||||
|
#include <QGraphicsView>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
@ -24,8 +26,6 @@
|
||||||
#include <libcockatrice/game/player/player_manager.h>
|
#include <libcockatrice/game/player/player_manager.h>
|
||||||
#include <libcockatrice/game/zones/hand_zone_logic.h>
|
#include <libcockatrice/game/zones/hand_zone_logic.h>
|
||||||
#include <libcockatrice/network/client/abstract/abstract_client.h>
|
#include <libcockatrice/network/client/abstract/abstract_client.h>
|
||||||
#include <libcockatrice/protocol/pb/response.pb.h>
|
|
||||||
#include <libcockatrice/protocol/pending_command.h>
|
|
||||||
#include <libcockatrice/utility/zone_names.h>
|
#include <libcockatrice/utility/zone_names.h>
|
||||||
|
|
||||||
class QWidget;
|
class QWidget;
|
||||||
|
|
@ -33,6 +33,7 @@ class QWidget;
|
||||||
HandMenu::HandMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(parent), player(_player)
|
HandMenu::HandMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(parent), player(_player)
|
||||||
{
|
{
|
||||||
auto *actions = player->getLogic()->getPlayerActions();
|
auto *actions = player->getLogic()->getPlayerActions();
|
||||||
|
connect(actions, &PlayerActions::randomHandRevealFailed, this, &HandMenu::onRandomHandRevealFailed);
|
||||||
|
|
||||||
if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) {
|
if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) {
|
||||||
aViewHand = new QAction(this);
|
aViewHand = new QAction(this);
|
||||||
|
|
@ -161,7 +162,7 @@ void HandMenu::retranslateUi()
|
||||||
|
|
||||||
mRevealRandomHandCard->setTitle(tr("Reveal r&andom card to..."));
|
mRevealRandomHandCard->setTitle(tr("Reveal r&andom card to..."));
|
||||||
aRevealRandomHandCardToAll->setText(tr("All players"));
|
aRevealRandomHandCardToAll->setText(tr("All players"));
|
||||||
mRevealRandomHandCards->setTitle(tr("Reveal random cards to..."));
|
mRevealRandomHandCards->setTitle(tr("Reveal a chosen number of random cards to..."));
|
||||||
aRevealRandomHandCardsToAll->setText(tr("All players"));
|
aRevealRandomHandCardsToAll->setText(tr("All players"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -253,15 +254,19 @@ void HandMenu::onRevealRandomHandCardTriggered()
|
||||||
|
|
||||||
void HandMenu::populateRevealRandomHandCardsMenuWithActivePlayers()
|
void HandMenu::populateRevealRandomHandCardsMenuWithActivePlayers()
|
||||||
{
|
{
|
||||||
|
const bool hasCards = !player->getLogic()->getHandZone()->getCards().isEmpty();
|
||||||
mRevealRandomHandCards->clear();
|
mRevealRandomHandCards->clear();
|
||||||
|
aRevealRandomHandCardsToAll->setEnabled(hasCards);
|
||||||
mRevealRandomHandCards->addAction(aRevealRandomHandCardsToAll);
|
mRevealRandomHandCards->addAction(aRevealRandomHandCardsToAll);
|
||||||
mRevealRandomHandCards->addSeparator();
|
mRevealRandomHandCards->addSeparator();
|
||||||
for (auto *other : player->getLogic()->getGame()->getPlayerManager()->getPlayers()) {
|
const auto &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values();
|
||||||
|
for (auto *other : players) {
|
||||||
if (other == player->getLogic()) {
|
if (other == player->getLogic()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto *action = mRevealRandomHandCards->addAction(other->getPlayerInfo()->getName());
|
auto *action = mRevealRandomHandCards->addAction(other->getPlayerInfo()->getName());
|
||||||
action->setData(other->getPlayerInfo()->getId());
|
action->setData(other->getPlayerInfo()->getId());
|
||||||
|
action->setEnabled(hasCards);
|
||||||
connect(action, &QAction::triggered, this, &HandMenu::onRevealRandomHandCardsTriggered);
|
connect(action, &QAction::triggered, this, &HandMenu::onRevealRandomHandCardsTriggered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -280,36 +285,45 @@ void HandMenu::onRevealRandomHandCardsTriggered()
|
||||||
if (!client) {
|
if (!client) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto *dialog = new QInputDialog(this);
|
auto *dialog = new QInputDialog(dialogParent());
|
||||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
dialog->setWindowTitle(tr("Reveal Random Hand Cards"));
|
dialog->setWindowTitle(tr("Reveal Random Hand Cards"));
|
||||||
dialog->setLabelText(tr("Number of distinct random cards to reveal:"));
|
dialog->setLabelText(tr("Number of distinct random cards to reveal to %1:").arg(action->text()));
|
||||||
dialog->setInputMode(QInputDialog::IntInput);
|
dialog->setInputMode(QInputDialog::IntInput);
|
||||||
dialog->setIntRange(1, handSize);
|
dialog->setIntRange(1, handSize);
|
||||||
dialog->setIntValue(qMin(2, handSize));
|
dialog->setIntValue(qMin(2, handSize));
|
||||||
|
connect(this, &QObject::destroyed, dialog, &QDialog::reject);
|
||||||
connect(client, &QObject::destroyed, dialog, &QDialog::reject);
|
connect(client, &QObject::destroyed, dialog, &QDialog::reject);
|
||||||
connect(actions, &QObject::destroyed, dialog, &QDialog::reject);
|
connect(actions, &QObject::destroyed, dialog, &QDialog::reject);
|
||||||
connect(dialog, &QDialog::accepted, this, [this, dialog, actions, client, targetId] {
|
connect(dialog, &QDialog::accepted, this, [dialog, actions, client, targetId] {
|
||||||
if (!actions || !client) {
|
if (!actions || !client) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto *pending = actions->prepareRandomHandReveal(targetId, dialog->intValue());
|
actions->actRevealRandomHandCards(targetId, dialog->intValue());
|
||||||
connect(pending, &PendingCommand::finished, this, [this, actions, client](const Response &response) {
|
|
||||||
if (!actions || !client || response.response_code() == Response::RespOk) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const QString text =
|
|
||||||
response.response_code() == Response::RespInvalidCommand
|
|
||||||
? tr("This server does not support revealing multiple random cards. No cards were revealed.")
|
|
||||||
: tr("The random reveal could not be completed. The hand or recipient may have changed.");
|
|
||||||
auto *message =
|
|
||||||
new QMessageBox(QMessageBox::Warning, tr("Reveal Random Hand Cards"), text, QMessageBox::Ok, this);
|
|
||||||
message->setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
connect(actions, &QObject::destroyed, message, &QDialog::reject);
|
|
||||||
connect(client, &QObject::destroyed, message, &QDialog::reject);
|
|
||||||
message->open();
|
|
||||||
});
|
|
||||||
actions->sendGameCommand(pending);
|
|
||||||
});
|
});
|
||||||
dialog->open();
|
dialog->open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget *HandMenu::dialogParent() const
|
||||||
|
{
|
||||||
|
if (auto *view = player->scene() ? player->scene()->views().value(0) : nullptr) {
|
||||||
|
return view->window();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandMenu::onRandomHandRevealFailed(bool unsupported)
|
||||||
|
{
|
||||||
|
const QString text =
|
||||||
|
unsupported ? tr("This server does not support revealing multiple random cards. No cards were revealed.")
|
||||||
|
: tr("The random reveal could not be completed. The hand or recipient may have changed.");
|
||||||
|
auto *message = new QMessageBox(QMessageBox::Warning, tr("Reveal Random Hand Cards"), text, QMessageBox::Ok,
|
||||||
|
dialogParent());
|
||||||
|
message->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
connect(this, &QObject::destroyed, message, &QDialog::reject);
|
||||||
|
connect(player->getLogic()->getPlayerActions(), &QObject::destroyed, message, &QDialog::reject);
|
||||||
|
if (auto *client = player->getLogic()->getGame()->getClientForPlayer(player->getLogic()->getPlayerInfo()->getId())) {
|
||||||
|
connect(client, &QObject::destroyed, message, &QDialog::reject);
|
||||||
|
}
|
||||||
|
message->open();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,10 @@ private slots:
|
||||||
void onRevealRandomHandCardTriggered();
|
void onRevealRandomHandCardTriggered();
|
||||||
void populateRevealRandomHandCardsMenuWithActivePlayers();
|
void populateRevealRandomHandCardsMenuWithActivePlayers();
|
||||||
void onRevealRandomHandCardsTriggered();
|
void onRevealRandomHandCardsTriggered();
|
||||||
|
void onRandomHandRevealFailed(bool unsupported);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QWidget *dialogParent() const;
|
||||||
PlayerGraphicsItem *player;
|
PlayerGraphicsItem *player;
|
||||||
|
|
||||||
QAction *aViewHand = nullptr;
|
QAction *aViewHand = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
@page revealing_cards Revealing Cards
|
@page revealing_cards Revealing Cards
|
||||||
|
|
||||||
The **Hand** menu offers **Reveal random cards to...**. Choose **All players** or a specific player, then choose how many cards to reveal.
|
The **Hand** menu offers **Reveal a chosen number of random cards to...**. Choose **All players** or a specific player, then choose how many cards to reveal. The count dialog displays the chosen recipient.
|
||||||
|
|
||||||
The server chooses distinct cards without replacement. Two copies of the same card are separate physical cards and can both be chosen. The operation does not reorder, move, or otherwise change the hand.
|
The server chooses distinct cards without replacement. Two copies of the same card are separate physical cards and can both be chosen. The operation does not reorder, move, or otherwise change the hand.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
#include <QPointF>
|
#include <QPointF>
|
||||||
|
#include <QPointer>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
@ -47,6 +48,7 @@
|
||||||
#include <libcockatrice/deck_list/loaded_deck.h>
|
#include <libcockatrice/deck_list/loaded_deck.h>
|
||||||
#include <libcockatrice/interfaces/interface_card_preference_provider.h>
|
#include <libcockatrice/interfaces/interface_card_preference_provider.h>
|
||||||
#include <libcockatrice/interfaces/interface_interface_settings_provider.h>
|
#include <libcockatrice/interfaces/interface_interface_settings_provider.h>
|
||||||
|
#include <libcockatrice/network/client/abstract/abstract_client.h>
|
||||||
#include <libcockatrice/protocol/pb/command_attach_card.pb.h>
|
#include <libcockatrice/protocol/pb/command_attach_card.pb.h>
|
||||||
#include <libcockatrice/protocol/pb/command_change_zone_properties.pb.h>
|
#include <libcockatrice/protocol/pb/command_change_zone_properties.pb.h>
|
||||||
#include <libcockatrice/protocol/pb/command_create_arrow.pb.h>
|
#include <libcockatrice/protocol/pb/command_create_arrow.pb.h>
|
||||||
|
|
@ -66,6 +68,8 @@
|
||||||
#include <libcockatrice/protocol/pb/command_shuffle.pb.h>
|
#include <libcockatrice/protocol/pb/command_shuffle.pb.h>
|
||||||
#include <libcockatrice/protocol/pb/command_undo_draw.pb.h>
|
#include <libcockatrice/protocol/pb/command_undo_draw.pb.h>
|
||||||
#include <libcockatrice/protocol/pb/context_move_card.pb.h>
|
#include <libcockatrice/protocol/pb/context_move_card.pb.h>
|
||||||
|
#include <libcockatrice/protocol/pb/response.pb.h>
|
||||||
|
#include <libcockatrice/protocol/pending_command.h>
|
||||||
#include <libcockatrice/utility/clamped_arithmetic.h>
|
#include <libcockatrice/utility/clamped_arithmetic.h>
|
||||||
#include <libcockatrice/utility/color.h>
|
#include <libcockatrice/utility/color.h>
|
||||||
#include <libcockatrice/utility/counter_limits.h>
|
#include <libcockatrice/utility/counter_limits.h>
|
||||||
|
|
@ -1756,15 +1760,25 @@ void PlayerActions::actRevealRandomHandCard(int revealToPlayerId)
|
||||||
sendGameCommand(cmd);
|
sendGameCommand(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingCommand *PlayerActions::prepareRandomHandReveal(int revealToPlayerId, int amount)
|
void PlayerActions::actRevealRandomHandCards(int revealToPlayerId, int amount)
|
||||||
{
|
{
|
||||||
|
QPointer<AbstractClient> client = player->getGame()->getClientForPlayer(player->getPlayerInfo()->getId());
|
||||||
|
if (!client) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Command_RevealRandomCards cmd;
|
Command_RevealRandomCards cmd;
|
||||||
if (revealToPlayerId != -1) {
|
if (revealToPlayerId != -1) {
|
||||||
cmd.set_player_id(revealToPlayerId);
|
cmd.set_player_id(revealToPlayerId);
|
||||||
}
|
}
|
||||||
cmd.set_zone_name(ZoneNames::HAND);
|
cmd.set_zone_name(ZoneNames::HAND);
|
||||||
cmd.set_number_of_cards(amount);
|
cmd.set_number_of_cards(amount);
|
||||||
return prepareGameCommand(cmd);
|
auto *pending = prepareGameCommand(cmd);
|
||||||
|
connect(pending, &PendingCommand::finished, this, [this, client](const Response &response) {
|
||||||
|
if (client && response.response_code() != Response::RespOk) {
|
||||||
|
emit randomHandRevealFailed(response.response_code() == Response::RespInvalidCommand);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sendGameCommand(pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerActions::actRevealLibrary(int revealToPlayerId)
|
void PlayerActions::actRevealLibrary(int revealToPlayerId)
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,6 @@ public:
|
||||||
* @param numberCards How many cards to dump, -1 for all.
|
* @param numberCards How many cards to dump, -1 for all.
|
||||||
*/
|
*/
|
||||||
PendingCommand *prepareZoneDump(CardZoneLogic *zone, int numberCards);
|
PendingCommand *prepareZoneDump(CardZoneLogic *zone, int numberCards);
|
||||||
PendingCommand *prepareRandomHandReveal(int revealToPlayerId, int amount);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the tapped state of the cards that do not already have it.
|
* @brief Sets the tapped state of the cards that do not already have it.
|
||||||
|
|
@ -121,6 +120,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void randomHandRevealFailed(bool unsupported);
|
||||||
void requestViewTopCardsDialog(int defaultNumberTopCards, int deckSize);
|
void requestViewTopCardsDialog(int defaultNumberTopCards, int deckSize);
|
||||||
void requestViewBottomCardsDialog(int defaultNumberBottomCards, int deckSize);
|
void requestViewBottomCardsDialog(int defaultNumberBottomCards, int deckSize);
|
||||||
void requestShuffleTopDialog(int defaultNumberTopCards, int maxCards);
|
void requestShuffleTopDialog(int defaultNumberTopCards, int maxCards);
|
||||||
|
|
@ -280,6 +280,7 @@ public slots:
|
||||||
void actReveal(QList<CardState *> selectedCards, QAction *action);
|
void actReveal(QList<CardState *> selectedCards, QAction *action);
|
||||||
void actRevealHand(int revealToPlayerId);
|
void actRevealHand(int revealToPlayerId);
|
||||||
void actRevealRandomHandCard(int revealToPlayerId);
|
void actRevealRandomHandCard(int revealToPlayerId);
|
||||||
|
void actRevealRandomHandCards(int revealToPlayerId, int amount);
|
||||||
void actRevealLibrary(int revealToPlayerId);
|
void actRevealLibrary(int revealToPlayerId);
|
||||||
|
|
||||||
void actSortHand();
|
void actSortHand();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue