#include "esmdata.hpp" #include "lessbyid.hpp" #include "record.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace EsmLoader { namespace { template auto returnAs(F&& f) { using Result = decltype(std::forward(f)(ESM::Static{})); if constexpr (!std::is_same_v) return Result{}; } template auto withStatic(const ESM::RefId& refId, const std::vector& values, F&& f) { const auto it = std::lower_bound(values.begin(), values.end(), refId, LessById{}); if (it == values.end() || it->mId != refId) return returnAs(std::forward(f)); return std::forward(f)(*it); } template auto withStatic(const ESM::RefId& refId, ESM::RecNameInts type, const EsmData& content, F&& f) { switch (type) { case ESM::REC_ACTI: return withStatic(refId, content.mActivators, std::forward(f)); case ESM::REC_CONT: return withStatic(refId, content.mContainers, std::forward(f)); case ESM::REC_DOOR: return withStatic(refId, content.mDoors, std::forward(f)); case ESM::REC_STAT: return withStatic(refId, content.mStatics, std::forward(f)); default: break; } return returnAs(std::forward(f)); } } EsmData::~EsmData() {} std::string_view getModel(const EsmData& content, const ESM::RefId& refId, ESM::RecNameInts type) { return withStatic(refId, type, content, [](const auto& v) { return std::string_view(v.mModel); }); } ESM::Variant getGameSetting(const std::vector& records, std::string_view id) { auto it = std::lower_bound(records.begin(), records.end(), id, LessById{}); if (it == records.end() || it->mId != id) throw std::runtime_error("Game settings \"" + std::string(id) + "\" is not found"); return it->mValue; } }