mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-11 04:43:56 -07:00
Store allowedCounts by format
Took 15 minutes Took 6 seconds
This commit is contained in:
parent
0d33a79387
commit
b1f0026b6c
4 changed files with 94 additions and 43 deletions
|
|
@ -109,10 +109,26 @@ static QSharedPointer<FormatRules> parseFormat(QXmlStreamReader &xml)
|
|||
rulesPtr->maxDeckSize = text.toInt();
|
||||
} else if (xmlName == "maxSideboardSize") {
|
||||
rulesPtr->maxSideboardSize = xml.readElementText().toInt();
|
||||
} else if (xmlName == "maxCopies") {
|
||||
rulesPtr->maxCopies = xml.readElementText().toInt();
|
||||
} else if (xmlName == "maxRestrictedCopies") {
|
||||
rulesPtr->maxRestrictedCopies = xml.readElementText().toInt();
|
||||
} else if (xmlName == "allowedCounts") {
|
||||
while (!xml.atEnd()) {
|
||||
token = xml.readNext();
|
||||
|
||||
if (token == QXmlStreamReader::EndElement && xml.name().toString() == "allowedCounts") {
|
||||
break;
|
||||
}
|
||||
|
||||
if (token == QXmlStreamReader::StartElement && xml.name().toString() == "count") {
|
||||
|
||||
AllowedCount c;
|
||||
|
||||
QString maxAttr = xml.attributes().value("max").toString();
|
||||
c.max = (maxAttr == "unlimited") ? -1 : maxAttr.toInt();
|
||||
|
||||
c.label = xml.readElementText().trimmed();
|
||||
|
||||
rulesPtr->allowedCounts.append(c);
|
||||
}
|
||||
}
|
||||
} else if (xmlName == "exceptions") {
|
||||
while (!xml.atEnd()) {
|
||||
token = xml.readNext();
|
||||
|
|
@ -387,8 +403,18 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const QSharedPointer<
|
|||
xml.writeTextElement("minDeckSize", QString::number(rules.minDeckSize));
|
||||
xml.writeTextElement("maxDeckSize", rules.maxDeckSize >= 0 ? QString::number(rules.maxDeckSize) : "0");
|
||||
xml.writeTextElement("maxSideboardSize", QString::number(rules.maxSideboardSize));
|
||||
xml.writeTextElement("maxCopies", QString::number(rules.maxCopies));
|
||||
xml.writeTextElement("maxRestrictedCopies", QString::number(rules.maxRestrictedCopies));
|
||||
if (!rules.allowedCounts.isEmpty()) {
|
||||
xml.writeStartElement("allowedCounts");
|
||||
|
||||
for (const AllowedCount &c : rules.allowedCounts) {
|
||||
xml.writeStartElement("count");
|
||||
xml.writeAttribute("max", c.max == -1 ? "unlimited" : QString::number(c.max));
|
||||
xml.writeCharacters(c.label);
|
||||
xml.writeEndElement(); // count
|
||||
}
|
||||
|
||||
xml.writeEndElement(); // allowedCounts
|
||||
}
|
||||
|
||||
if (!rules.exceptions.isEmpty()) {
|
||||
xml.writeStartElement("exceptions");
|
||||
|
|
|
|||
|
|
@ -15,6 +15,12 @@ struct CardCondition
|
|||
QString value; // e.g. "Basic Land"
|
||||
};
|
||||
|
||||
struct AllowedCount
|
||||
{
|
||||
int max = 0; // 4, 1, 0, or -1 for unlimited
|
||||
QString label; // "legal", "restricted", "banned"
|
||||
};
|
||||
|
||||
struct ExceptionRule
|
||||
{
|
||||
QList<CardCondition> conditions; // All must match
|
||||
|
|
@ -28,8 +34,7 @@ struct FormatRules
|
|||
int maxDeckSize = -1; // -1 = unlimited
|
||||
int maxSideboardSize = 15;
|
||||
|
||||
int maxCopies = 4; // default constructed rule
|
||||
int maxRestrictedCopies = 1; // Used for "restricted" legality tags
|
||||
QList<AllowedCount> allowedCounts;
|
||||
|
||||
QList<ExceptionRule> exceptions; // Cards allowed to break maxCopies
|
||||
};
|
||||
|
|
|
|||
|
|
@ -622,6 +622,17 @@ bool DeckListModel::isCardLegalForCurrentFormat(const CardInfoPtr cardInfo)
|
|||
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());
|
||||
|
|
@ -630,24 +641,29 @@ bool DeckListModel::isCardQuantityLegalForCurrentFormat(const CardInfoPtr cardIn
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cardHasAnyException(*cardInfo.data(), *formatRules.data())) {
|
||||
// Exceptions always win
|
||||
if (cardHasAnyException(*cardInfo, *formatRules)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cardInfo->getProperties().contains("format-" + deckList->getGameFormat())) {
|
||||
QString formatLegality = cardInfo->getProperty("format-" + deckList->getGameFormat());
|
||||
if (formatLegality == "legal") {
|
||||
if (quantity <= formatRules->maxCopies) {
|
||||
return true;
|
||||
}
|
||||
} else if (formatLegality == "restricted") {
|
||||
if (quantity <= formatRules->maxRestrictedCopies) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
const QString legalityProp = "format-" + deckList->getGameFormat();
|
||||
if (!cardInfo->getProperties().contains(legalityProp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@
|
|||
#include <libcockatrice/card/database/parser/cockatrice_xml_4.h>
|
||||
#include <libcockatrice/card/relation/card_relation.h>
|
||||
|
||||
static const QList<AllowedCount> kConstructedCounts = {{4, "legal"}, {1, "restricted"}, {0, "banned"}};
|
||||
|
||||
static const QList<AllowedCount> kSingletonCounts = {{1, "legal"}, {1, "restricted"}, {0, "banned"}};
|
||||
|
||||
SplitCardPart::SplitCardPart(const QString &_name,
|
||||
const QString &_text,
|
||||
const QVariantHash &_properties,
|
||||
|
|
@ -486,11 +490,11 @@ FormatRulesNameMap OracleImporter::createDefaultMagicFormats()
|
|||
FormatRulesNameMap defaultFormatRulesNameMap;
|
||||
|
||||
// ----------------- Helper lambda to create format -----------------
|
||||
auto makeFormat = [&](const QString &name, int maxCopies = 4, int minDeck = 60, int maxDeck = -1,
|
||||
int maxSideboardSize = 15) -> FormatRulesPtr {
|
||||
auto makeFormat = [&](const QString &name, int minDeck = 60, int maxDeck = -1, int maxSideboardSize = 15,
|
||||
const QList<AllowedCount> &allowedCounts = kConstructedCounts) -> FormatRulesPtr {
|
||||
FormatRulesPtr f(new FormatRules);
|
||||
f->formatName = name;
|
||||
f->maxCopies = maxCopies;
|
||||
f->allowedCounts = allowedCounts;
|
||||
f->minDeckSize = minDeck;
|
||||
f->maxDeckSize = maxDeck;
|
||||
f->maxSideboardSize = maxSideboardSize;
|
||||
|
|
@ -501,27 +505,27 @@ FormatRulesNameMap OracleImporter::createDefaultMagicFormats()
|
|||
};
|
||||
|
||||
// ----------------- Standard formats -----------------
|
||||
makeFormat("Alchemy", 4, 60);
|
||||
makeFormat("Brawl", 1, 60, 60);
|
||||
makeFormat("Commander", 1, 100, 100);
|
||||
makeFormat("Duel", 1, 100, 100);
|
||||
makeFormat("Future");
|
||||
makeFormat("Gladiator", 4, 60, 60, 0);
|
||||
makeFormat("Historic");
|
||||
makeFormat("Legacy");
|
||||
makeFormat("Modern");
|
||||
makeFormat("Oathbreaker", 1, 60, 60);
|
||||
makeFormat("OldSchool");
|
||||
makeFormat("Pauper");
|
||||
makeFormat("PauperCommander", 1, 100, 100);
|
||||
makeFormat("Penny");
|
||||
makeFormat("Pioneer");
|
||||
makeFormat("Predh", 1, 100, 100);
|
||||
makeFormat("Premodern");
|
||||
makeFormat("Standard");
|
||||
makeFormat("StandardBrawl", 1, 60, 60);
|
||||
makeFormat("Timeless");
|
||||
makeFormat("Modern");
|
||||
makeFormat("Legacy");
|
||||
makeFormat("Vintage");
|
||||
makeFormat("Pioneer");
|
||||
makeFormat("Historic");
|
||||
makeFormat("Timeless");
|
||||
makeFormat("Future");
|
||||
makeFormat("OldSchool");
|
||||
makeFormat("Premodern");
|
||||
makeFormat("Pauper");
|
||||
makeFormat("Penny");
|
||||
|
||||
// ----------------- Singleton formats -----------------
|
||||
makeFormat("Commander", 100, 100, 15, kSingletonCounts);
|
||||
makeFormat("Duel", 100, 100, 15, kSingletonCounts);
|
||||
makeFormat("Brawl", 60, 60, 15, kSingletonCounts);
|
||||
makeFormat("StandardBrawl", 60, 60, 15, kSingletonCounts);
|
||||
makeFormat("Oathbreaker", 60, 60, 15, kSingletonCounts);
|
||||
makeFormat("PauperCommander", 100, 100, 15, kSingletonCounts);
|
||||
makeFormat("Predh", 100, 100, 15, kSingletonCounts);
|
||||
|
||||
return defaultFormatRulesNameMap;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue