From 116397cdb38db5a59884d8fe14e0dda54df6bcc1 Mon Sep 17 00:00:00 2001 From: RickyRister <42636155+RickyRister@users.noreply.github.com> Date: Tue, 17 Dec 2024 20:47:49 -0800 Subject: [PATCH] add option to auto-play "put top card on stack until" hits (#5258) * rename variables * implement feature * readd null check --- .../src/dialogs/dlg_move_top_cards_until.cpp | 12 ++++++- .../src/dialogs/dlg_move_top_cards_until.h | 8 ++++- cockatrice/src/game/player/player.cpp | 32 +++++++++++++------ cockatrice/src/game/player/player.h | 7 ++-- 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp b/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp index c21bbef45..f93cbfe9d 100644 --- a/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp +++ b/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp @@ -14,7 +14,8 @@ #include #include -DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QString _expr, uint _numberOfHits) : QDialog(parent) +DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QString _expr, uint _numberOfHits, bool autoPlay) + : QDialog(parent) { exprLabel = new QLabel(tr("Card name (or search expressions):")); @@ -33,6 +34,9 @@ DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QString _expr, uint grid->addWidget(numberOfHitsLabel, 0, 0); grid->addWidget(numberOfHitsEdit, 0, 1); + autoPlayCheckBox = new QCheckBox(tr("Auto play hits")); + autoPlayCheckBox->setChecked(autoPlay); + buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgMoveTopCardsUntil::validateAndAccept); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); @@ -41,6 +45,7 @@ DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QString _expr, uint mainLayout->addWidget(exprLabel); mainLayout->addWidget(exprEdit); mainLayout->addItem(grid); + mainLayout->addWidget(autoPlayCheckBox); mainLayout->addWidget(buttonBox); setLayout(mainLayout); @@ -109,3 +114,8 @@ uint DlgMoveTopCardsUntil::getNumberOfHits() const { return numberOfHitsEdit->text().toUInt(); } + +bool DlgMoveTopCardsUntil::isAutoPlay() const +{ + return autoPlayCheckBox->isChecked(); +} diff --git a/cockatrice/src/dialogs/dlg_move_top_cards_until.h b/cockatrice/src/dialogs/dlg_move_top_cards_until.h index 96ce65baf..c4cc2e0cb 100644 --- a/cockatrice/src/dialogs/dlg_move_top_cards_until.h +++ b/cockatrice/src/dialogs/dlg_move_top_cards_until.h @@ -1,6 +1,7 @@ #ifndef DLG_MOVE_TOP_CARDS_UNTIL_H #define DLG_MOVE_TOP_CARDS_UNTIL_H +#include #include #include #include @@ -17,14 +18,19 @@ class DlgMoveTopCardsUntil : public QDialog QLineEdit *exprEdit; QSpinBox *numberOfHitsEdit; QDialogButtonBox *buttonBox; + QCheckBox *autoPlayCheckBox; void validateAndAccept(); bool validateMatchExists(const FilterString &filterString); public: - explicit DlgMoveTopCardsUntil(QWidget *parent = nullptr, QString expr = QString(), uint numberOfHits = 1); + explicit DlgMoveTopCardsUntil(QWidget *parent = nullptr, + QString expr = QString(), + uint numberOfHits = 1, + bool autoPlay = false); QString getExpr() const; uint getNumberOfHits() const; + bool isAutoPlay() const; }; #endif // DLG_MOVE_TOP_CARDS_UNTIL_H diff --git a/cockatrice/src/game/player/player.cpp b/cockatrice/src/game/player/player.cpp index ce8f6a0a2..c573d8ff8 100644 --- a/cockatrice/src/game/player/player.cpp +++ b/cockatrice/src/game/player/player.cpp @@ -74,6 +74,7 @@ #include #include #include +#include // milliseconds in between triggers of the move top cards until action static constexpr int MOVE_TOP_CARD_UNTIL_INTERVAL = 100; @@ -1351,30 +1352,43 @@ void Player::actMoveTopCardsUntil() { stopMoveTopCardsUntil(); - DlgMoveTopCardsUntil dlg(game, previousMovingCardsUntilExpr, previousMovingCardsUntilNumberOfHits); + DlgMoveTopCardsUntil dlg(game, movingCardsUntilExpr, movingCardsUntilNumberOfHits, movingCardsUntilAutoPlay); if (!dlg.exec()) { return; } - previousMovingCardsUntilExpr = dlg.getExpr(); - previousMovingCardsUntilNumberOfHits = dlg.getNumberOfHits(); + movingCardsUntilExpr = dlg.getExpr(); + movingCardsUntilNumberOfHits = dlg.getNumberOfHits(); + movingCardsUntilAutoPlay = dlg.isAutoPlay(); if (zones.value("deck")->getCards().empty()) { stopMoveTopCardsUntil(); } else { - movingCardsUntilFilter = FilterString(previousMovingCardsUntilExpr); - movingCardsUntilCounter = previousMovingCardsUntilNumberOfHits; + movingCardsUntilFilter = FilterString(movingCardsUntilExpr); + movingCardsUntilCounter = movingCardsUntilNumberOfHits; movingCardsUntil = true; actMoveTopCardToPlay(); } } -void Player::moveOneCardUntil(const CardInfoPtr card) +void Player::moveOneCardUntil(CardItem *card) { moveTopCardTimer->stop(); - if (zones.value("deck")->getCards().empty() || card.isNull()) { + + const bool isMatch = card && movingCardsUntilFilter.check(card->getInfo()); + + if (isMatch && movingCardsUntilAutoPlay) { + // Directly calling playCard will deadlock, since we are already in the middle of processing an event. + // Use QTimer::singleShot to queue up the playCard on the event loop. + QTimer::singleShot(0, this, [card, this] { + bool cipt = card && card->getInfo() && card->getInfo()->getCipt(); + playCard(card, false, cipt); + }); + } + + if (zones.value("deck")->getCards().empty() || !card) { stopMoveTopCardsUntil(); - } else if (movingCardsUntilFilter.check(card)) { + } else if (isMatch) { --movingCardsUntilCounter; if (movingCardsUntilCounter > 0) { moveTopCardTimer->start(); @@ -2278,7 +2292,7 @@ void Player::eventMoveCard(const Event_MoveCard &event, const GameEventContext & updateCardMenu(card); if (movingCardsUntil && startZoneString == "deck" && targetZone->getName() == "stack") { - moveOneCardUntil(card->getInfo()); + moveOneCardUntil(card); } } diff --git a/cockatrice/src/game/player/player.h b/cockatrice/src/game/player/player.h index f96ae97fd..a71d641f1 100644 --- a/cockatrice/src/game/player/player.h +++ b/cockatrice/src/game/player/player.h @@ -270,8 +270,9 @@ private: bool movingCardsUntil; QTimer *moveTopCardTimer; - QString previousMovingCardsUntilExpr = {}; - int previousMovingCardsUntilNumberOfHits = 1; + QString movingCardsUntilExpr = {}; + int movingCardsUntilNumberOfHits = 1; + bool movingCardsUntilAutoPlay = false; FilterString movingCardsUntilFilter; int movingCardsUntilCounter = 0; void stopMoveTopCardsUntil(); @@ -321,7 +322,7 @@ private: CardRelation::AttachType attach = CardRelation::DoesNotAttach, bool persistent = false); bool createRelatedFromRelation(const CardItem *sourceCard, const CardRelation *cardRelation); - void moveOneCardUntil(const CardInfoPtr card); + void moveOneCardUntil(CardItem *card); void addPlayerToList(QMenu *playerList, Player *player); static void removePlayerFromList(QMenu *playerList, Player *player);