BuildData/BuildMoves.cpp

120 lines
5.7 KiB
C++

#include "BuildMoves.hpp"
#include <fstream>
#include <iostream>
#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<PkmnLib::Library::MoveCategory>(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<uint8_t>() == 0)
continue;
auto type = types->GetTypeId(ArbUt::StringView(_type.get<std::string>().c_str()));
auto category = ParseCategory(_category.get<std::string>());
if (static_cast<int>(category) == 255)
return nullptr;
CreatureLib::Library::AttackTarget target;
if (!CreatureLib::Library::AttackTargetHelper::TryParse(_target.get<std::string>().c_str(), target)) {
std::cout << "Invalid target: '" << _target.get<std::string>() << "' for move with name '"
<< _name.get<std::string>() << "'\n";
return nullptr;
}
auto flags = std::unordered_set<uint32_t>();
for (auto& flagIndex : _flags.items()) {
flags.insert(ArbUt::StringView(flagIndex.value().get<std::string>().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<CreatureLib::Library::EffectParameter*> parameters;
auto chance = -1.0f;
if (chanceJson != nullptr) {
chance = chanceJson.get<float>();
}
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<bool>()));
break;
case json::value_t::number_integer:
case json::value_t::number_unsigned:
parameters.Append(new CreatureLib::Library::EffectParameter(p.get<int64_t>()));
break;
case json::value_t::number_float:
parameters.Append(new CreatureLib::Library::EffectParameter(p.get<float>()));
break;
case json::value_t ::string: {
auto s = p.get<std::string>();
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<std::string>().c_str()), parameters);
}
}
if (effect == nullptr) {
effect = new CreatureLib::Library::SecondaryEffect();
}
auto move = new PkmnLib::Library::MoveData(ArbUt::StringView(_name.get<std::string>().c_str()), type, category,
_power.get<uint8_t>(), _accuracy.get<uint8_t>(), _pp.get<uint8_t>(),
target, _priority.get<int8_t>(), effect, flags);
lib->Insert(ArbUt::StringView(move->GetName().c_str()), move);
}
return lib;
}
#undef GET