1

Precache misc items

This commit is contained in:
Eddoursul 2022-06-22 02:52:12 +02:00
parent 1e71ef6032
commit 4341644277
17 changed files with 102 additions and 84 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -24,6 +24,7 @@ set(sources
src/Main.cpp src/Main.cpp
src/Papyrus.cpp src/Papyrus.cpp
src/BookCheck.cpp src/BookCheck.cpp
src/MiscCheck.cpp
${CMAKE_CURRENT_BINARY_DIR}/version.rc) ${CMAKE_CURRENT_BINARY_DIR}/version.rc)

View File

@ -13,10 +13,10 @@ namespace BookCheck
return; return;
} }
RE::BGSKeyword* recipeKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xF5CB0, "Skyrim.esm"); // VendorItemRecipe const RE::BGSKeyword* recipeKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xF5CB0, "Skyrim.esm"); // VendorItemRecipe
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectBOOK>()) { for (const auto& form : dataHandler->GetFormArray<RE::TESObjectBOOK>()) {
if (!form || form->TeachesSpell()) { if (!form || !form->GetPlayable() || form->TeachesSpell()) {
continue; continue;
} }
if (form->HasKeyword(recipeKeyword) || IsBook(form)) { if (form->HasKeyword(recipeKeyword) || IsBook(form)) {

View File

@ -50,19 +50,19 @@ namespace Papyrus::ArtifactTracker
return false; return false;
} }
inline bool is_artifact(RE::TESForm* a_form, RE::TESForm* a_excludeForm = NULL) inline bool is_artifact(RE::TESForm* a_form)
{ {
if (!a_form->GetPlayable()) {
return false;
}
const auto formType = a_form->GetFormType(); const auto formType = a_form->GetFormType();
if (formType != RE::FormType::Armor && formType != RE::FormType::Weapon && formType != RE::FormType::Book && formType != RE::FormType::Misc) { return (
return false; formType == RE::FormType::Armor
} || (formType == RE::FormType::Weapon && a_form->formID != 0x000001F4)
|| (formType == RE::FormType::Book && BookCheck::GetBookList().contains(a_form->formID))
if (!a_form->GetPlayable() || is_excluded(a_form, a_excludeForm)) { || (formType == RE::FormType::Misc && MiscCheck::GetMiscList().contains(a_form->formID)));
return false;
}
return true;
} }
inline std::int32_t AddAllFormsToList(RE::StaticFunctionTag*, inline std::int32_t AddAllFormsToList(RE::StaticFunctionTag*,
@ -70,22 +70,36 @@ namespace Papyrus::ArtifactTracker
short a_formType, short a_formType,
RE::TESForm* a_excludeForm = NULL) RE::TESForm* a_excludeForm = NULL)
{ {
const auto dataHandler = RE::TESDataHandler::GetSingleton();
if (!dataHandler) {
return a_targetList->forms.size();
}
const auto formType = static_cast<RE::FormType>(a_formType); const auto formType = static_cast<RE::FormType>(a_formType);
for (const auto& form : dataHandler->GetFormArray(formType)) { if (formType == RE::FormType::Book) {
if (!form || !form->GetPlayable()) { for (auto const& item : BookCheck::GetBookList()) {
continue; if (!a_excludeForm || !is_excluded(item.second, a_excludeForm)) {
a_targetList->AddForm(item.second);
}
} }
if (a_excludeForm && is_excluded(form, a_excludeForm)) { } else if (formType == RE::FormType::Misc) {
continue; for (auto const& item : MiscCheck::GetMiscList()) {
if (!a_excludeForm || !is_excluded(item.second, a_excludeForm)) {
a_targetList->AddForm(item.second);
}
}
} else {
const auto dataHandler = RE::TESDataHandler::GetSingleton();
if (!dataHandler) {
return a_targetList->forms.size();
}
for (const auto& form : dataHandler->GetFormArray(formType)) {
if (!form || !form->GetPlayable()) {
continue;
}
if (a_excludeForm && is_excluded(form, a_excludeForm)) {
continue;
}
a_targetList->AddForm(form);
} }
a_targetList->AddForm(form);
} }
return a_targetList->forms.size(); return a_targetList->forms.size();
@ -94,8 +108,7 @@ namespace Papyrus::ArtifactTracker
inline std::int32_t AddArtifactsToList(VM* a_vm, StackID a_stackID, RE::StaticFunctionTag*, inline std::int32_t AddArtifactsToList(VM* a_vm, StackID a_stackID, RE::StaticFunctionTag*,
RE::TESForm* a_refOrList, RE::TESForm* a_refOrList,
RE::BGSListForm* a_targetList, RE::BGSListForm* a_targetList,
RE::TESForm* a_excludeForm = NULL, RE::TESForm* a_excludeForm = NULL)
bool excludeOnlyMisc = false)
{ {
if (!a_refOrList) { if (!a_refOrList) {
a_vm->TraceStack("a_refOrList in AddItemsOfTypeAndKeywordToList is None", a_stackID); a_vm->TraceStack("a_refOrList in AddItemsOfTypeAndKeywordToList is None", a_stackID);
@ -110,7 +123,7 @@ namespace Papyrus::ArtifactTracker
a_refOrList->As<RE::BGSListForm>()->ForEachForm([&](RE::TESForm& a_exform) { a_refOrList->As<RE::BGSListForm>()->ForEachForm([&](RE::TESForm& a_exform) {
const auto refrItem = a_exform.As<RE::TESObjectREFR>(); const auto refrItem = a_exform.As<RE::TESObjectREFR>();
if (refrItem) { if (refrItem) {
AddArtifactsToList(a_vm, a_stackID, {}, refrItem, a_targetList, a_excludeForm, excludeOnlyMisc); AddArtifactsToList(a_vm, a_stackID, {}, refrItem, a_targetList, a_excludeForm);
} }
return true; return true;
}); });
@ -124,17 +137,8 @@ namespace Papyrus::ArtifactTracker
return 0; return 0;
} }
RE::BGSKeyword* recipeKeyword = RE::TESDataHandler::GetSingleton()->LookupForm<RE::BGSKeyword>(0xF5CB0, "Skyrim.esm"); // VendorItemRecipe
auto inv = containerRef->GetInventory([&](RE::TESBoundObject& a_exform) { auto inv = containerRef->GetInventory([&](RE::TESBoundObject& a_exform) {
return a_exform.GetPlayable() return is_artifact(&a_exform) && !is_excluded(&a_exform, a_excludeForm);
&& (
a_exform.formType == RE::FormType::Armor
|| (a_exform.formType == RE::FormType::Weapon && a_exform.formID != 0x000001F4)
|| a_exform.formType == RE::FormType::Misc
|| (a_exform.formType == RE::FormType::Book && BookCheck::GetBookList().contains(a_exform.formID))
)
&& (excludeOnlyMisc ? (a_exform.formType != RE::FormType::Misc || !is_excluded(&a_exform, a_excludeForm)) : !is_excluded(&a_exform, a_excludeForm));
}); });
for (const auto& [item, data] : inv) { for (const auto& [item, data] : inv) {
@ -258,7 +262,7 @@ namespace Papyrus::ArtifactTracker
if (count > 0) { if (count > 0) {
cellItems[item->formID] = true; cellItems[item->formID] = true;
if (inv.find(item) == inv.end()) { if (inv.find(item) == inv.end()) {
if (is_artifact(item, a_excludeForm)) { if (is_artifact(item) && !is_excluded(item, a_excludeForm)) {
a_cellStorage->AddObjectToContainer(item, nullptr, 1, nullptr); a_cellStorage->AddObjectToContainer(item, nullptr, 1, nullptr);
} }
} }
@ -278,12 +282,14 @@ namespace Papyrus::ArtifactTracker
cellItems[baseObj->formID] = true; cellItems[baseObj->formID] = true;
if (!is_artifact(baseObj, a_excludeForm)) { if (!is_artifact(baseObj)) {
continue; continue;
} }
if (inv.find(baseObj) == inv.end()) { if (inv.find(baseObj) == inv.end()) {
a_cellStorage->AddObjectToContainer(baseObj, nullptr, 1, nullptr); if (!a_excludeForm || !is_excluded(baseObj, a_excludeForm)) {
a_cellStorage->AddObjectToContainer(baseObj, nullptr, 1, nullptr);
}
} }
} }
@ -297,30 +303,6 @@ namespace Papyrus::ArtifactTracker
cellItems.clear(); cellItems.clear();
} }
inline std::int32_t AddAllBooksToList(VM* a_vm, StackID a_stackID, RE::StaticFunctionTag*,
RE::BGSListForm* a_targetList,
RE::TESForm* a_excludeForm = NULL)
{
if (!a_targetList) {
a_vm->TraceStack("a_targetList in AddItemsOfTypeAndKeywordToList is None", a_stackID);
return 0;
}
if (a_excludeForm) {
for (auto const& item : BookCheck::GetBookList()) {
if (!is_excluded(item.second, a_excludeForm)) {
a_targetList->AddForm(item.second);
}
}
} else {
for (const auto& item : BookCheck::GetBookList()) {
a_targetList->AddForm(item.second);
}
}
return a_targetList->forms.size();
}
inline void Bind(VM& a_vm) inline void Bind(VM& a_vm)
{ {
BIND(AddAllFormsToList); BIND(AddAllFormsToList);
@ -333,7 +315,5 @@ namespace Papyrus::ArtifactTracker
logger::info("Registered HasRefInCell"sv); logger::info("Registered HasRefInCell"sv);
BIND(SyncCellStorage); BIND(SyncCellStorage);
logger::info("Registered SyncCellStorage"sv); logger::info("Registered SyncCellStorage"sv);
BIND(AddAllBooksToList);
logger::info("Registered AddAllBooksToList"sv);
} }
} }

View File

@ -1,5 +1,6 @@
#include "Papyrus.h" #include "Papyrus.h"
#include "BookCheck.h" #include "BookCheck.h"
#include "MiscCheck.h"
using namespace RE::BSScript; using namespace RE::BSScript;
using namespace SKSE; using namespace SKSE;
@ -30,6 +31,7 @@ namespace {
GetMessagingInterface()->RegisterListener([](MessagingInterface::Message* message) { GetMessagingInterface()->RegisterListener([](MessagingInterface::Message* message) {
if (message->type == MessagingInterface::kDataLoaded) { if (message->type == MessagingInterface::kDataLoaded) {
BookCheck::PreloadBookList(); BookCheck::PreloadBookList();
MiscCheck::PreloadMiscList();
} }
}); });
} }

View File

@ -0,0 +1,29 @@
#include "MiscCheck.h"
namespace MiscCheck
{
std::unordered_map<RE::FormID, RE::TESObjectMISC*> validMisc;
void PreloadMiscList()
{
const auto dataHandler = RE::TESDataHandler::GetSingleton();
if (!dataHandler) {
return;
}
RE::BGSListForm* excludeForms = dataHandler->LookupForm<RE::BGSListForm>(0x809, "Artifact Tracker.esp"); // ETR_ExcludeMiscForms
RE::BGSListForm* excludeKeywords = dataHandler->LookupForm<RE::BGSListForm>(0x808, "Artifact Tracker.esp"); // ETR_ExcludeMiscKeywords
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectMISC>()) {
if (form->GetPlayable() && !excludeForms->HasForm(form) && !form->HasKeywordInList(excludeKeywords, false)) {
validMisc[form->formID] = form;
}
}
}
std::unordered_map<RE::FormID, RE::TESObjectMISC*> GetMiscList()
{
return validMisc;
}
}

View File

@ -0,0 +1,8 @@
#pragma once
namespace MiscCheck
{
void PreloadMiscList();
std::unordered_map<RE::FormID, RE::TESObjectMISC*> GetMiscList();
}

View File

@ -1,5 +1,6 @@
#include "Papyrus.h" #include "Papyrus.h"
#include "BookCheck.h" #include "BookCheck.h"
#include "MiscCheck.h"
#include "Functions/ObjectReference.h" #include "Functions/ObjectReference.h"
#include "Functions/ArtifactTracker.h" #include "Functions/ArtifactTracker.h"

View File

@ -2,9 +2,7 @@ Scriptname ETR_Functions Hidden
int function AddAllFormsToList(FormList targetList, int formType, Form excludeForm = None) native global int function AddAllFormsToList(FormList targetList, int formType, Form excludeForm = None) native global
int function AddAllBooksToList(FormList targetList, Form excludeForm = None) native global int function AddArtifactsToList(Form refOrList, FormList targetList, Form excludeForm = None) native global
int function AddArtifactsToList(Form refOrList, FormList targetList, Form excludeForm = None, bool excludeOnlyMisc = false) native global
int function GetItemCountInList(FormList refList, Form baseForm) native global int function GetItemCountInList(FormList refList, Form baseForm) native global

View File

@ -6,7 +6,6 @@ FormList Property ETR_ItemsNew Auto
FormList Property ETR_ItemsFound Auto FormList Property ETR_ItemsFound Auto
FormList Property ETR_ItemsStored Auto FormList Property ETR_ItemsStored Auto
FormList Property ETR_PersistentStorageList Auto FormList Property ETR_PersistentStorageList Auto
FormList Property ETR_ExcludeFromNew Auto
FormList Property ETR_ExcludeMisc Auto FormList Property ETR_ExcludeMisc Auto
Container Property ETR_CellStorageContainer Auto Container Property ETR_CellStorageContainer Auto
@ -89,7 +88,7 @@ Event OnUpdate()
endif endif
bRescanHome = false bRescanHome = false
ObjectReference cellStorage = ETR_Functions.GetCellStorage(PlayerRef, ETR_PersistentStorageList, ETR_CellStorageContainer) ObjectReference cellStorage = ETR_Functions.GetCellStorage(PlayerRef, ETR_PersistentStorageList, ETR_CellStorageContainer)
ETR_Functions.SyncCellStorage(cellStorage, ETR_ExcludeMisc) ETR_Functions.SyncCellStorage(cellStorage)
if ! bRescanPersistent if ! bRescanPersistent
ETR_Functions.AddArtifactsToList(cellStorage, ETR_ItemsStored) ETR_Functions.AddArtifactsToList(cellStorage, ETR_ItemsStored)
endif endif
@ -101,18 +100,18 @@ Event OnUpdate()
int n = aContainers.length int n = aContainers.length
while n > 0 while n > 0
n -= 1 n -= 1
ETR_Functions.AddArtifactsToList(aContainers[n], ETR_ItemsStored, ETR_ExcludeMisc, true) ETR_Functions.AddArtifactsToList(aContainers[n], ETR_ItemsStored)
endwhile endwhile
endif endif
ETR_ItemsFound.Revert() ETR_ItemsFound.Revert()
ETR_Functions.AddArtifactsToList(PlayerRef, ETR_ItemsFound, ETR_ExcludeFromNew) ETR_Functions.AddArtifactsToList(PlayerRef, ETR_ItemsFound, ETR_ItemsStored)
Actor[] aFollowers = ETR_Functions.GetPlayerFollowers() Actor[] aFollowers = ETR_Functions.GetPlayerFollowers()
int i = aFollowers.length int i = aFollowers.length
while i > 0 while i > 0
i -= 1 i -= 1
ETR_Functions.AddArtifactsToList(aFollowers[i], ETR_ItemsFound, ETR_ExcludeFromNew) ETR_Functions.AddArtifactsToList(aFollowers[i], ETR_ItemsFound, ETR_ItemsStored)
endwhile endwhile
bBusy = false bBusy = false

View File

@ -47,23 +47,23 @@ event OnPlayerLoadGame()
; Rebuild all lists to avoid discrepancies, stale data, and broken records ; Rebuild all lists to avoid discrepancies, stale data, and broken records
ETR_ItemsStored.Revert() ETR_ItemsStored.Revert()
ETR_Functions.AddArtifactsToList(ETR_PersistentStorageList, ETR_ItemsStored, ETR_ExcludeMisc, true) ETR_Functions.AddArtifactsToList(ETR_PersistentStorageList, ETR_ItemsStored)
ETR_ItemsFound.Revert() ETR_ItemsFound.Revert()
ETR_Functions.AddArtifactsToList(PlayerRef, ETR_ItemsFound, ETR_ExcludeFromNew) ETR_Functions.AddArtifactsToList(PlayerRef, ETR_ItemsFound, ETR_ItemsStored)
Actor[] aFollowers = ETR_Functions.GetPlayerFollowers() Actor[] aFollowers = ETR_Functions.GetPlayerFollowers()
int i = aFollowers.length int i = aFollowers.length
while i > 0 while i > 0
i -= 1 i -= 1
ETR_Functions.AddArtifactsToList(aFollowers[i], ETR_ItemsFound, ETR_ExcludeFromNew) ETR_Functions.AddArtifactsToList(aFollowers[i], ETR_ItemsFound, ETR_ItemsStored)
endwhile endwhile
ETR_ItemsNew.Revert() ETR_ItemsNew.Revert()
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 26, ETR_FoundAndStored) ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 26, ETR_FoundAndStored)
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 41, ETR_FoundAndStored) ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 41, ETR_FoundAndStored)
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 32, ETR_ExcludeFromNew) ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 32, ETR_FoundAndStored)
ETR_Functions.AddAllBooksToList(ETR_ItemsNew, ETR_FoundAndStored) ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 27, ETR_FoundAndStored)
endevent endevent

