1

Updated to CommonLibSSE-NG 3.6 (1.6.629+ support); formlist of cells with persistent containers

This commit is contained in:
Eddoursul 2022-12-01 01:39:28 +01:00
parent 654067f863
commit 4919e92157
9 changed files with 64 additions and 37 deletions

Binary file not shown.

Binary file not shown.

View File

@ -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)

View File

@ -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<RE::FormID, RE::TESForm*> g_artifactMap;
std::unordered_set<RE::FormType> g_artifactFormTypes;
@ -52,6 +54,8 @@ namespace ArtifactTracker
g_listStored = dataHandler->LookupForm<RE::BGSListForm>(0x801, "Artifact Tracker.esp"); // ETR_ItemsStored
g_listFound = dataHandler->LookupForm<RE::BGSListForm>(0x802, "Artifact Tracker.esp"); // ETR_ItemsFound
g_persistentStorage = dataHandler->LookupForm<RE::BGSListForm>(0x803, "Artifact Tracker.esp"); // ETR_PersistentStorageList
g_persistentCells = dataHandler->LookupForm<RE::BGSListForm>(0x805, "Artifact Tracker.esp"); // ETR_PersistentCellList
g_persistentCellStorageList = dataHandler->LookupForm<RE::BGSListForm>(0x806, "Artifact Tracker.esp"); // ETR_PersistentCellStorageList
g_homeKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xFC1A3, "Skyrim.esm"); // LocTypePlayerHouse
@ -59,7 +63,7 @@ namespace ArtifactTracker
const auto notArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xAFC111, "Update.esm"); // ETR_NotArtifact
const auto npcRaceKeyword = dataHandler->LookupForm<RE::BGSKeyword>(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<RE::TESObjectREFR>();
}
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<RE::TESObjectCELL>();
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<RE::TESObjectCELL>(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<RE::TESCellFullyLoadedEvent>(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()

View File

@ -10,7 +10,7 @@ auto EventListener::GetSingleton() -> EventListener*
void EventListener::Install()
{
RE::PlayerCharacter::GetSingleton()->AddEventSink<RE::BGSActorCellEvent>(EventListener::GetSingleton());
RE::PlayerCharacter::GetSingleton()->AsBGSActorCellEventSource()->AddEventSink<RE::BGSActorCellEvent>(EventListener::GetSingleton());
RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink<RE::TESContainerChangedEvent>(EventListener::GetSingleton());
RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink<RE::TESActorLocationChangeEvent>(EventListener::GetSingleton());
RE::UI::GetSingleton()->AddEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton());

View File

@ -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<spdlog::sinks::basic_file_sink_mt>(path->string(), true);
auto log = std::make_shared<spdlog::logger>("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;
}

View File

@ -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;
}

View File

@ -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"
]
}
]
}

View File

@ -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/",