mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-14 10:04:46 -07:00
Refactor: split card_database into two files (#5715)
* make the duplicate * restore original * Refactor: split card_database into two files
This commit is contained in:
parent
ec536126b9
commit
4b7d1ebb59
9 changed files with 918 additions and 886 deletions
|
|
@ -26,6 +26,7 @@ set(cockatrice_SOURCES
|
||||||
src/client/ui/widgets/cards/card_info_text_widget.cpp
|
src/client/ui/widgets/cards/card_info_text_widget.cpp
|
||||||
src/client/ui/widgets/cards/card_info_display_widget.cpp
|
src/client/ui/widgets/cards/card_info_display_widget.cpp
|
||||||
src/client/ui/widgets/cards/card_size_widget.cpp
|
src/client/ui/widgets/cards/card_size_widget.cpp
|
||||||
|
src/game/cards/card_info.cpp
|
||||||
src/game/cards/card_item.cpp
|
src/game/cards/card_item.cpp
|
||||||
src/game/cards/card_list.cpp
|
src/game/cards/card_list.cpp
|
||||||
src/game/zones/card_zone.cpp
|
src/game/zones/card_zone.cpp
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
# cockatrice_xml.* = false
|
# cockatrice_xml.* = false
|
||||||
# cockatrice_xml.xml_3_parser = false
|
# cockatrice_xml.xml_3_parser = false
|
||||||
# cockatrice_xml.xml_4_parser = false
|
# cockatrice_xml.xml_4_parser = false
|
||||||
|
# card_info = false
|
||||||
# card_list = false
|
# card_list = false
|
||||||
|
|
||||||
# stack_zone = false
|
# stack_zone = false
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
#include "card_database.h"
|
#include "card_database.h"
|
||||||
|
|
||||||
#include "../../client/network/spoiler_background_updater.h"
|
|
||||||
#include "../../client/ui/picture_loader/picture_loader.h"
|
#include "../../client/ui/picture_loader/picture_loader.h"
|
||||||
#include "../../settings/cache_settings.h"
|
#include "../../settings/cache_settings.h"
|
||||||
#include "../../utility/card_set_comparator.h"
|
#include "../../utility/card_set_comparator.h"
|
||||||
#include "../game_specific_terms.h"
|
|
||||||
#include "./card_database_parser/cockatrice_xml_3.h"
|
#include "./card_database_parser/cockatrice_xml_3.h"
|
||||||
#include "./card_database_parser/cockatrice_xml_4.h"
|
#include "./card_database_parser/cockatrice_xml_4.h"
|
||||||
|
|
||||||
|
|
@ -20,351 +18,6 @@
|
||||||
|
|
||||||
const char *CardDatabase::TOKENS_SETNAME = "TK";
|
const char *CardDatabase::TOKENS_SETNAME = "TK";
|
||||||
|
|
||||||
CardSet::CardSet(const QString &_shortName,
|
|
||||||
const QString &_longName,
|
|
||||||
const QString &_setType,
|
|
||||||
const QDate &_releaseDate,
|
|
||||||
const CardSet::Priority _priority)
|
|
||||||
: shortName(_shortName), longName(_longName), releaseDate(_releaseDate), setType(_setType), priority(_priority)
|
|
||||||
{
|
|
||||||
loadSetOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
CardSetPtr CardSet::newInstance(const QString &_shortName,
|
|
||||||
const QString &_longName,
|
|
||||||
const QString &_setType,
|
|
||||||
const QDate &_releaseDate,
|
|
||||||
const Priority _priority)
|
|
||||||
{
|
|
||||||
CardSetPtr ptr(new CardSet(_shortName, _longName, _setType, _releaseDate, _priority));
|
|
||||||
// ptr->setSmartPointer(ptr);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CardSet::getCorrectedShortName() const
|
|
||||||
{
|
|
||||||
// For Windows machines.
|
|
||||||
QSet<QString> invalidFileNames;
|
|
||||||
invalidFileNames << "CON"
|
|
||||||
<< "PRN"
|
|
||||||
<< "AUX"
|
|
||||||
<< "NUL"
|
|
||||||
<< "COM1"
|
|
||||||
<< "COM2"
|
|
||||||
<< "COM3"
|
|
||||||
<< "COM4"
|
|
||||||
<< "COM5"
|
|
||||||
<< "COM6"
|
|
||||||
<< "COM7"
|
|
||||||
<< "COM8"
|
|
||||||
<< "COM9"
|
|
||||||
<< "LPT1"
|
|
||||||
<< "LPT2"
|
|
||||||
<< "LPT3"
|
|
||||||
<< "LPT4"
|
|
||||||
<< "LPT5"
|
|
||||||
<< "LPT6"
|
|
||||||
<< "LPT7"
|
|
||||||
<< "LPT8"
|
|
||||||
<< "LPT9";
|
|
||||||
|
|
||||||
return invalidFileNames.contains(shortName) ? shortName + "_" : shortName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardSet::loadSetOptions()
|
|
||||||
{
|
|
||||||
sortKey = SettingsCache::instance().cardDatabase().getSortKey(shortName);
|
|
||||||
enabled = SettingsCache::instance().cardDatabase().isEnabled(shortName);
|
|
||||||
isknown = SettingsCache::instance().cardDatabase().isKnown(shortName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardSet::setSortKey(unsigned int _sortKey)
|
|
||||||
{
|
|
||||||
sortKey = _sortKey;
|
|
||||||
SettingsCache::instance().cardDatabase().setSortKey(shortName, _sortKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardSet::setEnabled(bool _enabled)
|
|
||||||
{
|
|
||||||
enabled = _enabled;
|
|
||||||
SettingsCache::instance().cardDatabase().setEnabled(shortName, _enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardSet::setIsKnown(bool _isknown)
|
|
||||||
{
|
|
||||||
isknown = _isknown;
|
|
||||||
SettingsCache::instance().cardDatabase().setIsKnown(shortName, _isknown);
|
|
||||||
}
|
|
||||||
|
|
||||||
class SetList::KeyCompareFunctor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline bool operator()(const CardSetPtr &a, const CardSetPtr &b) const
|
|
||||||
{
|
|
||||||
if (a.isNull() || b.isNull()) {
|
|
||||||
qCDebug(CardDatabaseLog) << "SetList::KeyCompareFunctor a or b is null";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a->getSortKey() < b->getSortKey();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetList::sortByKey()
|
|
||||||
{
|
|
||||||
std::sort(begin(), end(), KeyCompareFunctor());
|
|
||||||
}
|
|
||||||
|
|
||||||
int SetList::getEnabledSetsNum()
|
|
||||||
{
|
|
||||||
int num = 0;
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set && set->getEnabled()) {
|
|
||||||
++num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SetList::getUnknownSetsNum()
|
|
||||||
{
|
|
||||||
int num = 0;
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
|
||||||
++num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList SetList::getUnknownSetsNames()
|
|
||||||
{
|
|
||||||
QStringList sets = QStringList();
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
|
||||||
sets << set->getShortName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sets;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetList::enableAllUnknown()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
|
||||||
set->setIsKnown(true);
|
|
||||||
set->setEnabled(true);
|
|
||||||
} else if (set && set->getIsKnownIgnored() && !set->getEnabled()) {
|
|
||||||
set->setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetList::enableAll()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
|
|
||||||
if (set == nullptr) {
|
|
||||||
qCDebug(CardDatabaseLog) << "enabledAll has null";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!set->getIsKnownIgnored()) {
|
|
||||||
set->setIsKnown(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
set->setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetList::markAllAsKnown()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
|
||||||
set->setIsKnown(true);
|
|
||||||
set->setEnabled(false);
|
|
||||||
} else if (set && set->getIsKnownIgnored() && !set->getEnabled()) {
|
|
||||||
set->setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetList::guessSortKeys()
|
|
||||||
{
|
|
||||||
defaultSort();
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set.isNull()) {
|
|
||||||
qCDebug(CardDatabaseLog) << "guessSortKeys set is null";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfo::CardInfo(const QString &_name,
|
|
||||||
const QString &_text,
|
|
||||||
bool _isToken,
|
|
||||||
QVariantHash _properties,
|
|
||||||
const QList<CardRelation *> &_relatedCards,
|
|
||||||
const QList<CardRelation *> &_reverseRelatedCards,
|
|
||||||
CardInfoPerSetMap _sets,
|
|
||||||
bool _cipt,
|
|
||||||
bool _landscapeOrientation,
|
|
||||||
int _tableRow,
|
|
||||||
bool _upsideDownArt)
|
|
||||||
: name(_name), text(_text), isToken(_isToken), properties(std::move(_properties)), relatedCards(_relatedCards),
|
|
||||||
reverseRelatedCards(_reverseRelatedCards), sets(std::move(_sets)), cipt(_cipt),
|
|
||||||
landscapeOrientation(_landscapeOrientation), tableRow(_tableRow), upsideDownArt(_upsideDownArt)
|
|
||||||
{
|
|
||||||
pixmapCacheKey = QLatin1String("card_") + name;
|
|
||||||
simpleName = CardInfo::simplifyName(name);
|
|
||||||
|
|
||||||
refreshCachedSetNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfo::~CardInfo()
|
|
||||||
{
|
|
||||||
PictureLoader::clearPixmapCache(smartThis);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPtr CardInfo::newInstance(const QString &_name)
|
|
||||||
{
|
|
||||||
return newInstance(_name, QString(), false, QVariantHash(), QList<CardRelation *>(), QList<CardRelation *>(),
|
|
||||||
CardInfoPerSetMap(), false, false, 0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPtr CardInfo::newInstance(const QString &_name,
|
|
||||||
const QString &_text,
|
|
||||||
bool _isToken,
|
|
||||||
QVariantHash _properties,
|
|
||||||
const QList<CardRelation *> &_relatedCards,
|
|
||||||
const QList<CardRelation *> &_reverseRelatedCards,
|
|
||||||
CardInfoPerSetMap _sets,
|
|
||||||
bool _cipt,
|
|
||||||
bool _landscapeOrientation,
|
|
||||||
int _tableRow,
|
|
||||||
bool _upsideDownArt)
|
|
||||||
{
|
|
||||||
CardInfoPtr ptr(new CardInfo(_name, _text, _isToken, std::move(_properties), _relatedCards, _reverseRelatedCards,
|
|
||||||
_sets, _cipt, _landscapeOrientation, _tableRow, _upsideDownArt));
|
|
||||||
ptr->setSmartPointer(ptr);
|
|
||||||
|
|
||||||
for (const auto &cardInfoPerSetList : _sets) {
|
|
||||||
for (const CardInfoPerSet &set : cardInfoPerSetList) {
|
|
||||||
set.getPtr()->append(ptr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CardInfo::getCorrectedName() const
|
|
||||||
{
|
|
||||||
// remove all the characters reserved in windows file paths,
|
|
||||||
// other oses only disallow a subset of these so it covers all
|
|
||||||
static const QRegularExpression rmrx(R"(( // |[*<>:"\\?\x00-\x08\x10-\x1f]))");
|
|
||||||
static const QRegularExpression spacerx(R"([/\x09-\x0f])");
|
|
||||||
static const QString space(' ');
|
|
||||||
QString result = name;
|
|
||||||
// Fire // Ice, Circle of Protection: Red, "Ach! Hans, Run!", Who/What/When/Where/Why, Question Elemental?
|
|
||||||
return result.remove(rmrx).replace(spacerx, space);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardInfo::addToSet(const CardSetPtr &_set, const CardInfoPerSet _info)
|
|
||||||
{
|
|
||||||
_set->append(smartThis);
|
|
||||||
sets[_set->getShortName()].append(_info);
|
|
||||||
|
|
||||||
refreshCachedSetNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardInfo::combineLegalities(const QVariantHash &props)
|
|
||||||
{
|
|
||||||
QHashIterator<QString, QVariant> it(props);
|
|
||||||
while (it.hasNext()) {
|
|
||||||
it.next();
|
|
||||||
if (it.key().startsWith("format-")) {
|
|
||||||
smartThis->setProperty(it.key(), it.value().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardInfo::refreshCachedSetNames()
|
|
||||||
{
|
|
||||||
QStringList setList;
|
|
||||||
// update the cached list of set names
|
|
||||||
for (const auto &cardInfoPerSetList : sets) {
|
|
||||||
for (const auto &set : cardInfoPerSetList) {
|
|
||||||
if (set.getPtr()->getEnabled()) {
|
|
||||||
setList << set.getPtr()->getShortName();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setsNames = setList.join(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CardInfo::simplifyName(const QString &name)
|
|
||||||
{
|
|
||||||
static const QRegularExpression spaceOrSplit("(\\s+|\\/\\/.*)");
|
|
||||||
static const QRegularExpression nonAlnum("[^a-z0-9]");
|
|
||||||
|
|
||||||
QString simpleName = name.toLower();
|
|
||||||
|
|
||||||
// remove spaces and right halves of split cards
|
|
||||||
simpleName.remove(spaceOrSplit);
|
|
||||||
|
|
||||||
// So Aetherling would work, but not Ætherling since 'Æ' would get replaced
|
|
||||||
// with nothing.
|
|
||||||
simpleName.replace("æ", "ae");
|
|
||||||
|
|
||||||
// Replace Jötun Grunt with Jotun Grunt.
|
|
||||||
simpleName = simpleName.normalized(QString::NormalizationForm_KD);
|
|
||||||
|
|
||||||
// remove all non alphanumeric characters from the name
|
|
||||||
simpleName.remove(nonAlnum);
|
|
||||||
return simpleName;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QChar CardInfo::getColorChar() const
|
|
||||||
{
|
|
||||||
QString colors = getColors();
|
|
||||||
switch (colors.size()) {
|
|
||||||
case 0:
|
|
||||||
return QChar();
|
|
||||||
case 1:
|
|
||||||
return colors.at(0);
|
|
||||||
default:
|
|
||||||
return QChar('m');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CardDatabase::CardDatabase(QObject *parent) : QObject(parent), loadStatus(NotLoaded)
|
CardDatabase::CardDatabase(QObject *parent) : QObject(parent), loadStatus(NotLoaded)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<CardInfoPtr>("CardInfoPtr");
|
qRegisterMetaType<CardInfoPtr>("CardInfoPtr");
|
||||||
|
|
@ -883,65 +536,4 @@ bool CardDatabase::saveCustomTokensToFile()
|
||||||
|
|
||||||
availableParsers.first()->saveToFile(tmpSets, tmpCards, fileName);
|
availableParsers.first()->saveToFile(tmpSets, tmpCards, fileName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CardRelation::CardRelation(const QString &_name,
|
|
||||||
AttachType _attachType,
|
|
||||||
bool _isCreateAllExclusion,
|
|
||||||
bool _isVariableCount,
|
|
||||||
int _defaultCount,
|
|
||||||
bool _isPersistent)
|
|
||||||
: name(_name), attachType(_attachType), isCreateAllExclusion(_isCreateAllExclusion),
|
|
||||||
isVariableCount(_isVariableCount), defaultCount(_defaultCount), isPersistent(_isPersistent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardInfo::resetReverseRelatedCards2Me()
|
|
||||||
{
|
|
||||||
for (CardRelation *cardRelation : this->getReverseRelatedCards2Me()) {
|
|
||||||
cardRelation->deleteLater();
|
|
||||||
}
|
|
||||||
reverseRelatedCardsToMe = QList<CardRelation *>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Back-compatibility methods. Remove ASAP
|
|
||||||
const QString CardInfo::getCardType() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::CardType);
|
|
||||||
}
|
|
||||||
void CardInfo::setCardType(const QString &value)
|
|
||||||
{
|
|
||||||
setProperty(Mtg::CardType, value);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getCmc() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::ConvertedManaCost);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getColors() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::Colors);
|
|
||||||
}
|
|
||||||
void CardInfo::setColors(const QString &value)
|
|
||||||
{
|
|
||||||
setProperty(Mtg::Colors, value);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getLoyalty() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::Loyalty);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getMainCardType() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::MainCardType);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getManaCost() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::ManaCost);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getPowTough() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::PowTough);
|
|
||||||
}
|
|
||||||
void CardInfo::setPowTough(const QString &value)
|
|
||||||
{
|
|
||||||
setProperty(Mtg::PowTough, value);
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +1,14 @@
|
||||||
#ifndef CARDDATABASE_H
|
#ifndef CARDDATABASE_H
|
||||||
#define CARDDATABASE_H
|
#define CARDDATABASE_H
|
||||||
|
|
||||||
|
#include "card_info.h"
|
||||||
|
|
||||||
#include <QBasicMutex>
|
#include <QBasicMutex>
|
||||||
#include <QDate>
|
#include <QDate>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
#include <QMap>
|
|
||||||
#include <QMetaType>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QVariant>
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|
@ -18,406 +16,8 @@ inline Q_LOGGING_CATEGORY(CardDatabaseLog, "card_database");
|
||||||
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingLog, "card_database.loading");
|
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingLog, "card_database.loading");
|
||||||
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingSuccessOrFailureLog, "card_database.loading.success_or_failure");
|
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingSuccessOrFailureLog, "card_database.loading.success_or_failure");
|
||||||
|
|
||||||
class CardDatabase;
|
|
||||||
class CardInfo;
|
|
||||||
class CardInfoPerSet;
|
|
||||||
class CardSet;
|
|
||||||
class CardRelation;
|
|
||||||
class ICardDatabaseParser;
|
class ICardDatabaseParser;
|
||||||
|
|
||||||
typedef QMap<QString, QString> QStringMap;
|
|
||||||
typedef QSharedPointer<CardInfo> CardInfoPtr;
|
|
||||||
typedef QSharedPointer<CardSet> CardSetPtr;
|
|
||||||
typedef QMap<QString, QList<CardInfoPerSet>> CardInfoPerSetMap;
|
|
||||||
|
|
||||||
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 Priority _priority = PriorityFallback);
|
|
||||||
static CardSetPtr newInstance(const QString &_shortName = QString(),
|
|
||||||
const QString &_longName = QString(),
|
|
||||||
const QString &_setType = QString(),
|
|
||||||
const QDate &_releaseDate = QDate(),
|
|
||||||
const Priority _priority = PriorityFallback);
|
|
||||||
QString getCorrectedShortName() const;
|
|
||||||
QString getShortName() const
|
|
||||||
{
|
|
||||||
return shortName;
|
|
||||||
}
|
|
||||||
QString getLongName() const
|
|
||||||
{
|
|
||||||
return longName;
|
|
||||||
}
|
|
||||||
QString getSetType() const
|
|
||||||
{
|
|
||||||
return setType;
|
|
||||||
}
|
|
||||||
QDate getReleaseDate() const
|
|
||||||
{
|
|
||||||
return releaseDate;
|
|
||||||
}
|
|
||||||
Priority getPriority() const
|
|
||||||
{
|
|
||||||
return priority;
|
|
||||||
}
|
|
||||||
void setLongName(const QString &_longName)
|
|
||||||
{
|
|
||||||
longName = _longName;
|
|
||||||
}
|
|
||||||
void setSetType(const QString &_setType)
|
|
||||||
{
|
|
||||||
setType = _setType;
|
|
||||||
}
|
|
||||||
void setReleaseDate(const QDate &_releaseDate)
|
|
||||||
{
|
|
||||||
releaseDate = _releaseDate;
|
|
||||||
}
|
|
||||||
void setPriority(const Priority _priority)
|
|
||||||
{
|
|
||||||
priority = _priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadSetOptions();
|
|
||||||
int getSortKey() const
|
|
||||||
{
|
|
||||||
return sortKey;
|
|
||||||
}
|
|
||||||
void setSortKey(unsigned int _sortKey);
|
|
||||||
bool getEnabled() const
|
|
||||||
{
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
void setEnabled(bool _enabled);
|
|
||||||
bool getIsKnown() const
|
|
||||||
{
|
|
||||||
return isknown;
|
|
||||||
}
|
|
||||||
void setIsKnown(bool _isknown);
|
|
||||||
|
|
||||||
// Determine incomplete sets.
|
|
||||||
bool getIsKnownIgnored() const
|
|
||||||
{
|
|
||||||
return longName.length() + setType.length() + releaseDate.toString().length() == 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SetList : public QList<CardSetPtr>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
class KeyCompareFunctor;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void sortByKey();
|
|
||||||
void guessSortKeys();
|
|
||||||
void enableAllUnknown();
|
|
||||||
void enableAll();
|
|
||||||
void markAllAsKnown();
|
|
||||||
int getEnabledSetsNum();
|
|
||||||
int getUnknownSetsNum();
|
|
||||||
QStringList getUnknownSetsNames();
|
|
||||||
void defaultSort();
|
|
||||||
};
|
|
||||||
|
|
||||||
class CardInfoPerSet
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit CardInfoPerSet(const CardSetPtr &_set = QSharedPointer<CardSet>(nullptr));
|
|
||||||
~CardInfoPerSet() = default;
|
|
||||||
|
|
||||||
bool operator==(const CardInfoPerSet &other) const
|
|
||||||
{
|
|
||||||
return this->set == other.set && this->properties == other.properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
CardSetPtr set;
|
|
||||||
// per-set card properties;
|
|
||||||
QVariantHash properties;
|
|
||||||
|
|
||||||
public:
|
|
||||||
const CardSetPtr getPtr() const
|
|
||||||
{
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
const QStringList getProperties() const
|
|
||||||
{
|
|
||||||
return properties.keys();
|
|
||||||
}
|
|
||||||
const QString getProperty(const QString &propertyName) const
|
|
||||||
{
|
|
||||||
return properties.value(propertyName).toString();
|
|
||||||
}
|
|
||||||
void setProperty(const QString &_name, const QString &_value)
|
|
||||||
{
|
|
||||||
properties.insert(_name, _value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CardInfo : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
private:
|
|
||||||
CardInfoPtr smartThis;
|
|
||||||
// The card name
|
|
||||||
QString name;
|
|
||||||
// The name without punctuation or capitalization, for better card name recognition.
|
|
||||||
QString simpleName;
|
|
||||||
// The key used to identify this card in the cache
|
|
||||||
QString pixmapCacheKey;
|
|
||||||
// card text
|
|
||||||
QString text;
|
|
||||||
// whether this is not a "real" card but a token
|
|
||||||
bool isToken;
|
|
||||||
// basic card properties; common for all the sets
|
|
||||||
QVariantHash properties;
|
|
||||||
// the cards i'm related to
|
|
||||||
QList<CardRelation *> relatedCards;
|
|
||||||
// the card i'm reverse-related to
|
|
||||||
QList<CardRelation *> reverseRelatedCards;
|
|
||||||
// the cards thare are reverse-related to me
|
|
||||||
QList<CardRelation *> reverseRelatedCardsToMe;
|
|
||||||
// card sets
|
|
||||||
CardInfoPerSetMap sets;
|
|
||||||
// cached set names
|
|
||||||
QString setsNames;
|
|
||||||
// positioning properties; used by UI
|
|
||||||
bool cipt;
|
|
||||||
bool landscapeOrientation;
|
|
||||||
int tableRow;
|
|
||||||
bool upsideDownArt;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CardInfo(const QString &_name,
|
|
||||||
const QString &_text,
|
|
||||||
bool _isToken,
|
|
||||||
QVariantHash _properties,
|
|
||||||
const QList<CardRelation *> &_relatedCards,
|
|
||||||
const QList<CardRelation *> &_reverseRelatedCards,
|
|
||||||
CardInfoPerSetMap _sets,
|
|
||||||
bool _cipt,
|
|
||||||
bool _landscapeOrientation,
|
|
||||||
int _tableRow,
|
|
||||||
bool _upsideDownArt);
|
|
||||||
CardInfo(const CardInfo &other)
|
|
||||||
: QObject(other.parent()), name(other.name), simpleName(other.simpleName), pixmapCacheKey(other.pixmapCacheKey),
|
|
||||||
text(other.text), isToken(other.isToken), properties(other.properties), relatedCards(other.relatedCards),
|
|
||||||
reverseRelatedCards(other.reverseRelatedCards), reverseRelatedCardsToMe(other.reverseRelatedCardsToMe),
|
|
||||||
sets(other.sets), setsNames(other.setsNames), cipt(other.cipt),
|
|
||||||
landscapeOrientation(other.landscapeOrientation), tableRow(other.tableRow), upsideDownArt(other.upsideDownArt)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~CardInfo() override;
|
|
||||||
|
|
||||||
static CardInfoPtr newInstance(const QString &_name);
|
|
||||||
|
|
||||||
static CardInfoPtr newInstance(const QString &_name,
|
|
||||||
const QString &_text,
|
|
||||||
bool _isToken,
|
|
||||||
QVariantHash _properties,
|
|
||||||
const QList<CardRelation *> &_relatedCards,
|
|
||||||
const QList<CardRelation *> &_reverseRelatedCards,
|
|
||||||
CardInfoPerSetMap _sets,
|
|
||||||
bool _cipt,
|
|
||||||
bool _landscapeOrientation,
|
|
||||||
int _tableRow,
|
|
||||||
bool _upsideDownArt);
|
|
||||||
|
|
||||||
CardInfoPtr clone() const
|
|
||||||
{
|
|
||||||
// Use the copy constructor to create a new instance
|
|
||||||
CardInfoPtr newCardInfo = CardInfoPtr(new CardInfo(*this));
|
|
||||||
newCardInfo->setSmartPointer(newCardInfo); // Set the smart pointer for the new instance
|
|
||||||
return newCardInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSmartPointer(CardInfoPtr _ptr)
|
|
||||||
{
|
|
||||||
smartThis = std::move(_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// basic properties
|
|
||||||
inline const QString &getName() const
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
const QString &getSimpleName() const
|
|
||||||
{
|
|
||||||
return simpleName;
|
|
||||||
}
|
|
||||||
void setPixmapCacheKey(QString _pixmapCacheKey)
|
|
||||||
{
|
|
||||||
pixmapCacheKey = _pixmapCacheKey;
|
|
||||||
}
|
|
||||||
const QString &getPixmapCacheKey() const
|
|
||||||
{
|
|
||||||
return pixmapCacheKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString &getText() const
|
|
||||||
{
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
void setText(const QString &_text)
|
|
||||||
{
|
|
||||||
text = _text;
|
|
||||||
emit cardInfoChanged(smartThis);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getIsToken() const
|
|
||||||
{
|
|
||||||
return isToken;
|
|
||||||
}
|
|
||||||
const QStringList getProperties() const
|
|
||||||
{
|
|
||||||
return properties.keys();
|
|
||||||
}
|
|
||||||
const QString getProperty(const QString &propertyName) const
|
|
||||||
{
|
|
||||||
return properties.value(propertyName).toString();
|
|
||||||
}
|
|
||||||
void setProperty(const QString &_name, const QString &_value)
|
|
||||||
{
|
|
||||||
properties.insert(_name, _value);
|
|
||||||
emit cardInfoChanged(smartThis);
|
|
||||||
}
|
|
||||||
bool hasProperty(const QString &propertyName) const
|
|
||||||
{
|
|
||||||
return properties.contains(propertyName);
|
|
||||||
}
|
|
||||||
const CardInfoPerSetMap &getSets() const
|
|
||||||
{
|
|
||||||
return sets;
|
|
||||||
}
|
|
||||||
const QString &getSetsNames() const
|
|
||||||
{
|
|
||||||
return setsNames;
|
|
||||||
}
|
|
||||||
const QString getSetProperty(const QString &setName, const QString &propertyName) const
|
|
||||||
{
|
|
||||||
if (!sets.contains(setName))
|
|
||||||
return "";
|
|
||||||
|
|
||||||
for (const auto &set : sets[setName]) {
|
|
||||||
if (QLatin1String("card_") + this->getName() + QString("_") + QString(set.getProperty("uuid")) ==
|
|
||||||
this->getPixmapCacheKey()) {
|
|
||||||
return set.getProperty(propertyName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sets[setName][0].getProperty(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// related cards
|
|
||||||
const QList<CardRelation *> &getRelatedCards() const
|
|
||||||
{
|
|
||||||
return relatedCards;
|
|
||||||
}
|
|
||||||
const QList<CardRelation *> &getReverseRelatedCards() const
|
|
||||||
{
|
|
||||||
return reverseRelatedCards;
|
|
||||||
}
|
|
||||||
const QList<CardRelation *> &getReverseRelatedCards2Me() const
|
|
||||||
{
|
|
||||||
return reverseRelatedCardsToMe;
|
|
||||||
}
|
|
||||||
const QList<CardRelation *> getAllRelatedCards() const
|
|
||||||
{
|
|
||||||
QList<CardRelation *> result;
|
|
||||||
result.append(getRelatedCards());
|
|
||||||
result.append(getReverseRelatedCards2Me());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
void resetReverseRelatedCards2Me();
|
|
||||||
void addReverseRelatedCards2Me(CardRelation *cardRelation)
|
|
||||||
{
|
|
||||||
reverseRelatedCardsToMe.append(cardRelation);
|
|
||||||
}
|
|
||||||
|
|
||||||
// positioning
|
|
||||||
bool getCipt() const
|
|
||||||
{
|
|
||||||
return cipt;
|
|
||||||
}
|
|
||||||
bool getLandscapeOrientation() const
|
|
||||||
{
|
|
||||||
return landscapeOrientation;
|
|
||||||
}
|
|
||||||
int getTableRow() const
|
|
||||||
{
|
|
||||||
return tableRow;
|
|
||||||
}
|
|
||||||
void setTableRow(int _tableRow)
|
|
||||||
{
|
|
||||||
tableRow = _tableRow;
|
|
||||||
}
|
|
||||||
bool getUpsideDownArt() const
|
|
||||||
{
|
|
||||||
return upsideDownArt;
|
|
||||||
}
|
|
||||||
const QChar getColorChar() const;
|
|
||||||
|
|
||||||
// Back-compatibility methods. Remove ASAP
|
|
||||||
const QString getCardType() const;
|
|
||||||
void setCardType(const QString &value);
|
|
||||||
const QString getCmc() const;
|
|
||||||
const QString getColors() const;
|
|
||||||
void setColors(const QString &value);
|
|
||||||
const QString getLoyalty() const;
|
|
||||||
const QString getMainCardType() const;
|
|
||||||
const QString getManaCost() const;
|
|
||||||
const QString getPowTough() const;
|
|
||||||
void setPowTough(const QString &value);
|
|
||||||
|
|
||||||
// methods using per-set properties
|
|
||||||
QString getCustomPicURL(const QString &set) const
|
|
||||||
{
|
|
||||||
return getSetProperty(set, "picurl");
|
|
||||||
}
|
|
||||||
QString getCorrectedName() const;
|
|
||||||
void addToSet(const CardSetPtr &_set, CardInfoPerSet _info = CardInfoPerSet());
|
|
||||||
void combineLegalities(const QVariantHash &props);
|
|
||||||
void emitPixmapUpdated()
|
|
||||||
{
|
|
||||||
emit pixmapUpdated();
|
|
||||||
}
|
|
||||||
void refreshCachedSetNames();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simplify a name to have no punctuation and lowercase all letters, for
|
|
||||||
* less strict name-matching.
|
|
||||||
*/
|
|
||||||
static QString simplifyName(const QString &name);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void pixmapUpdated();
|
|
||||||
void cardInfoChanged(CardInfoPtr card);
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LoadStatus
|
enum LoadStatus
|
||||||
{
|
{
|
||||||
Ok,
|
Ok,
|
||||||
|
|
@ -523,79 +123,4 @@ signals:
|
||||||
void cardRemoved(CardInfoPtr card);
|
void cardRemoved(CardInfoPtr card);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CardRelation : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum AttachType
|
|
||||||
{
|
|
||||||
DoesNotAttach = 0,
|
|
||||||
AttachTo = 1,
|
|
||||||
TransformInto = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString name;
|
|
||||||
AttachType attachType;
|
|
||||||
bool isCreateAllExclusion;
|
|
||||||
bool isVariableCount;
|
|
||||||
int defaultCount;
|
|
||||||
bool isPersistent;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CardRelation(const QString &_name = QString(),
|
|
||||||
AttachType _attachType = DoesNotAttach,
|
|
||||||
bool _isCreateAllExclusion = false,
|
|
||||||
bool _isVariableCount = false,
|
|
||||||
int _defaultCount = 1,
|
|
||||||
bool _isPersistent = false);
|
|
||||||
|
|
||||||
inline const QString &getName() const
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
AttachType getAttachType() const
|
|
||||||
{
|
|
||||||
return attachType;
|
|
||||||
}
|
|
||||||
bool getDoesAttach() const
|
|
||||||
{
|
|
||||||
return attachType != DoesNotAttach;
|
|
||||||
}
|
|
||||||
bool getDoesTransform() const
|
|
||||||
{
|
|
||||||
return attachType == TransformInto;
|
|
||||||
}
|
|
||||||
QString getAttachTypeAsString() const
|
|
||||||
{
|
|
||||||
switch (attachType) {
|
|
||||||
case AttachTo:
|
|
||||||
return "attach";
|
|
||||||
case TransformInto:
|
|
||||||
return "transform";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool getCanCreateAnother() const
|
|
||||||
{
|
|
||||||
return !getDoesAttach();
|
|
||||||
}
|
|
||||||
bool getIsCreateAllExclusion() const
|
|
||||||
{
|
|
||||||
return isCreateAllExclusion;
|
|
||||||
}
|
|
||||||
bool getIsVariable() const
|
|
||||||
{
|
|
||||||
return isVariableCount;
|
|
||||||
}
|
|
||||||
int getDefaultCount() const
|
|
||||||
{
|
|
||||||
return defaultCount;
|
|
||||||
}
|
|
||||||
bool getIsPersistent() const
|
|
||||||
{
|
|
||||||
return isPersistent;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
418
cockatrice/src/game/cards/card_info.cpp
Normal file
418
cockatrice/src/game/cards/card_info.cpp
Normal file
|
|
@ -0,0 +1,418 @@
|
||||||
|
#include "card_info.h"
|
||||||
|
|
||||||
|
#include "../../client/ui/picture_loader/picture_loader.h"
|
||||||
|
#include "../../settings/cache_settings.h"
|
||||||
|
#include "../game_specific_terms.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
CardSet::CardSet(const QString &_shortName,
|
||||||
|
const QString &_longName,
|
||||||
|
const QString &_setType,
|
||||||
|
const QDate &_releaseDate,
|
||||||
|
const CardSet::Priority _priority)
|
||||||
|
: shortName(_shortName), longName(_longName), releaseDate(_releaseDate), setType(_setType), priority(_priority)
|
||||||
|
{
|
||||||
|
loadSetOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
CardSetPtr CardSet::newInstance(const QString &_shortName,
|
||||||
|
const QString &_longName,
|
||||||
|
const QString &_setType,
|
||||||
|
const QDate &_releaseDate,
|
||||||
|
const Priority _priority)
|
||||||
|
{
|
||||||
|
CardSetPtr ptr(new CardSet(_shortName, _longName, _setType, _releaseDate, _priority));
|
||||||
|
// ptr->setSmartPointer(ptr);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CardSet::getCorrectedShortName() const
|
||||||
|
{
|
||||||
|
// For Windows machines.
|
||||||
|
QSet<QString> invalidFileNames;
|
||||||
|
invalidFileNames << "CON"
|
||||||
|
<< "PRN"
|
||||||
|
<< "AUX"
|
||||||
|
<< "NUL"
|
||||||
|
<< "COM1"
|
||||||
|
<< "COM2"
|
||||||
|
<< "COM3"
|
||||||
|
<< "COM4"
|
||||||
|
<< "COM5"
|
||||||
|
<< "COM6"
|
||||||
|
<< "COM7"
|
||||||
|
<< "COM8"
|
||||||
|
<< "COM9"
|
||||||
|
<< "LPT1"
|
||||||
|
<< "LPT2"
|
||||||
|
<< "LPT3"
|
||||||
|
<< "LPT4"
|
||||||
|
<< "LPT5"
|
||||||
|
<< "LPT6"
|
||||||
|
<< "LPT7"
|
||||||
|
<< "LPT8"
|
||||||
|
<< "LPT9";
|
||||||
|
|
||||||
|
return invalidFileNames.contains(shortName) ? shortName + "_" : shortName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardSet::loadSetOptions()
|
||||||
|
{
|
||||||
|
sortKey = SettingsCache::instance().cardDatabase().getSortKey(shortName);
|
||||||
|
enabled = SettingsCache::instance().cardDatabase().isEnabled(shortName);
|
||||||
|
isknown = SettingsCache::instance().cardDatabase().isKnown(shortName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardSet::setSortKey(unsigned int _sortKey)
|
||||||
|
{
|
||||||
|
sortKey = _sortKey;
|
||||||
|
SettingsCache::instance().cardDatabase().setSortKey(shortName, _sortKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardSet::setEnabled(bool _enabled)
|
||||||
|
{
|
||||||
|
enabled = _enabled;
|
||||||
|
SettingsCache::instance().cardDatabase().setEnabled(shortName, _enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardSet::setIsKnown(bool _isknown)
|
||||||
|
{
|
||||||
|
isknown = _isknown;
|
||||||
|
SettingsCache::instance().cardDatabase().setIsKnown(shortName, _isknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SetList::KeyCompareFunctor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline bool operator()(const CardSetPtr &a, const CardSetPtr &b) const
|
||||||
|
{
|
||||||
|
if (a.isNull() || b.isNull()) {
|
||||||
|
qCDebug(CardInfoLog) << "SetList::KeyCompareFunctor a or b is null";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a->getSortKey() < b->getSortKey();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void SetList::sortByKey()
|
||||||
|
{
|
||||||
|
std::sort(begin(), end(), KeyCompareFunctor());
|
||||||
|
}
|
||||||
|
|
||||||
|
int SetList::getEnabledSetsNum()
|
||||||
|
{
|
||||||
|
int num = 0;
|
||||||
|
for (int i = 0; i < size(); ++i) {
|
||||||
|
CardSetPtr set = at(i);
|
||||||
|
if (set && set->getEnabled()) {
|
||||||
|
++num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SetList::getUnknownSetsNum()
|
||||||
|
{
|
||||||
|
int num = 0;
|
||||||
|
for (int i = 0; i < size(); ++i) {
|
||||||
|
CardSetPtr set = at(i);
|
||||||
|
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
||||||
|
++num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList SetList::getUnknownSetsNames()
|
||||||
|
{
|
||||||
|
QStringList sets = QStringList();
|
||||||
|
for (int i = 0; i < size(); ++i) {
|
||||||
|
CardSetPtr set = at(i);
|
||||||
|
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
||||||
|
sets << set->getShortName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sets;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetList::enableAllUnknown()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size(); ++i) {
|
||||||
|
CardSetPtr set = at(i);
|
||||||
|
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
||||||
|
set->setIsKnown(true);
|
||||||
|
set->setEnabled(true);
|
||||||
|
} else if (set && set->getIsKnownIgnored() && !set->getEnabled()) {
|
||||||
|
set->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetList::enableAll()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size(); ++i) {
|
||||||
|
CardSetPtr set = at(i);
|
||||||
|
|
||||||
|
if (set == nullptr) {
|
||||||
|
qCDebug(CardInfoLog) << "enabledAll has null";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!set->getIsKnownIgnored()) {
|
||||||
|
set->setIsKnown(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
set->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetList::markAllAsKnown()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size(); ++i) {
|
||||||
|
CardSetPtr set = at(i);
|
||||||
|
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
||||||
|
set->setIsKnown(true);
|
||||||
|
set->setEnabled(false);
|
||||||
|
} else if (set && set->getIsKnownIgnored() && !set->getEnabled()) {
|
||||||
|
set->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetList::guessSortKeys()
|
||||||
|
{
|
||||||
|
defaultSort();
|
||||||
|
for (int i = 0; i < size(); ++i) {
|
||||||
|
CardSetPtr set = at(i);
|
||||||
|
if (set.isNull()) {
|
||||||
|
qCDebug(CardInfoLog) << "guessSortKeys set is null";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CardInfo::CardInfo(const QString &_name,
|
||||||
|
const QString &_text,
|
||||||
|
bool _isToken,
|
||||||
|
QVariantHash _properties,
|
||||||
|
const QList<CardRelation *> &_relatedCards,
|
||||||
|
const QList<CardRelation *> &_reverseRelatedCards,
|
||||||
|
CardInfoPerSetMap _sets,
|
||||||
|
bool _cipt,
|
||||||
|
bool _landscapeOrientation,
|
||||||
|
int _tableRow,
|
||||||
|
bool _upsideDownArt)
|
||||||
|
: name(_name), text(_text), isToken(_isToken), properties(std::move(_properties)), relatedCards(_relatedCards),
|
||||||
|
reverseRelatedCards(_reverseRelatedCards), sets(std::move(_sets)), cipt(_cipt),
|
||||||
|
landscapeOrientation(_landscapeOrientation), tableRow(_tableRow), upsideDownArt(_upsideDownArt)
|
||||||
|
{
|
||||||
|
pixmapCacheKey = QLatin1String("card_") + name;
|
||||||
|
simpleName = CardInfo::simplifyName(name);
|
||||||
|
|
||||||
|
refreshCachedSetNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
CardInfo::~CardInfo()
|
||||||
|
{
|
||||||
|
PictureLoader::clearPixmapCache(smartThis);
|
||||||
|
}
|
||||||
|
|
||||||
|
CardInfoPtr CardInfo::newInstance(const QString &_name)
|
||||||
|
{
|
||||||
|
return newInstance(_name, QString(), false, QVariantHash(), QList<CardRelation *>(), QList<CardRelation *>(),
|
||||||
|
CardInfoPerSetMap(), false, false, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
CardInfoPtr CardInfo::newInstance(const QString &_name,
|
||||||
|
const QString &_text,
|
||||||
|
bool _isToken,
|
||||||
|
QVariantHash _properties,
|
||||||
|
const QList<CardRelation *> &_relatedCards,
|
||||||
|
const QList<CardRelation *> &_reverseRelatedCards,
|
||||||
|
CardInfoPerSetMap _sets,
|
||||||
|
bool _cipt,
|
||||||
|
bool _landscapeOrientation,
|
||||||
|
int _tableRow,
|
||||||
|
bool _upsideDownArt)
|
||||||
|
{
|
||||||
|
CardInfoPtr ptr(new CardInfo(_name, _text, _isToken, std::move(_properties), _relatedCards, _reverseRelatedCards,
|
||||||
|
_sets, _cipt, _landscapeOrientation, _tableRow, _upsideDownArt));
|
||||||
|
ptr->setSmartPointer(ptr);
|
||||||
|
|
||||||
|
for (const auto &cardInfoPerSetList : _sets) {
|
||||||
|
for (const CardInfoPerSet &set : cardInfoPerSetList) {
|
||||||
|
set.getPtr()->append(ptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CardInfo::getCorrectedName() const
|
||||||
|
{
|
||||||
|
// remove all the characters reserved in windows file paths,
|
||||||
|
// other oses only disallow a subset of these so it covers all
|
||||||
|
static const QRegularExpression rmrx(R"(( // |[*<>:"\\?\x00-\x08\x10-\x1f]))");
|
||||||
|
static const QRegularExpression spacerx(R"([/\x09-\x0f])");
|
||||||
|
static const QString space(' ');
|
||||||
|
QString result = name;
|
||||||
|
// Fire // Ice, Circle of Protection: Red, "Ach! Hans, Run!", Who/What/When/Where/Why, Question Elemental?
|
||||||
|
return result.remove(rmrx).replace(spacerx, space);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardInfo::addToSet(const CardSetPtr &_set, const CardInfoPerSet _info)
|
||||||
|
{
|
||||||
|
_set->append(smartThis);
|
||||||
|
sets[_set->getShortName()].append(_info);
|
||||||
|
|
||||||
|
refreshCachedSetNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardInfo::combineLegalities(const QVariantHash &props)
|
||||||
|
{
|
||||||
|
QHashIterator<QString, QVariant> it(props);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
if (it.key().startsWith("format-")) {
|
||||||
|
smartThis->setProperty(it.key(), it.value().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardInfo::refreshCachedSetNames()
|
||||||
|
{
|
||||||
|
QStringList setList;
|
||||||
|
// update the cached list of set names
|
||||||
|
for (const auto &cardInfoPerSetList : sets) {
|
||||||
|
for (const auto &set : cardInfoPerSetList) {
|
||||||
|
if (set.getPtr()->getEnabled()) {
|
||||||
|
setList << set.getPtr()->getShortName();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setsNames = setList.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CardInfo::simplifyName(const QString &name)
|
||||||
|
{
|
||||||
|
static const QRegularExpression spaceOrSplit("(\\s+|\\/\\/.*)");
|
||||||
|
static const QRegularExpression nonAlnum("[^a-z0-9]");
|
||||||
|
|
||||||
|
QString simpleName = name.toLower();
|
||||||
|
|
||||||
|
// remove spaces and right halves of split cards
|
||||||
|
simpleName.remove(spaceOrSplit);
|
||||||
|
|
||||||
|
// So Aetherling would work, but not Ætherling since 'Æ' would get replaced
|
||||||
|
// with nothing.
|
||||||
|
simpleName.replace("æ", "ae");
|
||||||
|
|
||||||
|
// Replace Jötun Grunt with Jotun Grunt.
|
||||||
|
simpleName = simpleName.normalized(QString::NormalizationForm_KD);
|
||||||
|
|
||||||
|
// remove all non alphanumeric characters from the name
|
||||||
|
simpleName.remove(nonAlnum);
|
||||||
|
return simpleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QChar CardInfo::getColorChar() const
|
||||||
|
{
|
||||||
|
QString colors = getColors();
|
||||||
|
switch (colors.size()) {
|
||||||
|
case 0:
|
||||||
|
return QChar();
|
||||||
|
case 1:
|
||||||
|
return colors.at(0);
|
||||||
|
default:
|
||||||
|
return QChar('m');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CardRelation::CardRelation(const QString &_name,
|
||||||
|
AttachType _attachType,
|
||||||
|
bool _isCreateAllExclusion,
|
||||||
|
bool _isVariableCount,
|
||||||
|
int _defaultCount,
|
||||||
|
bool _isPersistent)
|
||||||
|
: name(_name), attachType(_attachType), isCreateAllExclusion(_isCreateAllExclusion),
|
||||||
|
isVariableCount(_isVariableCount), defaultCount(_defaultCount), isPersistent(_isPersistent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardInfo::resetReverseRelatedCards2Me()
|
||||||
|
{
|
||||||
|
for (CardRelation *cardRelation : this->getReverseRelatedCards2Me()) {
|
||||||
|
cardRelation->deleteLater();
|
||||||
|
}
|
||||||
|
reverseRelatedCardsToMe = QList<CardRelation *>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Back-compatibility methods. Remove ASAP
|
||||||
|
const QString CardInfo::getCardType() const
|
||||||
|
{
|
||||||
|
return getProperty(Mtg::CardType);
|
||||||
|
}
|
||||||
|
void CardInfo::setCardType(const QString &value)
|
||||||
|
{
|
||||||
|
setProperty(Mtg::CardType, value);
|
||||||
|
}
|
||||||
|
const QString CardInfo::getCmc() const
|
||||||
|
{
|
||||||
|
return getProperty(Mtg::ConvertedManaCost);
|
||||||
|
}
|
||||||
|
const QString CardInfo::getColors() const
|
||||||
|
{
|
||||||
|
return getProperty(Mtg::Colors);
|
||||||
|
}
|
||||||
|
void CardInfo::setColors(const QString &value)
|
||||||
|
{
|
||||||
|
setProperty(Mtg::Colors, value);
|
||||||
|
}
|
||||||
|
const QString CardInfo::getLoyalty() const
|
||||||
|
{
|
||||||
|
return getProperty(Mtg::Loyalty);
|
||||||
|
}
|
||||||
|
const QString CardInfo::getMainCardType() const
|
||||||
|
{
|
||||||
|
return getProperty(Mtg::MainCardType);
|
||||||
|
}
|
||||||
|
const QString CardInfo::getManaCost() const
|
||||||
|
{
|
||||||
|
return getProperty(Mtg::ManaCost);
|
||||||
|
}
|
||||||
|
const QString CardInfo::getPowTough() const
|
||||||
|
{
|
||||||
|
return getProperty(Mtg::PowTough);
|
||||||
|
}
|
||||||
|
void CardInfo::setPowTough(const QString &value)
|
||||||
|
{
|
||||||
|
setProperty(Mtg::PowTough, value);
|
||||||
|
}
|
||||||
491
cockatrice/src/game/cards/card_info.h
Normal file
491
cockatrice/src/game/cards/card_info.h
Normal file
|
|
@ -0,0 +1,491 @@
|
||||||
|
#ifndef CARD_INFO_H
|
||||||
|
#define CARD_INFO_H
|
||||||
|
|
||||||
|
#include <QDate>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QList>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
inline Q_LOGGING_CATEGORY(CardInfoLog, "card_info");
|
||||||
|
|
||||||
|
class CardInfo;
|
||||||
|
class CardInfoPerSet;
|
||||||
|
class CardSet;
|
||||||
|
class CardRelation;
|
||||||
|
class ICardDatabaseParser;
|
||||||
|
|
||||||
|
typedef QMap<QString, QString> QStringMap;
|
||||||
|
typedef QSharedPointer<CardInfo> CardInfoPtr;
|
||||||
|
typedef QSharedPointer<CardSet> CardSetPtr;
|
||||||
|
typedef QMap<QString, QList<CardInfoPerSet>> CardInfoPerSetMap;
|
||||||
|
|
||||||
|
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 Priority _priority = PriorityFallback);
|
||||||
|
static CardSetPtr newInstance(const QString &_shortName = QString(),
|
||||||
|
const QString &_longName = QString(),
|
||||||
|
const QString &_setType = QString(),
|
||||||
|
const QDate &_releaseDate = QDate(),
|
||||||
|
const Priority _priority = PriorityFallback);
|
||||||
|
QString getCorrectedShortName() const;
|
||||||
|
QString getShortName() const
|
||||||
|
{
|
||||||
|
return shortName;
|
||||||
|
}
|
||||||
|
QString getLongName() const
|
||||||
|
{
|
||||||
|
return longName;
|
||||||
|
}
|
||||||
|
QString getSetType() const
|
||||||
|
{
|
||||||
|
return setType;
|
||||||
|
}
|
||||||
|
QDate getReleaseDate() const
|
||||||
|
{
|
||||||
|
return releaseDate;
|
||||||
|
}
|
||||||
|
Priority getPriority() const
|
||||||
|
{
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
void setLongName(const QString &_longName)
|
||||||
|
{
|
||||||
|
longName = _longName;
|
||||||
|
}
|
||||||
|
void setSetType(const QString &_setType)
|
||||||
|
{
|
||||||
|
setType = _setType;
|
||||||
|
}
|
||||||
|
void setReleaseDate(const QDate &_releaseDate)
|
||||||
|
{
|
||||||
|
releaseDate = _releaseDate;
|
||||||
|
}
|
||||||
|
void setPriority(const Priority _priority)
|
||||||
|
{
|
||||||
|
priority = _priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadSetOptions();
|
||||||
|
int getSortKey() const
|
||||||
|
{
|
||||||
|
return sortKey;
|
||||||
|
}
|
||||||
|
void setSortKey(unsigned int _sortKey);
|
||||||
|
bool getEnabled() const
|
||||||
|
{
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
void setEnabled(bool _enabled);
|
||||||
|
bool getIsKnown() const
|
||||||
|
{
|
||||||
|
return isknown;
|
||||||
|
}
|
||||||
|
void setIsKnown(bool _isknown);
|
||||||
|
|
||||||
|
// Determine incomplete sets.
|
||||||
|
bool getIsKnownIgnored() const
|
||||||
|
{
|
||||||
|
return longName.length() + setType.length() + releaseDate.toString().length() == 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SetList : public QList<CardSetPtr>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
class KeyCompareFunctor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void sortByKey();
|
||||||
|
void guessSortKeys();
|
||||||
|
void enableAllUnknown();
|
||||||
|
void enableAll();
|
||||||
|
void markAllAsKnown();
|
||||||
|
int getEnabledSetsNum();
|
||||||
|
int getUnknownSetsNum();
|
||||||
|
QStringList getUnknownSetsNames();
|
||||||
|
void defaultSort();
|
||||||
|
};
|
||||||
|
|
||||||
|
class CardInfoPerSet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CardInfoPerSet(const CardSetPtr &_set = QSharedPointer<CardSet>(nullptr));
|
||||||
|
~CardInfoPerSet() = default;
|
||||||
|
|
||||||
|
bool operator==(const CardInfoPerSet &other) const
|
||||||
|
{
|
||||||
|
return this->set == other.set && this->properties == other.properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CardSetPtr set;
|
||||||
|
// per-set card properties;
|
||||||
|
QVariantHash properties;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const CardSetPtr getPtr() const
|
||||||
|
{
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
const QStringList getProperties() const
|
||||||
|
{
|
||||||
|
return properties.keys();
|
||||||
|
}
|
||||||
|
const QString getProperty(const QString &propertyName) const
|
||||||
|
{
|
||||||
|
return properties.value(propertyName).toString();
|
||||||
|
}
|
||||||
|
void setProperty(const QString &_name, const QString &_value)
|
||||||
|
{
|
||||||
|
properties.insert(_name, _value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CardInfo : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
CardInfoPtr smartThis;
|
||||||
|
// The card name
|
||||||
|
QString name;
|
||||||
|
// The name without punctuation or capitalization, for better card name recognition.
|
||||||
|
QString simpleName;
|
||||||
|
// The key used to identify this card in the cache
|
||||||
|
QString pixmapCacheKey;
|
||||||
|
// card text
|
||||||
|
QString text;
|
||||||
|
// whether this is not a "real" card but a token
|
||||||
|
bool isToken;
|
||||||
|
// basic card properties; common for all the sets
|
||||||
|
QVariantHash properties;
|
||||||
|
// the cards i'm related to
|
||||||
|
QList<CardRelation *> relatedCards;
|
||||||
|
// the card i'm reverse-related to
|
||||||
|
QList<CardRelation *> reverseRelatedCards;
|
||||||
|
// the cards thare are reverse-related to me
|
||||||
|
QList<CardRelation *> reverseRelatedCardsToMe;
|
||||||
|
// card sets
|
||||||
|
CardInfoPerSetMap sets;
|
||||||
|
// cached set names
|
||||||
|
QString setsNames;
|
||||||
|
// positioning properties; used by UI
|
||||||
|
bool cipt;
|
||||||
|
bool landscapeOrientation;
|
||||||
|
int tableRow;
|
||||||
|
bool upsideDownArt;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CardInfo(const QString &_name,
|
||||||
|
const QString &_text,
|
||||||
|
bool _isToken,
|
||||||
|
QVariantHash _properties,
|
||||||
|
const QList<CardRelation *> &_relatedCards,
|
||||||
|
const QList<CardRelation *> &_reverseRelatedCards,
|
||||||
|
CardInfoPerSetMap _sets,
|
||||||
|
bool _cipt,
|
||||||
|
bool _landscapeOrientation,
|
||||||
|
int _tableRow,
|
||||||
|
bool _upsideDownArt);
|
||||||
|
CardInfo(const CardInfo &other)
|
||||||
|
: QObject(other.parent()), name(other.name), simpleName(other.simpleName), pixmapCacheKey(other.pixmapCacheKey),
|
||||||
|
text(other.text), isToken(other.isToken), properties(other.properties), relatedCards(other.relatedCards),
|
||||||
|
reverseRelatedCards(other.reverseRelatedCards), reverseRelatedCardsToMe(other.reverseRelatedCardsToMe),
|
||||||
|
sets(other.sets), setsNames(other.setsNames), cipt(other.cipt),
|
||||||
|
landscapeOrientation(other.landscapeOrientation), tableRow(other.tableRow), upsideDownArt(other.upsideDownArt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~CardInfo() override;
|
||||||
|
|
||||||
|
static CardInfoPtr newInstance(const QString &_name);
|
||||||
|
|
||||||
|
static CardInfoPtr newInstance(const QString &_name,
|
||||||
|
const QString &_text,
|
||||||
|
bool _isToken,
|
||||||
|
QVariantHash _properties,
|
||||||
|
const QList<CardRelation *> &_relatedCards,
|
||||||
|
const QList<CardRelation *> &_reverseRelatedCards,
|
||||||
|
CardInfoPerSetMap _sets,
|
||||||
|
bool _cipt,
|
||||||
|
bool _landscapeOrientation,
|
||||||
|
int _tableRow,
|
||||||
|
bool _upsideDownArt);
|
||||||
|
|
||||||
|
CardInfoPtr clone() const
|
||||||
|
{
|
||||||
|
// Use the copy constructor to create a new instance
|
||||||
|
CardInfoPtr newCardInfo = CardInfoPtr(new CardInfo(*this));
|
||||||
|
newCardInfo->setSmartPointer(newCardInfo); // Set the smart pointer for the new instance
|
||||||
|
return newCardInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSmartPointer(CardInfoPtr _ptr)
|
||||||
|
{
|
||||||
|
smartThis = std::move(_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// basic properties
|
||||||
|
inline const QString &getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
const QString &getSimpleName() const
|
||||||
|
{
|
||||||
|
return simpleName;
|
||||||
|
}
|
||||||
|
void setPixmapCacheKey(QString _pixmapCacheKey)
|
||||||
|
{
|
||||||
|
pixmapCacheKey = _pixmapCacheKey;
|
||||||
|
}
|
||||||
|
const QString &getPixmapCacheKey() const
|
||||||
|
{
|
||||||
|
return pixmapCacheKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &getText() const
|
||||||
|
{
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
void setText(const QString &_text)
|
||||||
|
{
|
||||||
|
text = _text;
|
||||||
|
emit cardInfoChanged(smartThis);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getIsToken() const
|
||||||
|
{
|
||||||
|
return isToken;
|
||||||
|
}
|
||||||
|
const QStringList getProperties() const
|
||||||
|
{
|
||||||
|
return properties.keys();
|
||||||
|
}
|
||||||
|
const QString getProperty(const QString &propertyName) const
|
||||||
|
{
|
||||||
|
return properties.value(propertyName).toString();
|
||||||
|
}
|
||||||
|
void setProperty(const QString &_name, const QString &_value)
|
||||||
|
{
|
||||||
|
properties.insert(_name, _value);
|
||||||
|
emit cardInfoChanged(smartThis);
|
||||||
|
}
|
||||||
|
bool hasProperty(const QString &propertyName) const
|
||||||
|
{
|
||||||
|
return properties.contains(propertyName);
|
||||||
|
}
|
||||||
|
const CardInfoPerSetMap &getSets() const
|
||||||
|
{
|
||||||
|
return sets;
|
||||||
|
}
|
||||||
|
const QString &getSetsNames() const
|
||||||
|
{
|
||||||
|
return setsNames;
|
||||||
|
}
|
||||||
|
const QString getSetProperty(const QString &setName, const QString &propertyName) const
|
||||||
|
{
|
||||||
|
if (!sets.contains(setName))
|
||||||
|
return "";
|
||||||
|
|
||||||
|
for (const auto &set : sets[setName]) {
|
||||||
|
if (QLatin1String("card_") + this->getName() + QString("_") + QString(set.getProperty("uuid")) ==
|
||||||
|
this->getPixmapCacheKey()) {
|
||||||
|
return set.getProperty(propertyName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sets[setName][0].getProperty(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// related cards
|
||||||
|
const QList<CardRelation *> &getRelatedCards() const
|
||||||
|
{
|
||||||
|
return relatedCards;
|
||||||
|
}
|
||||||
|
const QList<CardRelation *> &getReverseRelatedCards() const
|
||||||
|
{
|
||||||
|
return reverseRelatedCards;
|
||||||
|
}
|
||||||
|
const QList<CardRelation *> &getReverseRelatedCards2Me() const
|
||||||
|
{
|
||||||
|
return reverseRelatedCardsToMe;
|
||||||
|
}
|
||||||
|
const QList<CardRelation *> getAllRelatedCards() const
|
||||||
|
{
|
||||||
|
QList<CardRelation *> result;
|
||||||
|
result.append(getRelatedCards());
|
||||||
|
result.append(getReverseRelatedCards2Me());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
void resetReverseRelatedCards2Me();
|
||||||
|
void addReverseRelatedCards2Me(CardRelation *cardRelation)
|
||||||
|
{
|
||||||
|
reverseRelatedCardsToMe.append(cardRelation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// positioning
|
||||||
|
bool getCipt() const
|
||||||
|
{
|
||||||
|
return cipt;
|
||||||
|
}
|
||||||
|
bool getLandscapeOrientation() const
|
||||||
|
{
|
||||||
|
return landscapeOrientation;
|
||||||
|
}
|
||||||
|
int getTableRow() const
|
||||||
|
{
|
||||||
|
return tableRow;
|
||||||
|
}
|
||||||
|
void setTableRow(int _tableRow)
|
||||||
|
{
|
||||||
|
tableRow = _tableRow;
|
||||||
|
}
|
||||||
|
bool getUpsideDownArt() const
|
||||||
|
{
|
||||||
|
return upsideDownArt;
|
||||||
|
}
|
||||||
|
const QChar getColorChar() const;
|
||||||
|
|
||||||
|
// Back-compatibility methods. Remove ASAP
|
||||||
|
const QString getCardType() const;
|
||||||
|
void setCardType(const QString &value);
|
||||||
|
const QString getCmc() const;
|
||||||
|
const QString getColors() const;
|
||||||
|
void setColors(const QString &value);
|
||||||
|
const QString getLoyalty() const;
|
||||||
|
const QString getMainCardType() const;
|
||||||
|
const QString getManaCost() const;
|
||||||
|
const QString getPowTough() const;
|
||||||
|
void setPowTough(const QString &value);
|
||||||
|
|
||||||
|
// methods using per-set properties
|
||||||
|
QString getCustomPicURL(const QString &set) const
|
||||||
|
{
|
||||||
|
return getSetProperty(set, "picurl");
|
||||||
|
}
|
||||||
|
QString getCorrectedName() const;
|
||||||
|
void addToSet(const CardSetPtr &_set, CardInfoPerSet _info = CardInfoPerSet());
|
||||||
|
void combineLegalities(const QVariantHash &props);
|
||||||
|
void emitPixmapUpdated()
|
||||||
|
{
|
||||||
|
emit pixmapUpdated();
|
||||||
|
}
|
||||||
|
void refreshCachedSetNames();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simplify a name to have no punctuation and lowercase all letters, for
|
||||||
|
* less strict name-matching.
|
||||||
|
*/
|
||||||
|
static QString simplifyName(const QString &name);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void pixmapUpdated();
|
||||||
|
void cardInfoChanged(CardInfoPtr card);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CardRelation : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum AttachType
|
||||||
|
{
|
||||||
|
DoesNotAttach = 0,
|
||||||
|
AttachTo = 1,
|
||||||
|
TransformInto = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString name;
|
||||||
|
AttachType attachType;
|
||||||
|
bool isCreateAllExclusion;
|
||||||
|
bool isVariableCount;
|
||||||
|
int defaultCount;
|
||||||
|
bool isPersistent;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CardRelation(const QString &_name = QString(),
|
||||||
|
AttachType _attachType = DoesNotAttach,
|
||||||
|
bool _isCreateAllExclusion = false,
|
||||||
|
bool _isVariableCount = false,
|
||||||
|
int _defaultCount = 1,
|
||||||
|
bool _isPersistent = false);
|
||||||
|
|
||||||
|
inline const QString &getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
AttachType getAttachType() const
|
||||||
|
{
|
||||||
|
return attachType;
|
||||||
|
}
|
||||||
|
bool getDoesAttach() const
|
||||||
|
{
|
||||||
|
return attachType != DoesNotAttach;
|
||||||
|
}
|
||||||
|
bool getDoesTransform() const
|
||||||
|
{
|
||||||
|
return attachType == TransformInto;
|
||||||
|
}
|
||||||
|
QString getAttachTypeAsString() const
|
||||||
|
{
|
||||||
|
switch (attachType) {
|
||||||
|
case AttachTo:
|
||||||
|
return "attach";
|
||||||
|
case TransformInto:
|
||||||
|
return "transform";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool getCanCreateAnother() const
|
||||||
|
{
|
||||||
|
return !getDoesAttach();
|
||||||
|
}
|
||||||
|
bool getIsCreateAllExclusion() const
|
||||||
|
{
|
||||||
|
return isCreateAllExclusion;
|
||||||
|
}
|
||||||
|
bool getIsVariable() const
|
||||||
|
{
|
||||||
|
return isVariableCount;
|
||||||
|
}
|
||||||
|
int getDefaultCount() const
|
||||||
|
{
|
||||||
|
return defaultCount;
|
||||||
|
}
|
||||||
|
bool getIsPersistent() const
|
||||||
|
{
|
||||||
|
return isPersistent;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
@ -9,6 +9,7 @@ set(dbconverter_SOURCES
|
||||||
../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
||||||
../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
||||||
../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
||||||
|
../cockatrice/src/game/cards/card_info.cpp
|
||||||
../cockatrice/src/settings/settings_manager.cpp
|
../cockatrice/src/settings/settings_manager.cpp
|
||||||
${VERSION_STRING_CPP}
|
${VERSION_STRING_CPP}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ set(oracle_SOURCES
|
||||||
src/qt-json/json.cpp
|
src/qt-json/json.cpp
|
||||||
../cockatrice/src/game/cards/card_database.cpp
|
../cockatrice/src/game/cards/card_database.cpp
|
||||||
../cockatrice/src/game/cards/card_database_manager.cpp
|
../cockatrice/src/game/cards/card_database_manager.cpp
|
||||||
|
../cockatrice/src/game/cards/card_info.cpp
|
||||||
../cockatrice/src/client/ui/picture_loader/picture_loader.cpp
|
../cockatrice/src/client/ui/picture_loader/picture_loader.cpp
|
||||||
../cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp
|
../cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp
|
||||||
../cockatrice/src/client/ui/picture_loader/picture_to_load.cpp
|
../cockatrice/src/client/ui/picture_loader/picture_to_load.cpp
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ add_executable(
|
||||||
../../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
../../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
||||||
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
||||||
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
||||||
|
../../cockatrice/src/game/cards/card_info.cpp
|
||||||
../../cockatrice/src/settings/settings_manager.cpp
|
../../cockatrice/src/settings/settings_manager.cpp
|
||||||
carddatabase_test.cpp
|
carddatabase_test.cpp
|
||||||
mocks.cpp
|
mocks.cpp
|
||||||
|
|
@ -35,6 +36,7 @@ add_executable(
|
||||||
../../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
../../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
||||||
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
||||||
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
||||||
|
../../cockatrice/src/game/cards/card_info.cpp
|
||||||
../../cockatrice/src/game/filters/filter_card.cpp
|
../../cockatrice/src/game/filters/filter_card.cpp
|
||||||
../../cockatrice/src/game/filters/filter_string.cpp
|
../../cockatrice/src/game/filters/filter_string.cpp
|
||||||
../../cockatrice/src/game/filters/filter_tree.cpp
|
../../cockatrice/src/game/filters/filter_tree.cpp
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue