Deck format legality checker (#6166)

* Deck legality checker.

Took 51 seconds

Took 1 minute

Took 1 minute

Took 5 minutes

Took 3 minutes

* Adjust format parsing.

Took 8 minutes


Took 3 seconds

* toString() the xmlName

Took 4 minutes

* more toStrings()

Took 5 minutes

* Comments

Took 3 minutes

* Layout

Took 2 minutes

* Layout part 2: Electric boogaloo

Took 59 seconds

* Update cockatrice/src/interface/widgets/visual_database_display/visual_database_display_format_legality_filter_widget.cpp

Co-authored-by: RickyRister <42636155+RickyRister@users.noreply.github.com>

* Move layout.

Took 4 minutes


Took 10 seconds

* Emit deckModified

Took 6 minutes

* Fix qOverloads

Took 4 minutes

* Fix qOverloads

Took 12 seconds

* Consider text and name in a special way.

Took 11 minutes

* Adjust "Any number of" oracle text

Took 5 minutes

* Store allowedCounts by format

Took 15 minutes

Took 6 seconds

* Only restrict vintage.

Took 2 minutes

* Adjust for DBConverter.

Took 6 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
Co-authored-by: RickyRister <42636155+RickyRister@users.noreply.github.com>
This commit is contained in:
BruebachL 2025-12-13 15:17:55 +01:00 committed by GitHub
parent 2e2682aad4
commit ccdda39e78
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 987 additions and 35 deletions

View file

@ -136,6 +136,8 @@ bool DeckList::readElement(QXmlStreamReader *xml)
metadata.lastLoadedTimestamp = xml->readElementText();
} else if (childName == "deckname") {
metadata.name = xml->readElementText();
} else if (childName == "format") {
metadata.gameFormat = xml->readElementText();
} else if (childName == "comments") {
metadata.comments = xml->readElementText();
} else if (childName == "bannerCard") {
@ -170,6 +172,7 @@ void writeMetadata(QXmlStreamWriter *xml, const DeckList::Metadata &metadata)
{
xml->writeTextElement("lastLoadedTimestamp", metadata.lastLoadedTimestamp);
xml->writeTextElement("deckname", metadata.name);
xml->writeTextElement("format", metadata.gameFormat);
xml->writeStartElement("bannerCard");
xml->writeAttribute("providerId", metadata.bannerCard.providerId);
xml->writeCharacters(metadata.bannerCard.name);
@ -594,15 +597,16 @@ DecklistCardNode *DeckList::addCard(const QString &cardName,
const int position,
const QString &cardSetName,
const QString &cardSetCollectorNumber,
const QString &cardProviderId)
const QString &cardProviderId,
const bool formatLegal)
{
auto *zoneNode = dynamic_cast<InnerDecklistNode *>(root->findChild(zoneName));
if (zoneNode == nullptr) {
zoneNode = new InnerDecklistNode(zoneName, root);
}
auto *node =
new DecklistCardNode(cardName, 1, zoneNode, position, cardSetName, cardSetCollectorNumber, cardProviderId);
auto *node = new DecklistCardNode(cardName, 1, zoneNode, position, cardSetName, cardSetCollectorNumber,
cardProviderId, formatLegal);
refreshDeckHash();
return node;

View file

@ -126,6 +126,7 @@ public:
{
QString name; ///< User-defined deck name.
QString comments; ///< Free-form comments or notes.
QString gameFormat; ///< The name of the game format this deck contains legal cards for
CardRef bannerCard; ///< Optional representative card for the deck.
QStringList tags; ///< User-defined tags for deck classification.
QString lastLoadedTimestamp; ///< Timestamp string of last load.
@ -181,6 +182,10 @@ public:
{
metadata.lastLoadedTimestamp = _lastLoadedTimestamp;
}
void setGameFormat(const QString &_gameFormat = QString())
{
metadata.gameFormat = _gameFormat;
}
///@}
/// @brief Construct an empty deck.
@ -219,6 +224,10 @@ public:
{
return metadata.lastLoadedTimestamp;
}
QString getGameFormat() const
{
return metadata.gameFormat;
}
///@}
bool isBlankDeck() const
@ -277,7 +286,8 @@ public:
int position,
const QString &cardSetName = QString(),
const QString &cardSetCollectorNumber = QString(),
const QString &cardProviderId = QString());
const QString &cardProviderId = QString(),
const bool formatLegal = true);
bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = nullptr);
///@}

View file

@ -88,6 +88,12 @@ public:
/// @param _cardSetNumber Set the collector number.
virtual void setCardCollectorNumber(const QString &_cardSetNumber) = 0;
/// @return The format legality of the card
virtual bool getFormatLegality() const = 0;
/// @param _formatLegal If the card is considered legal
virtual void setFormatLegality(const bool _formatLegal) = 0;
/**
* @brief Get the height of this node in the tree.
*

View file

@ -51,6 +51,7 @@ class DecklistCardNode : public AbstractDecklistCardNode
QString cardSetShortName; ///< Short set code (e.g., "NEO").
QString cardSetNumber; ///< Collector number within the set.
QString cardProviderId; ///< External provider identifier (e.g., UUID).
bool formatLegal; ///< Format legality
public:
/**
@ -63,6 +64,7 @@ public:
* @param _cardSetShortName Short set code (e.g., "NEO").
* @param _cardSetNumber Collector number within the set.
* @param _cardProviderId External provider ID (e.g., UUID).
* @param _formatLegality If the card is legal in the format
*
* On construction, if a parent is provided, this node is inserted into
* the parents children list automatically.
@ -73,10 +75,11 @@ public:
int position = -1,
QString _cardSetShortName = QString(),
QString _cardSetNumber = QString(),
QString _cardProviderId = QString())
QString _cardProviderId = QString(),
bool _formatLegality = true)
: AbstractDecklistCardNode(_parent, position), name(std::move(_name)), number(_number),
cardSetShortName(std::move(_cardSetShortName)), cardSetNumber(std::move(_cardSetNumber)),
cardProviderId(std::move(_cardProviderId))
cardProviderId(std::move(_cardProviderId)), formatLegal(_formatLegality)
{
}
@ -150,6 +153,18 @@ public:
cardSetNumber = _cardSetNumber;
}
/// @return The format legality of the card
[[nodiscard]] bool getFormatLegality() const override
{
return formatLegal;
}
/// @param _formatLegal If the card is considered legal
void setFormatLegality(const bool _formatLegal) override
{
formatLegal = _formatLegal;
}
/// @return Always false; card nodes are not deck headers.
[[nodiscard]] bool isDeckHeader() const override
{