diff --git a/SKSE/Plugins/ArtifactTracker.dll b/SKSE/Plugins/ArtifactTracker.dll index 931d343..0772de3 100644 Binary files a/SKSE/Plugins/ArtifactTracker.dll and b/SKSE/Plugins/ArtifactTracker.dll differ diff --git a/Source/ArtifactTrackerDLL/CMakeLists.txt b/Source/ArtifactTrackerDLL/CMakeLists.txt index 38be4c8..0b19997 100644 --- a/Source/ArtifactTrackerDLL/CMakeLists.txt +++ b/Source/ArtifactTrackerDLL/CMakeLists.txt @@ -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 $ $ - $) + $ + ${SIMPLEINI_INCLUDE_DIRS} +) target_include_directories(${PROJECT_NAME} PUBLIC diff --git a/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp b/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp index cc0a542..7f2914b 100644 --- a/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp +++ b/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp @@ -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(0xF5CB0, "Skyrim.esm"); // VendorItemRecipe const auto excludeKeywords = dataHandler->LookupForm(0x801, "Artifact Tracker.esp"); // ETR_ExcludeMiscKeywords const auto dummyKeyword = dataHandler->LookupForm(0xF3E6C, "Skyrim.esm"); // Dummy + const auto disallowEnchanting = dataHandler->LookupForm(0xC27BD, "Skyrim.esm"); // MagicDisallowEnchanting + const auto daedricArtifact = dataHandler->LookupForm(0xA8668, "Skyrim.esm"); // DaedricArtifact + const auto extraArtifactKeyword = dataHandler->LookupForm(0xDE3FD3, "Update.esm"); // ETR_ExtraArtifact const auto notArtifactKeyword = dataHandler->LookupForm(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,18 +60,34 @@ namespace ArtifactTracker // Preloading item lists + std::map 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()) { - if (form->GetPlayable() && !form->IsBound() && !form->weaponData.flags.all(RE::TESObjectWEAP::Data::Flag::kCantDrop) && !form->IsDeleted() && !form->HasKeyword(dummyKeyword) && !form->HasKeyword(notArtifactKeyword)) { - g_artifactMap[form->formID] = form; + if (form->GetPlayable() && !form->IsBound() && !form->weaponData.flags.all(RE::TESObjectWEAP::Data::Flag::kCantDrop) && !form->IsDeleted() && !form->HasKeyword(dummyKeyword)) { + if (!bExcludeDisenchantableItems || !form->As()->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()) { - if (form->GetPlayable() && !form->IsDeleted() && !form->HasKeyword(dummyKeyword) && !form->HasKeyword(notArtifactKeyword)) { - g_artifactMap[form->formID] = form; + if (form->GetPlayable() && !form->IsDeleted() && !form->HasKeyword(dummyKeyword)) { + if (!bExcludeDisenchantableItems || !form->As()->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 @@ -82,7 +103,7 @@ namespace ArtifactTracker g_artifactFormTypes.insert(RE::FormType::Misc); for (const auto& form : dataHandler->GetFormArray()) { - 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; } diff --git a/Source/ArtifactTrackerDLL/src/Main.cpp b/Source/ArtifactTrackerDLL/src/Main.cpp index eb7627f..af97400 100644 --- a/Source/ArtifactTrackerDLL/src/Main.cpp +++ b/Source/ArtifactTrackerDLL/src/Main.cpp @@ -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 diff --git a/Source/ArtifactTrackerDLL/src/Util.h b/Source/ArtifactTrackerDLL/src/Util.h index 67e8d41..f031910 100644 --- a/Source/ArtifactTrackerDLL/src/Util.h +++ b/Source/ArtifactTrackerDLL/src/Util.h @@ -1,5 +1,7 @@ #pragma once +#include + 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* 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 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()); + } +} \ No newline at end of file diff --git a/Source/ArtifactTrackerDLL/vcpkg.json b/Source/ArtifactTrackerDLL/vcpkg.json index 2a63dce..2c40103 100644 --- a/Source/ArtifactTrackerDLL/vcpkg.json +++ b/Source/ArtifactTrackerDLL/vcpkg.json @@ -10,7 +10,8 @@ "plugin": { "description": "Build the SKSE plugin.", "dependencies": [ - "commonlibsse-ng" + "commonlibsse-ng", + "simpleini" ] } },