[Game][Player] Move dialog creation out of player_actions and into player_dialogs (#6946)

* [Game][Player] Split Player into PlayerLogic/PlayerGraphicsItem

Took 4 minutes

Took 48 seconds

Took 2 minutes

* Drop early return.

Took 1 hour 13 minutes


Took 2 minutes

Took 1 minute

Took 24 seconds

* [Game][Player] Split Player into PlayerLogic/PlayerGraphicsItem

Took 4 minutes

Took 58 seconds

* [Game][Menus] Make Menus accept PlayerGraphicsItem instead of PlayerLogic

Took 7 minutes

Took 4 minutes

Took 9 seconds

Took 2 minutes


Took 5 minutes

Took 58 seconds

* [Game][Player] Split Player into PlayerLogic/PlayerGraphicsItem

Took 4 minutes

Took 2 minutes

* [Game][Menus] Make Menus accept PlayerGraphicsItem instead of PlayerLogic

Took 7 minutes


Took 1 minute

Took 57 seconds

* [Game][Player] Move dialog creation out of player_actions and into player_dialogs

Took 3 minutes

Took 1 second

* Fix typo.

Took 5 minutes

* Addressed comments.

Took 16 minutes

Took 11 seconds

* Reintroduce clearCardsToDelete check.

Took 3 minutes

* Capture cards before semaphore.

Took 1 minute

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-06-09 08:22:59 +02:00 committed by Vasco Guerreiro Vintém Morais
parent f80b43139d
commit 571da4f1c6
13 changed files with 664 additions and 231 deletions

View file

@ -101,6 +101,7 @@ set(cockatrice_SOURCES
src/game/player/menu/utility_menu.cpp src/game/player/menu/utility_menu.cpp
src/game/player/player_actions.cpp src/game/player/player_actions.cpp
src/game/player/player_area.cpp src/game/player/player_area.cpp
src/game/player/player_dialogs.cpp
src/game/player/player_event_handler.cpp src/game/player/player_event_handler.cpp
src/game/player/player_graphics_item.cpp src/game/player/player_graphics_item.cpp
src/game/player/player_info.cpp src/game/player/player_info.cpp

View file

@ -79,7 +79,7 @@ CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardItem *_card, bool _sho
// Actions using selection directly // Actions using selection directly
aUnattach = makeAction(this, [actions, sel]() { actions->actUnattach(sel()); }); aUnattach = makeAction(this, [actions, sel]() { actions->actUnattach(sel()); });
aSetAnnotation = makeAction(this, [actions, sel]() { actions->actSetAnnotation(sel()); }); aSetAnnotation = makeAction(this, [actions, sel]() { actions->actRequestSetAnnotationDialog(sel()); });
aPlay = makeAction(this, [actions, sel]() { actions->actPlay(sel()); }); aPlay = makeAction(this, [actions, sel]() { actions->actPlay(sel()); });
aPlayFacedown = makeAction(this, [actions, sel]() { actions->actPlayFacedown(sel()); }); aPlayFacedown = makeAction(this, [actions, sel]() { actions->actPlayFacedown(sel()); });
aHide = makeAction(this, [actions, sel]() { actions->actHide(sel()); }); aHide = makeAction(this, [actions, sel]() { actions->actHide(sel()); });
@ -115,7 +115,7 @@ CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardItem *_card, bool _sho
removeAction->setIcon(circleIcon); removeAction->setIcon(circleIcon);
aRemoveCounter.append(removeAction); aRemoveCounter.append(removeAction);
auto *setAction = makeAction(this, [actions, sel, i]() { actions->actSetCardCounter(sel(), i); }); auto *setAction = makeAction(this, [actions, sel, i]() { actions->actRequestSetCardCounterDialog(sel(), i); });
setAction->setIcon(circleIcon); setAction->setIcon(circleIcon);
aSetCounter.append(setAction); aSetCounter.append(setAction);
} }

View file

@ -62,7 +62,7 @@ HandMenu::HandMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(p
addSeparator(); addSeparator();
aMulligan = new QAction(this); aMulligan = new QAction(this);
connect(aMulligan, &QAction::triggered, actions, &PlayerActions::actMulligan); connect(aMulligan, &QAction::triggered, actions, &PlayerActions::actRequestMulliganDialog);
addAction(aMulligan); addAction(aMulligan);
// Mulligan same size // Mulligan same size

View file

@ -101,13 +101,13 @@ void LibraryMenu::createDrawActions()
aDrawCard = new QAction(this); aDrawCard = new QAction(this);
connect(aDrawCard, &QAction::triggered, playerActions, &PlayerActions::actDrawCard); connect(aDrawCard, &QAction::triggered, playerActions, &PlayerActions::actDrawCard);
aDrawCards = new QAction(this); aDrawCards = new QAction(this);
connect(aDrawCards, &QAction::triggered, playerActions, &PlayerActions::actDrawCards); connect(aDrawCards, &QAction::triggered, playerActions, &PlayerActions::actRequestDrawCardsDialog);
aUndoDraw = new QAction(this); aUndoDraw = new QAction(this);
connect(aUndoDraw, &QAction::triggered, playerActions, &PlayerActions::actUndoDraw); connect(aUndoDraw, &QAction::triggered, playerActions, &PlayerActions::actUndoDraw);
aDrawBottomCard = new QAction(this); aDrawBottomCard = new QAction(this);
connect(aDrawBottomCard, &QAction::triggered, playerActions, &PlayerActions::actDrawBottomCard); connect(aDrawBottomCard, &QAction::triggered, playerActions, &PlayerActions::actDrawBottomCard);
aDrawBottomCards = new QAction(this); aDrawBottomCards = new QAction(this);
connect(aDrawBottomCards, &QAction::triggered, playerActions, &PlayerActions::actDrawBottomCards); connect(aDrawBottomCards, &QAction::triggered, playerActions, &PlayerActions::actRequestDrawBottomCardsDialog);
} }
} }
@ -119,9 +119,9 @@ void LibraryMenu::createShuffleActions()
aShuffle = new QAction(this); aShuffle = new QAction(this);
connect(aShuffle, &QAction::triggered, playerActions, &PlayerActions::actShuffle); connect(aShuffle, &QAction::triggered, playerActions, &PlayerActions::actShuffle);
aShuffleTopCards = new QAction(this); aShuffleTopCards = new QAction(this);
connect(aShuffleTopCards, &QAction::triggered, playerActions, &PlayerActions::actShuffleTop); connect(aShuffleTopCards, &QAction::triggered, playerActions, &PlayerActions::actRequestShuffleTopDialog);
aShuffleBottomCards = new QAction(this); aShuffleBottomCards = new QAction(this);
connect(aShuffleBottomCards, &QAction::triggered, playerActions, &PlayerActions::actShuffleBottom); connect(aShuffleBottomCards, &QAction::triggered, playerActions, &PlayerActions::actRequestShuffleBottomDialog);
} }
} }
@ -150,7 +150,8 @@ void LibraryMenu::createMoveActions()
connect(aMoveTopCardsToExileFaceDown, &QAction::triggered, playerActions, connect(aMoveTopCardsToExileFaceDown, &QAction::triggered, playerActions,
&PlayerActions::actMoveTopCardsToExileFaceDown); &PlayerActions::actMoveTopCardsToExileFaceDown);
aMoveTopCardsUntil = new QAction(this); aMoveTopCardsUntil = new QAction(this);
connect(aMoveTopCardsUntil, &QAction::triggered, playerActions, &PlayerActions::actMoveTopCardsUntil); connect(aMoveTopCardsUntil, &QAction::triggered, playerActions,
&PlayerActions::actRequestMoveTopCardsUntilDialog);
aMoveTopCardToBottom = new QAction(this); aMoveTopCardToBottom = new QAction(this);
connect(aMoveTopCardToBottom, &QAction::triggered, playerActions, &PlayerActions::actMoveTopCardToBottom); connect(aMoveTopCardToBottom, &QAction::triggered, playerActions, &PlayerActions::actMoveTopCardToBottom);
@ -189,9 +190,9 @@ void LibraryMenu::createViewActions()
connect(aViewLibrary, &QAction::triggered, playerActions, &PlayerActions::actViewLibrary); connect(aViewLibrary, &QAction::triggered, playerActions, &PlayerActions::actViewLibrary);
aViewTopCards = new QAction(this); aViewTopCards = new QAction(this);
connect(aViewTopCards, &QAction::triggered, playerActions, &PlayerActions::actViewTopCards); connect(aViewTopCards, &QAction::triggered, playerActions, &PlayerActions::actRequestViewTopCardsDialog);
aViewBottomCards = new QAction(this); aViewBottomCards = new QAction(this);
connect(aViewBottomCards, &QAction::triggered, playerActions, &PlayerActions::actViewBottomCards); connect(aViewBottomCards, &QAction::triggered, playerActions, &PlayerActions::actRequestViewBottomCardsDialog);
aAlwaysRevealTopCard = new QAction(this); aAlwaysRevealTopCard = new QAction(this);
aAlwaysRevealTopCard->setCheckable(true); aAlwaysRevealTopCard->setCheckable(true);
connect(aAlwaysRevealTopCard, &QAction::triggered, playerActions, &PlayerActions::actAlwaysRevealTopCard); connect(aAlwaysRevealTopCard, &QAction::triggered, playerActions, &PlayerActions::actAlwaysRevealTopCard);

