diff --git a/Artifact Tracker.esp b/Artifact Tracker.esp index a640eff..ac24f3e 100644 Binary files a/Artifact Tracker.esp and b/Artifact Tracker.esp differ diff --git a/SKSE/Plugins/ArtifactTracker.dll b/SKSE/Plugins/ArtifactTracker.dll index 2eef3fa..ab367bf 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 b33709e..c8fdbcd 100644 --- a/Source/ArtifactTrackerDLL/CMakeLists.txt +++ b/Source/ArtifactTrackerDLL/CMakeLists.txt @@ -6,7 +6,7 @@ message("Using toolchain file ${CMAKE_TOOLCHAIN_FILE}.") ######################################################################################################################## project( ArtifactTracker - VERSION 1.0.7 + VERSION 1.0.8 DESCRIPTION "Artifact Tracker" LANGUAGES CXX) set(CMAKE_CXX_STANDARD 23) diff --git a/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp b/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp index ff229ea..f0b3ed9 100644 --- a/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp +++ b/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp @@ -22,6 +22,8 @@ namespace ArtifactTracker RE::BGSListForm* g_listStored; RE::BGSListForm* g_listFound; RE::BGSListForm* g_persistentStorage; + RE::BGSListForm* g_persistentCells; + RE::BGSListForm* g_persistentCellStorageList; RE::BGSKeyword* g_homeKeyword; std::unordered_map g_artifactMap; std::unordered_set g_artifactFormTypes; @@ -52,6 +54,8 @@ namespace ArtifactTracker g_listStored = dataHandler->LookupForm(0x801, "Artifact Tracker.esp"); // ETR_ItemsStored g_listFound = dataHandler->LookupForm(0x802, "Artifact Tracker.esp"); // ETR_ItemsFound g_persistentStorage = dataHandler->LookupForm(0x803, "Artifact Tracker.esp"); // ETR_PersistentStorageList + g_persistentCells = dataHandler->LookupForm(0x805, "Artifact Tracker.esp"); // ETR_PersistentCellList + g_persistentCellStorageList = dataHandler->LookupForm(0x806, "Artifact Tracker.esp"); // ETR_PersistentCellStorageList g_homeKeyword = dataHandler->LookupForm(0xFC1A3, "Skyrim.esm"); // LocTypePlayerHouse @@ -59,7 +63,7 @@ namespace ArtifactTracker const auto notArtifactKeyword = dataHandler->LookupForm(0xAFC111, "Update.esm"); // ETR_NotArtifact const auto npcRaceKeyword = dataHandler->LookupForm(0x13794, "Skyrim.esm"); // ActorTypeNPC - if (!g_cellContainer || !g_listNew || !g_listStored || !g_listFound || !g_persistentStorage || !g_homeKeyword || !extraArtifactKeyword || !notArtifactKeyword || !npcRaceKeyword) { + if (!g_cellContainer || !g_listNew || !g_listStored || !g_listFound || !g_persistentStorage || !g_persistentCells || !g_persistentCellStorageList || !g_homeKeyword || !extraArtifactKeyword || !notArtifactKeyword || !npcRaceKeyword) { 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; @@ -147,6 +151,7 @@ namespace ArtifactTracker EventListener::Install(); OnGameLoad(); // covers new game and coc'ing from the main menu + g_bLoaded = true; if (bKID) { @@ -202,7 +207,27 @@ namespace ArtifactTracker if (&a_exform) { g_persistentMap[a_exform.formID] = a_exform.As(); } - return true; + return RE::BSContainer::ForEachResult::kContinue; + }); + + const auto parentCell = RE::PlayerCharacter::GetSingleton()->GetParentCell(); + + ListRevert(g_persistentCellStorageList); + g_persistentCells->ForEachForm([&](RE::TESForm& a_exform) { + if (&a_exform) { + const auto cell = a_exform.As(); + if (cell && cell != parentCell) { + cell->ForEachReference([&parentCell](RE::TESObjectREFR& a_ref) { + if (&a_ref && (a_ref.formFlags & RE::TESObjectREFR::RecordFlags::kPersistent) != 0 && a_ref.GetBaseObject()->Is(RE::FormType::Container)) { + //RE::DebugNotification(a_ref.GetBaseObject()->GetName()); + g_persistentMap[a_ref.formID] = &a_ref; + g_persistentCellStorageList->AddForm(&a_ref); + } + return RE::BSContainer::ForEachResult::kContinue; + }); + } + } + return RE::BSContainer::ForEachResult::kContinue; }); std::uint32_t savedCount = g_listStored->forms.size() + g_listFound->forms.size() + g_listNew->forms.size(); @@ -362,7 +387,7 @@ namespace ArtifactTracker RE::TESObjectCELL* cell = RE::TESForm::LookupByID(a_formID); RE::BGSLocation* location = cell ? cell->GetLocation() : nullptr; - if (!cell || !location || !cell->IsInteriorCell() || !location->HasKeyword(g_homeKeyword)) { + if (!cell || !location || !cell->IsInteriorCell() || !location->HasKeyword(g_homeKeyword) || g_persistentCells->HasForm(cell)) { if (IsHome()) { RE::ScriptEventSourceHolder::GetSingleton()->RemoveEventSink(EventListener::GetSingleton()); ToggleHomeMode(nullptr); @@ -383,7 +408,7 @@ namespace ArtifactTracker cellStorage = refr; } } - return true; + return RE::BSContainer::ForEachResult::kContinue; }); #ifdef _DEBUG @@ -408,7 +433,7 @@ namespace ArtifactTracker return; } - if (!location || !cell->IsInteriorCell() || cell != RE::PlayerCharacter::GetSingleton()->GetParentCell() || !location->HasKeyword(g_homeKeyword)) { + if (!location || !cell->IsInteriorCell() || cell != RE::PlayerCharacter::GetSingleton()->GetParentCell() || !location->HasKeyword(g_homeKeyword) || g_persistentCells->HasForm(cell)) { ToggleHomeMode(nullptr); return; } @@ -424,7 +449,7 @@ namespace ArtifactTracker cellStorage = &a_ref; } } - return true; + return RE::BSContainer::ForEachResult::kContinue; }); for (int i = 0; i < dupes.size(); i++) { @@ -495,14 +520,14 @@ namespace ArtifactTracker cell->ForEachReference([&](RE::TESObjectREFR& a_ref) { if (ignoreFormID && ignoreFormID == a_ref.formID) { - return true; + return RE::BSContainer::ForEachResult::kContinue; } const auto baseObj = a_ref.GetBaseObject(); if (IsValidContainer(&a_ref)) { if (g_cellContainer == baseObj || baseObj->formID == 0xDC9E7 || g_persistentMap.contains(a_ref.formID)) { // skip persistent and PlayerBookShelfContainer - return true; + return RE::BSContainer::ForEachResult::kContinue; } const auto contInv = a_ref.GetInventory([&](RE::TESBoundObject& a_object) -> bool { @@ -523,11 +548,11 @@ namespace ArtifactTracker } } - return true; + return RE::BSContainer::ForEachResult::kContinue; } if (!g_artifactAllFormTypes.contains(baseObj->GetFormType()) || a_ref.IsDisabled() || a_ref.IsMarkedForDeletion() || cellItems.contains(baseObj->formID)) { - return true; + return RE::BSContainer::ForEachResult::kContinue; } cellItems.insert(baseObj->formID); @@ -542,7 +567,7 @@ namespace ArtifactTracker g_listStored->AddForm(baseObj); } - return true; + return RE::BSContainer::ForEachResult::kContinue; }); for (const auto& [item, data] : inv) { @@ -550,7 +575,7 @@ namespace ArtifactTracker if (count > 0 && !cellItems.contains(item->formID)) { g_cellStorage->RemoveItem(item, count, RE::ITEM_REMOVE_REASON::kRemove, nullptr, nullptr); - if (IsArtifact(item) && !RefListHasItem(g_persistentStorage, item->formID)) { + if (IsArtifact(item) && !RefListHasItem(g_persistentStorage, item->formID) && !RefListHasItem(g_persistentCellStorageList, item->formID)) { ListRemoveItem(g_listStored, item); if (GetItemCount(RE::PlayerCharacter::GetSingleton(), item) || FollowersHaveItem(item)) { ListRemoveItem(g_listNew, item); @@ -788,7 +813,7 @@ namespace ArtifactTracker if (refrItem) { AddRefArtifactsToList(refrItem, a_targetList, a_excludeList); } - return true; + return RE::BSContainer::ForEachResult::kContinue; }); return; } @@ -826,6 +851,7 @@ namespace ArtifactTracker { ListRevert(g_listStored); AddRefArtifactsToList(g_persistentStorage, g_listStored); + AddRefArtifactsToList(g_persistentCellStorageList, g_listStored); } void RescanNewArtifacts() diff --git a/Source/ArtifactTrackerDLL/src/EventListener.cpp b/Source/ArtifactTrackerDLL/src/EventListener.cpp index 6d53663..ec7f541 100644 --- a/Source/ArtifactTrackerDLL/src/EventListener.cpp +++ b/Source/ArtifactTrackerDLL/src/EventListener.cpp @@ -10,7 +10,7 @@ auto EventListener::GetSingleton() -> EventListener* void EventListener::Install() { - RE::PlayerCharacter::GetSingleton()->AddEventSink(EventListener::GetSingleton()); + RE::PlayerCharacter::GetSingleton()->AsBGSActorCellEventSource()->AddEventSink(EventListener::GetSingleton()); RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink(EventListener::GetSingleton()); RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink(EventListener::GetSingleton()); RE::UI::GetSingleton()->AddEventSink(EventListener::GetSingleton()); diff --git a/Source/ArtifactTrackerDLL/src/Main.cpp b/Source/ArtifactTrackerDLL/src/Main.cpp index 34dbbd4..26062ab 100644 --- a/Source/ArtifactTrackerDLL/src/Main.cpp +++ b/Source/ArtifactTrackerDLL/src/Main.cpp @@ -13,7 +13,8 @@ namespace { stl::report_and_fail("Failed to find standard logging directory"sv); } - *path /= "ArtifactTracker.log"sv; + *path /= PluginDeclaration::GetSingleton()->GetName(); + *path += ".log"sv; auto sink = std::make_shared(path->string(), true); auto log = std::make_shared("global log"s, std::move(sink)); @@ -28,9 +29,7 @@ namespace { void InitializeMessaging() { GetMessagingInterface()->RegisterListener([](MessagingInterface::Message* message) { - if (message->type == MessagingInterface::kPostLoad) { - SKSE::GetModCallbackEventSource()->AddEventSink(EventListener::GetSingleton()); // runs, if KID is installed - } else if (message->type == MessagingInterface::kDataLoaded) { + if (message->type == MessagingInterface::kDataLoaded) { const auto kidSE = ArtifactTracker::g_loadInterface->GetPluginInfo("po3_KeywordItemDistributor"); const auto kidAE = ArtifactTracker::g_loadInterface->GetPluginInfo("Keyword Item Distributor"); // KID 2.0 for AE has a different internal name if (!kidSE && !kidAE) { @@ -64,6 +63,8 @@ SKSEPluginLoad(const LoadInterface* skse) { ArtifactTracker::g_loadInterface = skse; + SKSE::GetModCallbackEventSource()->AddEventSink(EventListener::GetSingleton()); // runs when KID is installed + log::info("{} has finished loading.", plugin->GetName()); return true; } diff --git a/Source/ArtifactTrackerDLL/src/Util.h b/Source/ArtifactTrackerDLL/src/Util.h index 781c49b..25666f0 100644 --- a/Source/ArtifactTrackerDLL/src/Util.h +++ b/Source/ArtifactTrackerDLL/src/Util.h @@ -42,9 +42,9 @@ inline std::uint32_t GetItemCount(RE::TESObjectREFR* a_container, RE::TESForm* a container->ForEachContainerObject([&](RE::ContainerObject& a_entry) { if (a_entry.obj == a_form) { iResult += a_entry.count; - return false; + return RE::BSContainer::ForEachResult::kStop; } - return true; + return RE::BSContainer::ForEachResult::kContinue; }); } @@ -74,9 +74,9 @@ inline std::int32_t GetItemCount(RE::TESObjectREFR* a_container, RE::FormID a_fo container->ForEachContainerObject([&](RE::ContainerObject& a_entry) { if (a_entry.obj && a_entry.obj->formID == a_formID) { iResult += a_entry.count; - return false; + return RE::BSContainer::ForEachResult::kStop; } - return true; + return RE::BSContainer::ForEachResult::kContinue; }); } @@ -103,9 +103,9 @@ inline bool RefListHasItem(RE::TESForm* a_refOrList, RE::FormID a_formID) list->ForEachForm([&](RE::TESForm& a_form) { if (&a_form && RefListHasItem(&a_form, a_formID)) { bResult = true; - return false; + return RE::BSContainer::ForEachResult::kStop; } - return true; + return RE::BSContainer::ForEachResult::kContinue; }); return bResult; } diff --git a/Source/ArtifactTrackerDLL/vcpkg-configuration.json b/Source/ArtifactTrackerDLL/vcpkg-configuration.json index 337bdfa..4e73c46 100644 --- a/Source/ArtifactTrackerDLL/vcpkg-configuration.json +++ b/Source/ArtifactTrackerDLL/vcpkg-configuration.json @@ -1,15 +1,15 @@ { "registries": [ - { - "kind": "git", - "repository": "https://gitlab.com/colorglass/vcpkg-colorglass", - "baseline": "5a11d06fd1b2d7cd6339d6aea48d450309e89cc1", - "packages": [ - "commonlibsse-ng", - "gluino", - "script-extender-common", - "skse" - ] - } + { + "kind": "git", + "repository": "https://gitlab.com/colorglass/vcpkg-colorglass", + "baseline": "6fb127f7d425ae3cf3fab0f79005d907c885c0d8", + "packages": [ + "commonlibsse-ng", + "gluino", + "script-extender-common", + "skse" + ] + } ] } diff --git a/Source/ArtifactTrackerDLL/vcpkg.json b/Source/ArtifactTrackerDLL/vcpkg.json index 320276b..b633b1b 100644 --- a/Source/ArtifactTrackerDLL/vcpkg.json +++ b/Source/ArtifactTrackerDLL/vcpkg.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json", "name": "artifact-tracker", - "version-string": "1.0.7", + "version-string": "1.0.8", "port-version": 0, "description": "Artifact Tracker", "homepage": "https://eddoursul.win/mods/artifact-tracker/",