View File

@ -80,7 +80,7 @@ Event OnUpdate()
return return
endif endif
ObjectReference cellStorage = ETR_Functions.GetCellStorage(PlayerRef, ETR_PersistentStorageList, ETR_CellStorageContainer) ObjectReference cellStorage = ETR_Functions.GetCellStorage(PlayerRef, ETR_PersistentStorageList, ETR_CellStorageContainer)
ETR_Functions.SyncCellStorage(cellStorage, ETR_ExcludeMisc) ETR_Functions.SyncCellStorage(cellStorage)
endif endif
if bRescanPersistent if bRescanPersistent
@ -90,17 +90,17 @@ Event OnUpdate()
int n = aContainers.length int n = aContainers.length
while n > 0 while n > 0
n -= 1 n -= 1
ETR_Functions.AddArtifactsToList(aContainers[n], ETR_ItemsStored, ETR_ExcludeMisc, true) ETR_Functions.AddArtifactsToList(aContainers[n], ETR_ItemsStored)
endwhile endwhile
ETR_ItemsFound.Revert() ETR_ItemsFound.Revert()
ETR_Functions.AddArtifactsToList(PlayerRef, ETR_ItemsFound, ETR_ExcludeFromNew) ETR_Functions.AddArtifactsToList(PlayerRef, ETR_ItemsFound, ETR_ItemsStored)
Actor[] aFollowers = ETR_Functions.GetPlayerFollowers() Actor[] aFollowers = ETR_Functions.GetPlayerFollowers()
int i = aFollowers.length int i = aFollowers.length
while i > 0 while i > 0
i -= 1 i -= 1
ETR_Functions.AddArtifactsToList(aFollowers[i], ETR_ItemsFound, ETR_ExcludeFromNew) ETR_Functions.AddArtifactsToList(aFollowers[i], ETR_ItemsFound, ETR_ItemsStored)
endwhile endwhile
endif endif
@ -126,7 +126,7 @@ event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemRefere
elseif bAtHome elseif bAtHome
ObjectReference cellStorage = ETR_Functions.GetCellStorage(PlayerRef, ETR_PersistentStorageList, ETR_CellStorageContainer) ObjectReference cellStorage = ETR_Functions.GetCellStorage(PlayerRef, ETR_PersistentStorageList, ETR_CellStorageContainer)
if cellStorage.GetItemCount(akBaseItem) if cellStorage.GetItemCount(akBaseItem)
ETR_Functions.SyncCellStorage(cellStorage, ETR_ExcludeMisc) ETR_Functions.SyncCellStorage(cellStorage)
if ETR_Functions.GetItemCountInList(ETR_PersistentStorageList, akBaseItem) == 0 if ETR_Functions.GetItemCountInList(ETR_PersistentStorageList, akBaseItem) == 0
ETR_ItemsStored.RemoveAddedForm(akBaseItem) ETR_ItemsStored.RemoveAddedForm(akBaseItem)
ETR_ItemsFound.AddForm(akBaseItem) ETR_ItemsFound.AddForm(akBaseItem)