#include "BuildSpecies.hpp" #include #include #define GET(o, objectKey, key) \ auto _##objectKey = o[#objectKey]; \ if (_##objectKey.is_null()) { \ std::cout << "Failed to retrieve key '" << #objectKey << "' for object with key '" << key << "' in file '" \ << path << "'\n"; \ return nullptr; \ } PkmnLib::Library::SpeciesLibrary* BuildSpecies::BuildLibrary(const std::string& path, const CreatureLib::Library::TypeLibrary* types) { std::ifstream fileStream(path.c_str()); if (fileStream.fail()) { std::cout << "Failed to load Pokemon data file at '" << path << "'\n"; return nullptr; } auto lib = new PkmnLib::Library::SpeciesLibrary(); json j; fileStream >> j; for (json::iterator it = j.begin(); it != j.end(); ++it) { if (it.key().starts_with("$")){ continue; } auto val = it.value(); GET(val, id, it.key()); GET(val, species, it.key()); GET(val, genderRatio, it.key()); GET(val, growthRate, it.key()); GET(val, baseHappiness, it.key()); GET(val, catchRate, it.key()); GET(val, color, it.key()); GET(val, genderDifference, it.key()); GET(val, eggGroups, it.key()); GET(val, eggCycles, it.key()); GET(val, tags, it.key()); GET(val, formes, it.key()); PkmnLib::Library::PokemonSpecies* species = nullptr; ArbUt::List eggGroups; for (const auto& eg : _eggGroups){ eggGroups.Append(eg.get().c_str()); } auto defaultForme = _formes["default"]; if (!defaultForme.is_null()) { auto forme = BuildForme("default", defaultForme, it.key(), path, types); species = new PkmnLib::Library::PokemonSpecies( _id.get(), ArbUt::StringView(_species.get().c_str()), forme, _genderRatio.get() / static_cast(100), ArbUt::StringView(_growthRate.get().c_str()), _catchRate.get(), _baseHappiness.get(), eggGroups); } for (json::iterator formeIt = _formes.begin(); formeIt != _formes.end(); ++formeIt) { if (formeIt.key() == "default") { continue; } auto forme = BuildForme(formeIt.key(), formeIt.value(), it.key(), path, types); if (forme == nullptr) return nullptr; if (species == nullptr) { species = new PkmnLib::Library::PokemonSpecies( _id.get(), ArbUt::StringView(_species.get().c_str()), forme, static_cast(_genderRatio.get()) / static_cast(100), ArbUt::StringView(_growthRate.get().c_str()), _catchRate.get(), _baseHappiness.get(), eggGroups); } else { if (species->HasForme(ArbUt::StringView(formeIt.key().c_str()))) { std::cout << "Species '" << it.key() << "' has duplicate forme '" << formeIt.key() << "'. Skipping.\n"; delete forme; continue; } species->SetVariant(ArbUt::StringView(formeIt.key().c_str()), forme); } } if (species == nullptr) { std::cout << "Pokemon with key '" << it.key() << "' does not have any formes.\n"; return nullptr; } lib->Insert(ArbUt::StringView(it.key().c_str()), species); } return lib; } static CreatureLib::Library::StatisticSet ParseStatistics(json& json) { return CreatureLib::Library::StatisticSet( json["hp"].get(), json["attack"].get(), json["defense"].get(), json["specialAttack"].get(), json["specialDefense"].get(), json["speed"].get()); } const PkmnLib::Library::PokemonForme* BuildSpecies::BuildForme(const std::string& name, json& forme, const std::string& baseKeyName, const std::string& path, const CreatureLib::Library::TypeLibrary* typeLibrary) { GET(forme, abilities, baseKeyName << " -> " << name); GET(forme, hiddenAbilities, baseKeyName << " -> " << name); GET(forme, baseStats, baseKeyName << " -> " << name); GET(forme, evReward, baseKeyName << " -> " << name); GET(forme, types, baseKeyName << " -> " << name); GET(forme, height, baseKeyName << " -> " << name); GET(forme, weight, baseKeyName << " -> " << name); GET(forme, baseExp, baseKeyName << " -> " << name); GET(forme, moves, baseKeyName << " -> " << name); auto typeStrings = _types.get>(); auto types = ArbUt::List(typeStrings.size()); for (size_t i = 0; i < typeStrings.size(); i++) { types.Append(typeLibrary->GetTypeId(ArbUt::StringView(typeStrings[i].c_str()))); } auto stats = ParseStatistics(_baseStats); auto abilityStrings = _abilities.get>(); auto abilities = ArbUt::List(abilityStrings.size()); for (size_t i = 0; i < abilityStrings.size(); i++) { abilities.Append(ArbUt::StringView(abilityStrings[i].c_str())); } auto hiddenAbilityStrings = _abilities.get>(); auto hiddenAbilities = ArbUt::List(hiddenAbilityStrings.size()); for (size_t i = 0; i < hiddenAbilityStrings.size(); i++) { hiddenAbilities.Append(ArbUt::StringView(abilityStrings[i].c_str())); } return new PkmnLib::Library::PokemonForme(ArbUt::StringView(name.c_str()), _height.get(), _weight.get(), _baseExp.get(), types, stats, abilities, hiddenAbilities, nullptr); } #undef GET