Added INI support, excludes disenchantable items by default
This commit is contained in:
parent
81b174e028
commit
db410f6537
Binary file not shown.
@ -15,6 +15,8 @@ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
find_path(SIMPLEINI_INCLUDE_DIRS "ConvertUTF.c")
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.rc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version.rc
|
||||
@ -47,7 +49,9 @@ target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/src>
|
||||
$<INSTALL_INTERFACE:src>)
|
||||
$<INSTALL_INTERFACE:src>
|
||||
${SIMPLEINI_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
|
@ -24,6 +24,8 @@ namespace ArtifactTracker
|
||||
return true;
|
||||
}
|
||||
|
||||
SKSE::GetModCallbackEventSource()->RemoveEventSink(EventListener::GetSingleton());
|
||||
|
||||
const auto dataHandler = RE::TESDataHandler::GetSingleton();
|
||||
|
||||
if (!dataHandler) {
|
||||
@ -44,10 +46,13 @@ namespace ArtifactTracker
|
||||
const auto recipeKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xF5CB0, "Skyrim.esm"); // VendorItemRecipe
|
||||
const auto excludeKeywords = dataHandler->LookupForm<RE::BGSListForm>(0x801, "Artifact Tracker.esp"); // ETR_ExcludeMiscKeywords
|
||||
const auto dummyKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xF3E6C, "Skyrim.esm"); // Dummy
|
||||
const auto disallowEnchanting = dataHandler->LookupForm<RE::BGSKeyword>(0xC27BD, "Skyrim.esm"); // MagicDisallowEnchanting
|
||||
const auto daedricArtifact = dataHandler->LookupForm<RE::BGSKeyword>(0xA8668, "Skyrim.esm"); // DaedricArtifact
|
||||
|
||||
const auto extraArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xDE3FD3, "Update.esm"); // ETR_ExtraArtifact
|
||||
const auto notArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xDE3FD4, "Update.esm"); // ETR_NotArtifact
|
||||
|
||||
if (!g_cellContainer || !g_listNew || !g_listStored || !g_listFound || !g_persistentStorage || !g_homeKeyword || !recipeKeyword || !excludeKeywords || !dummyKeyword || !extraArtifactKeyword || !notArtifactKeyword) {
|
||||
if (!g_cellContainer || !g_listNew || !g_listStored || !g_listFound || !g_persistentStorage || !g_homeKeyword || !recipeKeyword || !excludeKeywords || !dummyKeyword || !extraArtifactKeyword || !notArtifactKeyword || !disallowEnchanting || !daedricArtifact) {
|
||||
SKSE::log::warn("Unable to load data from Artifact Tracker.esp");
|
||||
RE::DebugMessageBox("Unable to load data from Artifact Tracker.esp, the mod is disabled.");
|
||||
return false;
|
||||
@ -55,20 +60,36 @@ namespace ArtifactTracker
|
||||
|
||||
// Preloading item lists
|
||||
|
||||
std::map<std::string, bool> settings{
|
||||
{ "ExcludeDisenchantableItems", true },
|
||||
{ "DumpItemNames", false },
|
||||
};
|
||||
LoadINI(&settings, "Data/SKSE/Plugins/ArtifactTracker.ini");
|
||||
|
||||
bool bExcludeDisenchantableItems = settings.at("ExcludeDisenchantableItems");
|
||||
|
||||
g_artifactFormTypes.insert(RE::FormType::Weapon);
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectWEAP>()) {
|
||||
if (form->GetPlayable() && !form->IsBound() && !form->weaponData.flags.all(RE::TESObjectWEAP::Data::Flag::kCantDrop) && !form->IsDeleted() && !form->HasKeyword(dummyKeyword) && !form->HasKeyword(notArtifactKeyword)) {
|
||||
if (form->GetPlayable() && !form->IsBound() && !form->weaponData.flags.all(RE::TESObjectWEAP::Data::Flag::kCantDrop) && !form->IsDeleted() && !form->HasKeyword(dummyKeyword)) {
|
||||
if (!bExcludeDisenchantableItems || !form->As<RE::TESEnchantableForm>()->formEnchanting || form->HasKeyword(disallowEnchanting) || form->HasKeyword(daedricArtifact) || form->HasKeyword(extraArtifactKeyword)) {
|
||||
if (!form->HasKeyword(notArtifactKeyword) && strlen(form->GetName()) > 0) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g_artifactMap.erase(0x1F4); // Unarmed
|
||||
|
||||
g_artifactFormTypes.insert(RE::FormType::Armor);
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectARMO>()) {
|
||||
if (form->GetPlayable() && !form->IsDeleted() && !form->HasKeyword(dummyKeyword) && !form->HasKeyword(notArtifactKeyword)) {
|
||||
if (form->GetPlayable() && !form->IsDeleted() && !form->HasKeyword(dummyKeyword)) {
|
||||
if (!bExcludeDisenchantableItems || !form->As<RE::TESEnchantableForm>()->formEnchanting || form->HasKeyword(disallowEnchanting) || form->HasKeyword(daedricArtifact) || form->HasKeyword(extraArtifactKeyword)) {
|
||||
if (!form->HasKeyword(notArtifactKeyword) && strlen(form->GetName()) > 0) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g_artifactMap.erase(0xD64); // SkinNaked
|
||||
g_artifactMap.erase(0x69CE3); // SkinNakedBeast
|
||||
g_artifactMap.erase(0xCDD86); // SkinNakedWerewolfBeast
|
||||
@ -82,7 +103,7 @@ namespace ArtifactTracker
|
||||
|
||||
g_artifactFormTypes.insert(RE::FormType::Misc);
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectMISC>()) {
|
||||
if (form->GetPlayable() && !form->IsDeleted() && (form->HasKeyword(extraArtifactKeyword) || !form->HasKeywordInList(excludeKeywords, false)) && !form->HasKeyword(notArtifactKeyword)) {
|
||||
if (form->GetPlayable() && !form->IsDeleted() && (form->HasKeyword(extraArtifactKeyword) || !form->HasKeywordInList(excludeKeywords, false)) && !form->HasKeyword(notArtifactKeyword) && strlen(form->GetName()) > 0) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
}
|
||||
}
|
||||
@ -121,8 +142,16 @@ namespace ArtifactTracker
|
||||
|
||||
OnGameLoad();
|
||||
EventListener::Install();
|
||||
|
||||
g_bLoaded = true;
|
||||
|
||||
SKSE::log::info("Total artifacts: {}", g_artifactMap.size());
|
||||
|
||||
if (settings.at("DumpItemNames")) {
|
||||
for (const auto& item : g_artifactMap) {
|
||||
SKSE::log::info("[{:08X}] {}", item.second->formID, item.second->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,6 @@ namespace {
|
||||
if (message->type == MessagingInterface::kPostLoad) {
|
||||
SKSE::GetModCallbackEventSource()->AddEventSink(EventListener::GetSingleton());
|
||||
} else if (message->type == MessagingInterface::kNewGame || message->type == MessagingInterface::kPreLoadGame) {
|
||||
SKSE::GetModCallbackEventSource()->RemoveEventSink(EventListener::GetSingleton());
|
||||
ArtifactTracker::Init(); // if KID is not installed
|
||||
} else if (message->type == MessagingInterface::kPostLoadGame) {
|
||||
ArtifactTracker::OnGameLoad(); // refresh g_persistentMap from savegame
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <SimpleIni.h>
|
||||
|
||||
inline void ListRemoveItem(RE::BGSListForm* a_List, RE::TESForm* a_form)
|
||||
{
|
||||
using func_t = decltype(&ListRemoveItem);
|
||||
@ -129,3 +131,50 @@ inline bool IsInSameCell(RE::TESObjectREFR* ref)
|
||||
{
|
||||
return ref && (ref->GetParentCell() == RE::PlayerCharacter::GetSingleton()->GetParentCell());
|
||||
}
|
||||
|
||||
inline void LoadINI(std::map<std::string, bool>* settings, const char* iniPath)
|
||||
{
|
||||
for (auto it = settings->begin(); it != settings->end(); it++) {
|
||||
SKSE::log::info("[DEFAULT] {} = {}", it->first, it->second);
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists(iniPath)) {
|
||||
SKSE::log::warn("{} does not exists, using default values.", iniPath);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
CSimpleIniA ini;
|
||||
ini.SetUnicode(false);
|
||||
ini.SetMultiKey(false);
|
||||
ini.LoadFile(iniPath);
|
||||
|
||||
std::list<CSimpleIniA::Entry> keysList;
|
||||
ini.GetAllKeys("", keysList);
|
||||
|
||||
bool bUpdateINI = false;
|
||||
for (auto it = settings->begin(); it != settings->end(); it++) {
|
||||
bool bExists = false;
|
||||
for (const auto& k : keysList) {
|
||||
if (it->first == k.pItem) {
|
||||
settings->insert_or_assign(k.pItem, ini.GetBoolValue("", k.pItem, settings->at(k.pItem)));
|
||||
SKSE::log::info("[INI] {} = {}", k.pItem, settings->at(k.pItem));
|
||||
bExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bExists) {
|
||||
ini.SetBoolValue("", it->first.c_str(), it->second);
|
||||
bUpdateINI = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bUpdateINI) {
|
||||
SKSE::log::info("New settings detected, adding to ArtifactTracker.ini");
|
||||
ini.SaveFile(iniPath);
|
||||
}
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
SKSE::log::error(e.what());
|
||||
}
|
||||
}
|
@ -10,7 +10,8 @@
|
||||
"plugin": {
|
||||
"description": "Build the SKSE plugin.",
|
||||
"dependencies": [
|
||||
"commonlibsse-ng"
|
||||
"commonlibsse-ng",
|
||||
"simpleini"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user