mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-18 04:51:33 -07:00
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:
parent
2e2682aad4
commit
ccdda39e78
37 changed files with 987 additions and 35 deletions
|
|
@ -168,6 +168,10 @@ QVariant DeckListModel::data(const QModelIndex &index, int role) const
|
|||
return card->depth();
|
||||
}
|
||||
|
||||
case DeckRoles::IsLegalRole: {
|
||||
return card->getFormatLegality();
|
||||
}
|
||||
|
||||
default: {
|
||||
return {};
|
||||
}
|
||||
|
|
@ -268,6 +272,7 @@ bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, con
|
|||
switch (index.column()) {
|
||||
case DeckListModelColumns::CARD_AMOUNT:
|
||||
node->setNumber(value.toInt());
|
||||
refreshCardFormatLegalities();
|
||||
break;
|
||||
case DeckListModelColumns::CARD_NAME:
|
||||
node->setName(value.toString());
|
||||
|
|
@ -414,8 +419,9 @@ QModelIndex DeckListModel::addCard(const ExactCard &card, const QString &zoneNam
|
|||
// Determine the correct index
|
||||
int insertRow = findSortedInsertRow(groupNode, cardInfo);
|
||||
|
||||
auto *decklistCard = deckList->addCard(cardInfo->getName(), zoneName, insertRow, cardSetName,
|
||||
printingInfo.getProperty("num"), printingInfo.getProperty("uuid"));
|
||||
auto *decklistCard =
|
||||
deckList->addCard(cardInfo->getName(), zoneName, insertRow, cardSetName, printingInfo.getProperty("num"),
|
||||
printingInfo.getProperty("uuid"), isCardLegalForCurrentFormat(cardInfo));
|
||||
|
||||
beginInsertRows(parentIndex, insertRow, insertRow);
|
||||
cardNode = new DecklistModelCardNode(decklistCard, groupNode, insertRow);
|
||||
|
|
@ -532,6 +538,13 @@ void DeckListModel::setActiveGroupCriteria(DeckListModelGroupCriteria::Type newC
|
|||
rebuildTree();
|
||||
}
|
||||
|
||||
void DeckListModel::setActiveFormat(const QString &_format)
|
||||
{
|
||||
deckList->setGameFormat(_format);
|
||||
refreshCardFormatLegalities();
|
||||
emitBackgroundUpdates(QModelIndex()); // start from root
|
||||
}
|
||||
|
||||
void DeckListModel::cleanList()
|
||||
{
|
||||
setDeckList(new DeckList);
|
||||
|
|
@ -595,4 +608,90 @@ QList<QString> DeckListModel::getZones() const
|
|||
[](auto zoneNode) { return zoneNode->getName(); });
|
||||
|
||||
return zones;
|
||||
}
|
||||
}
|
||||
|
||||
bool DeckListModel::isCardLegalForCurrentFormat(const CardInfoPtr cardInfo)
|
||||
{
|
||||
if (!deckList->getGameFormat().isEmpty()) {
|
||||
if (cardInfo->getProperties().contains("format-" + deckList->getGameFormat())) {
|
||||
QString formatLegality = cardInfo->getProperty("format-" + deckList->getGameFormat());
|
||||
return formatLegality == "legal" || formatLegality == "restricted";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int maxAllowedForLegality(const FormatRules &format, const QString &legality)
|
||||
{
|
||||
for (const AllowedCount &c : format.allowedCounts) {
|
||||
if (c.label == legality) {
|
||||
return c.max;
|
||||
}
|
||||
}
|
||||
return -1; // unknown legality → treat as illegal
|
||||
}
|
||||
|
||||
|
||||
bool DeckListModel::isCardQuantityLegalForCurrentFormat(const CardInfoPtr cardInfo, int quantity)
|
||||
{
|
||||
auto formatRules = CardDatabaseManager::query()->getFormat(deckList->getGameFormat());
|
||||
|
||||
if (!formatRules) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Exceptions always win
|
||||
if (cardHasAnyException(*cardInfo, *formatRules)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const QString legalityProp = "format-" + deckList->getGameFormat();
|
||||
if (!cardInfo->getProperties().contains(legalityProp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString legality = cardInfo->getProperty(legalityProp);
|
||||
|
||||
int maxAllowed = maxAllowedForLegality(*formatRules, legality);
|
||||
|
||||
if (maxAllowed == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (maxAllowed < 0) { // unlimited
|
||||
return true;
|
||||
}
|
||||
|
||||
return quantity <= maxAllowed;
|
||||
}
|
||||
|
||||
void DeckListModel::refreshCardFormatLegalities()
|
||||
{
|
||||
InnerDecklistNode *listRoot = deckList->getRoot();
|
||||
|
||||
for (int i = 0; i < listRoot->size(); i++) {
|
||||
auto *currentZone = static_cast<InnerDecklistNode *>(listRoot->at(i));
|
||||
for (int j = 0; j < currentZone->size(); j++) {
|
||||
auto *currentCard = static_cast<DecklistCardNode *>(currentZone->at(j));
|
||||
|
||||
// TODO: better sanity checking
|
||||
if (currentCard == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ExactCard exactCard = CardDatabaseManager::query()->getCard(currentCard->toCardRef());
|
||||
if (!exactCard) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool legal = isCardLegalForCurrentFormat(exactCard.getCardPtr());
|
||||
|
||||
if (legal) {
|
||||
legal = isCardQuantityLegalForCurrentFormat(exactCard.getCardPtr(), currentCard->getNumber());
|
||||
}
|
||||
|
||||
currentCard->setFormatLegality(legal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,6 +164,14 @@ public:
|
|||
{
|
||||
dataNode->setCardCollectorNumber(_cardSetNumber);
|
||||
}
|
||||
bool getFormatLegality() const override
|
||||
{
|
||||
return dataNode->getFormatLegality();
|
||||
}
|
||||
void setFormatLegality(const bool _formatLegal) override
|
||||
{
|
||||
dataNode->setFormatLegality(_formatLegal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the underlying data node.
|
||||
|
|
@ -209,6 +217,9 @@ public slots:
|
|||
*/
|
||||
void rebuildTree();
|
||||
|
||||
public slots:
|
||||
void setActiveFormat(const QString &_format);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Emitted whenever the deck hash changes due to modifications in the model.
|
||||
|
|
@ -301,6 +312,9 @@ public:
|
|||
[[nodiscard]] QList<ExactCard> getCards() const;
|
||||
[[nodiscard]] QList<ExactCard> getCardsForZone(const QString &zoneName) const;
|
||||
[[nodiscard]] QList<QString> getZones() const;
|
||||
bool isCardLegalForCurrentFormat(CardInfoPtr cardInfo);
|
||||
bool isCardQuantityLegalForCurrentFormat(CardInfoPtr cardInfo, int quantity);
|
||||
void refreshCardFormatLegalities();
|
||||
|
||||
/**
|
||||
* @brief Sets the criteria used to group cards in the model.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue