mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-03-12 21:22:55 -07:00
feat: set prioritization by set type (#5097)
* feat: prefer 'Core' and 'Expansion' sets for prioritization * rework set prioritization * clean up priority enum * formatting * revert changes to CockatriceXml3Parser * re-add missing null check * remove priority fallback ternary from CardSet model * make defaultSort logic easier to follow * revert changes to v3 card database xsd * remove unused invisible priority col from sets dialog * move draft innovation and duel deck sets to secondary prio * minor fixes * change PriorityFallback to 1 * make priority optional in xml * remove PriorityUndefined and set PriorityFallback to 0 * set priority when not found to PriorityOther in case a new set type is added it's unlikey we want it sorted first, it'll probably be a new product so it's probably best to sort it with the funny things * simplify sort function --------- Co-authored-by: tooomm <tooomm@users.noreply.github.com> Co-authored-by: ebbit1q <ebbit1q@gmail.com>
This commit is contained in:
committed by
GitHub
parent
5156495b47
commit
b9ed9a6c0b
@@ -195,6 +195,13 @@ void SetsModel::swapRows(int oldRow, int newRow)
|
||||
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
|
||||
}
|
||||
|
||||
void SetsModel::restoreOriginalOrder()
|
||||
{
|
||||
int numRows = rowCount();
|
||||
sets.defaultSort();
|
||||
emit dataChanged(index(0, 0), index(numRows - 1, columnCount() - 1));
|
||||
}
|
||||
|
||||
void SetsModel::sort(int column, Qt::SortOrder order)
|
||||
{
|
||||
QMultiMap<QString, CardSetPtr> setMap;
|
||||
|
||||
@@ -49,7 +49,8 @@ public:
|
||||
LongNameCol,
|
||||
ShortNameCol,
|
||||
SetTypeCol,
|
||||
ReleaseDateCol
|
||||
ReleaseDateCol,
|
||||
PriorityCol
|
||||
};
|
||||
enum Role
|
||||
{
|
||||
@@ -80,6 +81,7 @@ public:
|
||||
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
|
||||
void save(CardDatabase *db);
|
||||
void restore(CardDatabase *db);
|
||||
void restoreOriginalOrder();
|
||||
};
|
||||
|
||||
class SetsDisplayModel : public QSortFilterProxyModel
|
||||
|
||||
@@ -102,6 +102,7 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||
view->sortByColumn(SetsModel::SortKeyCol, Qt::AscendingOrder);
|
||||
view->setColumnHidden(SetsModel::SortKeyCol, true);
|
||||
view->setColumnHidden(SetsModel::IsKnownCol, true);
|
||||
view->setColumnHidden(SetsModel::PriorityCol, true);
|
||||
view->setRootIsDecorated(false);
|
||||
|
||||
connect(view->header(), SIGNAL(sectionClicked(int)), this, SLOT(actSort(int)));
|
||||
@@ -254,7 +255,7 @@ void WndSets::actRestore()
|
||||
void WndSets::actRestoreOriginalOrder()
|
||||
{
|
||||
view->header()->setSortIndicator(SORT_RESET, Qt::DescendingOrder);
|
||||
model->sort(model->ReleaseDateCol, Qt::DescendingOrder);
|
||||
model->restoreOriginalOrder();
|
||||
sortWarning->setVisible(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,9 @@ const char *CardDatabase::TOKENS_SETNAME = "TK";
|
||||
CardSet::CardSet(const QString &_shortName,
|
||||
const QString &_longName,
|
||||
const QString &_setType,
|
||||
const QDate &_releaseDate)
|
||||
: shortName(_shortName), longName(_longName), releaseDate(_releaseDate), setType(_setType)
|
||||
const QDate &_releaseDate,
|
||||
const CardSet::Priority _priority)
|
||||
: shortName(_shortName), longName(_longName), releaseDate(_releaseDate), setType(_setType), priority(_priority)
|
||||
{
|
||||
loadSetOptions();
|
||||
}
|
||||
@@ -32,9 +33,10 @@ CardSet::CardSet(const QString &_shortName,
|
||||
CardSetPtr CardSet::newInstance(const QString &_shortName,
|
||||
const QString &_longName,
|
||||
const QString &_setType,
|
||||
const QDate &_releaseDate)
|
||||
const QDate &_releaseDate,
|
||||
const Priority _priority)
|
||||
{
|
||||
CardSetPtr ptr(new CardSet(_shortName, _longName, _setType, _releaseDate));
|
||||
CardSetPtr ptr(new CardSet(_shortName, _longName, _setType, _releaseDate, _priority));
|
||||
// ptr->setSmartPointer(ptr);
|
||||
return ptr;
|
||||
}
|
||||
@@ -195,25 +197,31 @@ void SetList::markAllAsKnown()
|
||||
|
||||
void SetList::guessSortKeys()
|
||||
{
|
||||
// sort by release date DESC; invalid dates to the bottom.
|
||||
QDate distantFuture(2050, 1, 1);
|
||||
int aHundredYears = 36500;
|
||||
defaultSort();
|
||||
for (int i = 0; i < size(); ++i) {
|
||||
CardSetPtr set = at(i);
|
||||
if (set.isNull()) {
|
||||
qDebug() << "guessSortKeys set is null";
|
||||
continue;
|
||||
}
|
||||
|
||||
QDate date = set->getReleaseDate();
|
||||
if (date.isNull()) {
|
||||
set->setSortKey(static_cast<unsigned int>(aHundredYears));
|
||||
} else {
|
||||
set->setSortKey(static_cast<unsigned int>(date.daysTo(distantFuture)));
|
||||
}
|
||||
set->setSortKey(i);
|
||||
}
|
||||
}
|
||||
|
||||
void SetList::defaultSort()
|
||||
{
|
||||
std::sort(begin(), end(), [](const CardSetPtr &a, const CardSetPtr &b) {
|
||||
// Sort by priority, then by release date, then by short name
|
||||
if (a->getPriority() != b->getPriority()) {
|
||||
return a->getPriority() < b->getPriority(); // lowest first
|
||||
} else if (a->getReleaseDate() != b->getReleaseDate()) {
|
||||
return a->getReleaseDate() > b->getReleaseDate(); // most recent first
|
||||
} else {
|
||||
return a->getShortName() < b->getShortName(); // alphabetically
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CardInfoPerSet::CardInfoPerSet(const CardSetPtr &_set) : set(_set)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,22 +29,36 @@ Q_DECLARE_METATYPE(CardInfoPtr)
|
||||
|
||||
class CardSet : public QList<CardInfoPtr>
|
||||
{
|
||||
public:
|
||||
enum Priority
|
||||
{
|
||||
PriorityFallback = 0,
|
||||
PriorityPrimary = 10,
|
||||
PrioritySecondary = 20,
|
||||
PriorityReprint = 30,
|
||||
PriorityOther = 40,
|
||||
PriorityLowest = 100,
|
||||
};
|
||||
|
||||
private:
|
||||
QString shortName, longName;
|
||||
unsigned int sortKey;
|
||||
QDate releaseDate;
|
||||
QString setType;
|
||||
Priority priority;
|
||||
bool enabled, isknown;
|
||||
|
||||
public:
|
||||
explicit CardSet(const QString &_shortName = QString(),
|
||||
const QString &_longName = QString(),
|
||||
const QString &_setType = QString(),
|
||||
const QDate &_releaseDate = QDate());
|
||||
const QDate &_releaseDate = QDate(),
|
||||
const Priority _priority = PriorityFallback);
|
||||
static CardSetPtr newInstance(const QString &_shortName = QString(),
|
||||
const QString &_longName = QString(),
|
||||
const QString &_setType = QString(),
|
||||
const QDate &_releaseDate = QDate());
|
||||
const QDate &_releaseDate = QDate(),
|
||||
const Priority _priority = PriorityFallback);
|
||||
QString getCorrectedShortName() const;
|
||||
QString getShortName() const
|
||||
{
|
||||
@@ -62,6 +76,10 @@ public:
|
||||
{
|
||||
return releaseDate;
|
||||
}
|
||||
Priority getPriority() const
|
||||
{
|
||||
return priority;
|
||||
}
|
||||
void setLongName(const QString &_longName)
|
||||
{
|
||||
longName = _longName;
|
||||
@@ -74,6 +92,10 @@ public:
|
||||
{
|
||||
releaseDate = _releaseDate;
|
||||
}
|
||||
void setPriority(const Priority _priority)
|
||||
{
|
||||
priority = _priority;
|
||||
}
|
||||
|
||||
void loadSetOptions();
|
||||
int getSortKey() const
|
||||
@@ -113,6 +135,7 @@ public:
|
||||
int getEnabledSetsNum();
|
||||
int getUnknownSetsNum();
|
||||
QStringList getUnknownSetsNames();
|
||||
void defaultSort();
|
||||
};
|
||||
|
||||
class CardInfoPerSet
|
||||
|
||||
@@ -10,7 +10,8 @@ void ICardDatabaseParser::clearSetlist()
|
||||
CardSetPtr ICardDatabaseParser::internalAddSet(const QString &setName,
|
||||
const QString &longName,
|
||||
const QString &setType,
|
||||
const QDate &releaseDate)
|
||||
const QDate &releaseDate,
|
||||
const CardSet::Priority priority)
|
||||
{
|
||||
if (sets.contains(setName)) {
|
||||
return sets.value(setName);
|
||||
@@ -20,8 +21,9 @@ CardSetPtr ICardDatabaseParser::internalAddSet(const QString &setName,
|
||||
newSet->setLongName(longName);
|
||||
newSet->setSetType(setType);
|
||||
newSet->setReleaseDate(releaseDate);
|
||||
newSet->setPriority(priority);
|
||||
|
||||
sets.insert(setName, newSet);
|
||||
emit addSet(newSet);
|
||||
return newSet;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ protected:
|
||||
CardSetPtr internalAddSet(const QString &setName,
|
||||
const QString &longName = "",
|
||||
const QString &setType = "",
|
||||
const QDate &releaseDate = QDate());
|
||||
const QDate &releaseDate = QDate(),
|
||||
const CardSet::Priority priority = CardSet::PriorityFallback);
|
||||
signals:
|
||||
virtual void addCard(CardInfoPtr card) = 0;
|
||||
virtual void addSet(CardSetPtr set) = 0;
|
||||
@@ -40,4 +41,4 @@ signals:
|
||||
|
||||
Q_DECLARE_INTERFACE(ICardDatabaseParser, "ICardDatabaseParser")
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -77,6 +77,7 @@ void CockatriceXml4Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
||||
if (xmlName == "set") {
|
||||
QString shortName, longName, setType;
|
||||
QDate releaseDate;
|
||||
short priority;
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
@@ -92,6 +93,8 @@ void CockatriceXml4Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
||||
} else if (xmlName == "releasedate") {
|
||||
releaseDate =
|
||||
QDate::fromString(xml.readElementText(QXmlStreamReader::IncludeChildElements), Qt::ISODate);
|
||||
} else if (xmlName == "priority") {
|
||||
priority = xml.readElementText(QXmlStreamReader::IncludeChildElements).toShort();
|
||||
} else if (!xmlName.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown set property" << xmlName
|
||||
<< ", trying to continue anyway";
|
||||
@@ -99,7 +102,7 @@ void CockatriceXml4Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
||||
}
|
||||
}
|
||||
|
||||
internalAddSet(shortName, longName, setType, releaseDate);
|
||||
internalAddSet(shortName, longName, setType, releaseDate, static_cast<CardSet::Priority>(priority));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,6 +252,7 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSetPtr &set
|
||||
xml.writeTextElement("longname", set->getLongName());
|
||||
xml.writeTextElement("settype", set->getSetType());
|
||||
xml.writeTextElement("releasedate", set->getReleaseDate().toString(Qt::ISODate));
|
||||
xml.writeTextElement("priority", QString::number(set->getPriority()));
|
||||
xml.writeEndElement();
|
||||
|
||||
return xml;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<xs:element type="xs:string" name="longname" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element type="xs:string" name="settype" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element type="xs:string" name="releasedate" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element type="xs:integer" name="priority" minOccurs="0" maxOccurs="1"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="cardInSetType">
|
||||
|
||||
@@ -19,6 +19,18 @@ OracleImporter::OracleImporter(const QString &_dataDir, QObject *parent) : CardD
|
||||
{
|
||||
}
|
||||
|
||||
CardSet::Priority OracleImporter::getSetPriority(QString &setType, QString &shortName)
|
||||
{
|
||||
if (!setTypePriorities.contains(setType.toLower())) {
|
||||
qDebug() << "warning: Set type" << setType << "unrecognized for prioritization";
|
||||
}
|
||||
CardSet::Priority priority = setTypePriorities.value(setType.toLower(), CardSet::PriorityOther);
|
||||
if (nonEnglishSets.contains(shortName)) {
|
||||
priority = CardSet::PriorityLowest;
|
||||
}
|
||||
return priority;
|
||||
}
|
||||
|
||||
bool OracleImporter::readSetsFromByteArray(const QByteArray &data)
|
||||
{
|
||||
QList<SetToDownload> newSetList;
|
||||
@@ -38,6 +50,7 @@ bool OracleImporter::readSetsFromByteArray(const QByteArray &data)
|
||||
QList<QVariant> setCards;
|
||||
QString setType;
|
||||
QDate releaseDate;
|
||||
CardSet::Priority priority;
|
||||
|
||||
while (it.hasNext()) {
|
||||
map = it.next().toMap();
|
||||
@@ -45,6 +58,8 @@ bool OracleImporter::readSetsFromByteArray(const QByteArray &data)
|
||||
longName = map.value("name").toString();
|
||||
setCards = map.value("cards").toList();
|
||||
setType = map.value("type").toString();
|
||||
releaseDate = map.value("releaseDate").toDate();
|
||||
priority = getSetPriority(setType, shortName);
|
||||
// capitalize set type
|
||||
if (setType.length() > 0) {
|
||||
// basic grammar for words that aren't capitalized, like in "From the Vault"
|
||||
@@ -62,12 +77,7 @@ bool OracleImporter::readSetsFromByteArray(const QByteArray &data)
|
||||
}
|
||||
setType = setType.trimmed();
|
||||
}
|
||||
if (!nonEnglishSets.contains(shortName)) {
|
||||
releaseDate = map.value("releaseDate").toDate();
|
||||
} else {
|
||||
releaseDate = QDate();
|
||||
}
|
||||
newSetList.append(SetToDownload(shortName, longName, setCards, setType, releaseDate));
|
||||
newSetList.append(SetToDownload(shortName, longName, setCards, priority, setType, releaseDate));
|
||||
}
|
||||
|
||||
std::sort(newSetList.begin(), newSetList.end());
|
||||
@@ -493,8 +503,9 @@ int OracleImporter::startImport()
|
||||
sets.insert(TOKENS_SETNAME, tokenSet);
|
||||
|
||||
for (const SetToDownload &curSetToParse : allSets) {
|
||||
CardSetPtr newSet = CardSet::newInstance(curSetToParse.getShortName(), curSetToParse.getLongName(),
|
||||
curSetToParse.getSetType(), curSetToParse.getReleaseDate());
|
||||
CardSetPtr newSet =
|
||||
CardSet::newInstance(curSetToParse.getShortName(), curSetToParse.getLongName(), curSetToParse.getSetType(),
|
||||
curSetToParse.getReleaseDate(), curSetToParse.getPriority());
|
||||
if (!sets.contains(newSet->getShortName()))
|
||||
sets.insert(newSet->getShortName(), newSet);
|
||||
|
||||
|
||||
@@ -7,11 +7,36 @@
|
||||
#include <utility>
|
||||
|
||||
// many users prefer not to see these sets with non english arts
|
||||
// as a solution we remove the date property on these sets
|
||||
// that way they will be sorted last by default
|
||||
// this will cause their art to not get priority over english cards
|
||||
// users will still be able to find these sets and prioritize them manually
|
||||
// they will given priority PriorityLowest
|
||||
const QStringList nonEnglishSets = {"4BB", "FBB", "PS11", "PSAL", "REN", "RIN"};
|
||||
const QMap<QString, CardSet::Priority> setTypePriorities{
|
||||
{"core", CardSet::PriorityPrimary},
|
||||
{"expansion", CardSet::PriorityPrimary},
|
||||
|
||||
{"commander", CardSet::PrioritySecondary},
|
||||
{"starter", CardSet::PrioritySecondary},
|
||||
{"draft_innovation", CardSet::PrioritySecondary},
|
||||
{"duel_deck", CardSet::PrioritySecondary},
|
||||
|
||||
{"archenemy", CardSet::PriorityReprint},
|
||||
{"arsenal", CardSet::PriorityReprint},
|
||||
{"box", CardSet::PriorityReprint},
|
||||
{"from_the_vault", CardSet::PriorityReprint},
|
||||
{"masterpiece", CardSet::PriorityReprint},
|
||||
{"masters", CardSet::PriorityReprint},
|
||||
{"memorabilia", CardSet::PriorityReprint},
|
||||
{"planechase", CardSet::PriorityReprint},
|
||||
{"premium_deck", CardSet::PriorityReprint},
|
||||
{"promo", CardSet::PriorityReprint},
|
||||
{"spellbook", CardSet::PriorityReprint},
|
||||
{"token", CardSet::PriorityReprint},
|
||||
{"treasure_chest", CardSet::PriorityReprint},
|
||||
|
||||
{"alchemy", CardSet::PriorityOther},
|
||||
{"funny", CardSet::PriorityOther},
|
||||
{"minigame", CardSet::PriorityOther},
|
||||
{"vanguard", CardSet::PriorityOther},
|
||||
};
|
||||
|
||||
class SetToDownload
|
||||
{
|
||||
@@ -20,6 +45,7 @@ private:
|
||||
QList<QVariant> cards;
|
||||
QDate releaseDate;
|
||||
QString setType;
|
||||
CardSet::Priority priority;
|
||||
|
||||
public:
|
||||
const QString &getShortName() const
|
||||
@@ -42,13 +68,18 @@ public:
|
||||
{
|
||||
return releaseDate;
|
||||
}
|
||||
CardSet::Priority getPriority() const
|
||||
{
|
||||
return priority;
|
||||
}
|
||||
SetToDownload(QString _shortName,
|
||||
QString _longName,
|
||||
QList<QVariant> _cards,
|
||||
CardSet::Priority _priority,
|
||||
QString _setType = QString(),
|
||||
const QDate &_releaseDate = QDate())
|
||||
: shortName(std::move(_shortName)), longName(std::move(_longName)), cards(std::move(_cards)),
|
||||
releaseDate(_releaseDate), setType(std::move(_setType))
|
||||
releaseDate(_releaseDate), setType(std::move(_setType)), priority(_priority)
|
||||
{
|
||||
}
|
||||
bool operator<(const SetToDownload &set) const
|
||||
@@ -108,6 +139,7 @@ signals:
|
||||
|
||||
public:
|
||||
explicit OracleImporter(const QString &_dataDir, QObject *parent = nullptr);
|
||||
CardSet::Priority getSetPriority(QString &setType, QString &shortName);
|
||||
bool readSetsFromByteArray(const QByteArray &data);
|
||||
int startImport();
|
||||
bool saveToFile(const QString &fileName, const QString &sourceUrl, const QString &sourceVersion);
|
||||
|
||||
Reference in New Issue
Block a user