Added INI settings
This commit is contained in:
parent
d22595f6d2
commit
76d611147a
@ -1,9 +1,21 @@
|
|||||||
#include "EventListener.h"
|
#include "EventListener.h"
|
||||||
|
#include "IniLoader.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
RE::BGSKeyword* EventListener::keywordGem;
|
RE::BGSKeyword* EventListener::keywordGem;
|
||||||
RE::BGSKeyword* EventListener::keywordHide;
|
RE::BGSKeyword* EventListener::keywordHide;
|
||||||
RE::BGSKeyword* EventListener::keywordIngot;
|
RE::BGSKeyword* EventListener::keywordIngot;
|
||||||
|
|
||||||
|
inline std::map<std::string, std::any> g_settings{
|
||||||
|
{ "fRadius", 350.0f },
|
||||||
|
{ "bPickupGold", true },
|
||||||
|
{ "bPickupLockpicks", true },
|
||||||
|
{ "bPickupMaterials", true },
|
||||||
|
{ "bPickupArrows", true },
|
||||||
|
{ "bPickupFlora", true },
|
||||||
|
{ "bPickupIngredients", true },
|
||||||
|
};
|
||||||
|
|
||||||
auto EventListener::GetSingleton() -> EventListener*
|
auto EventListener::GetSingleton() -> EventListener*
|
||||||
{
|
{
|
||||||
static EventListener singleton{};
|
static EventListener singleton{};
|
||||||
@ -12,6 +24,8 @@ auto EventListener::GetSingleton() -> EventListener*
|
|||||||
|
|
||||||
void EventListener::Install()
|
void EventListener::Install()
|
||||||
{
|
{
|
||||||
|
LoadINI(&g_settings, std::format("Data/SKSE/Plugins/{}.ini", SKSE::PluginDeclaration::GetSingleton()->GetName()).c_str());
|
||||||
|
|
||||||
RE::ScriptEventSourceHolder::GetSingleton()->GetEventSource<RE::TESActivateEvent>()->AddEventSink(EventListener::GetSingleton());
|
RE::ScriptEventSourceHolder::GetSingleton()->GetEventSource<RE::TESActivateEvent>()->AddEventSink(EventListener::GetSingleton());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,19 +54,19 @@ auto EventListener::ProcessEvent(
|
|||||||
RE::TESBoundObject* produceItem = nullptr;
|
RE::TESBoundObject* produceItem = nullptr;
|
||||||
|
|
||||||
bool bIsCoinPouch = IsCoinPouch(baseObj);
|
bool bIsCoinPouch = IsCoinPouch(baseObj);
|
||||||
bool bIsGold = bIsCoinPouch || baseObj->IsGold();
|
bool bIsGold = std::any_cast<bool>(g_settings["bPickupGold"]) && (bIsCoinPouch || baseObj->IsGold());
|
||||||
bool bIsLockpick = baseObj->IsLockpick();
|
bool bIsLockpick = std::any_cast<bool>(g_settings["bPickupLockpicks"]) && baseObj->IsLockpick();
|
||||||
|
|
||||||
RE::BGSKeywordForm* keywordForm = baseObj->Is(RE::FormType::Misc) ? baseObj->As<RE::BGSKeywordForm>() : nullptr;
|
RE::BGSKeywordForm* keywordForm = (baseObj->Is(RE::FormType::Misc) && std::any_cast<bool>(g_settings["bPickupMaterials"])) ? baseObj->As<RE::BGSKeywordForm>() : nullptr;
|
||||||
bool bIsGem = keywordForm && keywordForm->HasKeyword(keywordGem);
|
bool bIsGem = keywordForm && keywordForm->HasKeyword(keywordGem);
|
||||||
bool bIsHide = keywordForm && keywordForm->HasKeyword(keywordHide);
|
bool bIsHide = keywordForm && keywordForm->HasKeyword(keywordHide);
|
||||||
bool bIsIngot = keywordForm && keywordForm->HasKeyword(keywordIngot);
|
bool bIsIngot = keywordForm && keywordForm->HasKeyword(keywordIngot);
|
||||||
|
|
||||||
bool bIsAmmo = (baseObj->IsAmmo() || baseObj->Is(RE::FormType::Projectile)) && baseObj->GetPlayable();
|
bool bIsAmmo = std::any_cast<bool>(g_settings["bPickupArrows"]) && (baseObj->IsAmmo() || baseObj->Is(RE::FormType::Projectile)) && baseObj->GetPlayable();
|
||||||
|
|
||||||
bool bIsFlora = !bIsCoinPouch && baseObj->Is(RE::FormType::Flora) && (produceItem = baseObj->As<RE::TESFlora>()->produceItem);
|
bool bIsFlora = std::any_cast<bool>(g_settings["bPickupFlora"]) && !bIsCoinPouch && baseObj->Is(RE::FormType::Flora) && (produceItem = baseObj->As<RE::TESFlora>()->produceItem);
|
||||||
bool bIsTree = baseObj->Is(RE::FormType::Tree) && (produceItem = baseObj->As<RE::TESObjectTREE>()->produceItem);
|
bool bIsTree = std::any_cast<bool>(g_settings["bPickupFlora"]) && baseObj->Is(RE::FormType::Tree) && (produceItem = baseObj->As<RE::TESObjectTREE>()->produceItem);
|
||||||
bool bIsIngredient = baseObj->Is(RE::FormType::Ingredient);
|
bool bIsIngredient = std::any_cast<bool>(g_settings["bPickupIngredients"]) && baseObj->Is(RE::FormType::Ingredient);
|
||||||
|
|
||||||
if (!bIsGold && !bIsLockpick && !bIsGem && !bIsHide && !bIsIngot && !bIsAmmo && !bIsFlora && !bIsTree && !bIsIngredient) {
|
if (!bIsGold && !bIsLockpick && !bIsGem && !bIsHide && !bIsIngot && !bIsAmmo && !bIsFlora && !bIsTree && !bIsIngredient) {
|
||||||
return RE::BSEventNotifyControl::kContinue;
|
return RE::BSEventNotifyControl::kContinue;
|
||||||
@ -70,7 +84,7 @@ auto EventListener::ProcessEvent(
|
|||||||
|
|
||||||
std::unordered_set<RE::TESObjectREFR*> refQueue;
|
std::unordered_set<RE::TESObjectREFR*> refQueue;
|
||||||
|
|
||||||
TES->ForEachReferenceInRange(baseRef, 300.0f, [&](RE::TESObjectREFR* a_ref) {
|
TES->ForEachReferenceInRange(baseRef, std::any_cast<float>(g_settings["fRadius"]), [&](RE::TESObjectREFR* a_ref) {
|
||||||
if (!a_ref) {
|
if (!a_ref) {
|
||||||
return RE::BSContainer::ForEachResult::kContinue;
|
return RE::BSContainer::ForEachResult::kContinue;
|
||||||
}
|
}
|
||||||
|
91
src/IniLoader.h
Normal file
91
src/IniLoader.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SimpleIni.h>
|
||||||
|
#include <any>
|
||||||
|
|
||||||
|
inline void LoadINI(std::map<std::string, std::any>* settings, const char* iniPath)
|
||||||
|
{
|
||||||
|
for (auto it = settings->begin(); it != settings->end(); it++) {
|
||||||
|
if (it->first[0] == 'f') {
|
||||||
|
logger::info("[DEFAULT] {} = {}", it->first, std::any_cast<float>(it->second));
|
||||||
|
} else if (it->first[0] == 'i') {
|
||||||
|
logger::info("[DEFAULT] {} = {}", it->first, std::any_cast<int>(it->second));
|
||||||
|
} else if (it->first[0] == 's') {
|
||||||
|
logger::info("[DEFAULT] {} = {}", it->first, std::any_cast<const char*>(it->second));
|
||||||
|
} else {
|
||||||
|
logger::info("[DEFAULT] {} = {}", it->first, std::any_cast<bool>(it->second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(iniPath)) {
|
||||||
|
logger::warn("{} does not exist, using default values.", iniPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
CSimpleIniA ini;
|
||||||
|
ini.SetUnicode(false);
|
||||||
|
ini.SetMultiKey(false);
|
||||||
|
SI_Error rc = ini.LoadFile(iniPath);
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
logger::error("{}", rc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<CSimpleIniA::Entry> keysList;
|
||||||
|
ini.GetAllKeys("", keysList);
|
||||||
|
|
||||||
|
bool bUpdateINI = false;
|
||||||
|
for (auto it = settings->begin(); it != settings->end(); it++) {
|
||||||
|
try {
|
||||||
|
bool bExists = false;
|
||||||
|
for (const auto& k : keysList) {
|
||||||
|
if (it->first == k.pItem) {
|
||||||
|
if (k.pItem[0] == 'f') {
|
||||||
|
float fValue = ini.GetDoubleValue("", k.pItem, std::any_cast<float>(settings->at(k.pItem)));
|
||||||
|
settings->insert_or_assign(k.pItem, fValue);
|
||||||
|
logger::info("[INI] {} = {}", k.pItem, fValue);
|
||||||
|
} else if (k.pItem[0] == 'i') {
|
||||||
|
int iValue = ini.GetLongValue("", k.pItem, std::any_cast<int>(settings->at(k.pItem)));
|
||||||
|
settings->insert_or_assign(k.pItem, iValue);
|
||||||
|
logger::info("[INI] {} = {}", k.pItem, iValue);
|
||||||
|
} else if (k.pItem[0] == 's') {
|
||||||
|
const char* sValue = ini.GetValue("", k.pItem, std::any_cast<const char*>(settings->at(k.pItem)));
|
||||||
|
settings->insert_or_assign(k.pItem, sValue);
|
||||||
|
logger::info("[INI] {} = {}", k.pItem, sValue);
|
||||||
|
} else {
|
||||||
|
bool bValue = ini.GetBoolValue("", k.pItem, std::any_cast<bool>(settings->at(k.pItem)));
|
||||||
|
settings->insert_or_assign(k.pItem, bValue);
|
||||||
|
logger::info("[INI] {} = {}", k.pItem, bValue);
|
||||||
|
}
|
||||||
|
bExists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!bExists) {
|
||||||
|
if (it->first.c_str()[0] == 'f') {
|
||||||
|
ini.SetDoubleValue("", it->first.c_str(), std::any_cast<float>(it->second));
|
||||||
|
} else if (it->first.c_str()[0] == 'i') {
|
||||||
|
ini.SetLongValue("", it->first.c_str(), std::any_cast<int>(it->second));
|
||||||
|
} else if (it->first.c_str()[0] == 's') {
|
||||||
|
ini.SetValue("", it->first.c_str(), std::any_cast<const char*>(it->second));
|
||||||
|
} else {
|
||||||
|
ini.SetBoolValue("", it->first.c_str(), std::any_cast<bool>(it->second));
|
||||||
|
}
|
||||||
|
bUpdateINI = true;
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
logger::error("[INI] {} = {}", it->first, e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bUpdateINI) {
|
||||||
|
logger::info("New settings detected, adding to {}", iniPath);
|
||||||
|
ini.SaveFile(iniPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
logger::error("{}", e.what());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user