Skip to content

Commit

Permalink
Add CLibUtil dependancy
Browse files Browse the repository at this point in the history
  • Loading branch information
powerof3 committed Nov 10, 2022
1 parent 12bdd6a commit e7da60e
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 155 deletions.
2 changes: 2 additions & 0 deletions SPID/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ find_package(frozen CONFIG REQUIRED)
find_path(SIMPLEINI_INCLUDE_DIRS "ConvertUTF.c")
find_path(SRELL_INCLUDE_DIRS "srell.hpp")
find_path(MERGEMAPPER_INCLUDE_DIRS "MergeMapperPluginAPI.h")
find_path(CLIB_UTIL_INCLUDE_DIRS "ClibUtil/utils.hpp")

# ---- Add source files ----

Expand Down Expand Up @@ -193,6 +194,7 @@ target_include_directories(
${SIMPLEINI_INCLUDE_DIRS}
${SRELL_INCLUDE_DIRS}
${MERGEMAPPER_INCLUDE_DIRS}
${CLIB_UTIL_INCLUDE_DIRS}
)

target_link_libraries(
Expand Down
13 changes: 5 additions & 8 deletions SPID/include/Defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,11 @@ struct form_sorter<RE::BGSKeyword>

using EventResult = RE::BSEventNotifyControl;

using FormIDPair = std::pair<
std::optional<RE::FormID>,
std::optional<std::string>>;
using FormIDPairVec = std::vector<FormIDPair>;
using FormIDPair = std::pair<std::optional<RE::FormID>,std::optional<std::string>>;
using FormOrEditorID = std::variant<FormIDPair,std::string>;
using FormIDVec = std::vector<FormOrEditorID>;
using StringVec = std::vector<std::string>;
using FormVec = std::vector<
std::variant<RE::TESForm*, const RE::TESFile*>>;
using FormOrEditorID = std::variant<FormIDPair, std::string>;
using FormVec = std::vector<std::variant<RE::TESForm*, const RE::TESFile*>>;

using ActorLevel = std::pair<std::uint16_t, std::uint16_t>;
using SkillLevel = std::pair<
Expand All @@ -119,7 +116,7 @@ using NPCCount = std::uint32_t;
using INIData = std::tuple<
FormOrEditorID,
std::array<StringVec, 4>,
std::array<FormIDPairVec, 3>,
std::array<FormIDVec, 3>,
std::pair<ActorLevel, std::vector<SkillLevel>>,
Traits,
IdxOrCount,
Expand Down
94 changes: 22 additions & 72 deletions SPID/include/LookupConfigs.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,6 @@ namespace INI

namespace detail
{
inline bool is_valid_entry(const std::string& a_str)
{
return !a_str.empty() && !a_str.contains("NONE"sv);
}

inline std::vector<std::string> split_sub_string(const std::string& a_str, const std::string& a_delimiter = ",")
{
if (is_valid_entry(a_str)) {
return string::split(a_str, a_delimiter);
}
return {};
}

inline FormIDPair get_formID(const std::string& a_str)
{
if (a_str.contains("~"sv)) {
auto splitID = string::split(a_str, "~");
return std::make_pair(
string::lexical_cast<RE::FormID>(splitID.at(kFormID), true),
splitID.at(kESP));
}
if (is_mod_name(a_str) || !string::is_only_hex(a_str)) {
return std::make_pair(
std::nullopt,
a_str);
}
return std::make_pair(
string::lexical_cast<RE::FormID>(a_str, true),
std::nullopt);
}

inline std::string sanitize(const std::string& a_value)
{
auto newValue = a_value;
Expand Down Expand Up @@ -88,36 +57,17 @@ namespace INI

//[FORMID/ESP] / EDITORID
if (kFormID < size) {
auto& formSection = sections[kFormID];
if (formSection.contains('~') || string::is_only_hex(formSection)) {
FormIDPair pair;
pair.second = std::nullopt;

if (string::is_only_hex(formSection)) {
// formID
pair.first = string::lexical_cast<RE::FormID>(formSection, true);
} else {
// formID~esp
pair = detail::get_formID(formSection);
}

recordID.emplace<FormIDPair>(pair);
} else {
recordID.emplace<std::string>(formSection);
}
} else {
FormIDPair pair = { 0, std::nullopt };
recordID.emplace<FormIDPair>(pair);
recordID = distribution::get_record(sections[kFormID]);
}

//KEYWORDS
if (kStrings < size) {
auto& [strings_ALL, strings_NOT, strings_MATCH, strings_ANY] = strings_ini;

auto split_str = detail::split_sub_string(sections[kStrings]);
auto split_str = distribution::split_entry(sections[kStrings]);
for (auto& str : split_str) {
if (str.contains("+"sv)) {
auto strings = detail::split_sub_string(str, "+");
auto strings = distribution::split_entry(str, "+");
strings_ALL.insert(strings_ALL.end(), strings.begin(), strings.end());

} else if (str.at(0) == '-') {
Expand All @@ -138,19 +88,19 @@ namespace INI
if (kFilterIDs < size) {
auto& [filterIDs_ALL, filterIDs_NOT, filterIDs_MATCH] = filterIDs_ini;

auto split_IDs = detail::split_sub_string(sections[kFilterIDs]);
auto split_IDs = distribution::split_entry(sections[kFilterIDs]);
for (auto& IDs : split_IDs) {
if (IDs.contains("+"sv)) {
auto splitIDs_ALL = detail::split_sub_string(IDs, "+");
auto splitIDs_ALL = distribution::split_entry(IDs, "+");
for (auto& IDs_ALL : splitIDs_ALL) {
filterIDs_ALL.push_back(detail::get_formID(IDs_ALL));
filterIDs_ALL.push_back(distribution::get_record(IDs_ALL));
}
} else if (IDs.at(0) == '-') {
IDs.erase(0, 1);
filterIDs_NOT.push_back(detail::get_formID(IDs));
filterIDs_NOT.push_back(distribution::get_record(IDs));

} else {
filterIDs_MATCH.push_back(detail::get_formID(IDs));
filterIDs_MATCH.push_back(distribution::get_record(IDs));
}
}
}
Expand All @@ -159,7 +109,7 @@ namespace INI
ActorLevel actorLevelPair = { UINT16_MAX, UINT16_MAX };
std::vector<SkillLevel> skillLevelPairs;
if (kLevel < size) {
auto split_levels = detail::split_sub_string(sections[kLevel]);
auto split_levels = distribution::split_entry(sections[kLevel]);
for (auto& levels : split_levels) {
if (levels.contains('(')) {
//skill(min/max)
Expand All @@ -168,27 +118,27 @@ namespace INI
//skill min max
if (!skills.empty()) {
if (skills.size() > 2) {
auto type = string::lexical_cast<std::uint32_t>(skills.at(0));
auto minLevel = string::lexical_cast<std::uint8_t>(skills.at(1));
auto maxLevel = string::lexical_cast<std::uint8_t>(skills.at(2));
auto type = string::to_num<std::uint32_t>(skills.at(0));
auto minLevel = string::to_num<std::uint8_t>(skills.at(1));
auto maxLevel = string::to_num<std::uint8_t>(skills.at(2));

skillLevelPairs.push_back({ type, { minLevel, maxLevel } });
} else {
auto type = string::lexical_cast<std::uint32_t>(skills.at(0));
auto minLevel = string::lexical_cast<std::uint8_t>(skills.at(1));
auto type = string::to_num<std::uint32_t>(skills.at(0));
auto minLevel = string::to_num<std::uint8_t>(skills.at(1));

skillLevelPairs.push_back({ type, { minLevel, UINT8_MAX } });
}
}
} else {
auto split_level = string::split(levels, "/");
if (split_level.size() > 1) {
auto minLevel = string::lexical_cast<std::uint16_t>(split_level.at(0));
auto maxLevel = string::lexical_cast<std::uint16_t>(split_level.at(1));
auto minLevel = string::to_num<std::uint16_t>(split_level.at(0));
auto maxLevel = string::to_num<std::uint16_t>(split_level.at(1));

actorLevelPair = { minLevel, maxLevel };
} else {
auto level = string::lexical_cast<std::uint16_t>(levels);
auto level = string::to_num<std::uint16_t>(levels);

actorLevelPair = { level, UINT16_MAX };
}
Expand All @@ -201,7 +151,7 @@ namespace INI
if (kTraits < size) {
auto& [sex, unique, summonable, child] = traits_ini;

auto split_traits = detail::split_sub_string(sections[kTraits], "/");
auto split_traits = distribution::split_entry(sections[kTraits], "/");
for (auto& trait : split_traits) {
if (trait == "M") {
sex = RE::SEX::kMale;
Expand All @@ -227,17 +177,17 @@ namespace INI
idxOrCount_ini = a_key == "Package" ? 0 : 1; //reuse item count for package stack index
if (kIdxOrCount < size) {
const auto& str = sections[kIdxOrCount];
if (detail::is_valid_entry(str)) {
idxOrCount_ini = string::lexical_cast<std::int32_t>(str);
if (distribution::is_valid_entry(str)) {
idxOrCount_ini = string::to_num<std::int32_t>(str);
}
}

//CHANCE
chance_ini = 100;
if (kChance < size) {
const auto& str = sections[kChance];
if (detail::is_valid_entry(str)) {
chance_ini = string::lexical_cast<float>(str);
if (distribution::is_valid_entry(str)) {
chance_ini = string::to_num<float>(str);
}
}

Expand Down
4 changes: 3 additions & 1 deletion SPID/include/LookupFilters.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ enum class SECONDARY_RESULT

namespace Filter
{
bool strings(RE::TESNPC& a_actorbase, const StringFilters& a_stringFilters);
inline RNG staticRNG;

bool strings(RE::TESNPC& a_actorbase, const StringFilters& a_stringFilters);

bool forms(RE::TESNPC& a_actorbase, const FormFilters& a_formFilters);

Expand Down
101 changes: 47 additions & 54 deletions SPID/include/LookupForms.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,63 +36,73 @@ namespace Lookup

namespace detail
{
inline bool formID_to_form(RE::TESDataHandler* a_dataHandler, FormIDPairVec& a_formIDVec, FormVec& a_formVec, const std::string& a_path)
inline void get_merged_IDs(std::optional<RE::FormID>& a_formID, std::optional<std::string>& a_modName)
{
const auto [mergedModName, mergedFormID] = g_mergeMapperInterface->GetNewFormID(a_modName.value_or("").c_str(), a_formID.value_or(0));
std::string conversion_log{};
if (a_formID.value_or(0) && mergedFormID && a_formID.value_or(0) != mergedFormID) {
conversion_log = std::format("0x{:X}->0x{:X}", a_formID.value_or(0), mergedFormID);
a_formID.emplace(mergedFormID);
}
const std::string mergedModString{ mergedModName };
if (!(a_modName.value_or("").empty()) && !mergedModString.empty() && a_modName.value_or("") != mergedModString) {
if (conversion_log.empty()) {
conversion_log = std::format("{}->{}", a_modName.value_or(""), mergedModString);
} else {
conversion_log = std::format("{}~{}->{}", conversion_log, a_modName.value_or(""), mergedModString);
}
a_modName.emplace(mergedModName);
}
if (!conversion_log.empty()) {
logger::info("\t\tFound merged: {}", conversion_log);
}
}

inline bool formID_to_form(RE::TESDataHandler* a_dataHandler, FormIDVec& a_formIDVec, FormVec& a_formVec, const std::string& a_path)
{
if (a_formIDVec.empty()) {
return true;
}
for (auto& [formID, modName] : a_formIDVec) {
if (g_mergeMapperInterface) {
const auto [mergedModName, mergedFormID] = g_mergeMapperInterface->GetNewFormID(modName.value_or("").c_str(), formID.value_or(0));
std::string conversion_log{};
if (formID.value_or(0) && mergedFormID && formID.value_or(0) != mergedFormID) {
conversion_log = std::format("0x{:X}->0x{:X}", formID.value_or(0), mergedFormID);
formID.emplace(mergedFormID);
}
const std::string mergedModString{ mergedModName };
if (!(modName.value_or("").empty()) && !mergedModString.empty() && modName.value_or("") != mergedModString) {
if (conversion_log.empty())
conversion_log = std::format("{}->{}", modName.value_or(""), mergedModString);
else
conversion_log = std::format("{}~{}->{}", conversion_log, modName.value_or(""), mergedModString);
modName.emplace(mergedModName);
for (auto& formOrEditorID : a_formIDVec) {
if (const auto formIDPair(std::get_if<FormIDPair>(&formOrEditorID)); formIDPair) {
auto& [formID, modName] = *formIDPair;
if (g_mergeMapperInterface) {
get_merged_IDs(formID, modName);
}
if (!conversion_log.empty())
logger::info("\t\tFound merged: {}", conversion_log);
}
if (modName && !formID) {
if (INI::is_mod_name(*modName)) {
if (modName && !formID) {
if (const RE::TESFile* filterMod = a_dataHandler->LookupModByName(*modName); filterMod) {
logger::info(" [{}] Filter ({}) INFO - mod found", a_path, filterMod->fileName);
a_formVec.push_back(filterMod);
} else {
logger::error(" [{}] Filter ({}) SKIP - mod cannot be found", a_path, *modName);
}
} else {
if (auto filterForm = RE::TESForm::LookupByEditorID(*modName); filterForm) {
} else if (formID) {
auto filterForm = modName ?
a_dataHandler->LookupForm(*formID, *modName) :
RE::TESForm::LookupByID(*formID);
if (filterForm) {
const auto formType = filterForm->GetFormType();
if (Cache::FormType::GetWhitelisted(formType)) {
a_formVec.push_back(filterForm);
} else {
logger::error(" [{}] Filter ({}) SKIP - invalid formtype ({})", a_path, *modName, formType);
logger::error(" [{}] Filter [0x{:X}] ({}) SKIP - invalid formtype ({})", a_path, *formID, modName.value_or(""), formType);
}
} else {
logger::error(" [{}] Filter ({}) SKIP - form doesn't exist", a_path, *modName);
logger::error(" [{}] Filter [0x{:X}] ({}) SKIP - form doesn't exist", a_path, *formID, modName.value_or(""));
}
}
} else if (formID) {
auto filterForm = modName ?
a_dataHandler->LookupForm(*formID, *modName) :
RE::TESForm::LookupByID(*formID);
if (filterForm) {
const auto formType = filterForm->GetFormType();
if (Cache::FormType::GetWhitelisted(formType)) {
a_formVec.push_back(filterForm);
} else if (std::holds_alternative<std::string>(formOrEditorID)) {
if (auto editorID = std::get<std::string>(formOrEditorID); !editorID.empty()) {
if (auto filterForm = RE::TESForm::LookupByEditorID(editorID); filterForm) {
const auto formType = filterForm->GetFormType();
if (Cache::FormType::GetWhitelisted(formType)) {
a_formVec.push_back(filterForm);
} else {
logger::error(" [{}] Filter ({}) SKIP - invalid formtype ({})", a_path, editorID, formType);
}
} else {
logger::error(" [{}] Filter [0x{:X}] ({}) SKIP - invalid formtype ({})", a_path, *formID, modName.value_or(""), formType);
logger::error(" [{}] Filter ({}) SKIP - form doesn't exist", a_path, editorID);
}
} else {
logger::error(" [{}] Filter [0x{:X}] ({}) SKIP - form doesn't exist", a_path, *formID, modName.value_or(""));
}
}
}
Expand Down Expand Up @@ -132,24 +142,7 @@ namespace Lookup
if (std::holds_alternative<FormIDPair>(formOrEditorID)) {
if (auto [formID, modName] = std::get<FormIDPair>(formOrEditorID); formID) {
if (g_mergeMapperInterface) {
const auto [mergedModName, mergedFormID] = g_mergeMapperInterface->GetNewFormID(modName.value_or("").c_str(), formID.value_or(0));
std::string conversion_log{};
if (formID.value_or(0) && mergedFormID && formID.value_or(0) != mergedFormID) {
conversion_log = std::format("0x{:X}->0x{:X}", formID.value_or(0), mergedFormID);
formID.emplace(mergedFormID);
}
const std::string mergedModString{ mergedModName };
if (!(modName.value_or("").empty()) && !mergedModString.empty() && modName.value_or("") != mergedModString) {
if (conversion_log.empty()) {
conversion_log = std::format("{}->{}", modName.value_or(""), mergedModString);
} else {
conversion_log = std::format("{}~{}->{}", conversion_log, modName.value_or(""), mergedModString);
}
modName.emplace(mergedModName);
}
if (!conversion_log.empty()) {
logger::info("\t\tFound merged: {}", conversion_log);
}
detail::get_merged_IDs(formID, modName);
}
if (modName) {
form = a_dataHandler->LookupForm<Form>(*formID, *modName);
Expand Down
8 changes: 5 additions & 3 deletions SPID/include/PCH.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "RE/Skyrim.h"
#include "SKSE/SKSE.h"

#include <ClibUtil/utils.hpp>
#include <SimpleIni.h>
#include <frozen/set.h>
#include <spdlog/sinks/basic_file_sink.h>
Expand All @@ -17,11 +18,12 @@
#define DLLEXPORT __declspec(dllexport)

namespace logger = SKSE::log;
namespace numeric = SKSE::stl::numeric;
namespace string = SKSE::stl::string;
namespace numeric = clib_util::numeric;
namespace string = clib_util::string;
namespace distribution = clib_util::distribution;

using namespace std::literals;
using RNG = SKSE::stl::RNG;
using RNG = clib_util::RNG;

namespace stl
{
Expand Down
Loading

0 comments on commit e7da60e

Please sign in to comment.