1

All moving parts have been moved to the DLL

This commit is contained in:
Eddoursul 2022-07-11 13:41:07 +02:00
parent 77ef7c15da
commit e836f4134d
14 changed files with 143 additions and 1320 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -24,7 +24,6 @@ configure_file(
set(sources set(sources
src/Main.cpp src/Main.cpp
src/Papyrus.cpp
src/ArtifactTracker.cpp src/ArtifactTracker.cpp
src/EventListener.cpp src/EventListener.cpp
src/BookCheck.cpp src/BookCheck.cpp

View File

@ -3,6 +3,9 @@
#include "EventListener.h" #include "EventListener.h"
#include "Util.h" #include "Util.h"
using namespace SKSE;
using namespace SKSE::log;
namespace ArtifactTracker namespace ArtifactTracker
{ {
bool g_bLoaded; bool g_bLoaded;
@ -18,7 +21,8 @@ namespace ArtifactTracker
std::unordered_set<RE::FormType> g_artifactFormTypes; std::unordered_set<RE::FormType> g_artifactFormTypes;
std::unordered_map<RE::FormID, RE::TESObjectREFR*> g_persistentMap; std::unordered_map<RE::FormID, RE::TESObjectREFR*> g_persistentMap;
RE::TESObjectREFR* g_cellStorage; RE::TESObjectREFR* g_cellStorage;
std::uint32_t g_iFollowerIndex; const SKSE::LoadInterface* g_loadInterface;
std::int32_t g_iFollowerIndex;
bool Init(bool bKID) bool Init(bool bKID)
{ {
@ -26,36 +30,36 @@ namespace ArtifactTracker
return true; return true;
} }
SKSE::GetModCallbackEventSource()->RemoveEventSink(EventListener::GetSingleton());
const auto dataHandler = RE::TESDataHandler::GetSingleton(); const auto dataHandler = RE::TESDataHandler::GetSingleton();
if (!dataHandler) { if (!dataHandler) {
SKSE::log::error("Unable to call RE::TESDataHandler::GetSingleton()"); // Called before kDataLoaded?
RE::DebugMessageBox("Unable to initialize Artifact Tracker."); log::error("RE::TESDataHandler is not initialized.");
return false; return false;
} }
g_cellContainer = dataHandler->LookupForm(0x800, "Artifact Tracker.esp")->As<RE::TESBoundObject>(); // ETR_CellStorageContainer SKSE::GetModCallbackEventSource()->RemoveEventSink(EventListener::GetSingleton());
g_listNew = dataHandler->LookupForm<RE::BGSListForm>(0x803, "Artifact Tracker.esp"); // ETR_ItemsNew g_cellContainer = dataHandler->LookupForm(0x804, "Artifact Tracker.esp")->As<RE::TESBoundObject>(); // ETR_CellStorageContainer
g_listStored = dataHandler->LookupForm<RE::BGSListForm>(0x805, "Artifact Tracker.esp"); // ETR_ItemsStored
g_listFound = dataHandler->LookupForm<RE::BGSListForm>(0x806, "Artifact Tracker.esp"); // ETR_ItemsFound g_listNew = dataHandler->LookupForm<RE::BGSListForm>(0x800, "Artifact Tracker.esp"); // ETR_ItemsNew
g_persistentStorage = dataHandler->LookupForm<RE::BGSListForm>(0x807, "Artifact Tracker.esp"); // ETR_PersistentStorageList 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_homeKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xFC1A3, "Skyrim.esm"); // LocTypePlayerHouse g_homeKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xFC1A3, "Skyrim.esm"); // LocTypePlayerHouse
const auto extraArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xAFC11A, "Update.esm"); // ETR_ExtraArtifact const auto extraArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xAFC110, "Update.esm"); // ETR_ExtraArtifact
const auto notArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xAFC11C, "Update.esm"); // ETR_NotArtifact const auto notArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xAFC111, "Update.esm"); // ETR_NotArtifact
const auto npcRaceKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0x13794, "Skyrim.esm"); // ActorTypeNPC 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_homeKeyword || !extraArtifactKeyword || !notArtifactKeyword || !npcRaceKeyword) {
SKSE::log::warn("Unable to load data from Artifact Tracker.esp"); log::warn("Unable to load data from Artifact Tracker.esp");
RE::DebugMessageBox("Unable to load data from Artifact Tracker.esp, the mod is disabled."); RE::DebugMessageBox("Unable to load data from Artifact Tracker.esp, the mod is disabled.");
return false; return false;
} }
std::map<std::string, bool> settings { std::map<std::string, bool> settings{
{ "DumpItemList", false }, { "DumpItemList", false },
}; };
LoadINI(&settings, "Data/SKSE/Plugins/ArtifactTracker.ini"); LoadINI(&settings, "Data/SKSE/Plugins/ArtifactTracker.ini");
@ -121,15 +125,15 @@ namespace ArtifactTracker
} }
} }
OnGameLoad();
EventListener::Install(); EventListener::Install();
OnGameLoad(); // covers new game and coc'ing from the main menu
g_bLoaded = true; g_bLoaded = true;
SKSE::log::info("Total artifacts: {}", g_artifactMap.size()); log::info("Total artifacts: {}", g_artifactMap.size());
if (settings.at("DumpItemList")) { if (settings.at("DumpItemList")) {
for (const auto& item : g_artifactMap) { for (const auto& item : g_artifactMap) {
SKSE::log::info("[{:08X}] {}", item.second->formID, item.second->GetName()); log::info("[{:08X}] {}", item.second->formID, item.second->GetName());
} }
} }
@ -154,7 +158,7 @@ namespace ArtifactTracker
void OnGameLoad() void OnGameLoad()
{ {
#ifdef _DEBUG #ifdef _DEBUG
SKSE::log::info("OnGameLoad"); log::info("OnGameLoad");
#endif #endif
g_persistentMap.clear(); g_persistentMap.clear();
@ -164,6 +168,70 @@ namespace ArtifactTracker
} }
return true; return true;
}); });
if (g_listStored->forms.size() + g_listFound->forms.size() + g_listNew->forms.size() != g_artifactMap.size()) {
log::info("Reverting g_listNew");
ListRevert(g_listNew);
}
RescanStoredArtifacts();
RescanFoundArtifacts();
RescanNewArtifacts();
const auto vm = RE::BSScript::Internal::VirtualMachine::GetSingleton();
RE::BSTSmartPointer<RE::BSScript::IStackCallbackFunctor> stackCallback;
if (const auto pluginInfo = g_loadInterface->GetPluginInfo("Ahzaab's moreHUD Plugin"); pluginInfo) {
if (!g_bLoaded) log::info("Detected {} v{}", pluginInfo->name, pluginInfo->version);
if (pluginInfo->version == 0) {
log::error("MoreHUD has not been detected.");
} else if (pluginInfo->version < 30800) {
log::error("MoreHUD is outdated.");
} else if (vm->TypeIsValid("AhzMoreHud")) {
if (!g_bLoaded) log::info("Registering icons in MoreHUD...");
vm->DispatchStaticCall("AhzMoreHud", "RegisterIconFormList", RE::MakeFunctionArguments<RE::BSString, RE::BGSListForm*>("dbmNew", std::move(g_listNew)), stackCallback);
vm->DispatchStaticCall("AhzMoreHud", "RegisterIconFormList", RE::MakeFunctionArguments<RE::BSString, RE::BGSListForm*>("dbmFound", std::move(g_listFound)), stackCallback);
vm->DispatchStaticCall("AhzMoreHud", "RegisterIconFormList", RE::MakeFunctionArguments<RE::BSString, RE::BGSListForm*>("dbmDisp", std::move(g_listStored)), stackCallback);
} else {
log::error("MoreHUD has not been installed correctly.");
}
} else if (!g_bLoaded) {
log::error("MoreHUD has not been detected.");
}
if (const auto pluginInfo = g_loadInterface->GetPluginInfo("Ahzaab's moreHUD Inventory Plugin"); pluginInfo) {
if (!g_bLoaded) log::info("Detected {} v{}", pluginInfo->name, pluginInfo->version);
if (pluginInfo->version == 0) {
log::error("MoreHUD Inventory Edition has not been detected.");
} else if (pluginInfo->version < 10017) {
log::error("MoreHUD Inventory Edition is outdated.");
} else if (vm->TypeIsValid("AhzMoreHudIE")) {
if (!g_bLoaded) log::info("Registering icons in MoreHUD Inventory Edition...");
vm->DispatchStaticCall("AhzMoreHudIE", "RegisterIconFormList", RE::MakeFunctionArguments<RE::BSString, RE::BGSListForm*>("dbmNew", std::move(g_listNew)), stackCallback);
vm->DispatchStaticCall("AhzMoreHudIE", "RegisterIconFormList", RE::MakeFunctionArguments<RE::BSString, RE::BGSListForm*>("dbmFound", std::move(g_listFound)), stackCallback);
vm->DispatchStaticCall("AhzMoreHudIE", "RegisterIconFormList", RE::MakeFunctionArguments<RE::BSString, RE::BGSListForm*>("dbmDisp", std::move(g_listStored)), stackCallback);
} else {
log::error("MoreHUD Inventory Edition has not been installed correctly.");
}
} else if (!g_bLoaded) {
log::error("MoreHUD Inventory Edition has not been detected.");
}
if (const auto pluginInfo = g_loadInterface->GetPluginInfo("QuickLootEE"); pluginInfo) {
if (!g_bLoaded) log::info("Detected {} v{}", pluginInfo->name, pluginInfo->version);
if (pluginInfo->version == 0) {
log::error("QuickLoot EE has not been detected.");
} else if (vm->TypeIsValid("QuickLootEE")) {
if (!g_bLoaded) log::info("Registering icons with QuickLootEE...");
vm->DispatchStaticCall("QuickLootEE", "RegisterNewItemsList", RE::MakeFunctionArguments<RE::BGSListForm*>(std::move(g_listNew)), stackCallback);
vm->DispatchStaticCall("QuickLootEE", "RegisterFoundItemsList", RE::MakeFunctionArguments<RE::BGSListForm*>(std::move(g_listFound)), stackCallback);
vm->DispatchStaticCall("QuickLootEE", "RegisterDisplayedItemsList", RE::MakeFunctionArguments<RE::BGSListForm*>(std::move(g_listStored)), stackCallback);
} else {
log::error("QuickLoot EE has not been installed correctly.");
}
} else if (!g_bLoaded) {
log::error("QuickLoot EE has not been detected.");
}
} }
void SetContainerMode(const bool bOpening) void SetContainerMode(const bool bOpening)
@ -213,7 +281,7 @@ namespace ArtifactTracker
RE::UI::GetSingleton()->AddEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton()); RE::UI::GetSingleton()->AddEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton());
RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink<RE::TESActivateEvent>(EventListener::GetSingleton()); RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink<RE::TESActivateEvent>(EventListener::GetSingleton());
#ifdef _DEBUG #ifdef _DEBUG
SKSE::log::info("Home mode ON"); log::info("Home mode ON");
#endif #endif
return true; return true;
} else if (g_cellStorage) { } else if (g_cellStorage) {
@ -222,7 +290,7 @@ namespace ArtifactTracker
RE::UI::GetSingleton()->RemoveEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton()); RE::UI::GetSingleton()->RemoveEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton());
RE::ScriptEventSourceHolder::GetSingleton()->RemoveEventSink<RE::TESActivateEvent>(EventListener::GetSingleton()); RE::ScriptEventSourceHolder::GetSingleton()->RemoveEventSink<RE::TESActivateEvent>(EventListener::GetSingleton());
#ifdef _DEBUG #ifdef _DEBUG
SKSE::log::info("Home mode OFF"); log::info("Home mode OFF");
#endif #endif
} }
return false; return false;
@ -236,7 +304,7 @@ namespace ArtifactTracker
const auto baseObj = a_ref->GetBaseObject(); const auto baseObj = a_ref->GetBaseObject();
return baseObj->formType == RE::FormType::Container || (baseObj->formType == RE::FormType::NPC && !a_ref->IsDisabled() && baseObj->As<RE::TESNPC>()->GetRace()->formID == 0x0010760A); return baseObj->formType == RE::FormType::Container || (baseObj->formType == RE::FormType::NPC && !a_ref->IsDisabled() && baseObj->As<RE::TESNPC>()->GetRace()->formID == 0x10760A);
} }
void OnCellEnter(const RE::FormID a_formID) void OnCellEnter(const RE::FormID a_formID)
@ -292,11 +360,12 @@ namespace ArtifactTracker
g_persistentMap[cellStorage->formID] = cellStorage; g_persistentMap[cellStorage->formID] = cellStorage;
} }
ToggleHomeMode(cellStorage); ToggleHomeMode(cellStorage);
SyncCellStorage();
return; return;
} }
#ifdef _DEBUG #ifdef _DEBUG
SKSE::log::info("Adding new storage in {}", cell->GetName()); log::info("Adding new storage in {}", cell->GetName());
#endif #endif
cellStorage = RE::PlayerCharacter::GetSingleton()->PlaceObjectAtMe(g_cellContainer, true).get(); cellStorage = RE::PlayerCharacter::GetSingleton()->PlaceObjectAtMe(g_cellContainer, true).get();
@ -308,7 +377,7 @@ namespace ArtifactTracker
ToggleHomeMode(cellStorage); ToggleHomeMode(cellStorage);
SyncCellStorage(); SyncCellStorage();
} else { } else {
SKSE::log::error("Failed to create cell storage in OnCellEnter"); log::error("Failed to create cell storage in OnCellEnter");
ToggleHomeMode(nullptr); ToggleHomeMode(nullptr);
} }
} }
@ -317,13 +386,13 @@ namespace ArtifactTracker
{ {
if (!IsHome()) { if (!IsHome()) {
#ifdef _DEBUG #ifdef _DEBUG
SKSE::log::info("SyncCellStorage called while not at home"); log::info("SyncCellStorage called while not at home");
#endif #endif
return; return;
} }
#ifdef _DEBUG #ifdef _DEBUG
SKSE::log::info("Running SyncCellStorage"); log::info("Running SyncCellStorage");
#endif #endif
std::unordered_set<RE::FormID> cellItems; std::unordered_set<RE::FormID> cellItems;
@ -339,7 +408,7 @@ namespace ArtifactTracker
const auto baseObj = a_ref->GetBaseObject(); const auto baseObj = a_ref->GetBaseObject();
if (IsValidContainer(a_ref.get())) { if (IsValidContainer(a_ref.get())) {
if (g_cellContainer->formID == baseObj->formID || baseObj->formID == 0xDC9E7 || g_persistentMap.contains(a_ref->formID)) { // skip persistent and PlayerBookShelfContainer if (g_cellContainer == baseObj || baseObj->formID == 0xDC9E7 || g_persistentMap.contains(a_ref->formID)) { // skip persistent and PlayerBookShelfContainer
continue; continue;
} }
@ -501,7 +570,7 @@ namespace ArtifactTracker
if (!GetItemCount(g_cellStorage, form)) { if (!GetItemCount(g_cellStorage, form)) {
#ifdef _DEBUG #ifdef _DEBUG
SKSE::log::info("Added dropped {} to cell storage", form->GetName()); log::info("Added dropped {} to cell storage", form->GetName());
RE::DebugNotification("Adding to cell storage"); RE::DebugNotification("Adding to cell storage");
#endif #endif
g_cellStorage->AddObjectToContainer(form->As<RE::TESBoundObject>(), nullptr, 1, nullptr); g_cellStorage->AddObjectToContainer(form->As<RE::TESBoundObject>(), nullptr, 1, nullptr);
@ -596,7 +665,7 @@ namespace ArtifactTracker
void AddRefArtifactsToList(RE::TESForm* a_refOrList, RE::BGSListForm* a_targetList, RE::BGSListForm* a_excludeList) void AddRefArtifactsToList(RE::TESForm* a_refOrList, RE::BGSListForm* a_targetList, RE::BGSListForm* a_excludeList)
{ {
if (!a_refOrList || !a_targetList) { if (!a_refOrList || !a_targetList) {
SKSE::log::warn("Invalid arguments in AddRefArtifactsToList"); log::warn("Invalid arguments in AddRefArtifactsToList");
return; return;
} }
@ -614,7 +683,7 @@ namespace ArtifactTracker
const auto containerRef = a_refOrList->As<RE::TESObjectREFR>(); const auto containerRef = a_refOrList->As<RE::TESObjectREFR>();
if (!containerRef) { if (!containerRef) {
SKSE::log::warn("containerRef in AddRefArtifactsToList is not a reference"); log::warn("containerRef in AddRefArtifactsToList is not a reference");
return; return;
} }
@ -630,22 +699,6 @@ namespace ArtifactTracker
} }
} }
// From po3's Papyrus Extender
std::vector<RE::Actor*> GetPlayerFollowers()
{
std::vector<RE::Actor*> 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() void RescanFoundArtifacts()
{ {
ListRevert(g_listFound); ListRevert(g_listFound);
@ -656,9 +709,24 @@ namespace ArtifactTracker
} }
} }
void RescanStoredArtifacts()
{
ListRevert(g_listStored);
AddRefArtifactsToList(g_persistentStorage, g_listStored);
}
void RescanNewArtifacts()
{
for (auto const& item : g_artifactMap) {
if (!g_listNew->HasForm(item.second) && !g_listStored->HasForm(item.second) && !g_listFound->HasForm(item.second)) {
g_listNew->AddForm(item.second);
}
}
}
void OnLocationChange() void OnLocationChange()
{ {
std::uint32_t iCurrentFollowers; std::uint32_t iCurrentFollowers = 0;
for (const auto& actor : GetPlayerFollowers()) { for (const auto& actor : GetPlayerFollowers()) {
iCurrentFollowers += actor->formID; iCurrentFollowers += actor->formID;

View File

@ -15,6 +15,7 @@ namespace ArtifactTracker
extern std::unordered_set<RE::FormType> g_artifactFormTypes; extern std::unordered_set<RE::FormType> g_artifactFormTypes;
extern std::unordered_map<RE::FormID, RE::TESObjectREFR*> g_persistentMap; extern std::unordered_map<RE::FormID, RE::TESObjectREFR*> g_persistentMap;
extern RE::TESObjectREFR* g_cellStorage; extern RE::TESObjectREFR* g_cellStorage;
extern const SKSE::LoadInterface* g_loadInterface;
bool Init(bool bKID = false); bool Init(bool bKID = false);
@ -39,4 +40,10 @@ namespace ArtifactTracker
void AddRefArtifactsToList(RE::TESForm* a_refOrList, RE::BGSListForm* a_targetList, RE::BGSListForm* a_excludeList = NULL); void AddRefArtifactsToList(RE::TESForm* a_refOrList, RE::BGSListForm* a_targetList, RE::BGSListForm* a_excludeList = NULL);
void OnLocationChange(); void OnLocationChange();
void RescanFoundArtifacts();
void RescanStoredArtifacts();
void RescanNewArtifacts();
} }

View File

@ -1,4 +1,3 @@
#include "Papyrus.h"
#include "ArtifactTracker.h" #include "ArtifactTracker.h"
#include "EventListener.h" #include "EventListener.h"
@ -50,7 +49,7 @@ SKSEPluginLoad(const LoadInterface* skse) {
Init(skse); Init(skse);
InitializeMessaging(); InitializeMessaging();
SKSE::GetPapyrusInterface()->Register(Papyrus::Bind); ArtifactTracker::g_loadInterface = skse;
log::info("{} has finished loading.", plugin->GetName()); log::info("{} has finished loading.", plugin->GetName());
return true; return true;

View File

@ -1,19 +0,0 @@
#include "Papyrus.h"
#include "PapyrusFunctions.h"
namespace Papyrus
{
bool Bind(VM* a_vm)
{
if (!a_vm) {
logger::critical("couldn't get VM State"sv);
return false;
}
logger::info("{:*^30}", "FUNCTIONS"sv);
PapyrusFunctions::Bind(*a_vm);
return true;
}
}

View File

@ -1,15 +0,0 @@
#pragma once
#define BIND(a_method, ...) a_vm.RegisterFunction(#a_method##sv, script, a_method __VA_OPT__(, ) __VA_ARGS__)
#include <RE/Skyrim.h>
namespace Papyrus {
using VM = RE::BSScript::Internal::VirtualMachine;
using StackID = RE::VMStackID;
using Severity = RE::BSScript::ErrorLogger::Severity;
inline constexpr auto script = "ArtifactTrackerPlayer"sv;
bool Bind(VM* a_vm);
}

View File

@ -1,108 +0,0 @@
#pragma once
#include "ArtifactTracker.h"
#include "Util.h"
namespace Papyrus::PapyrusFunctions
{
inline bool Load(RE::StaticFunctionTag*)
{
return ArtifactTracker::Init();
}
inline RE::TESObjectREFR* GetCellStorage(RE::StaticFunctionTag*)
{
return ArtifactTracker::g_cellStorage;
}
inline void SyncCellStorage(RE::StaticFunctionTag*)
{
ArtifactTracker::SyncCellStorage();
}
inline std::uint32_t GetArtifactCount(RE::StaticFunctionTag*)
{
return (ArtifactTracker::g_artifactMap).size();
}
// From po3's Papyrus Extender
inline std::vector<RE::Actor*> GetPlayerFollowers(RE::StaticFunctionTag*)
{
std::vector<RE::Actor*> 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;
}
inline RE::TESObjectREFR* GetCurrentContainer(RE::StaticFunctionTag*)
{
const auto handle = RE::ContainerMenu::GetTargetRefHandle();
const auto refr = RE::TESObjectREFR::LookupByHandle(handle);
return refr ? refr.get() : nullptr;
}
inline void RescanStoredArtifacts(RE::StaticFunctionTag*)
{
ListRevert(ArtifactTracker::g_listStored);
ArtifactTracker::AddRefArtifactsToList(ArtifactTracker::g_persistentStorage, ArtifactTracker::g_listStored);
}
inline void RescanFoundArtifacts(RE::StaticFunctionTag*)
{
ListRevert(ArtifactTracker::g_listFound);
ArtifactTracker::AddRefArtifactsToList(RE::PlayerCharacter::GetSingleton(), ArtifactTracker::g_listFound, ArtifactTracker::g_listStored);
for (const auto& ref : GetPlayerFollowers(nullptr)) {
ArtifactTracker::AddRefArtifactsToList(ref, ArtifactTracker::g_listFound, ArtifactTracker::g_listStored);
}
}
inline void RescanNewArtifacts(RE::StaticFunctionTag*)
{
for (auto const& item : ArtifactTracker::g_artifactMap) {
if (!ArtifactTracker::g_listNew->HasForm(item.second) && !ArtifactTracker::g_listStored->HasForm(item.second) && !ArtifactTracker::g_listFound->HasForm(item.second)) {
ArtifactTracker::g_listNew->AddForm(item.second);
}
}
}
inline void RegisterPersistentStorage(RE::StaticFunctionTag*,
RE::TESObjectREFR* ref)
{
if (ref) {
ArtifactTracker::g_persistentStorage->AddForm(ref);
ArtifactTracker::g_persistentMap[ref->formID] = ref;
}
}
inline void Bind(VM& a_vm)
{
BIND(Load);
logger::info("Registered Load"sv);
BIND(GetArtifactCount);
logger::info("Registered GetArtifactCount"sv);
BIND(RescanStoredArtifacts);
logger::info("Registered RescanStoredArtifacts"sv);
BIND(RescanFoundArtifacts);
logger::info("Registered RescanFoundArtifacts"sv);
BIND(RescanNewArtifacts);
logger::info("Registered RescanNewArtifacts"sv);
BIND(GetCellStorage);
logger::info("Registered GetCellStorage"sv);
BIND(SyncCellStorage);
logger::info("Registered SyncCellStorage"sv);
BIND(GetPlayerFollowers);
logger::info("Registered GetPlayerFollowers"sv);
BIND(GetCurrentContainer);
logger::info("Registered GetCurrentContainer"sv);
BIND(RegisterPersistentStorage);
logger::info("Registered RegisterPersistentStorage"sv);
}
}

View File

@ -188,3 +188,18 @@ inline void RunBenchmark(std::function<void()> benchmark, std::string desc)
const auto elapsed = std::chrono::duration<double>(end - start); const auto elapsed = std::chrono::duration<double>(end - start);
SKSE::log::info("{}: Elapsed time: {} seconds", desc, elapsed.count()); SKSE::log::info("{}: Elapsed time: {} seconds", desc, elapsed.count());
} }
inline std::vector<RE::Actor*> GetPlayerFollowers()
{
std::vector<RE::Actor*> 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;
}

View File

@ -1,80 +0,0 @@
Scriptname ArtifactTrackerPlayer extends ReferenceAlias
FormList Property ETR_ItemsNew Auto
FormList Property ETR_ItemsFound Auto
FormList Property ETR_ItemsStored Auto
int iArtifactCount = 0
event OnInit()
Utility.wait(3.0) ; wait for quickstart scripts to finish
OnPlayerLoadGame()
endevent
Event OnPlayerLoadGame()
if ! Load()
ETR_ItemsNew.Revert()
ETR_ItemsFound.Revert()
ETR_ItemsStored.Revert()
UnregisterForUpdate()
Debug.Notification("Failed to initialize ArtifactTracker.dll")
return
endif
if skse.GetPluginVersion("Ahzaab's moreHUD Plugin") >= 30800
ahzmorehud.RegisterIconFormList("dbmNew", ETR_ItemsNew)
ahzmorehud.RegisterIconFormList("dbmFound", ETR_ItemsFound)
ahzmorehud.RegisterIconFormList("dbmDisp", ETR_ItemsStored)
endif
if skse.GetPluginVersion("Ahzaab's moreHUD Inventory Plugin") >= 10017
ahzmorehudie.RegisterIconFormList("dbmNew", ETR_ItemsNew)
ahzmorehudie.RegisterIconFormList("dbmFound", ETR_ItemsFound)
ahzmorehudie.RegisterIconFormList("dbmDisp", ETR_ItemsStored)
endif
if SKSE.GetPluginVersion("QuickLootEE") >= 0
QuickLootEE.RegisterNewItemsList(ETR_ItemsNew)
QuickLootEE.RegisterDisplayedItemsList(ETR_ItemsStored)
QuickLootEE.RegisterFoundItemsList(ETR_ItemsFound)
endif
int iNewArtifactCount = GetArtifactCount()
if iNewArtifactCount != iArtifactCount
iArtifactCount = iNewArtifactCount
Debug.Notification("Artifact list changed, rebuilding the list")
ETR_ItemsNew.Revert() ; rebuild the list
endif
; Rebuild all lists to avoid discrepancies, stale data, and broken records
RescanStoredArtifacts()
RescanFoundArtifacts()
RescanNewArtifacts()
EndEvent
; NATIVE FUNCTIONS
bool function Load() native global
int function GetArtifactCount() native global
function RescanStoredArtifacts() native global
function RescanFoundArtifacts() native global
function RescanNewArtifacts() native global
ObjectReference function GetCellStorage() native global
ObjectReference function GetCurrentContainer() native global
function SyncCellStorage() native global
Actor[] function GetPlayerFollowers() native global
function RegisterPersistentStorage(ObjectReference ref) native global

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +0,0 @@
Scriptname QuickLootEE Hidden
{Script used for adding custom icons to QuickLootEE}
int Function GetVersion() global native
{Gets the version e.g 292 for 2.9.2}
;iEquip Functions ---------------------------------------
Function RegisterNewItemsList(FormList alist) global native
{Registers a form list to be used to check wheather an item is not
displayed in LOTD and is not in our inventory or LOTD containers.}
Function RegisterFoundItemsList(FormList alist) global native
{Registers a form list to be used to check wheather an item is not
displayed in LOTD and is in our inventory or LOTD containers.}
Function RegisterDisplayedItemsList(FormList alist) global native
{Registers a form list to be used to check wheather an item is displayed in LOTD.}
; Gets the version as a string for viewing
string Function GetVersionString() global
int iVersion = QuickLootEE.GetVersion()
if (iVersion == 0)
return ""
endif
int iMajor = iVersion / 100
int iMinor = (iVersion / 10) % 10
int iBug = iVersion % 10
string aVersion = iMajor + "." + iMinor + "." + iBug
return aVersion
EndFunction