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
|
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
|
||||||
|
@ -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");
|
||||||
@ -71,7 +75,7 @@ namespace ArtifactTracker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_artifactMap.erase(0x1F4); // Unarmed
|
g_artifactMap.erase(0x1F4); // Unarmed
|
||||||
|
|
||||||
g_artifactFormTypes.insert(RE::FormType::Armor);
|
g_artifactFormTypes.insert(RE::FormType::Armor);
|
||||||
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectARMO>()) {
|
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectARMO>()) {
|
||||||
if (form->GetPlayable() && form->race && (form->race->formID == 0x19 || form->race->HasKeyword(npcRaceKeyword))) {
|
if (form->GetPlayable() && form->race && (form->race->formID == 0x19 || form->race->HasKeyword(npcRaceKeyword))) {
|
||||||
@ -80,9 +84,9 @@ namespace ArtifactTracker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_artifactMap.erase(0xD64); // SkinNaked
|
g_artifactMap.erase(0xD64); // SkinNaked
|
||||||
g_artifactMap.erase(0x69CE3); // SkinNakedBeast
|
g_artifactMap.erase(0x69CE3); // SkinNakedBeast
|
||||||
g_artifactMap.erase(0xCDD86); // SkinNakedWerewolfBeast
|
g_artifactMap.erase(0xCDD86); // SkinNakedWerewolfBeast
|
||||||
|
|
||||||
g_artifactFormTypes.insert(RE::FormType::Book);
|
g_artifactFormTypes.insert(RE::FormType::Book);
|
||||||
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectBOOK>()) {
|
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectBOOK>()) {
|
||||||
@ -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;
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -187,4 +187,19 @@ 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;
|
||||||
|
}
|
||||||
|
@ -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