View file

@ -30,9 +30,8 @@ MoveMenu::MoveMenu(PlayerGraphicsItem *player) : QMenu(tr("Move to"))
connect(aMoveToTopLibrary, &QAction::triggered, actions, invoke(cmMoveToTopLibrary)); connect(aMoveToTopLibrary, &QAction::triggered, actions, invoke(cmMoveToTopLibrary));
connect(aMoveToBottomLibrary, &QAction::triggered, actions, invoke(cmMoveToBottomLibrary)); connect(aMoveToBottomLibrary, &QAction::triggered, actions, invoke(cmMoveToBottomLibrary));
connect(aMoveToXfromTopOfLibrary, &QAction::triggered, actions, [player]() { connect(aMoveToXfromTopOfLibrary, &QAction::triggered, actions,
player->getLogic()->getPlayerActions()->actMoveCardXCardsFromTop(player->getGameScene()->selectedCards()); &PlayerActions::actRequestMoveCardXCardsFromTopDialog);
});
connect(aMoveToTable, &QAction::triggered, actions, invoke(cmMoveToTable)); connect(aMoveToTable, &QAction::triggered, actions, invoke(cmMoveToTable));
connect(aMoveToHand, &QAction::triggered, actions, invoke(cmMoveToHand)); connect(aMoveToHand, &QAction::triggered, actions, invoke(cmMoveToHand));
connect(aMoveToGraveyard, &QAction::triggered, actions, invoke(cmMoveToGraveyard)); connect(aMoveToGraveyard, &QAction::triggered, actions, invoke(cmMoveToGraveyard));

View file

