diff --git a/SKSE/Plugins/ArtifactTracker.dll b/SKSE/Plugins/ArtifactTracker.dll index 65f3e4b..07b58d3 100644 Binary files a/SKSE/Plugins/ArtifactTracker.dll and b/SKSE/Plugins/ArtifactTracker.dll differ diff --git a/Source/ArtifactTrackerDLL/.clang-format b/Source/ArtifactTrackerDLL/.clang-format index a74ee9e..baf5bb7 100644 --- a/Source/ArtifactTrackerDLL/.clang-format +++ b/Source/ArtifactTrackerDLL/.clang-format @@ -44,7 +44,7 @@ BraceWrapping: SplitEmptyNamespace: 'false' BreakBeforeBinaryOperators: None BreakBeforeBraces: Custom -BreakBeforeTernaryOperators: 'false' +BreakBeforeTernaryOperators: 'true' BreakConstructorInitializers: AfterColon BreakInheritanceList: AfterColon BreakStringLiterals: 'true' diff --git a/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp b/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp index b9caf19..1b36612 100644 --- a/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp +++ b/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp @@ -186,7 +186,7 @@ namespace ArtifactTracker RE::TESObjectCELL* cell = RE::TESForm::LookupByID(a_formID); RE::BGSLocation* location = cell ? cell->GetLocation() : nullptr; - if (!cell || !cell->IsInteriorCell() || !location || !location->HasKeyword(g_homeKeyword)) { + if (!cell || !location || !cell->IsInteriorCell() || !location->HasKeyword(g_homeKeyword)) { if (IsHome()) { RE::ScriptEventSourceHolder::GetSingleton()->RemoveEventSink(EventListener::GetSingleton()); ToggleHomeMode(nullptr); @@ -373,16 +373,8 @@ namespace ArtifactTracker return; } - } else if (g_cellStorage) { // probably, picked up at home (can also be crafted, but oh well) - - // OnContainerChanged fires before a picked item gets marked for deletion - const auto crosshairObj = RE::CrosshairPickData::GetSingleton()->target; - if (crosshairObj && crosshairObj.get() && crosshairObj.get().get()->GetBaseObject()->formID == a_event->baseObj) { - // Picked up items are handled in the perk - return; - } - - SyncCellStorage(); + } else if (g_cellStorage) { + // Items picked up at home are handled in the perk return; } @@ -425,7 +417,8 @@ namespace ArtifactTracker return; } - if (!RefHasItem(RE::PlayerCharacter::GetSingleton(), form->formID) && !FollowersHaveItem(form)) { + // NB: During OnContainerChanged, InventoryChanges do not have the current change included yet + if ((GetItemCount(RE::PlayerCharacter::GetSingleton(), form->formID) - a_event->itemCount <= 0) && GetFollowerItemCount(form->formID) <= 0) { ListRemoveItem(g_listFound, form); ListRemoveItem(g_listNew, form); g_listNew->AddForm(form); @@ -462,8 +455,9 @@ namespace ArtifactTracker g_listStored->AddForm(form); } } - - } else if (g_listFound->HasForm(form) && !RefHasItem(RE::PlayerCharacter::GetSingleton(), form->formID) && !FollowersHaveItem(form)) { + + // NB: During OnContainerChanged, InventoryChanges do not have the current change included yet + } else if (g_listFound->HasForm(form) && (GetItemCount(RE::PlayerCharacter::GetSingleton(), form->formID) - a_event->itemCount <= 0) && GetFollowerItemCount(form->formID) <= 0) { ListRemoveItem(g_listFound, form); g_listNew->AddForm(form); } diff --git a/Source/ArtifactTrackerDLL/src/Main.cpp b/Source/ArtifactTrackerDLL/src/Main.cpp index b1760cb..0f27fb0 100644 --- a/Source/ArtifactTrackerDLL/src/Main.cpp +++ b/Source/ArtifactTrackerDLL/src/Main.cpp @@ -1,7 +1,6 @@ #include "Papyrus.h" #include "ArtifactTracker.h" -using namespace RE::BSScript; using namespace SKSE; using namespace SKSE::log; using namespace SKSE::stl; diff --git a/Source/ArtifactTrackerDLL/src/Util.h b/Source/ArtifactTrackerDLL/src/Util.h index fa13069..a875a9f 100644 --- a/Source/ArtifactTrackerDLL/src/Util.h +++ b/Source/ArtifactTrackerDLL/src/Util.h @@ -14,6 +14,38 @@ inline void ListRevert(RE::BGSListForm* a_form) return func(a_form); } +inline std::int32_t GetItemCount(RE::TESObjectREFR* a_container, RE::FormID a_formID) +{ + std::int32_t iResult = 0; + + auto invChanges = a_container->GetInventoryChanges(); + if (invChanges && invChanges->entryList) { + for (auto& entry : *invChanges->entryList) { + if (entry && entry->object && entry->object->formID == a_formID) { + if (entry->IsLeveled()) { + return entry->countDelta > 0 ? entry->countDelta : 0; + } else { + iResult = entry->countDelta; + break; + } + } + } + } + + auto container = a_container->GetContainer(); + if (container) { + container->ForEachContainerObject([&](RE::ContainerObject& a_entry) { + if (a_entry.obj->formID == a_formID) { + iResult += a_entry.count; + return false; + } + return true; + }); + } + + return iResult > 0 ? iResult : 0; +} + inline bool RefHasItem(RE::TESForm* a_refOrList, RE::FormID a_formID) { if (!a_refOrList || !a_formID) { @@ -24,15 +56,7 @@ inline bool RefHasItem(RE::TESForm* a_refOrList, RE::FormID a_formID) const auto refr = a_refOrList->As(); if (refr) { - const auto invChanges = refr->GetInventoryChanges(); - if (invChanges && invChanges->entryList) { - for (auto& entry : *invChanges->entryList) { - if (entry && entry->object && entry->object->formID == a_formID) { - return entry->countDelta > 0; - } - } - } - return false; + return GetItemCount(refr, a_formID) > 0; } const auto list = a_refOrList->As(); @@ -48,19 +72,19 @@ inline bool RefHasItem(RE::TESForm* a_refOrList, RE::FormID a_formID) return false; } -inline bool FollowersHaveItem(RE::TESForm* a_form) +inline std::uint32_t GetFollowerItemCount(RE::FormID a_formID) { + std::int32_t iResult = 0; + if (const auto processLists = RE::ProcessLists::GetSingleton(); processLists) { for (auto& actorHandle : processLists->highActorHandles) { if (auto actor = actorHandle.get(); actor && actor->IsPlayerTeammate()) { - if (RefHasItem(actor->As(), a_form->formID)) { - return true; - } + iResult += GetItemCount(actor->As(), a_formID); } } } - return false; -} \ No newline at end of file + return iResult; +}