add option to auto-play "put top card on stack until" hits (#5258)

* rename variables

* implement feature

* readd null check
This commit is contained in:
RickyRister 2024-12-17 20:47:49 -08:00 committed by GitHub
parent a6b5abf271
commit 116397cdb3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 45 additions and 14 deletions

View file

@ -14,7 +14,8 @@
#include <QVBoxLayout>
#include <QWidget>
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();
}

View file

@ -1,6 +1,7 @@
#ifndef DLG_MOVE_TOP_CARDS_UNTIL_H
#define DLG_MOVE_TOP_CARDS_UNTIL_H
#include <QCheckBox>
#include <QDialog>
#include <QDialogButtonBox>
#include <QLabel>
@ -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

View file

@ -74,6 +74,7 @@
#include <QPainter>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <QtConcurrent>
// 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);
}
}

View file

@ -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);