diff --git a/SKSE/Plugins/ArtifactTracker.dll b/SKSE/Plugins/ArtifactTracker.dll index ae8e490..7dba8c4 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 3c67b2f..1fe920f 100644 Binary files a/Scripts/ArtifactTrackerPlayer.pex and b/Scripts/ArtifactTrackerPlayer.pex differ diff --git a/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp b/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp index 1c598d5..04edb10 100644 --- a/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp +++ b/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp @@ -177,7 +177,7 @@ namespace ArtifactTracker g_bHomeContainer = IsHome() && refr - && refr.get()->GetParentCell() == RE::PlayerCharacter::GetSingleton()->GetParentCell() + && IsInSameCell(refr.get()) && !g_persistentMap.contains(refr.get()->formID); #ifdef _DEBUG @@ -408,10 +408,10 @@ namespace ArtifactTracker const auto ref = it->second; - if (ref && GetItemCount(ref, form) - a_event->itemCount <= 0) { // no items left in the container + if (ref && GetItemCount(ref, form) <= 0) { // no items left in the container for (const auto& persref : g_persistentMap) { if (persref.second != ref) { - if (GetItemCount(persref.second, form) > 0) { + if (GetItemCount(persref.second, form)) { // if other containers have it, do nothing return; } @@ -421,15 +421,19 @@ namespace ArtifactTracker g_listFound->AddForm(form); } - } else if (g_cellStorage && !g_bHomeContainer) { // taken from a container at home + return; - const auto container = RE::TESForm::LookupByID(a_event->oldContainer); - if (container && GetItemCount(container, form) - a_event->itemCount <= 0) { - SyncCellStorage(container->formID); + } else if (g_cellStorage) { // taken from a container at home + + if (!g_bHomeContainer) { + const auto container = RE::TESForm::LookupByID(a_event->oldContainer); + if (container && !GetItemCount(container, form)) { + SyncCellStorage(container->formID); + } } + return; } - return; } if (!g_listStored->HasForm(form) && !g_listFound->HasForm(form)) { // it's a new item, move it to found @@ -460,7 +464,7 @@ namespace ArtifactTracker } else { const auto container = ref->As(); if (container) { - if (g_cellStorage && container->GetParentCell() == RE::PlayerCharacter::GetSingleton()->GetParentCell()) { // stored at home + if (g_cellStorage && IsInSameCell(container)) { // stored at home if (!g_bHomeContainer && !g_listStored->HasForm(form)) { ListRemoveItem(g_listFound, form); @@ -468,8 +472,7 @@ namespace ArtifactTracker g_listStored->AddForm(form); } - // During OnContainerChanged, InventoryChanges do not have the current change included yet - } else if (a_event->oldContainer == 0x14 && !g_listStored->HasForm(form) && (GetItemCount(RE::PlayerCharacter::GetSingleton(), form) - a_event->itemCount <= 0) && !FollowersHaveItem(form)) { + } else if (a_event->oldContainer == 0x14 && !g_listStored->HasForm(form) && !GetItemCount(RE::PlayerCharacter::GetSingleton(), form) && !FollowersHaveItem(form)) { // disposed by player ListRemoveItem(g_listFound, form); g_listNew->AddForm(form); @@ -482,7 +485,14 @@ namespace ArtifactTracker if (g_cellStorage && a_event->reference) { // dropped or placed on rack at home by any actor - if (GetItemCount(g_cellStorage, form) <= 0) { + if (a_event->oldContainer != 0x14) { + const auto ref = RE::TESForm::LookupByID(a_event->oldContainer); + if (!ref || !IsInSameCell(ref)) { + return; + } + } + + if (!GetItemCount(g_cellStorage, form)) { #ifdef _DEBUG SKSE::log::info("Added dropped {} to cell storage", form->GetName()); RE::DebugNotification("Adding to cell storage"); @@ -496,14 +506,12 @@ namespace ArtifactTracker g_listStored->AddForm(form); } - } else if (a_event->oldContainer == 0x14) { // dropped, dismantled, consumed, removed by a script + } else if (a_event->oldContainer == 0x14) { // dropped, consumed, dismantle, removed by script if (!g_listStored->HasForm(form)) { - if ((GetItemCount(RE::PlayerCharacter::GetSingleton(), form) - a_event->itemCount <= 0) && !FollowersHaveItem(form)) { - if (g_listFound->HasForm(form)) { - ListRemoveItem(g_listFound, form); - g_listNew->AddForm(form); - } + if (!GetItemCount(RE::PlayerCharacter::GetSingleton(), form) && !FollowersHaveItem(form)) { + ListRemoveItem(g_listFound, form); + g_listNew->AddForm(form); } else if (!g_listFound->HasForm(form)) { ListRemoveItem(g_listNew, form); @@ -518,10 +526,10 @@ namespace ArtifactTracker const auto ref = it->second; - if (ref && GetItemCount(ref, form) - a_event->itemCount <= 0) { // no items left in the container + if (ref && !GetItemCount(ref, form)) { // no items left in the container for (const auto& persref : g_persistentMap) { if (persref.second != ref) { - if (GetItemCount(persref.second, form) > 0) { + if (GetItemCount(persref.second, form)) { // if other containers have it, do nothing return; } @@ -539,15 +547,15 @@ namespace ArtifactTracker const auto ref = RE::TESForm::LookupByID(a_event->oldContainer); if (ref->Is(RE::FormType::ActorCharacter)) { - if (ref->As()->IsPlayerTeammate() && GetItemCount(ref->As(), form) - a_event->itemCount <= 0) { // removed from companion (probably, disarmed) + if (ref->As()->IsPlayerTeammate() && GetItemCount(ref->As(), form) <= 0) { // removed from companion (probably, disarmed) if (!g_listStored->HasForm(form) && g_listFound->HasForm(form)) { - if (GetItemCount(RE::PlayerCharacter::GetSingleton(), form) <= 0) { + if (!GetItemCount(RE::PlayerCharacter::GetSingleton(), form)) { // player does not have it, check companions if (const auto processLists = RE::ProcessLists::GetSingleton(); processLists) { for (auto& actorHandle : processLists->highActorHandles) { if (auto actor = actorHandle.get(); actor && actor->IsPlayerTeammate() && actor->formID != ref->formID) { - if (GetItemCount(actor.get(), form) > 0) { + if (GetItemCount(actor.get(), form)) { // other companion has it, do nothing return; } @@ -564,9 +572,9 @@ namespace ArtifactTracker } else { const auto container = ref->As(); if (container) { - if (g_cellStorage && container->GetParentCell() == RE::PlayerCharacter::GetSingleton()->GetParentCell()) { // deleted from container at home + if (g_cellStorage && IsInSameCell(container)) { // deleted from container at home - if (GetItemCount(container, form) - a_event->itemCount <= 0) { + if (!GetItemCount(container, form)) { SyncCellStorage(container->formID); } diff --git a/Source/ArtifactTrackerDLL/src/Util.h b/Source/ArtifactTrackerDLL/src/Util.h index 7def5bb..67e8d41 100644 --- a/Source/ArtifactTrackerDLL/src/Util.h +++ b/Source/ArtifactTrackerDLL/src/Util.h @@ -14,7 +14,7 @@ inline void ListRevert(RE::BGSListForm* a_form) return func(a_form); } -inline std::int32_t GetItemCount(RE::TESObjectREFR* a_container, RE::TESForm* a_form) +inline std::uint32_t GetItemCount(RE::TESObjectREFR* a_container, RE::TESForm* a_form) { std::int32_t iResult = 0; @@ -124,3 +124,8 @@ inline bool FollowersHaveItem(RE::TESForm* a_form) return false; } + +inline bool IsInSameCell(RE::TESObjectREFR* ref) +{ + return ref && (ref->GetParentCell() == RE::PlayerCharacter::GetSingleton()->GetParentCell()); +} diff --git a/Source/Scripts/ArtifactTrackerPlayer.psc b/Source/Scripts/ArtifactTrackerPlayer.psc index 1091c9d..04bd35a 100644 --- a/Source/Scripts/ArtifactTrackerPlayer.psc +++ b/Source/Scripts/ArtifactTrackerPlayer.psc @@ -15,6 +15,7 @@ int iArtifactCount = 0 event OnInit() + Utility.wait(3.0) ; wait for quickstart scripts to finish OnPlayerLoadGame() endevent