#include "BuildItems.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 CreatureLib::Library::ItemCategory ParseItemCategory(std::string& in) { std::transform(in.begin(), in.end(), in.end(), tolower); if (in == "item") return CreatureLib::Library::ItemCategory::MiscItem; if (in == "medicine") return CreatureLib::Library::ItemCategory::Medicine; if (in == "berry") return CreatureLib::Library::ItemCategory::Berry; if (in == "mail") return CreatureLib::Library::ItemCategory::Mail; if (in == "key") return CreatureLib::Library::ItemCategory::KeyItem; if (in == "pokeball") return CreatureLib::Library::ItemCategory::CaptureDevice; if (in == "tm") return CreatureLib::Library::ItemCategory::MoveLearner; std::cout << "Unknown Item Type: '" << in << "'\n"; return static_cast(255); } PkmnLib::Library::ItemLibrary* BuildItems::Build(const std::string& path) { std::ifstream fileStream(path.c_str()); if (fileStream.fail()) { std::cout << "Failed to load Items data file at '" << path << "'\n"; return nullptr; } auto lib = new PkmnLib::Library::ItemLibrary(); json j; fileStream >> j; for (const auto& i : j.items()) { if (i.key().starts_with("$")) { continue; } auto& val = i.value(); GET(val, name, i); GET(val, itemType, i); GET(val, flags, i); GET(val, price, i); GET(val, flingPower, i); auto itemTypeStr = _itemType.get(); CreatureLib::Library::ItemCategory itemType = ParseItemCategory(itemTypeStr); if (static_cast(itemType) == 255) 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& effectJson = val["effect"]; if (effectJson != nullptr) { auto& effectName = effectJson["name"]; auto& parametersJson = effectJson["parameters"]; ArbUt::List parameters; 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( 100, ArbUt::StringView(effectName.get().c_str()), parameters); } CreatureLib::Library::SecondaryEffect* battleEffect = nullptr; auto& battleEffectJson = val["battleEffect"]; if (battleEffectJson != nullptr) { auto& effectName = battleEffectJson["name"]; auto& parametersJson = battleEffectJson["parameters"]; ArbUt::List parameters; 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; } } } battleEffect = new CreatureLib::Library::SecondaryEffect( 100, ArbUt::StringView(effectName.get().c_str()), parameters); } auto item = new PkmnLib::Library::Item(ArbUt::StringView(_name.get().c_str()), itemType, CreatureLib::Library::BattleItemCategory::None, _price.get(), effect, battleEffect, flags, _flingPower.get()); lib->Insert(item->GetName(), item); } return lib; } #undef GET