All moving parts have been moved to the DLL
This commit is contained in:
parent
77ef7c15da
commit
e836f4134d
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -24,7 +24,6 @@ configure_file(
|
||||
|
||||
set(sources
|
||||
src/Main.cpp
|
||||
src/Papyrus.cpp
|
||||
src/ArtifactTracker.cpp
|
||||
src/EventListener.cpp
|
||||
src/BookCheck.cpp
|
||||
|
@ -3,6 +3,9 @@
|
||||
#include "EventListener.h"
|
||||
#include "Util.h"
|
||||
|
||||
using namespace SKSE;
|
||||
using namespace SKSE::log;
|
||||
|
||||
namespace ArtifactTracker
|
||||
{
|
||||
bool g_bLoaded;
|
||||
@ -18,7 +21,8 @@ namespace ArtifactTracker
|
||||
std::unordered_set<RE::FormType> g_artifactFormTypes;
|
||||
std::unordered_map<RE::FormID, RE::TESObjectREFR*> g_persistentMap;
|
||||
RE::TESObjectREFR* g_cellStorage;
|
||||
std::uint32_t g_iFollowerIndex;
|
||||
const SKSE::LoadInterface* g_loadInterface;
|
||||
std::int32_t g_iFollowerIndex;
|
||||
|
||||
bool Init(bool bKID)
|
||||
{
|
||||
@ -26,36 +30,36 @@ namespace ArtifactTracker
|
||||
return true;
|
||||
}
|
||||
|
||||
SKSE::GetModCallbackEventSource()->RemoveEventSink(EventListener::GetSingleton());
|
||||
|
||||
const auto dataHandler = RE::TESDataHandler::GetSingleton();
|
||||
|
||||
if (!dataHandler) {
|
||||
SKSE::log::error("Unable to call RE::TESDataHandler::GetSingleton()");
|
||||
RE::DebugMessageBox("Unable to initialize Artifact Tracker.");
|
||||
// Called before kDataLoaded?
|
||||
log::error("RE::TESDataHandler is not initialized.");
|
||||
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_listStored = dataHandler->LookupForm<RE::BGSListForm>(0x805, "Artifact Tracker.esp"); // ETR_ItemsStored
|
||||
g_listFound = dataHandler->LookupForm<RE::BGSListForm>(0x806, "Artifact Tracker.esp"); // ETR_ItemsFound
|
||||
g_persistentStorage = dataHandler->LookupForm<RE::BGSListForm>(0x807, "Artifact Tracker.esp"); // ETR_PersistentStorageList
|
||||
g_cellContainer = dataHandler->LookupForm(0x804, "Artifact Tracker.esp")->As<RE::TESBoundObject>(); // ETR_CellStorageContainer
|
||||
|
||||
g_listNew = dataHandler->LookupForm<RE::BGSListForm>(0x800, "Artifact Tracker.esp"); // ETR_ItemsNew
|
||||
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
|
||||
|
||||
const auto extraArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xAFC11A, "Update.esm"); // ETR_ExtraArtifact
|
||||
const auto notArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xAFC11C, "Update.esm"); // ETR_NotArtifact
|
||||
const auto extraArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xAFC110, "Update.esm"); // ETR_ExtraArtifact
|
||||
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) {
|
||||
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.");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<std::string, bool> settings {
|
||||
std::map<std::string, bool> settings{
|
||||
{ "DumpItemList", false },
|
||||
};
|
||||
LoadINI(&settings, "Data/SKSE/Plugins/ArtifactTracker.ini");
|
||||
@ -121,15 +125,15 @@ namespace ArtifactTracker
|
||||
}
|
||||
}
|
||||
|
||||
OnGameLoad();
|
||||
EventListener::Install();
|
||||
OnGameLoad(); // covers new game and coc'ing from the main menu
|
||||
g_bLoaded = true;
|
||||
|
||||
SKSE::log::info("Total artifacts: {}", g_artifactMap.size());
|
||||
log::info("Total artifacts: {}", g_artifactMap.size());
|
||||
|
||||
if (settings.at("DumpItemList")) {
|
||||
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()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
SKSE::log::info("OnGameLoad");
|
||||
log::info("OnGameLoad");
|
||||
#endif
|
||||
|
||||
g_persistentMap.clear();
|
||||
@ -164,6 +168,70 @@ namespace ArtifactTracker
|
||||
}
|
||||
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)
|
||||
@ -213,7 +281,7 @@ namespace ArtifactTracker
|
||||
RE::UI::GetSingleton()->AddEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton());
|
||||
RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink<RE::TESActivateEvent>(EventListener::GetSingleton());
|
||||
#ifdef _DEBUG
|
||||
SKSE::log::info("Home mode ON");
|
||||
log::info("Home mode ON");
|
||||
#endif
|
||||
return true;
|
||||
} else if (g_cellStorage) {
|
||||
@ -222,7 +290,7 @@ namespace ArtifactTracker
|
||||
RE::UI::GetSingleton()->RemoveEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton());
|
||||
RE::ScriptEventSourceHolder::GetSingleton()->RemoveEventSink<RE::TESActivateEvent>(EventListener::GetSingleton());
|
||||
#ifdef _DEBUG
|
||||
SKSE::log::info("Home mode OFF");
|
||||
log::info("Home mode OFF");
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
@ -236,7 +304,7 @@ namespace ArtifactTracker
|
||||
|
||||
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)
|
||||
@ -292,11 +360,12 @@ namespace ArtifactTracker
|
||||
g_persistentMap[cellStorage->formID] = cellStorage;
|
||||
}
|
||||
ToggleHomeMode(cellStorage);
|
||||
SyncCellStorage();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
SKSE::log::info("Adding new storage in {}", cell->GetName());
|
||||
log::info("Adding new storage in {}", cell->GetName());
|
||||
#endif
|
||||
|
||||
cellStorage = RE::PlayerCharacter::GetSingleton()->PlaceObjectAtMe(g_cellContainer, true).get();
|
||||
@ -308,7 +377,7 @@ namespace ArtifactTracker
|
||||
ToggleHomeMode(cellStorage);
|
||||
SyncCellStorage();
|
||||
} else {
|
||||
SKSE::log::error("Failed to create cell storage in OnCellEnter");
|
||||
log::error("Failed to create cell storage in OnCellEnter");
|
||||
ToggleHomeMode(nullptr);
|
||||
}
|
||||
}
|
||||
@ -317,13 +386,13 @@ namespace ArtifactTracker
|
||||
{
|
||||
if (!IsHome()) {
|
||||
#ifdef _DEBUG
|
||||
SKSE::log::info("SyncCellStorage called while not at home");
|
||||
log::info("SyncCellStorage called while not at home");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
SKSE::log::info("Running SyncCellStorage");
|
||||
log::info("Running SyncCellStorage");
|
||||
#endif
|
||||
|
||||
std::unordered_set<RE::FormID> cellItems;
|
||||
@ -339,7 +408,7 @@ namespace ArtifactTracker
|
||||
const auto baseObj = a_ref->GetBaseObject();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -501,7 +570,7 @@ namespace ArtifactTracker
|
||||
|
||||
if (!GetItemCount(g_cellStorage, form)) {
|
||||
#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");
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
if (!a_refOrList || !a_targetList) {
|
||||
SKSE::log::warn("Invalid arguments in AddRefArtifactsToList");
|
||||
log::warn("Invalid arguments in AddRefArtifactsToList");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -614,7 +683,7 @@ namespace ArtifactTracker
|
||||
const auto containerRef = a_refOrList->As<RE::TESObjectREFR>();
|
||||
|
||||
if (!containerRef) {
|
||||
SKSE::log::warn("containerRef in AddRefArtifactsToList is not a reference");
|
||||
log::warn("containerRef in AddRefArtifactsToList is not a reference");
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
std::uint32_t iCurrentFollowers;
|
||||
std::uint32_t iCurrentFollowers = 0;
|
||||
|
||||
for (const auto& actor : GetPlayerFollowers()) {
|
||||
iCurrentFollowers += actor->formID;
|
||||
|
@ -15,6 +15,7 @@ namespace ArtifactTracker
|
||||
extern std::unordered_set<RE::FormType> g_artifactFormTypes;
|
||||
extern std::unordered_map<RE::FormID, RE::TESObjectREFR*> g_persistentMap;
|
||||
extern RE::TESObjectREFR* g_cellStorage;
|
||||
extern const SKSE::LoadInterface* g_loadInterface;
|
||||
|
||||
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 OnLocationChange();
|
||||
|
||||
void RescanFoundArtifacts();
|
||||
|
||||
void RescanStoredArtifacts();
|
||||
|
||||
void RescanNewArtifacts();
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include "Papyrus.h"
|
||||
#include "ArtifactTracker.h"
|
||||
#include "EventListener.h"
|
||||
|
||||
@ -50,7 +49,7 @@ SKSEPluginLoad(const LoadInterface* skse) {
|
||||
Init(skse);
|
||||
InitializeMessaging();
|
||||
|
||||
SKSE::GetPapyrusInterface()->Register(Papyrus::Bind);
|
||||
ArtifactTracker::g_loadInterface = skse;
|
||||
|
||||
log::info("{} has finished loading.", plugin->GetName());
|
||||
return true;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -188,3 +188,18 @@ inline void RunBenchmark(std::function<void()> benchmark, std::string desc)
|
||||
const auto elapsed = std::chrono::duration<double>(end - start);
|
||||
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;
|
||||
}
|
||||
|
@ -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
@ -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
|
Loading…
Reference in New Issue
Block a user