#include "BuildMoves.hpp" #include #include #include "json.hpp" using json = nlohmann::json; #define GET(o, objectKey, key) \ auto& _##objectKey = o[#objectKey]; \ if (_##objectKey.is_null()) { \ auto errorKeyFunc = [=]() { return key; }; \ std::cout << "Failed to retrieve key '" << #objectKey << "' for object with key '" << errorKeyFunc() << path \ << "'\n"; \ return nullptr; \ } static PkmnLib::Library::MoveCategory ParseCategory(const std::string& input) { if (input == "physical") return PkmnLib::Library::MoveCategory::Physical; else if (input == "special") return PkmnLib::Library::MoveCategory::Special; else if (input == "status") return PkmnLib::Library::MoveCategory::Status; std::cout << "Invalid move category '" << input << ".\n"; return static_cast(255); } PkmnLib::Library::MoveLibrary* BuildMoves::Build(const std::string& path, const CreatureLib::Library::TypeLibrary* types) { std::ifstream fileStream(path.c_str()); if (fileStream.fail()) { std::cout << "Failed to load Move data file at '" << path << "'\n"; return nullptr; } auto lib = new PkmnLib::Library::MoveLibrary(); json j; fileStream >> j; for (const auto& i : j["data"].items()) { auto& val = i.value(); GET(val, name, i); GET(val, type, i); GET(val, power, i); GET(val, pp, i); GET(val, accuracy, i); GET(val, priority, i); GET(val, target, i); GET(val, category, i); GET(val, flags, i); if (_pp.get() == 0) continue; auto type = types->GetTypeId(ArbUt::StringView(_type.get().c_str())); auto category = ParseCategory(_category.get()); if (static_cast(category) == 255) return nullptr; CreatureLib::Library::AttackTarget target; if (!CreatureLib::Library::AttackTargetHelper::TryParse(_target.get().c_str(), target)) { std::cout << "Invalid target: '" << _target.get() << "' for move with name '" << _name.get() << "'\n"; return nullptr; } auto flags = std::unordered_set(); for (auto& flagIndex : _flags.items()) { flags.insert(ArbUt::StringView(flagIndex.value().get().c_str())); } CreatureLib::Library::SecondaryEffect* effect = nullptr; auto& jsonEffect = val["effect"]; if (jsonEffect != nullptr) { auto& name = jsonEffect["name"]; auto& chanceJson = jsonEffect["chance"]; auto& parametersJson = jsonEffect["parameters"]; if (name != nullptr) { ArbUt::List parameters; auto chance = -1.0f; if (chanceJson != nullptr) { chance = chanceJson.get(); } if (parametersJson != nullptr) { for (auto& kv : parametersJson.items()) { auto& p = kv.value(); auto t = p.type(); switch (t) { case json::value_t::boolean: parameters.Append(new CreatureLib::Library::EffectParameter(p.get())); break; case json::value_t::number_integer: case json::value_t::number_unsigned: parameters.Append(new CreatureLib::Library::EffectParameter(p.get())); break; case json::value_t::number_float: parameters.Append(new CreatureLib::Library::EffectParameter(p.get())); break; case json::value_t ::string: { auto s = p.get(); parameters.Append(new CreatureLib::Library::EffectParameter( ArbUt::StringView(s.c_str(), s.length()))); break; } default: continue; } } } effect = new CreatureLib::Library::SecondaryEffect( chance, ArbUt::StringView(name.get().c_str()), parameters); } } if (effect == nullptr) { effect = new CreatureLib::Library::SecondaryEffect(); } auto move = new PkmnLib::Library::MoveData(ArbUt::StringView(_name.get().c_str()), type, category, _power.get(), _accuracy.get(), _pp.get(), target, _priority.get(), effect, flags); lib->Insert(ArbUt::StringView(move->GetName().c_str()), move); } return lib; } #undef GET