diff --git a/SKSE/Plugins/ArtifactTracker.dll b/SKSE/Plugins/ArtifactTracker.dll index 652c2b3..7cafb52 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 3bff73f..c8cad76 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 a7a2e80..4582a40 100644 --- a/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp +++ b/Source/ArtifactTrackerDLL/src/ArtifactTracker.cpp @@ -18,6 +18,7 @@ namespace ArtifactTracker std::unordered_set g_artifactFormTypes; std::unordered_map g_persistentMap; RE::TESObjectREFR* g_cellStorage; + std::uint32_t g_iFollowerIndex; bool Init(bool bKID) { @@ -628,4 +629,48 @@ namespace ArtifactTracker } } } + + // From po3's Papyrus Extender + std::vector GetPlayerFollowers() + { + std::vector result; + + if (const auto processLists = RE::ProcessLists::GetSingleton(); processLists) { + for (auto& actorHandle : processLists->highActorHandles) { + if (auto actor = actorHandle.get(); actor && actor->IsPlayerTeammate()) { + result.push_back(actor.get()); + } + } + } + + return result; + } + + void RescanFoundArtifacts() + { + ListRevert(g_listFound); + AddRefArtifactsToList(RE::PlayerCharacter::GetSingleton(), g_listFound, g_listStored); + + for (const auto& ref : GetPlayerFollowers()) { + AddRefArtifactsToList(ref, g_listFound, g_listStored); + } + } + + void OnLocationChange() + { + std::uint32_t iCurrentFollowers; + + for (const auto& actor : GetPlayerFollowers()) { + iCurrentFollowers += actor->formID; + } + + if (iCurrentFollowers != g_iFollowerIndex) { + g_iFollowerIndex = iCurrentFollowers; + std::thread([]() { + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); // wait for followers to load into the new cell + RE::DebugNotification("Team changed, rescanning the found list"); + RescanFoundArtifacts(); + }).detach(); + } + } } diff --git a/Source/ArtifactTrackerDLL/src/ArtifactTracker.h b/Source/ArtifactTrackerDLL/src/ArtifactTracker.h index 13df36b..dada79f 100644 --- a/Source/ArtifactTrackerDLL/src/ArtifactTracker.h +++ b/Source/ArtifactTrackerDLL/src/ArtifactTracker.h @@ -37,4 +37,6 @@ namespace ArtifactTracker void OnContainerChanged(const RE::TESContainerChangedEvent* a_event, RE::TESForm* form); void AddRefArtifactsToList(RE::TESForm* a_refOrList, RE::BGSListForm* a_targetList, RE::BGSListForm* a_excludeList = NULL); + + void OnLocationChange(); } diff --git a/Source/ArtifactTrackerDLL/src/EventListener.cpp b/Source/ArtifactTrackerDLL/src/EventListener.cpp index 4a3d367..bfe36b5 100644 --- a/Source/ArtifactTrackerDLL/src/EventListener.cpp +++ b/Source/ArtifactTrackerDLL/src/EventListener.cpp @@ -12,6 +12,7 @@ void EventListener::Install() { RE::PlayerCharacter::GetSingleton()->AddEventSink(EventListener::GetSingleton()); RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink(EventListener::GetSingleton()); + RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink(EventListener::GetSingleton()); } auto EventListener::ProcessEvent( @@ -106,3 +107,15 @@ auto EventListener::ProcessEvent( return RE::BSEventNotifyControl::kContinue; } + +auto EventListener::ProcessEvent( + const RE::TESActorLocationChangeEvent* a_event, + RE::BSTEventSource* a_eventSource) + -> RE::BSEventNotifyControl +{ + if (a_event->actor->IsPlayerRef()) { + ArtifactTracker::OnLocationChange(); + } + + return RE::BSEventNotifyControl::kContinue; +} diff --git a/Source/ArtifactTrackerDLL/src/EventListener.h b/Source/ArtifactTrackerDLL/src/EventListener.h index b1b00dc..d64623c 100644 --- a/Source/ArtifactTrackerDLL/src/EventListener.h +++ b/Source/ArtifactTrackerDLL/src/EventListener.h @@ -6,7 +6,8 @@ class EventListener : public RE::BSTEventSink, public RE::BSTEventSink, public RE::BSTEventSink, - public RE::BSTEventSink + public RE::BSTEventSink, + public RE::BSTEventSink { public: ~EventListener() = default; @@ -48,6 +49,11 @@ public: RE::BSTEventSource* a_eventSource) -> RE::BSEventNotifyControl override; + auto ProcessEvent( + const RE::TESActorLocationChangeEvent* a_event, + RE::BSTEventSource* a_eventSource) + -> RE::BSEventNotifyControl override; + private: EventListener() = default; }; \ No newline at end of file diff --git a/Source/Scripts/ArtifactTrackerPlayer.psc b/Source/Scripts/ArtifactTrackerPlayer.psc index 1a8a322..e811190 100644 --- a/Source/Scripts/ArtifactTrackerPlayer.psc +++ b/Source/Scripts/ArtifactTrackerPlayer.psc @@ -4,7 +4,6 @@ FormList Property ETR_ItemsNew Auto FormList Property ETR_ItemsFound Auto FormList Property ETR_ItemsStored Auto -int iFollowerIndex = 0 int iArtifactCount = 0 @@ -58,32 +57,6 @@ Event OnPlayerLoadGame() EndEvent -Event OnLocationChange(Location akOldLoc, Location akNewLoc) - - int iCurrentFollowers = 0; - Actor[] aFollowers = GetPlayerFollowers() - int i = aFollowers.length - while i > 0 - i -= 1 - iCurrentFollowers += aFollowers[i].GetFormID() - endwhile - - if iCurrentFollowers != iFollowerIndex - iFollowerIndex = iCurrentFollowers - RegisterForSingleUpdate(5.0) ; wait until followers load into the location - endif - -endEvent - - -Event OnUpdate() - - Debug.Notification("Team changed, updating ETR_ItemsFound") - RescanFoundArtifacts() - -EndEvent - - ; NATIVE FUNCTIONS bool function Load() native global