diff --git a/Artifact Tracker.esp b/Artifact Tracker.esp index 608ebeb..7ef9724 100644 Binary files a/Artifact Tracker.esp and b/Artifact Tracker.esp differ diff --git a/Artifact Tracker_KID.ini b/Artifact Tracker_KID.ini index 2a3f9c3..4e600a5 100644 --- a/Artifact Tracker_KID.ini +++ b/Artifact Tracker_KID.ini @@ -3,3 +3,6 @@ Keyword = ETR_ExtraArtifact|Misc Item|0x1F6D4,0x200B6,0x200BA,0x20949,0x59654,0x ; Treasure Maps Keyword = ETR_ExtraArtifact|Book|0xEF07A,0xF33CD,0xF33CE,0xF33CF,0xF33D0,0xF33D1,0xF33D2,0xF33D3,0xF33D4,0xF33D5,0xF33E0 + +; Soul Gem Fragments +Keyword = ETR_NotArtifact|Misc Item|0x67181,0x67182,0x67183,0x67184,0x67185 diff --git a/SKSE/Plugins/ArtifactTracker.dll b/SKSE/Plugins/ArtifactTracker.dll index 7dba8c4..931d343 100644 Binary files a/SKSE/Plugins/ArtifactTracker.dll and b/SKSE/Plugins/ArtifactTracker.dll differ diff --git a/Scripts/ArtifactTrackerPlayer.pex b/Scripts/ArtifactTrackerPlayer.pex index 1fe920f..90de806 100644 Binary files a/Scripts/ArtifactTrackerPlayer.pex and b/Scripts/ArtifactTrackerPlayer.pex differ diff --git a/Source/ArtifactTrackerDLL/.clang-format b/Source/ArtifactTrackerDLL/.clang-format index baf5bb7..083b415 100644 --- a/Source/ArtifactTrackerDLL/.clang-format +++ b/Source/ArtifactTrackerDLL/.clang-format @@ -60,7 +60,7 @@ DisableFormat: 'false' FixNamespaceComments: 'false' IncludeBlocks: Preserve IndentCaseBlocks: 'true' -IndentCaseLabels: 'false' +IndentCaseLabels: 'true' IndentExternBlock: Indent IndentGotoLabels: 'false' IndentPPDirectives: AfterHash diff --git a/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp b/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp index 04edb10..cc0a542 100644 --- a/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp +++ b/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp @@ -18,15 +18,18 @@ namespace ArtifactTracker std::unordered_map g_persistentMap; RE::TESObjectREFR* g_cellStorage; - void Init() + bool Init() { - g_bLoaded = false; + if (g_bLoaded) { + return true; + } const auto dataHandler = RE::TESDataHandler::GetSingleton(); if (!dataHandler) { - SKSE::log::error("Failed to call RE::TESDataHandler::GetSingleton()"); - return; + SKSE::log::error("Unable to call RE::TESDataHandler::GetSingleton()"); + RE::DebugMessageBox("Unable to initialize Artifact Tracker."); + return false; } g_cellContainer = dataHandler->LookupForm(0x800, "Artifact Tracker.esp")->As(); // ETR_CellStorageContainer @@ -40,111 +43,95 @@ 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 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) { - SKSE::log::warn("Failed to load data from Artifact Tracker.esp"); - RE::DebugMessageBox("Failed to load data from Artifact Tracker.esp, the mod is disabled."); - return; + if (!g_cellContainer || !g_listNew || !g_listStored || !g_listFound || !g_persistentStorage || !g_homeKeyword || !recipeKeyword || !excludeKeywords || !dummyKeyword || !extraArtifactKeyword || !notArtifactKeyword) { + 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; } // Preloading item lists g_artifactFormTypes.insert(RE::FormType::Weapon); - for (const auto& form : dataHandler->GetFormArray(RE::FormType::Weapon)) { - if (form->GetPlayable()) { + 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; } } g_artifactMap.erase(0x1F4); // Unarmed g_artifactFormTypes.insert(RE::FormType::Armor); - for (const auto& form : dataHandler->GetFormArray(RE::FormType::Armor)) { - if (form->GetPlayable()) { + for (const auto& form : dataHandler->GetFormArray()) { + if (form->GetPlayable() && !form->IsDeleted() && !form->HasKeyword(dummyKeyword) && !form->HasKeyword(notArtifactKeyword)) { g_artifactMap[form->formID] = form; } } + g_artifactMap.erase(0xD64); // SkinNaked + g_artifactMap.erase(0x69CE3); // SkinNakedBeast + g_artifactMap.erase(0xCDD86); // SkinNakedWerewolfBeast g_artifactFormTypes.insert(RE::FormType::Book); for (const auto& form : dataHandler->GetFormArray()) { - if (form && !form->TeachesSpell() && (form->HasKeyword(recipeKeyword) || BookCheck::IsBook(form))) { + if (!form->TeachesSpell() && !form->IsDeleted() && (form->HasKeyword(recipeKeyword) || form->HasKeyword(extraArtifactKeyword) || BookCheck::IsBook(form)) && !form->HasKeyword(notArtifactKeyword)) { g_artifactMap[form->formID] = form; } } g_artifactFormTypes.insert(RE::FormType::Misc); for (const auto& form : dataHandler->GetFormArray()) { - if (form->GetPlayable() && !form->HasKeywordInList(excludeKeywords, false)) { + if (form->GetPlayable() && !form->IsDeleted() && (form->HasKeyword(extraArtifactKeyword) || !form->HasKeywordInList(excludeKeywords, false)) && !form->HasKeyword(notArtifactKeyword)) { g_artifactMap[form->formID] = form; } } g_artifactMap.erase(0xA); // Lockpick g_artifactMap.erase(0xF); // Gold - // Fishing CC - const auto plaqueFish = dataHandler->LookupForm(0xF4B, "ccBGSSSE001-Fish.esm"); // ccBGSSSE001_FishPlaqueGiftFilterList - if (plaqueFish) { - plaqueFish->ForEachForm([&](RE::TESForm& a_form) { - g_artifactMap[a_form.formID] = &a_form; - return true; - }); - } - - OnGameLoad(); - EventListener::Install(); - - g_bLoaded = true; - } - - void OnKeywordDistribution() - { - const auto dataHandler = RE::TESDataHandler::GetSingleton(); - const auto extraArtifactKeyword = dataHandler->LookupForm(0xDE3FD3, "Update.esm"); // ETR_ExtraArtifact - - if (!dataHandler || !extraArtifactKeyword) { - SKSE::log::error("Unable to load ETR_ExtraArtifact in OnKeywordDistribution"); - return; - } - - for (const auto& form : dataHandler->GetFormArray()) { - if (form->HasKeyword(extraArtifactKeyword)) { - g_artifactMap[form->formID] = form; - } - } - - for (const auto& form : dataHandler->GetFormArray()) { - if (form->GetPlayable() && form->HasKeyword(extraArtifactKeyword)) { - g_artifactMap[form->formID] = form; - } - } - for (const auto& form : dataHandler->GetFormArray()) { - if (form->HasKeyword(extraArtifactKeyword)) { + if (!form->IsDeleted() && form->HasKeyword(extraArtifactKeyword) && !form->HasKeyword(notArtifactKeyword)) { g_artifactMap[form->formID] = form; g_artifactFormTypes.insert(RE::FormType::AlchemyItem); } } - + for (const auto& form : dataHandler->GetFormArray()) { - if (form->HasKeyword(extraArtifactKeyword)) { + if (!form->IsDeleted() && form->HasKeyword(extraArtifactKeyword) && !form->HasKeyword(notArtifactKeyword)) { g_artifactMap[form->formID] = form; g_artifactFormTypes.insert(RE::FormType::Ingredient); } } - + for (const auto& form : dataHandler->GetFormArray()) { - if (form->HasKeyword(extraArtifactKeyword)) { + if (!form->IsDeleted() && form->HasKeyword(extraArtifactKeyword) && !form->HasKeyword(notArtifactKeyword)) { g_artifactMap[form->formID] = form; g_artifactFormTypes.insert(RE::FormType::SoulGem); } } + + // Fishing CC (remove, when KID adds formlist support) + const auto plaqueFish = dataHandler->LookupForm(0xF4B, "ccBGSSSE001-Fish.esm"); // ccBGSSSE001_FishPlaqueGiftFilterList + if (plaqueFish) { + plaqueFish->ForEachForm([&](RE::TESForm& a_form) { + g_artifactMap[a_form.formID] = &a_form; + return true; + }); + } + + OnGameLoad(); + EventListener::Install(); + + g_bLoaded = true; + return true; } - bool IsArtifact(RE::TESForm* a_form) + bool IsArtifact(const RE::TESForm* a_form) { return a_form && g_artifactFormTypes.contains(a_form->GetFormType()) && g_artifactMap.contains(a_form->formID); } - RE::TESForm* GetArtifactByID(RE::FormID a_formID) + RE::TESForm* GetArtifactByID(const RE::FormID a_formID) { if (!a_formID) { return nullptr; @@ -169,7 +156,7 @@ namespace ArtifactTracker }); } - void SetContainerMode(bool bOpening) + void SetContainerMode(const bool bOpening) { if (bOpening) { @@ -229,7 +216,7 @@ namespace ArtifactTracker return baseObj->formType == RE::FormType::Container || (baseObj->formType == RE::FormType::NPC && !a_ref->IsDisabled() && baseObj->As()->GetRace()->formID == 0x0010760A); } - void OnCellEnter(RE::FormID a_formID) + void OnCellEnter(const RE::FormID a_formID) { RE::TESObjectCELL* cell = RE::TESForm::LookupByID(a_formID); RE::BGSLocation* location = cell ? cell->GetLocation() : nullptr; @@ -260,7 +247,7 @@ namespace ArtifactTracker } } - void OnCellEnter(RE::BGSLocation* location, RE::TESObjectCELL* cell) + void OnCellEnter(const RE::BGSLocation* location, const RE::TESObjectCELL* cell) { if (!location || !cell->IsInteriorCell() || cell != RE::PlayerCharacter::GetSingleton()->GetParentCell() || !location->HasKeyword(g_homeKeyword)) { ToggleHomeMode(nullptr); @@ -303,7 +290,7 @@ namespace ArtifactTracker } } - void SyncCellStorage(RE::FormID a_ignoreRef) + void SyncCellStorage(const RE::TESObjectREFR* a_ignoreRef) { if (!IsHome()) { #ifdef _DEBUG @@ -322,7 +309,7 @@ namespace ArtifactTracker const auto inv = g_cellStorage->GetInventory(); for (const auto& a_ref : cell->references) { - if (a_ignoreRef == a_ref->formID) { + if (a_ignoreRef && a_ignoreRef->formID == a_ref->formID) { continue; } @@ -428,7 +415,7 @@ namespace ArtifactTracker if (!g_bHomeContainer) { const auto container = RE::TESForm::LookupByID(a_event->oldContainer); if (container && !GetItemCount(container, form)) { - SyncCellStorage(container->formID); + SyncCellStorage(container); } } @@ -575,7 +562,7 @@ namespace ArtifactTracker if (g_cellStorage && IsInSameCell(container)) { // deleted from container at home if (!GetItemCount(container, form)) { - SyncCellStorage(container->formID); + SyncCellStorage(container); } } diff --git a/Source/ArtifactTrackerDLL/src/ArtifactTracker.h b/Source/ArtifactTrackerDLL/src/ArtifactTracker.h index 8fdcba3..e62e0fb 100644 --- a/Source/ArtifactTrackerDLL/src/ArtifactTracker.h +++ b/Source/ArtifactTrackerDLL/src/ArtifactTracker.h @@ -15,25 +15,23 @@ namespace ArtifactTracker extern std::unordered_map g_persistentMap; extern RE::TESObjectREFR* g_cellStorage; - void Init(); + bool Init(); - void OnKeywordDistribution(); + bool IsArtifact(const RE::TESForm* a_item); - bool IsArtifact(RE::TESForm* a_item); - - RE::TESForm* GetArtifactByID(RE::FormID a_formID); + RE::TESForm* GetArtifactByID(const RE::FormID a_formID); bool IsHome(); void OnGameLoad(); - void SetContainerMode(bool bOpening); + void SetContainerMode(const bool bOpening); - void OnCellEnter(RE::FormID a_formID); + void OnCellEnter(const RE::FormID a_formID); - void OnCellEnter(RE::BGSLocation* location, RE::TESObjectCELL* cell); + void OnCellEnter(const RE::BGSLocation* location, const RE::TESObjectCELL* cell); - void SyncCellStorage(RE::FormID a_ignoreRef = NULL); + void SyncCellStorage(const RE::TESObjectREFR* a_ignoreRef = nullptr); void OnContainerChanged(const RE::TESContainerChangedEvent* a_event, RE::TESForm* form); diff --git a/Source/ArtifactTrackerDLL/src/EventListener.cpp b/Source/ArtifactTrackerDLL/src/EventListener.cpp index ba97498..f722091 100644 --- a/Source/ArtifactTrackerDLL/src/EventListener.cpp +++ b/Source/ArtifactTrackerDLL/src/EventListener.cpp @@ -20,7 +20,7 @@ auto EventListener::ProcessEvent( { if (a_event->eventName == "KID_KeywordDistributionDone") { SKSE::GetModCallbackEventSource()->RemoveEventSink(EventListener::GetSingleton()); - ArtifactTracker::OnKeywordDistribution(); + ArtifactTracker::Init(); } return RE::BSEventNotifyControl::kContinue; diff --git a/Source/ArtifactTrackerDLL/src/Main.cpp b/Source/ArtifactTrackerDLL/src/Main.cpp index 70f881c..eb7627f 100644 --- a/Source/ArtifactTrackerDLL/src/Main.cpp +++ b/Source/ArtifactTrackerDLL/src/Main.cpp @@ -29,14 +29,13 @@ namespace { void InitializeMessaging() { GetMessagingInterface()->RegisterListener([](MessagingInterface::Message* message) { - - if (message->type == MessagingInterface::kPostPostLoad) { + if (message->type == MessagingInterface::kPostLoad) { SKSE::GetModCallbackEventSource()->AddEventSink(EventListener::GetSingleton()); - } else if (message->type == MessagingInterface::kDataLoaded) { - ArtifactTracker::Init(); - } else if (message->type == MessagingInterface::kPostLoadGame) { + } else if (message->type == MessagingInterface::kNewGame || message->type == MessagingInterface::kPreLoadGame) { SKSE::GetModCallbackEventSource()->RemoveEventSink(EventListener::GetSingleton()); - ArtifactTracker::OnGameLoad(); + 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/PapyrusFunctions.h b/Source/ArtifactTrackerDLL/src/PapyrusFunctions.h index 6df33f5..9eccee1 100644 --- a/Source/ArtifactTrackerDLL/src/PapyrusFunctions.h +++ b/Source/ArtifactTrackerDLL/src/PapyrusFunctions.h @@ -5,9 +5,9 @@ namespace Papyrus::PapyrusFunctions { - constexpr bool IsLoaded(RE::StaticFunctionTag*) + inline bool Load(RE::StaticFunctionTag*) { - return ArtifactTracker::g_bLoaded; + return ArtifactTracker::Init(); } inline RE::TESObjectREFR* GetCellStorage(RE::StaticFunctionTag*) @@ -75,8 +75,8 @@ namespace Papyrus::PapyrusFunctions inline void Bind(VM& a_vm) { - BIND(IsLoaded); - logger::info("Registered IsLoaded"sv); + BIND(Load); + logger::info("Registered Load"sv); BIND(GetArtifactCount); logger::info("Registered GetArtifactCount"sv); BIND(RescanStoredArtifacts); diff --git a/Source/Scripts/ArtifactTrackerPlayer.psc b/Source/Scripts/ArtifactTrackerPlayer.psc index 04bd35a..1641dd9 100644 --- a/Source/Scripts/ArtifactTrackerPlayer.psc +++ b/Source/Scripts/ArtifactTrackerPlayer.psc @@ -22,7 +22,7 @@ endevent Event OnPlayerLoadGame() - if ! IsLoaded() + if ! Load() ETR_ItemsNew.Revert() ETR_ItemsFound.Revert() ETR_ItemsStored.Revert() @@ -166,7 +166,7 @@ endstate ; NATIVE FUNCTIONS -bool function IsLoaded() native global +bool function Load() native global int function GetArtifactCount() native global