46 toName = data[
"toName"].toString();
47 if (data[
"level"].isDouble())
level =
static_cast<var8>(data[
"level"].toDouble());
48 if (data[
"trade"].isBool())
trade = data[
"trade"].toBool();
49 if (data[
"item"].isString())
item = data[
"item"].toString();
59 if (!
toEvolution) qCritical() <<
"Evolution:" <<
toName <<
"could not be deep linked.";
60 if (!deEvolution) qCritical() <<
"Evolution:" <<
toName <<
"null deEvolution provided.";
61 if (!
item.isEmpty() && !
toItem) qCritical() <<
"Evolution item:" <<
item <<
"could not be deep linked.";
69 toItem->toEvolvePokemon.append(
this);
78 level =
static_cast<var8>(data[
"level"].toDouble());
79 move = data[
"move"].toString();
86 if (!
toMove) qCritical() <<
"Pokemon move:" <<
move <<
"could not be deep linked.";
89 toMove->toPokemonLearned.append(
this);
97 name = data[
"name"].toString();
98 ind =
static_cast<var8>(data[
"ind"].toDouble());
99 readable = data[
"readable"].toString();
101 if (data[
"pokedex"].isDouble())
pokedex =
static_cast<var8>(data[
"pokedex"].toDouble());
102 if (data[
"growthRate"].isDouble())
growthRate =
static_cast<var8>(data[
"growthRate"].toDouble());
103 if (data[
"baseHp"].isDouble())
baseHp =
static_cast<var8>(data[
"baseHp"].toDouble());
104 if (data[
"baseAttack"].isDouble())
baseAttack =
static_cast<var8>(data[
"baseAttack"].toDouble());
105 if (data[
"baseDefense"].isDouble())
baseDefense =
static_cast<var8>(data[
"baseDefense"].toDouble());
106 if (data[
"baseSpeed"].isDouble())
baseSpeed =
static_cast<var8>(data[
"baseSpeed"].toDouble());
107 if (data[
"baseSpecial"].isDouble())
baseSpecial =
static_cast<var8>(data[
"baseSpecial"].toDouble());
108 if (data[
"baseExpYield"].isDouble())
baseExpYield =
static_cast<var8>(data[
"baseExpYield"].toDouble());
109 if (data[
"catchRate"].isDouble())
catchRate =
static_cast<var8>(data[
"catchRate"].toDouble());
110 if (data[
"type1"].isString())
type1 = data[
"type1"].toString();
111 if (data[
"type2"].isString())
type2 = data[
"type2"].toString();
112 if (data[
"glitch"].isBool())
glitch = data[
"glitch"].toBool();
114 if (data[
"moves"].isArray())
115 for (QJsonValue e : data[
"moves"].toArray())
118 if (data[
"initial"].isArray())
119 for (QJsonValue e : data[
"initial"].toArray())
122 if (data[
"tmHm"].isArray())
123 for (QJsonValue e : data[
"tmHm"].toArray())
124 tmHm.append(
static_cast<var8>(e.toDouble()));
126 if (data[
"evolution"].isArray()) {
127 for (QJsonValue e : data[
"evolution"].toArray())
129 }
else if (data[
"evolution"].isObject()) {
130 auto tmp = data[
"evolution"];
137 if (!
type1.isEmpty()) {
141 if (!
toType1) qCritical() <<
"Pokemon type1:" <<
type1 <<
"could not be deep linked.";
144 if (!
type2.isEmpty()) {
148 if (!
toType2) qCritical() <<
"Pokemon type2:" <<
type2 <<
"could not be deep linked.";
153 evolEntry->deepLink(
this);
155 for (
auto* pokeMoveEntry :
moves)
156 pokeMoveEntry->deepLink();
158 for (
const auto& initMove :
initial) {
162 if (!link) qCritical() <<
"Pokemon initial move:" << initMove <<
"could not be deep linked.";
164 if (link) link->toPokemonInitial.append(
this);
167 for (
auto tmHmMove :
tmHm) {
173 if (!moveLink) qCritical() <<
"Pokemon TM/HM move:" << tmHmMove <<
"could not be deep linked.";
174 if (!itemLink) qCritical() <<
"Pokemon TM/HM item:" << tmHmMove <<
"could not be deep linked.";
176 if (moveLink) moveLink->toPokemonTmHm.append(
this);
177 if (itemLink) itemLink->toTeachPokemon.append(
this);
185 static PokemonDB* _inst =
new PokemonDB;
195 if (idx < 0 || idx >= store.size())
return nullptr;
196 return store.at(idx);
201 return ind.value(key,
nullptr);
206 static bool once =
false;
209 for (QJsonValue entry : jsonData.array())
216 static bool once =
false;
218 for (
auto* entry : store) {
219 ind.insert(entry->name, entry);
220 ind.insert(QString::number(entry->ind), entry);
221 ind.insert(entry->readable, entry);
223 ind.insert(
"dex" + QString::number(*entry->pokedex), entry);
230 static bool once =
false;
232 for (
auto* entry : store)
242void PokemonDB::qmlRegister()
const
244 static bool once =
false;
246 qmlRegisterUncreatableType<PokemonDB>(
"PSE.DB.PokemonDB", 1, 0,
"PokemonDB",
"Can't instantiate in QML");
250PokemonDB::PokemonDB()
const QJsonDocument json(const QString filename) const
Parsed document for filename.
static GameData * inst()
The process-wide GameData singleton.
ItemDBEntry * getIndAt(const QString val) const
Item by name key (for QML).
static ItemsDB * inst()
< Number of items.
MoveDBEntry * getIndAt(const QString &key) const
Move by name key (for QML).
static MovesDB * inst()
< Number of moves.
void qmlProtect(const QQmlEngine *const engine) const
Pin to C++ ownership.
static PokemonDB * inst()
< Number of species.
void deepLink()
Resolve every species' cross-reference web.
PokemonDBEntry * getStoreAt(int idx) const
Species by store index (for QML).
int getStoreSize() const
Species count.
const QHash< QString, PokemonDBEntry * > getInd() const
Name->species index.
void index()
Build the name->species index.
const QVector< PokemonDBEntry * > getStore() const
All species.
void load()
Load species from JSON.
PokemonDBEntry * getIndAt(const QString &key) const
Species by name key (for QML).
TypeDBEntry * getIndAt(const QString &key) const
Type by name key (for QML).
static TypesDB * inst()
< Number of types.
static void qmlProtectUtil(const QObject *const obj, const QQmlEngine *const engine)
Pin obj to C++ ownership so the QML engine never garbage-collects it.
var8e var8
Everyday 8-bit alias. Exact (not "fastest") to dodge the pointer-width bug noted above.
One evolution edge of a species: how it evolves (and de-evolves).
QString item
Evolution item, if any.
void deepLink(PokemonDBEntry *deEvolution)
Resolve target/item; set deEvolution back-link.
std::optional< var8 > level
Evolution level, if level-based.
PokemonDBEntry * toDeEvolution
Resolved pre-evolution.
PokemonDBEntry * toEvolution
Resolved evolved species.
ItemDBEntry * toItem
Resolved evolution item.
QString toName
Name of the species this evolves into.
PokemonDBEntry * parent
Owning species.
PokemonDBEntryEvolution()
Empty edge.
bool trade
Evolves on trade.
One learnable move of a species, with the level it's learned at.
void deepLink()
Resolve the move link.
PokemonDBEntryMove()
Empty learn entry.
QString move
Move name (resolved to toMove).
MoveDBEntry * toMove
Resolved move.
var8 level
Level the move is learned at.
PokemonDBEntry * parent
Owning species.
One species' complete static data – the richest entry in the db layer.
QString type1
Primary type name (resolved to toType1).
PokemonDBEntry()
Empty species.
bool glitch
Whether this is a glitch species.
std::optional< var8 > baseHp
Base HP.
QVector< ItemDBEntry * > toTmHmItem
Resolved TM/HM items.
QString type2
Secondary type name (resolved to toType2).
std::optional< var8 > baseDefense
Base Defense.
std::optional< var8 > catchRate
Catch rate.
QVector< MoveDBEntry * > toTmHmMove
Resolved TM/HM moves.
std::optional< var8 > growthRate
EXP growth-rate group.
QString name
Internal species name (key).
QVector< PokemonDBEntryMove * > moves
Level-up learnset.
void deepLink()
Resolve the full cross-reference web (the to* members).
std::optional< var8 > baseSpeed
Base Speed.
QVector< MoveDBEntry * > toInitial
Resolved capture moves.
var8 ind
Internal species index.
QVector< var8 > tmHm
TM/HM numbers it can learn.
std::optional< var8 > baseSpecial
Base Special.
QVector< QString > initial
Moves known at capture (resolved to toInitial).
QString readable
Human-readable species name.
std::optional< var8 > baseExpYield
Base EXP yield.
QVector< PokemonDBEntryEvolution * > evolution
Evolution edges.
TypeDBEntry * toType1
Resolved primary type.
TypeDBEntry * toType2
Resolved secondary type.
std::optional< var8 > baseAttack
Base Attack.
std::optional< var8 > pokedex
Pokedex number, if assigned.