@ -33,7 +33,7 @@ PtMenu::PtMenu(PlayerGraphicsItem *player) : QMenu(tr("Power / toughness"))
[player, playerActions] { playerActions->actFlowT(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actFlowT(player->getGameScene()->selectedCards()); });
aSetPT = new QAction(this); aSetPT = new QAction(this);
connect(aSetPT, &QAction::triggered, playerActions, connect(aSetPT, &QAction::triggered, playerActions,
[player, playerActions] { playerActions->actSetPT(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actRequestSetPTDialog(player->getGameScene()->selectedCards()); });
aResetPT = new QAction(this); aResetPT = new QAction(this);
connect(aResetPT, &QAction::triggered, playerActions, connect(aResetPT, &QAction::triggered, playerActions,
[player, playerActions] { playerActions->actResetPT(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actResetPT(player->getGameScene()->selectedCards()); });

View file

@ -20,14 +20,15 @@ UtilityMenu::UtilityMenu(PlayerGraphicsItem *_player, QMenu *playerMenu) : QMenu
connect(aUntapAll, &QAction::triggered, playerActions, &PlayerActions::actUntapAll); connect(aUntapAll, &QAction::triggered, playerActions, &PlayerActions::actUntapAll);
aRollDie = new QAction(this); aRollDie = new QAction(this);
connect(aRollDie, &QAction::triggered, playerActions, &PlayerActions::actRollDie); connect(aRollDie, &QAction::triggered, playerActions, &PlayerActions::actRequestRollDieDialog);
aFlipCoin = new QAction(this); aFlipCoin = new QAction(this);
connect(aFlipCoin, &QAction::triggered, playerActions, &PlayerActions::actFlipCoin); connect(aFlipCoin, &QAction::triggered, playerActions, &PlayerActions::actFlipCoin);
aCreateToken = new QAction(this); aCreateToken = new QAction(this);
connect(aCreateToken, &QAction::triggered, playerActions, connect(aCreateToken, &QAction::triggered, playerActions, [this]() {
[this]() { player->getLogic()->getPlayerActions()->actCreateToken(getPredefinedTokens()); }); player->getLogic()->getPlayerActions()->actRequestCreateTokenDialog(getPredefinedTokens());
});
aCreateAnotherToken = new QAction(this); aCreateAnotherToken = new QAction(this);
connect(aCreateAnotherToken, &QAction::triggered, playerActions, &PlayerActions::actCreateAnotherToken); connect(aCreateAnotherToken, &QAction::triggered, playerActions, &PlayerActions::actCreateAnotherToken);

View file

@ -5,7 +5,6 @@
#include "../../interface/widgets/tabs/tab_game.h" #include "../../interface/widgets/tabs/tab_game.h"
#include "../../interface/widgets/utility/get_text_with_max.h" #include "../../interface/widgets/utility/get_text_with_max.h"
#include "../board/card_item.h" #include "../board/card_item.h"
#include "../client/settings/card_counter_settings.h"
#include "../dialogs/dlg_move_top_cards_until.h" #include "../dialogs/dlg_move_top_cards_until.h"
#include "../dialogs/dlg_roll_dice.h" #include "../dialogs/dlg_roll_dice.h"
#include "../zones/view_zone_logic.h" #include "../zones/view_zone_logic.h"
@ -175,30 +174,26 @@ void PlayerActions::actSortHand()
emit requestSortHand(sortOptions + defaultOptions); emit requestSortHand(sortOptions + defaultOptions);
} }
void PlayerActions::actViewTopCards() void PlayerActions::actRequestViewTopCardsDialog()
{ {
int deckSize = player->getDeckZone()->getCards().size(); emit requestViewTopCardsDialog(defaultNumberTopCards, player->getDeckZone()->getCards().size());
bool ok;
int number = QInputDialog::getInt(player->getGame()->getTab(), tr("View top cards of library"),
tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberTopCards, 1,
deckSize, 1, &ok);
if (ok) {
defaultNumberTopCards = number;
emit requestZoneViewToggle(ZoneNames::DECK, number);
}
} }
void PlayerActions::actViewBottomCards() void PlayerActions::actViewTopCards(int number)
{ {
int deckSize = player->getDeckZone()->getCards().size(); defaultNumberTopCards = number;
bool ok; emit requestZoneViewToggle(ZoneNames::DECK, number);
int number = QInputDialog::getInt(player->getGame()->getTab(), tr("View bottom cards of library"), }
tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberBottomCards, 1,
deckSize, 1, &ok); void PlayerActions::actRequestViewBottomCardsDialog()
if (ok) { {
defaultNumberBottomCards = number; emit requestViewBottomCardsDialog(defaultNumberBottomCards, player->getDeckZone()->getCards().size());
emit requestZoneViewToggle(ZoneNames::DECK, number, true); }
}
void PlayerActions::actViewBottomCards(int number)
{
defaultNumberBottomCards = number;
emit requestZoneViewToggle(ZoneNames::DECK, number, true);
} }
void PlayerActions::actAlwaysRevealTopCard(bool alwaysRevealTopCard) void PlayerActions::actAlwaysRevealTopCard(bool alwaysRevealTopCard)
@ -244,18 +239,20 @@ void PlayerActions::actShuffle()
sendGameCommand(Command_Shuffle()); sendGameCommand(Command_Shuffle());
} }
void PlayerActions::actShuffleTop() void PlayerActions::actRequestShuffleTopDialog()
{ {
const int maxCards = player->getDeckZone()->getCards().size(); const int maxCards = player->getDeckZone()->getCards().size();
if (maxCards == 0) { if (maxCards == 0) {
return; return;
} }
bool ok; emit requestShuffleTopDialog(defaultNumberTopCards, maxCards);
int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Shuffle top cards of library"), }
tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberTopCards, 1,
maxCards, 1, &ok); void PlayerActions::actShuffleTop(int number)
if (!ok) { {
const int maxCards = player->getDeckZone()->getCards().size();
if (maxCards == 0) {
return; return;
} }
@ -273,18 +270,20 @@ void PlayerActions::actShuffleTop()
sendGameCommand(cmd); sendGameCommand(cmd);
} }
void PlayerActions::actShuffleBottom() void PlayerActions::actRequestShuffleBottomDialog()
{ {
const int maxCards = player->getDeckZone()->getCards().size(); const int maxCards = player->getDeckZone()->getCards().size();
if (maxCards == 0) { if (maxCards == 0) {
return; return;
} }
bool ok; emit requestShuffleBottomDialog(defaultNumberBottomCards, maxCards);
int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Shuffle bottom cards of library"), }
tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1,
maxCards, 1, &ok); void PlayerActions::actShuffleBottom(int number)
if (!ok) { {
const int maxCards = player->getDeckZone()->getCards().size();
if (maxCards == 0) {
return; return;
} }
@ -309,21 +308,18 @@ void PlayerActions::actDrawCard()
sendGameCommand(cmd); sendGameCommand(cmd);
} }
void PlayerActions::actMulligan() void PlayerActions::actRequestMulliganDialog()
{ {
int startSize = SettingsCache::instance().getStartingHandSize(); int startSize = SettingsCache::instance().getStartingHandSize();
int handSize = player->getHandZone()->getCards().size(); int handSize = player->getHandZone()->getCards().size();
int deckSize = player->getDeckZone()->getCards().size() + handSize; int deckSize = player->getDeckZone()->getCards().size() + handSize;
bool ok; emit requestMulliganDialog(startSize, handSize, deckSize);
int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Draw hand"), }
tr("Number of cards: (max. %1)").arg(deckSize) + '\n' +
tr("0 and lower are in comparison to current hand size"),
startSize, -handSize, deckSize, 1, &ok);
if (!ok) { void PlayerActions::actMulligan(int number)
return; {
} int handSize = player->getHandZone()->getCards().size();
if (number < 1) { if (number < 1) {
number = handSize + number; number = handSize + number;
@ -357,19 +353,19 @@ void PlayerActions::doMulligan(int number)
sendGameCommand(cmd); sendGameCommand(cmd);
} }
void PlayerActions::actDrawCards() void PlayerActions::actRequestDrawCardsDialog()
{ {
int deckSize = player->getDeckZone()->getCards().size(); int deckSize = player->getDeckZone()->getCards().size();
bool ok;
int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Draw cards"), emit requestDrawCardsDialog(defaultNumberTopCards, deckSize);
tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberTopCards, 1, }
deckSize, 1, &ok);
if (ok) { void PlayerActions::actDrawCards(int number)
defaultNumberTopCards = number; {
Command_DrawCards cmd; defaultNumberTopCards = number;
cmd.set_number(static_cast<google::protobuf::uint32>(number)); Command_DrawCards cmd;
sendGameCommand(cmd); cmd.set_number(static_cast<google::protobuf::uint32>(number));
} sendGameCommand(cmd);
} }
void PlayerActions::actUndoDraw() void PlayerActions::actUndoDraw()
@ -427,36 +423,40 @@ void PlayerActions::actMoveTopCardToExile()
void PlayerActions::actMoveTopCardsToGrave() void PlayerActions::actMoveTopCardsToGrave()
{ {
moveTopCardsTo(ZoneNames::GRAVE, tr("grave"), false); actRequestMoveTopCardsToDialog(ZoneNames::GRAVE, tr("grave"), false);
} }
void PlayerActions::actMoveTopCardsToGraveFaceDown() void PlayerActions::actMoveTopCardsToGraveFaceDown()
{ {
moveTopCardsTo(ZoneNames::GRAVE, tr("grave"), true); actRequestMoveTopCardsToDialog(ZoneNames::GRAVE, tr("grave"), true);
} }
void PlayerActions::actMoveTopCardsToExile() void PlayerActions::actMoveTopCardsToExile()
{ {
moveTopCardsTo(ZoneNames::EXILE, tr("exile"), false); actRequestMoveTopCardsToDialog(ZoneNames::EXILE, tr("exile"), false);
} }
void PlayerActions::actMoveTopCardsToExileFaceDown() void PlayerActions::actMoveTopCardsToExileFaceDown()
{ {
moveTopCardsTo(ZoneNames::EXILE, tr("exile"), true); actRequestMoveTopCardsToDialog(ZoneNames::EXILE, tr("exile"), true);
} }
void PlayerActions::moveTopCardsTo(const QString &targetZone, const QString &zoneDisplayName, bool faceDown) void PlayerActions::actRequestMoveTopCardsToDialog(const QString &targetZone,
const QString &zoneDisplayName,
bool faceDown)
{ {
const int maxCards = player->getDeckZone()->getCards().size(); const int maxCards = player->getDeckZone()->getCards().size();
if (maxCards == 0) { if (maxCards == 0) {
return; return;
} }
bool ok; emit requestMoveTopCardsToDialog(defaultNumberTopCards, maxCards, targetZone, zoneDisplayName, faceDown);
int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Move top cards to %1").arg(zoneDisplayName), }
tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberTopCards, 1,
maxCards, 1, &ok); void PlayerActions::moveTopCardsTo(int number, const QString &targetZone, bool faceDown)
if (!ok) { {
const int maxCards = player->getDeckZone()->getCards().size();
if (maxCards == 0) {
return; return;
} }
@ -483,17 +483,16 @@ void PlayerActions::moveTopCardsTo(const QString &targetZone, const QString &zon
sendGameCommand(cmd); sendGameCommand(cmd);
} }
void PlayerActions::actMoveTopCardsUntil() void PlayerActions::actRequestMoveTopCardsUntilDialog()
{ {
stopMoveTopCardsUntil(); stopMoveTopCardsUntil();
DlgMoveTopCardsUntil dlg(player->getGame()->getTab(), movingCardsUntilOptions); emit requestMoveTopCardsUntilDialog(movingCardsUntilOptions);
if (!dlg.exec()) { }
return;
}
auto expr = dlg.getExpr(); void PlayerActions::moveTopCardsUntil(const QString &expr, MoveTopCardsUntilOptions options)
movingCardsUntilOptions = dlg.getOptions(); {
movingCardsUntilOptions = options;
if (player->getDeckZone()->getCards().empty()) { if (player->getDeckZone()->getCards().empty()) {
stopMoveTopCardsUntil(); stopMoveTopCardsUntil();
@ -622,36 +621,40 @@ void PlayerActions::actMoveBottomCardToExile()
void PlayerActions::actMoveBottomCardsToGrave() void PlayerActions::actMoveBottomCardsToGrave()
{ {
moveBottomCardsTo(ZoneNames::GRAVE, tr("grave"), false); actRequestMoveBottomCardsToDialog(ZoneNames::GRAVE, tr("grave"), false);
} }
void PlayerActions::actMoveBottomCardsToGraveFaceDown() void PlayerActions::actMoveBottomCardsToGraveFaceDown()
{ {
moveBottomCardsTo(ZoneNames::GRAVE, tr("grave"), true); actRequestMoveBottomCardsToDialog(ZoneNames::GRAVE, tr("grave"), true);
} }
void PlayerActions::actMoveBottomCardsToExile() void PlayerActions::actMoveBottomCardsToExile()
{ {
moveBottomCardsTo(ZoneNames::EXILE, tr("exile"), false); actRequestMoveBottomCardsToDialog(ZoneNames::EXILE, tr("exile"), false);
} }
void PlayerActions::actMoveBottomCardsToExileFaceDown() void PlayerActions::actMoveBottomCardsToExileFaceDown()
{ {
moveBottomCardsTo(ZoneNames::EXILE, tr("exile"), true); actRequestMoveBottomCardsToDialog(ZoneNames::EXILE, tr("exile"), true);
} }
void PlayerActions::moveBottomCardsTo(const QString &targetZone, const QString &zoneDisplayName, bool faceDown) void PlayerActions::actRequestMoveBottomCardsToDialog(const QString &targetZone,
const QString &zoneDisplayName,
bool faceDown)
{ {
const int maxCards = player->getDeckZone()->getCards().size(); const int maxCards = player->getDeckZone()->getCards().size();
if (maxCards == 0) { if (maxCards == 0) {
return; return;
} }
bool ok; emit requestMoveBottomCardsToDialog(defaultNumberBottomCards, maxCards, targetZone, zoneDisplayName, faceDown);
int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Move bottom cards to %1").arg(zoneDisplayName), }
tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1,
maxCards, 1, &ok); void PlayerActions::moveBottomCardsTo(int number, const QString &targetZone, bool faceDown)
if (!ok) { {
const int maxCards = player->getDeckZone()->getCards().size();
if (maxCards == 0) {
return; return;
} }
@ -763,20 +766,24 @@ void PlayerActions::actDrawBottomCard()
sendGameCommand(cmd); sendGameCommand(cmd);
} }
void PlayerActions::actDrawBottomCards() void PlayerActions::actRequestDrawBottomCardsDialog()
{ {
const int maxCards = player->getDeckZone()->getCards().size(); const int maxCards = player->getDeckZone()->getCards().size();
if (maxCards == 0) { if (maxCards == 0) {
return; return;
} }
bool ok; emit requestDrawBottomCardsDialog(defaultNumberBottomCards, maxCards);
int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Draw bottom cards"), }
tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1,
maxCards, 1, &ok); void PlayerActions::actDrawBottomCards(int number)
if (!ok) { {
const int maxCards = player->getDeckZone()->getCards().size();
if (maxCards == 0) {
return; return;
} else if (number > maxCards) { }
if (number > maxCards) {
number = maxCards; number = maxCards;
} }
defaultNumberBottomCards = number; defaultNumberBottomCards = number;
@ -843,16 +850,16 @@ void PlayerActions::actUntapAll()
sendGameCommand(cmd); sendGameCommand(cmd);
} }
void PlayerActions::actRollDie() void PlayerActions::actRequestRollDieDialog()
{ {
DlgRollDice dlg(player->getGame()->getTab()); emit requestRollDieDialog();
if (!dlg.exec()) { }
return;
}
void PlayerActions::actRollDie(int sides, int count)
{
Command_RollDie cmd; Command_RollDie cmd;
cmd.set_sides(dlg.getDieSideCount()); cmd.set_sides(sides);
cmd.set_count(dlg.getDiceToRollCount()); cmd.set_count(count);
sendGameCommand(cmd); sendGameCommand(cmd);
} }
@ -864,14 +871,14 @@ void PlayerActions::actFlipCoin()
sendGameCommand(cmd); sendGameCommand(cmd);
} }
void PlayerActions::actCreateToken(const QStringList &predefinedTokens) void PlayerActions::actRequestCreateTokenDialog(const QStringList &predefinedTokens)
{ {
DlgCreateToken dlg(predefinedTokens, player->getGame()->getTab()); emit requestCreateTokenDialog(predefinedTokens);
if (!dlg.exec()) { }
return;
}
lastTokenInfo = dlg.getTokenInfo(); void PlayerActions::actCreateToken(TokenInfo tokenToCreate)
{
lastTokenInfo = tokenToCreate;
ExactCard correctedCard = CardDatabaseManager::query()->guessCard({lastTokenInfo.name, lastTokenInfo.providerId}); ExactCard correctedCard = CardDatabaseManager::query()->guessCard({lastTokenInfo.name, lastTokenInfo.providerId});
if (correctedCard) { if (correctedCard) {
@ -951,23 +958,17 @@ void PlayerActions::actCreatePredefinedToken()
void PlayerActions::actCreateRelatedCard() void PlayerActions::actCreateRelatedCard()
{ {
const CardItem *sourceCard = player->getGame()->getActiveCard(); const CardItem *sourceCard = player->getGame()->getActiveCard();
if (!sourceCard) { if (!sourceCard) {
return; return;
} }
auto *action = static_cast<QAction *>(sender()); auto *action = static_cast<QAction *>(sender());
// If there is a better way of passing a CardRelation through a QAction, please add it here. // If there is a better way of passing a CardRelation through a QAction, please add it here.
auto relatedCards = sourceCard->getCardInfo().getAllRelatedCards(); auto relatedCards = sourceCard->getCardInfo().getAllRelatedCards();
CardRelation *cardRelation = relatedCards.at(action->data().toInt());
/* CardRelation *cardRelation = relatedCards.at(action->data().toInt());
* If we make a token via "Token: TokenName" actRequestCreateRelatedFromRelationDialog(sourceCard, cardRelation);
* then let's allow it to be created via "create another token"
*/
if (createRelatedFromRelation(sourceCard, cardRelation) && cardRelation->getCanCreateAnother()) {
ExactCard relatedCard = CardDatabaseManager::query()->getCardFromSameSet(cardRelation->getName(),
sourceCard->getCard().getPrinting());
setLastToken(relatedCard.getCardPtr());
}
} }
void PlayerActions::actCreateAllRelatedCards() void PlayerActions::actCreateAllRelatedCards()
@ -987,7 +988,9 @@ void PlayerActions::actCreateAllRelatedCards()
if (relatedCards.length() == 1) { if (relatedCards.length() == 1) {
cardRelation = relatedCards.at(0); cardRelation = relatedCards.at(0);
if (createRelatedFromRelation(sourceCard, cardRelation)) { lastRelatedCreationSucceeded = false; // reset before emit
actRequestCreateRelatedFromRelationDialog(sourceCard, cardRelation);
if (lastRelatedCreationSucceeded) {
++tokensTypesCreated; ++tokensTypesCreated;
} }
} else { } else {
@ -999,15 +1002,18 @@ void PlayerActions::actCreateAllRelatedCards()
} }
} }
switch (nonExcludedRelatedCards.length()) { switch (nonExcludedRelatedCards.length()) {
case 1: // if nonExcludedRelatedCards == 1 case 1:
cardRelation = nonExcludedRelatedCards.at(0); cardRelation = nonExcludedRelatedCards.at(0);
if (createRelatedFromRelation(sourceCard, cardRelation)) { lastRelatedCreationSucceeded = false; // reset before emit
actRequestCreateRelatedFromRelationDialog(sourceCard, cardRelation);
if (lastRelatedCreationSucceeded) {
++tokensTypesCreated; ++tokensTypesCreated;
} }
break; break;
// If all are marked "Exclude", then treat the situation as if none of them are. // If all are marked "Exclude", then treat the situation as if none of them are.
// We won't accept "garbage in, garbage out", here. // We won't accept "garbage in, garbage out", here.
case 0: // else if nonExcludedRelatedCards == 0 case 0:
for (CardRelation *cardRelationAll : relatedCards) { for (CardRelation *cardRelationAll : relatedCards) {
if (!cardRelationAll->getDoesAttach() && !cardRelationAll->getIsVariable()) { if (!cardRelationAll->getDoesAttach() && !cardRelationAll->getIsVariable()) {
dbName = cardRelationAll->getName(); dbName = cardRelationAll->getName();
@ -1022,7 +1028,8 @@ void PlayerActions::actCreateAllRelatedCards()
} }
} }
break; break;
default: // else
default:
for (CardRelation *cardRelationNotExcluded : nonExcludedRelatedCards) { for (CardRelation *cardRelationNotExcluded : nonExcludedRelatedCards) {
if (!cardRelationNotExcluded->getDoesAttach() && !cardRelationNotExcluded->getIsVariable()) { if (!cardRelationNotExcluded->getDoesAttach() && !cardRelationNotExcluded->getIsVariable()) {
dbName = cardRelationNotExcluded->getName(); dbName = cardRelationNotExcluded->getName();
@ -1050,50 +1057,83 @@ void PlayerActions::actCreateAllRelatedCards()
} }
} }
bool PlayerActions::createRelatedFromRelation(const CardItem *sourceCard, const CardRelation *cardRelation) void PlayerActions::actRequestCreateRelatedFromRelationDialog(const CardItem *sourceCard,
const CardRelation *cardRelation)
{
emit requestCreateRelatedFromRelationDialog(sourceCard, cardRelation);
}
bool PlayerActions::createRelatedFromRelation(const CardItem *sourceCard,
const CardRelation *cardRelation,
int variableCount)
{ {
if (sourceCard == nullptr || cardRelation == nullptr) { if (sourceCard == nullptr || cardRelation == nullptr) {
return false; return false;
} }
QString dbName = cardRelation->getName();
bool persistent = cardRelation->getIsPersistent(); const QString dbName = cardRelation->getName();
const bool persistent = cardRelation->getIsPersistent();
// Variable relations always use DoesNotAttach, regardless of the count the user
// entered.
if (cardRelation->getIsVariable()) { if (cardRelation->getIsVariable()) {
bool ok; if (variableCount <= 0) {
player->setDialogSemaphore(true);
int count = QInputDialog::getInt(player->getGame()->getTab(), tr("Create tokens"), tr("Number:"),
cardRelation->getDefaultCount(), 1, MAX_TOKENS_PER_DIALOG, 1, &ok);
player->setDialogSemaphore(false);
if (!ok) {
return false; return false;
} }
for (int i = 0; i < variableCount; ++i) {
createCard(sourceCard, dbName, CardRelationType::DoesNotAttach, persistent);
}
return true;
}
const int count = cardRelation->getDefaultCount();
if (count > 1) {
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
createCard(sourceCard, dbName, CardRelationType::DoesNotAttach, persistent); createCard(sourceCard, dbName, CardRelationType::DoesNotAttach, persistent);
} }
} else if (cardRelation->getDefaultCount() > 1) { return true;
for (int i = 0; i < cardRelation->getDefaultCount(); ++i) {
createCard(sourceCard, dbName, CardRelationType::DoesNotAttach, persistent);
}
} else {
CardRelationType attachType;
// do not attempt to attach to another player's cards, this causes the card to attempt to attach to the same
// cardid on the local player's field instead, which is an entirely different card!
if (player->getPlayerInfo()->getLocalOrJudge()) {
attachType = cardRelation->getAttachType();
} else {
attachType = CardRelationType::DoesNotAttach;
}
// 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 == CardRelationType::AttachTo && sourceCard->getZone()->getName() != ZoneNames::TABLE) {
playCardToTable(sourceCard, false);
}
createCard(sourceCard, dbName, attachType, persistent);
} }
CardRelationType attachType;
// do not attempt to attach to another player's cards, this causes the card to attempt to attach to the same
// cardid on the local player's field instead, which is an entirely different card!
if (player->getPlayerInfo()->getLocalOrJudge()) {
attachType = cardRelation->getAttachType();
} else {
attachType = CardRelationType::DoesNotAttach;
}
// 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 == CardRelationType::AttachTo && sourceCard->getZone()->getName() != ZoneNames::TABLE) {
playCardToTable(sourceCard, false);
}
createCard(sourceCard, dbName, attachType, persistent);
return true; return true;
} }
void PlayerActions::onRelatedCardCreated(const CardItem *sourceCard, const CardRelation *cardRelation)
{
if (sourceCard == nullptr || cardRelation == nullptr) {
return;
}
/*
* If we make a token via "Token: TokenName"
* then let's allow it to be created via "create another token"
*/
if (!cardRelation->getCanCreateAnother()) {
return;
}
ExactCard relatedCard =
CardDatabaseManager::query()->getCardFromSameSet(cardRelation->getName(), sourceCard->getCard().getPrinting());
setLastToken(relatedCard.getCardPtr());
}
void PlayerActions::createCard(const CardItem *sourceCard, void PlayerActions::createCard(const CardItem *sourceCard,
const QString &dbCardName, const QString &dbCardName,
CardRelationType attachType, CardRelationType attachType,
@ -1171,35 +1211,29 @@ void PlayerActions::actSayMessage()
sendGameCommand(cmd); sendGameCommand(cmd);
} }
void PlayerActions::actMoveCardXCardsFromTop(QList<CardItem *> selectedCards) void PlayerActions::actRequestMoveCardXCardsFromTopDialog()
{ {
int deckSize = player->getDeckZone()->getCards().size() + 1; // add the card to move to the deck int deckSize = player->getDeckZone()->getCards().size() + 1; // add the card to move to the deck
bool ok;
int number =
QInputDialog::getInt(player->getGame()->getTab(), tr("Place card X cards from top of library"),
tr("Which position should this card be placed:") + "\n" + tr("(max. %1)").arg(deckSize),
defaultNumberTopCardsToPlaceBelow, 1, deckSize, 1, &ok);
number -= 1; // indexes start at 0
if (!ok) { emit requestMoveCardXCardsFromTopDialog(defaultNumberTopCardsToPlaceBelow, deckSize);
return; }
}
void PlayerActions::actMoveCardXCardsFromTop(QList<CardItem *> selectedCards, int number)
{
defaultNumberTopCardsToPlaceBelow = number; defaultNumberTopCardsToPlaceBelow = number;
QList<CardItem *> cardList = selectedCards; if (selectedCards.isEmpty()) {
if (cardList.isEmpty()) {
return; return;
} }
QList<const ::google::protobuf::Message *> commandList; QList<const ::google::protobuf::Message *> commandList;
ListOfCardsToMove idList; ListOfCardsToMove idList;
for (const auto &i : cardList) { for (const auto &i : selectedCards) {
idList.add_card()->set_card_id(i->getId()); idList.add_card()->set_card_id(i->getId());
} }
int startPlayerId = cardList[0]->getZone()->getPlayer()->getPlayerInfo()->getId(); int startPlayerId = selectedCards[0]->getZone()->getPlayer()->getPlayerInfo()->getId();
QString startZone = cardList[0]->getZone()->getName(); QString startZone = selectedCards[0]->getZone()->getName();
auto *cmd = new Command_MoveCard; auto *cmd = new Command_MoveCard;
cmd->set_start_player_id(startPlayerId); cmd->set_start_player_id(startPlayerId);
@ -1284,24 +1318,22 @@ void PlayerActions::actResetPT(QList<CardItem *> selectedCards)
} }
} }
void PlayerActions::actSetPT(QList<CardItem *> selectedCards) void PlayerActions::actRequestSetPTDialog(QList<CardItem *> selectedCards)
{ {
QString oldPT; QString oldPT;
int playerid = player->getPlayerInfo()->getId();
for (auto card : selectedCards) { for (auto card : selectedCards) {
if (!card->getPT().isEmpty()) { if (!card->getPT().isEmpty()) {
oldPT = card->getPT(); oldPT = card->getPT();
} }
} }
bool ok;
player->setDialogSemaphore(true); emit requestSetPTDialog(oldPT);
QString pt = getTextWithMax(player->getGame()->getTab(), tr("Change power/toughness"), tr("Change stats to:"), }
QLineEdit::Normal, oldPT, &ok);
player->setDialogSemaphore(false); void PlayerActions::actSetPT(QList<CardItem *> selectedCards, const QString &pt)
if (player->clearCardsToDelete() || !ok) { {
return; int playerid = player->getPlayerInfo()->getId();
}
const auto ptList = CardItem::parsePT(pt); const auto ptList = CardItem::parsePT(pt);
bool empty = ptList.isEmpty(); bool empty = ptList.isEmpty();
@ -1426,7 +1458,7 @@ void AnnotationDialog::keyPressEvent(QKeyEvent *event)
QInputDialog::keyPressEvent(event); QInputDialog::keyPressEvent(event);
} }
void PlayerActions::actSetAnnotation(QList<CardItem *> selectedCards) void PlayerActions::actRequestSetAnnotationDialog(QList<CardItem *> selectedCards)
{ {
QString oldAnnotation; QString oldAnnotation;
for (auto card : selectedCards) { for (auto card : selectedCards) {
@ -1435,19 +1467,11 @@ void PlayerActions::actSetAnnotation(QList<CardItem *> selectedCards)
} }
} }
player->setDialogSemaphore(true); emit requestSetAnnotationDialog(oldAnnotation);
AnnotationDialog *dialog = new AnnotationDialog(player->getGame()->getTab()); }
dialog->setOptions(QInputDialog::UsePlainTextEditForTextInput);
dialog->setWindowTitle(tr("Set annotation"));
dialog->setLabelText(tr("Please enter the new annotation:"));
dialog->setTextValue(oldAnnotation);
bool ok = dialog->exec();
player->setDialogSemaphore(false);
if (player->clearCardsToDelete() || !ok) {
return;
}
QString annotation = dialog->textValue().left(MAX_NAME_LENGTH);
void PlayerActions::actSetAnnotation(QList<CardItem *> selectedCards, const QString &annotation)
{
QList<const ::google::protobuf::Message *> commandList; QList<const ::google::protobuf::Message *> commandList;
for (auto card : selectedCards) { for (auto card : selectedCards) {
auto *cmd = new Command_SetCardAttr; auto *cmd = new Command_SetCardAttr;
@ -1519,10 +1543,8 @@ void PlayerActions::offsetCardCounter(QList<CardItem *> selectedCards, int count
sendGameCommand(prepareGameCommand(commandList)); sendGameCommand(prepareGameCommand(commandList));
} }
void PlayerActions::actSetCardCounter(QList<CardItem *> selectedCards, int counterId) void PlayerActions::actRequestSetCardCounterDialog(QList<CardItem *> selectedCards, int counterId)
{ {
player->setDialogSemaphore(true);
// If a single card is selected, we show the old value in the dialog. Otherwise, we show "x" // If a single card is selected, we show the old value in the dialog. Otherwise, we show "x"
QString oldValueForDlg = "x"; QString oldValueForDlg = "x";
if (selectedCards.size() == 1) { if (selectedCards.size() == 1) {
@ -1530,22 +1552,16 @@ void PlayerActions::actSetCardCounter(QList<CardItem *> selectedCards, int count
oldValueForDlg = QString::number(card->getCounters().value(counterId, 0)); oldValueForDlg = QString::number(card->getCounters().value(counterId, 0));
} }
auto &cardCounterSettings = SettingsCache::instance().cardCounters(); emit requestSetCardCounterDialog(counterId, oldValueForDlg);
QString counterName = cardCounterSettings.displayName(counterId); }
AbstractCounterDialog dialog(counterName, oldValueForDlg, player->getGame()->getTab());
int ok = dialog.exec();
player->setDialogSemaphore(false);
if (player->clearCardsToDelete() || !ok) {
return;
}
void PlayerActions::actSetCardCounter(QList<CardItem *> selectedCards, int counterId, const QString &counterValue)
{
QList<const ::google::protobuf::Message *> commandList; QList<const ::google::protobuf::Message *> commandList;
for (auto card : selectedCards) { for (auto card : selectedCards) {
int oldValue = card->getCounters().value(counterId, 0); int oldValue = card->getCounters().value(counterId, 0);
Expression exp(oldValue); Expression exp(oldValue);
double parsed = exp.parse(dialog.textValue()); double parsed = exp.parse(counterValue);
// Clamp in double precision first to avoid UB, then cast // Clamp in double precision first to avoid UB, then cast
int number = static_cast<int>(qBound(0.0, parsed, static_cast<double>(MAX_COUNTERS_ON_CARD))); int number = static_cast<int>(qBound(0.0, parsed, static_cast<double>(MAX_COUNTERS_ON_CARD)));

View file

@ -58,6 +58,31 @@ public:
} }
signals: signals:
void requestViewTopCardsDialog(int defaultNumberTopCards, int deckSize);
void requestViewBottomCardsDialog(int defaultNumberBottomCards, int deckSize);
void requestShuffleTopDialog(int defaultNumberTopCards, int maxCards);
void requestShuffleBottomDialog(int defaultNumberBottomCards, int maxCards);
void requestMulliganDialog(int startSize, int handSize, int deckSize);
void requestDrawCardsDialog(int defaultNumberTopCards, int deckSize);
void requestMoveTopCardsToDialog(int defaultNumberTopCards,
int maxCards,
const QString &targetZone,
const QString &zoneDisplayName,
bool faceDown);
void requestMoveTopCardsUntilDialog(MoveTopCardsUntilOptions options);
void requestMoveBottomCardsToDialog(int defaultNumberBottomCards,
int maxCards,
const QString &targetZone,
const QString &zoneDisplayName,
bool faceDown);
void requestDrawBottomCardsDialog(int defaultNumberBottomCards, int maxCards);
void requestRollDieDialog();
void requestCreateTokenDialog(const QStringList &predefinedTokens);
void requestCreateRelatedFromRelationDialog(const CardItem *sourceCard, const CardRelation *cardRelation);
void requestMoveCardXCardsFromTopDialog(int defaultNumberTopCardsToPlaceBelow, int deckSize);
void requestSetPTDialog(const QString &oldPT);
void requestSetAnnotationDialog(const QString &oldAnnotation);
void requestSetCardCounterDialog(int counterId, const QString &oldValueForDlg);
void requestZoneViewToggle(const QString &zoneName, int numberCards, bool isReversed = false); void requestZoneViewToggle(const QString &zoneName, int numberCards, bool isReversed = false);
void requestSortHand(const QList<CardList::SortOption> &options); void requestSortHand(const QList<CardList::SortOption> &options);
void requestEnableAndSetCreateAnotherTokenAction(const QString &lastTokenName); void requestEnableAndSetCreateAnotherTokenAction(const QString &lastTokenName);
@ -70,17 +95,30 @@ public slots:
void playCardToTable(const CardItem *c, bool faceDown); void playCardToTable(const CardItem *c, bool faceDown);
void actUntapAll(); void actUntapAll();
void actRollDie(); void actRequestRollDieDialog();
void actRollDie(int sides, int count);
void actFlipCoin(); void actFlipCoin();
void actCreateToken(const QStringList &predefinedTokens); void actRequestCreateTokenDialog(const QStringList &predefinedTokens);
void actCreateToken(TokenInfo tokenToCreate);
void actCreateAnotherToken(); void actCreateAnotherToken();
void actRequestCreateRelatedFromRelationDialog(const CardItem *sourceCard, const CardRelation *cardRelation);
bool createRelatedFromRelation(const CardItem *sourceCard, const CardRelation *cardRelation, int variableCount);
void onRelatedCardCreated(const CardItem *sourceCard, const CardRelation *cardRelation);
void setLastRelatedCreationSucceeded(bool succeeded)
{
lastRelatedCreationSucceeded = succeeded;
}
void actShuffle(); void actShuffle();
void actShuffleTop(); void actRequestShuffleTopDialog();
void actShuffleBottom(); void actShuffleTop(int number);
void actRequestShuffleBottomDialog();
void actShuffleBottom(int number);
void actDrawCard(); void actDrawCard();
void actDrawCards(); void actRequestDrawCardsDialog();
void actDrawCards(int number);
void actUndoDraw(); void actUndoDraw();
void actMulligan(); void actRequestMulliganDialog();
void actMulligan(int number);
void actMulliganSameSize(); void actMulliganSameSize();
void actMulliganMinusOne(); void actMulliganMinusOne();
void doMulligan(int number); void doMulligan(int number);
@ -97,10 +135,14 @@ public slots:
void actMoveTopCardsToGraveFaceDown(); void actMoveTopCardsToGraveFaceDown();
void actMoveTopCardsToExile(); void actMoveTopCardsToExile();
void actMoveTopCardsToExileFaceDown(); void actMoveTopCardsToExileFaceDown();
void actMoveTopCardsUntil(); void actRequestMoveTopCardsUntilDialog();
void moveTopCardsUntil(const QString &expr, MoveTopCardsUntilOptions options);
void actMoveTopCardToBottom(); void actMoveTopCardToBottom();
void actRequestMoveTopCardsToDialog(const QString &targetZone, const QString &zoneDisplayName, bool faceDown);
void moveTopCardsTo(int number, const QString &targetZone, bool faceDown);
void actDrawBottomCard(); void actDrawBottomCard();
void actDrawBottomCards(); void actRequestDrawBottomCardsDialog();
void actDrawBottomCards(int number);
void actMoveBottomCardToPlay(); void actMoveBottomCardToPlay();
void actMoveBottomCardToPlayFaceDown(); void actMoveBottomCardToPlayFaceDown();
void actMoveBottomCardToGrave(); void actMoveBottomCardToGrave();
@ -110,6 +152,8 @@ public slots:
void actMoveBottomCardsToExile(); void actMoveBottomCardsToExile();
void actMoveBottomCardsToExileFaceDown(); void actMoveBottomCardsToExileFaceDown();
void actMoveBottomCardToTop(); void actMoveBottomCardToTop();
void actRequestMoveBottomCardsToDialog(const QString &targetZone, const QString &zoneDisplayName, bool faceDown);
void moveBottomCardsTo(int number, const QString &targetZone, bool faceDown);
void actSelectAll(); void actSelectAll();
void actSelectRow(); void actSelectRow();
@ -117,8 +161,10 @@ public slots:
void actViewLibrary(); void actViewLibrary();
void actViewHand(); void actViewHand();
void actViewTopCards(); void actRequestViewTopCardsDialog();
void actViewBottomCards(); void actViewTopCards(int number);
void actRequestViewBottomCardsDialog();
void actViewBottomCards(int number);
void actAlwaysRevealTopCard(bool alwaysRevealTopCard); void actAlwaysRevealTopCard(bool alwaysRevealTopCard);
void actAlwaysLookAtTopCard(bool alwaysRevealTopCard); void actAlwaysLookAtTopCard(bool alwaysRevealTopCard);
void actViewGraveyard(); void actViewGraveyard();
@ -135,17 +181,20 @@ public slots:
void actCreateRelatedCard(); void actCreateRelatedCard();
void actCreateAllRelatedCards(); void actCreateAllRelatedCards();
void actMoveCardXCardsFromTop(QList<CardItem *> selectedCards); void actRequestMoveCardXCardsFromTopDialog();
void actMoveCardXCardsFromTop(QList<CardItem *> selectedCards, int number);
void actRemoveCardCounter(QList<CardItem *> selectedCards, int counterId); void actRemoveCardCounter(QList<CardItem *> selectedCards, int counterId);
void actAddCardCounter(QList<CardItem *> selectedCards, int counterId); void actAddCardCounter(QList<CardItem *> selectedCards, int counterId);
void actSetCardCounter(QList<CardItem *> selectedCards, int counterId); void actRequestSetCardCounterDialog(QList<CardItem *> selectedCards, int counterId);
void actSetCardCounter(QList<CardItem *> selectedCards, int counterId, const QString &counterValue);
void actIncrementAllCardCounters(QList<CardItem *> cardsToUpdate); void actIncrementAllCardCounters(QList<CardItem *> cardsToUpdate);
void actAttach(); void actAttach();
void actUnattach(QList<CardItem *> selectedCards); void actUnattach(QList<CardItem *> selectedCards);
void actDrawArrow(); void actDrawArrow();
void actIncPT(QList<CardItem *> selectedCards, int deltaP, int deltaT); void actIncPT(QList<CardItem *> selectedCards, int deltaP, int deltaT);
void actResetPT(QList<CardItem *> selectedCards); void actResetPT(QList<CardItem *> selectedCards);
void actSetPT(QList<CardItem *> selectedCards); void actRequestSetPTDialog(QList<CardItem *> selectedCards);
void actSetPT(QList<CardItem *> selectedCards, const QString &pt);
void actIncP(QList<CardItem *> selectedCards); void actIncP(QList<CardItem *> selectedCards);
void actDecP(QList<CardItem *> selectedCards); void actDecP(QList<CardItem *> selectedCards);
void actIncT(QList<CardItem *> selectedCards); void actIncT(QList<CardItem *> selectedCards);
@ -157,7 +206,8 @@ public slots:
void actReduceLifeByPower(QList<CardItem *> selectedCards); void actReduceLifeByPower(QList<CardItem *> selectedCards);
void actSetAnnotation(QList<CardItem *> selectedCards); void actRequestSetAnnotationDialog(QList<CardItem *> selectedCards);
void actSetAnnotation(QList<CardItem *> selectedCards, const QString &annotation);
void actReveal(QList<CardItem *> selectedCards, QAction *action); void actReveal(QList<CardItem *> selectedCards, QAction *action);
void actRevealHand(int revealToPlayerId); void actRevealHand(int revealToPlayerId);
void actRevealRandomHandCard(int revealToPlayerId); void actRevealRandomHandCard(int revealToPlayerId);
@ -184,14 +234,12 @@ private:
int movingCardsUntilCounter = 0; int movingCardsUntilCounter = 0;
MoveTopCardsUntilOptions movingCardsUntilOptions; MoveTopCardsUntilOptions movingCardsUntilOptions;
void moveTopCardsTo(const QString &targetZone, const QString &zoneDisplayName, bool faceDown); bool lastRelatedCreationSucceeded = false;
void moveBottomCardsTo(const QString &targetZone, const QString &zoneDisplayName, bool faceDown);
void createCard(const CardItem *sourceCard, void createCard(const CardItem *sourceCard,
const QString &dbCardName, const QString &dbCardName,
CardRelationType attach = CardRelationType::DoesNotAttach, CardRelationType attach = CardRelationType::DoesNotAttach,
bool persistent = false); bool persistent = false);
bool createRelatedFromRelation(const CardItem *sourceCard, const CardRelation *cardRelation);
void playSelectedCards(QList<CardItem *> selectedCards, bool faceDown = false); void playSelectedCards(QList<CardItem *> selectedCards, bool faceDown = false);

View file

@ -0,0 +1,298 @@
#include "player_dialogs.h"
#include "../../client/settings/card_counter_settings.h"
#include "../../interface/widgets/utility/get_text_with_max.h"
#include "../board/card_item.h"
#include "../dialogs/dlg_roll_dice.h"
#include "../player/player_graphics_item.h"
#include <QInputDialog>
#include <libcockatrice/card/relation/card_relation.h>
PlayerDialogs::PlayerDialogs(PlayerGraphicsItem *_player, PlayerActions *_playerActions)
: QObject(_player), player(_player), playerActions(_playerActions)
{
connect(playerActions, &PlayerActions::requestViewTopCardsDialog, this,
&PlayerDialogs::onViewTopCardsDialogRequested);
connect(playerActions, &PlayerActions::requestViewBottomCardsDialog, this,
&PlayerDialogs::onViewBottomCardsDialogRequested);
connect(playerActions, &PlayerActions::requestShuffleTopDialog, this, &PlayerDialogs::onShuffleTopDialogRequested);
connect(playerActions, &PlayerActions::requestShuffleBottomDialog, this,
&PlayerDialogs::onShuffleBottomDialogRequested);
connect(playerActions, &PlayerActions::requestMulliganDialog, this, &PlayerDialogs::onMulliganDialogRequested);
connect(playerActions, &PlayerActions::requestDrawCardsDialog, this, &PlayerDialogs::onDrawCardsDialogRequested);
connect(playerActions, &PlayerActions::requestMoveTopCardsToDialog, this,
&PlayerDialogs::onMoveTopCardsToDialogRequested);
connect(playerActions, &PlayerActions::requestMoveTopCardsUntilDialog, this,
&PlayerDialogs::onMoveTopCardsUntilDialogRequested);
connect(playerActions, &PlayerActions::requestMoveBottomCardsToDialog, this,
&PlayerDialogs::onMoveBottomCardsToDialogRequested);
connect(playerActions, &PlayerActions::requestDrawBottomCardsDialog, this,
&PlayerDialogs::onDrawBottomCardsDialogRequested);
connect(playerActions, &PlayerActions::requestRollDieDialog, this, &PlayerDialogs::onRollDieDialogRequested);
connect(playerActions, &PlayerActions::requestCreateTokenDialog, this,
&PlayerDialogs::onCreateTokenDialogRequested);
connect(playerActions, &PlayerActions::requestCreateRelatedFromRelationDialog, this,
&PlayerDialogs::onCreateRelatedFromRelationDialogRequested);
connect(playerActions, &PlayerActions::requestMoveCardXCardsFromTopDialog, this,
&PlayerDialogs::onMoveCardXCardsFromTopDialogRequested);
connect(playerActions, &PlayerActions::requestSetPTDialog, this, &PlayerDialogs::onSetPTDialogRequested);
connect(playerActions, &PlayerActions::requestSetAnnotationDialog, this,
&PlayerDialogs::onSetAnnotationDialogRequested);
connect(playerActions, &PlayerActions::requestSetCardCounterDialog, this,
&PlayerDialogs::onSetCardCounterDialogRequested);
}
void PlayerDialogs::onViewTopCardsDialogRequested(int defaultNumberTopCards, int deckSize)
{
bool ok;
int number = QInputDialog::getInt(dialogParent(), tr("View top cards of library"),
tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberTopCards, 1,
deckSize, 1, &ok);
if (ok) {
playerActions->actViewTopCards(number);
}
}
void PlayerDialogs::onViewBottomCardsDialogRequested(int defaultNumberBottomCards, int deckSize)
{
bool ok;
int number = QInputDialog::getInt(dialogParent(), tr("View bottom cards of library"),
tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberBottomCards, 1,
deckSize, 1, &ok);
if (ok) {
playerActions->actViewBottomCards(number);
}
}
void PlayerDialogs::onShuffleTopDialogRequested(int defaultNumberTopCards, int maxCards)
{
bool ok;
int number = QInputDialog::getInt(dialogParent(), tr("Shuffle top cards of library"),
tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberTopCards, 1,
maxCards, 1, &ok);
if (ok) {
playerActions->actShuffleTop(number);
}
}
void PlayerDialogs::onShuffleBottomDialogRequested(int defaultNumberBottomCards, int maxCards)
{
bool ok;
int number = QInputDialog::getInt(dialogParent(), tr("Shuffle bottom cards of library"),
tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1,
maxCards, 1, &ok);
if (ok) {
playerActions->actShuffleBottom(number);
}
}
void PlayerDialogs::onMulliganDialogRequested(int startSize, int handSize, int deckSize)
{
bool ok;
int number = QInputDialog::getInt(dialogParent(), tr("Draw hand"),
tr("Number of cards: (max. %1)").arg(deckSize) + '\n' +
tr("0 and lower are in comparison to current hand size"),
startSize, -handSize, deckSize, 1, &ok);
if (ok) {
playerActions->actMulligan(number);
}
}
void PlayerDialogs::onDrawCardsDialogRequested(int defaultNumberTopCards, int deckSize)
{
bool ok;
int number = QInputDialog::getInt(dialogParent(), tr("Draw cards"), tr("Number of cards: (max. %1)").arg(deckSize),
defaultNumberTopCards, 1, deckSize, 1, &ok);
if (ok) {
playerActions->actDrawCards(number);
}
}
void PlayerDialogs::onMoveTopCardsToDialogRequested(int defaultNumberTopCards,
int maxCards,
const QString &targetZone,
const QString &zoneDisplayName,
bool faceDown)
{
bool ok;
int number = QInputDialog::getInt(dialogParent(), tr("Move top cards to %1").arg(zoneDisplayName),
tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberTopCards, 1,
maxCards, 1, &ok);
if (ok) {
playerActions->moveTopCardsTo(number, targetZone, faceDown);
}
}
void PlayerDialogs::onMoveTopCardsUntilDialogRequested(MoveTopCardsUntilOptions options)
{
DlgMoveTopCardsUntil dlg(dialogParent(), options);
if (!dlg.exec()) {
return;
}
playerActions->moveTopCardsUntil(dlg.getExpr(), dlg.getOptions());
}
void PlayerDialogs::onMoveBottomCardsToDialogRequested(int defaultNumberBottomCards,
int maxCards,
const QString &targetZone,
const QString &zoneDisplayName,
bool faceDown)
{
bool ok;
int number = QInputDialog::getInt(dialogParent(), tr("Move bottom cards to %1").arg(zoneDisplayName),
tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1,
maxCards, 1, &ok);
if (ok) {
playerActions->moveBottomCardsTo(number, targetZone, faceDown);
}
}
void PlayerDialogs::onDrawBottomCardsDialogRequested(int defaultNumberBottomCards, int maxCards)
{
bool ok;
int number =
QInputDialog::getInt(dialogParent(), tr("Draw bottom cards"), tr("Number of cards: (max. %1)").arg(maxCards),
defaultNumberBottomCards, 1, maxCards, 1, &ok);
if (ok) {
playerActions->actDrawBottomCards(number);
}
}
void PlayerDialogs::onRollDieDialogRequested()
{
DlgRollDice dlg(dialogParent());
if (!dlg.exec()) {
return;
}
playerActions->actRollDie(dlg.getDieSideCount(), dlg.getDiceToRollCount());
}
void PlayerDialogs::onCreateRelatedFromRelationDialogRequested(const CardItem *sourceCard,
const CardRelation *cardRelation)
{
if (sourceCard == nullptr || cardRelation == nullptr) {
playerActions->setLastRelatedCreationSucceeded(false);
return;
}
int variableCount = cardRelation->getDefaultCount();
if (cardRelation->getIsVariable()) {
bool ok;
emit requestDialogSemaphore(true);
variableCount = QInputDialog::getInt(dialogParent(), tr("Create tokens"), tr("Number:"),
cardRelation->getDefaultCount(), 1, MAX_TOKENS_PER_DIALOG, 1, &ok);
emit requestDialogSemaphore(false);
if (!ok) {
playerActions->setLastRelatedCreationSucceeded(false); // cancelled
return;
}
}
const bool succeeded = playerActions->createRelatedFromRelation(sourceCard, cardRelation, variableCount);
playerActions->setLastRelatedCreationSucceeded(succeeded);
if (succeeded) {
playerActions->onRelatedCardCreated(sourceCard, cardRelation); // only on confirmed success
}
}
void PlayerDialogs::onCreateTokenDialogRequested(const QStringList &predefinedTokens)
{
DlgCreateToken dlg(predefinedTokens, dialogParent());
if (!dlg.exec()) {
return;
}
playerActions->actCreateToken(dlg.getTokenInfo());
}
void PlayerDialogs::onMoveCardXCardsFromTopDialogRequested(int defaultNumberTopCardsToPlaceBelow, int deckSize)
{
bool ok;
int number =
QInputDialog::getInt(dialogParent(), tr("Place card X cards from top of library"),
tr("Which position should this card be placed:") + "\n" + tr("(max. %1)").arg(deckSize),
defaultNumberTopCardsToPlaceBelow, 1, deckSize, 1, &ok);
number -= 1; // indexes start at 0
if (ok) {
playerActions->actMoveCardXCardsFromTop(player->getGameScene()->selectedCards(), number);
}
}
void PlayerDialogs::onSetPTDialogRequested(const QString &oldPT)
{
bool ok;
auto cards = player->getGameScene()->selectedCards();
emit requestDialogSemaphore(true);
QString pt = getTextWithMax(dialogParent(), tr("Change power/toughness"), tr("Change stats to:"), QLineEdit::Normal,
oldPT, &ok);
emit requestDialogSemaphore(false);
if (!ok || player->getLogic()->clearCardsToDelete()) {
return;
}
playerActions->actSetPT(cards, pt);
}
void PlayerDialogs::onSetAnnotationDialogRequested(const QString &oldAnnotation)
{
auto cards = player->getGameScene()->selectedCards();
emit requestDialogSemaphore(true);
AnnotationDialog *dialog = new AnnotationDialog(dialogParent());
dialog->setOptions(QInputDialog::UsePlainTextEditForTextInput);
dialog->setWindowTitle(tr("Set annotation"));
dialog->setLabelText(tr("Please enter the new annotation:"));
dialog->setTextValue(oldAnnotation);
bool ok = dialog->exec();
emit requestDialogSemaphore(false);
if (!ok || player->getLogic()->clearCardsToDelete()) {
return;
}
QString annotation = dialog->textValue().left(MAX_NAME_LENGTH);
playerActions->actSetAnnotation(cards, annotation);
}
void PlayerDialogs::onSetCardCounterDialogRequested(int counterId, const QString &oldValueForDlg)
{
auto cards = player->getGameScene()->selectedCards();
emit requestDialogSemaphore(true);
auto &cardCounterSettings = SettingsCache::instance().cardCounters();
QString counterName = cardCounterSettings.displayName(counterId);
AbstractCounterDialog dialog(counterName, oldValueForDlg, dialogParent());
int ok = dialog.exec();
emit requestDialogSemaphore(false);
if (!ok || player->getLogic()->clearCardsToDelete()) {
return;
}
playerActions->actSetCardCounter(cards, counterId, dialog.textValue());
}

View file

@ -0,0 +1,62 @@
#ifndef COCKATRICE_PLAYER_DIALOGS_H
#define COCKATRICE_PLAYER_DIALOGS_H
#include "player_actions.h"
#include <QGraphicsView>
#include <QObject>
class PlayerGraphicsItem;
class PlayerDialogs : public QObject
{
Q_OBJECT
public:
explicit PlayerDialogs(PlayerGraphicsItem *player, PlayerActions *playerActions);
signals:
void requestDialogSemaphore(bool active);
public slots:
void onViewTopCardsDialogRequested(int defaultNumberTopCards, int deckSize);
void onViewBottomCardsDialogRequested(int defaultNumberBottomCards, int deckSize);
void onShuffleTopDialogRequested(int defaultNumberTopCards, int maxCards);
void onShuffleBottomDialogRequested(int defaultNumberBottomCards, int maxCards);
void onMulliganDialogRequested(int startSize, int handSize, int deckSize);
void onDrawCardsDialogRequested(int defaultNumberTopCards, int deckSize);
void onMoveTopCardsToDialogRequested(int defaultNumberTopCards,
int maxCards,
const QString &targetZone,
const QString &zoneDisplayName,
bool faceDown);
void onMoveTopCardsUntilDialogRequested(MoveTopCardsUntilOptions options);
void onMoveBottomCardsToDialogRequested(int defaultNumberBottomCards,
int maxCards,
const QString &targetZone,
const QString &zoneDisplayName,
bool faceDown);
void onDrawBottomCardsDialogRequested(int defaultNumberBottomCards, int maxCards);
void onRollDieDialogRequested();
void onCreateRelatedFromRelationDialogRequested(const CardItem *sourceCard, const CardRelation *cardRelation);
void onCreateTokenDialogRequested(const QStringList &predefinedTokens);
void onMoveCardXCardsFromTopDialogRequested(int defaultNumberTopCardsToPlaceBelow, int deckSize);
void onSetPTDialogRequested(const QString &oldPT);
void onSetAnnotationDialogRequested(const QString &oldAnnotation);
void onSetCardCounterDialogRequested(int counterId, const QString &oldValueForDlg);
private:
PlayerGraphicsItem *player;
PlayerActions *playerActions;
QWidget *dialogParent() const
{
if (auto *s = player->scene()) {
if (auto *v = s->views().value(0)) {
return v->window();
}
}
return nullptr;
}
};
#endif // COCKATRICE_PLAYER_DIALOGS_H

View file

@ -9,6 +9,7 @@
#include "../board/counter_general.h" #include "../board/counter_general.h"
#include "../hand_counter.h" #include "../hand_counter.h"
#include "player_actions.h" #include "player_actions.h"
#include "player_dialogs.h"
#include <QGraphicsView> #include <QGraphicsView>
@ -44,6 +45,10 @@ PlayerGraphicsItem::PlayerGraphicsItem(PlayerLogic *_player) : player(_player)
} }
}); });
playerDialogs = new PlayerDialogs(this, player->getPlayerActions());
connect(playerDialogs, &PlayerDialogs::requestDialogSemaphore, player, &PlayerLogic::setDialogSemaphore);
playerArea = new PlayerArea(this); playerArea = new PlayerArea(this);
playerTarget = new PlayerTarget(player, playerArea); playerTarget = new PlayerTarget(player, playerArea);

View file

@ -14,6 +14,7 @@
class HandZone; class HandZone;
class PileZone; class PileZone;
class PlayerDialogs;
class PlayerTarget; class PlayerTarget;
class StackZone; class StackZone;
class TableZone; class TableZone;
@ -122,6 +123,7 @@ signals:
private: private:
PlayerLogic *player; PlayerLogic *player;
PlayerMenu *playerMenu; PlayerMenu *playerMenu;
PlayerDialogs *playerDialogs;
PlayerArea *playerArea; PlayerArea *playerArea;
PlayerTarget *playerTarget; PlayerTarget *playerTarget;
QMap<int, AbstractCounter *> counterWidgets; QMap<int, AbstractCounter *> counterWidgets;