Delayed processing of items moved to a container
This commit is contained in:
parent
90d5e69df4
commit
d22ec901b5
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -2,6 +2,54 @@
|
||||
|
||||
namespace Papyrus::ArtifactTracker
|
||||
{
|
||||
inline bool is_excluded(RE::TESForm* a_form, RE::TESForm* a_excludeForm = NULL)
|
||||
{
|
||||
if (!a_excludeForm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const RE::BGSListForm* list = a_excludeForm->As<RE::BGSListForm>();
|
||||
|
||||
if (list) {
|
||||
if (list->HasForm(a_form)) {
|
||||
return true;
|
||||
} else {
|
||||
bool isExcluded = false;
|
||||
|
||||
list->ForEachForm([&](RE::TESForm& a_exform) {
|
||||
const auto exlist = a_exform.As<RE::BGSListForm>();
|
||||
if (exlist) {
|
||||
if (exlist->forms.size() > 0) {
|
||||
if (exlist->forms[0]->Is(RE::FormType::Keyword) ? a_form->HasKeywordInList(exlist, false) : exlist->HasForm(a_form)) {
|
||||
isExcluded = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const auto exkeyword = a_exform.As<RE::BGSKeyword>();
|
||||
if (exkeyword && a_form->As<RE::BGSKeywordForm>()->HasKeyword(exkeyword)) {
|
||||
isExcluded = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return isExcluded;
|
||||
}
|
||||
}
|
||||
|
||||
const RE::BGSKeyword* keyword = a_excludeForm->As<RE::BGSKeyword>();
|
||||
|
||||
if (keyword) {
|
||||
if (a_form->As<RE::BGSKeywordForm>()->HasKeyword(keyword)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool is_artifact(RE::TESForm* a_form, RE::TESForm* a_excludeForm = NULL)
|
||||
{
|
||||
const auto formType = a_form->GetFormType();
|
||||
@ -10,13 +58,93 @@ namespace Papyrus::ArtifactTracker
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Papyrus::ObjectReference::inv_util::is_excluded(a_form, a_excludeForm)) {
|
||||
if (!a_form->GetPlayable() || is_excluded(a_form, a_excludeForm)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline std::int32_t AddAllFormsToList(RE::StaticFunctionTag*,
|
||||
RE::BGSListForm* a_targetList,
|
||||
short a_formType,
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return a_targetList->forms.size();
|
||||
}
|
||||
|
||||
inline std::int32_t AddArtifactsToList(VM* a_vm, StackID a_stackID, RE::StaticFunctionTag*,
|
||||
RE::TESForm* a_refOrList,
|
||||
RE::BGSListForm* a_targetList,
|
||||
RE::TESForm* a_excludeForm = NULL,
|
||||
bool excludeOnlyMisc = false)
|
||||
{
|
||||
if (!a_refOrList) {
|
||||
a_vm->TraceStack("a_refOrList in AddItemsOfTypeAndKeywordToList is None", a_stackID);
|
||||
return 0;
|
||||
}
|
||||
if (!a_targetList) {
|
||||
a_vm->TraceStack("a_targetList in AddItemsOfTypeAndKeywordToList is None", a_stackID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a_refOrList->Is(RE::FormType::FormList)) {
|
||||
a_refOrList->As<RE::BGSListForm>()->ForEachForm([&](RE::TESForm& a_exform) {
|
||||
const auto refrItem = a_exform.As<RE::TESObjectREFR>();
|
||||
if (refrItem) {
|
||||
AddArtifactsToList(a_vm, a_stackID, {}, refrItem, a_targetList, a_excludeForm, excludeOnlyMisc);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return a_targetList->forms.size();
|
||||
}
|
||||
|
||||
const auto containerRef = a_refOrList->As<RE::TESObjectREFR>();
|
||||
|
||||
if (!containerRef) {
|
||||
a_vm->TraceStack("containerRef in AddItemsOfTypeAndKeywordToList is not a reference", a_stackID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto inv = containerRef->GetInventory([&](RE::TESBoundObject& a_exform) {
|
||||
return a_exform.GetPlayable()
|
||||
&& (
|
||||
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
|
||||
)
|
||||
&& (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) {
|
||||
const auto& [count, entry] = data;
|
||||
if (count > 0) {
|
||||
a_targetList->AddForm(item);
|
||||
}
|
||||
}
|
||||
|
||||
return a_targetList->forms.size();
|
||||
}
|
||||
|
||||
inline RE::TESObjectREFR* GetCellStorage(RE::StaticFunctionTag*,
|
||||
RE::TESObjectREFR* a_ref,
|
||||
RE::BGSListForm* a_refList,
|
||||
@ -119,12 +247,11 @@ namespace Papyrus::ArtifactTracker
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto contInv = a_ref->GetInventory();
|
||||
const auto contInv = a_ref->GetInventory([&](RE::TESBoundObject& a_object) -> bool {
|
||||
return !cellItems.contains(a_object.formID);
|
||||
});
|
||||
|
||||
for (const auto& [item, data] : contInv) {
|
||||
if (cellItems.contains(item->formID)) {
|
||||
continue;
|
||||
}
|
||||
const auto& [count, entry] = data;
|
||||
if (count > 0) {
|
||||
cellItems[item->formID] = true;
|
||||
@ -146,12 +273,12 @@ namespace Papyrus::ArtifactTracker
|
||||
if (cellItems.contains(baseObj->formID)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cellItems[baseObj->formID] = true;
|
||||
|
||||
if (!is_artifact(baseObj, a_excludeForm)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cellItems[baseObj->formID] = true;
|
||||
|
||||
if (inv.find(baseObj) == inv.end()) {
|
||||
a_cellStorage->AddObjectToContainer(baseObj, nullptr, 1, nullptr);
|
||||
@ -170,6 +297,10 @@ namespace Papyrus::ArtifactTracker
|
||||
|
||||
inline void Bind(VM& a_vm)
|
||||
{
|
||||
BIND(AddAllFormsToList);
|
||||
logger::info("Registered AddAllFormsToList"sv);
|
||||
BIND(AddArtifactsToList);
|
||||
logger::info("Registered AddArtifactsToList"sv);
|
||||
BIND(GetCellStorage);
|
||||
logger::info("Registered GetCellStorage"sv);
|
||||
BIND(HasRefInCell);
|
||||
|
@ -2,194 +2,6 @@
|
||||
|
||||
namespace Papyrus::ObjectReference
|
||||
{
|
||||
namespace inv_util
|
||||
{
|
||||
inline bool can_be_taken(const std::unique_ptr<RE::InventoryEntryData>& a_entry, bool a_noEquipped, bool a_noFavourited, bool a_noQuestItem)
|
||||
{
|
||||
if (a_noEquipped && a_entry->IsWorn()) {
|
||||
return false;
|
||||
}
|
||||
if (a_noFavourited && a_entry->IsFavorited()) {
|
||||
return false;
|
||||
}
|
||||
if (a_noQuestItem && a_entry->IsQuestObject()) {
|
||||
return false;
|
||||
}
|
||||
if (a_entry->object->formID == 0x000001F4) { // Unarmed
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool is_excluded(RE::TESForm* a_form, RE::TESForm* a_excludeForm = NULL)
|
||||
{
|
||||
if (!a_excludeForm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const RE::BGSListForm* list = a_excludeForm->As<RE::BGSListForm>();
|
||||
|
||||
if (list) {
|
||||
if (list->HasForm(a_form)) {
|
||||
return true;
|
||||
} else {
|
||||
bool isExcluded = false;
|
||||
|
||||
list->ForEachForm([&](RE::TESForm& a_exform) {
|
||||
const auto exlist = a_exform.As<RE::BGSListForm>();
|
||||
if (exlist) {
|
||||
if (exlist->forms.size() > 0) {
|
||||
if (exlist->forms[0]->Is(RE::FormType::Keyword) ? a_form->HasKeywordInList(exlist, false) : exlist->HasForm(a_form)) {
|
||||
isExcluded = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const auto exkeyword = a_exform.As<RE::BGSKeyword>();
|
||||
if (exkeyword && a_form->As<RE::BGSKeywordForm>()->HasKeyword(exkeyword)) {
|
||||
isExcluded = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return isExcluded;
|
||||
}
|
||||
}
|
||||
|
||||
const RE::BGSKeyword* keyword = a_excludeForm->As<RE::BGSKeyword>();
|
||||
|
||||
if (keyword) {
|
||||
if (a_form->As<RE::BGSKeywordForm>()->HasKeyword(keyword)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline RE::ITEM_REMOVE_REASON get_remove_reason(RE::TESObjectREFR* atargetRef)
|
||||
{
|
||||
RE::ITEM_REMOVE_REASON iReason = RE::ITEM_REMOVE_REASON::kStoreInContainer;
|
||||
|
||||
if (atargetRef->As<RE::Actor>() && atargetRef->As<RE::Actor>()->IsPlayerTeammate()) {
|
||||
iReason = RE::ITEM_REMOVE_REASON::kStoreInTeammate;
|
||||
}
|
||||
|
||||
return iReason;
|
||||
}
|
||||
}
|
||||
|
||||
inline std::int32_t AddAllFormsToList(RE::StaticFunctionTag*,
|
||||
RE::BGSListForm* a_targetList,
|
||||
std::int32_t a_formType,
|
||||
RE::TESForm* a_keywordOrList = NULL,
|
||||
RE::TESForm* a_excludeForm = NULL,
|
||||
bool a_onlyPlayable = true)
|
||||
{
|
||||
const auto formType = static_cast<RE::FormType>(a_formType);
|
||||
|
||||
const auto keyword = a_keywordOrList ? a_keywordOrList->As<RE::BGSKeyword>() : nullptr;
|
||||
const auto keywordList = a_keywordOrList ? a_keywordOrList->As<RE::BGSListForm>() : nullptr;
|
||||
|
||||
const auto dataHandler = RE::TESDataHandler::GetSingleton();
|
||||
|
||||
if (!dataHandler) {
|
||||
return a_targetList->forms.size();
|
||||
}
|
||||
|
||||
for (const auto& form : dataHandler->GetFormArray(formType)) {
|
||||
if (!form) {
|
||||
continue;
|
||||
}
|
||||
if (a_onlyPlayable && !form->GetPlayable()) {
|
||||
continue;
|
||||
}
|
||||
if ((keyword && !form->As<RE::BGSKeywordForm>()->HasKeyword(keyword)) || (keywordList && !form->HasKeywordInList(keywordList, false))) {
|
||||
continue;
|
||||
}
|
||||
if (a_excludeForm && inv_util::is_excluded(form, a_excludeForm)) {
|
||||
continue;
|
||||
}
|
||||
a_targetList->AddForm(form);
|
||||
}
|
||||
|
||||
return a_targetList->forms.size();
|
||||
}
|
||||
|
||||
inline std::int32_t AddItemsOfTypeAndKeywordToList(VM* a_vm, StackID a_stackID, RE::StaticFunctionTag*,
|
||||
RE::TESForm* a_refOrList,
|
||||
RE::BGSListForm* a_targetList,
|
||||
std::uint32_t a_formType = 0,
|
||||
RE::TESForm* a_keywordOrList = NULL,
|
||||
RE::TESForm* a_excludeForm = NULL,
|
||||
bool a_noEquipped = TRUE,
|
||||
bool a_noFavourited = TRUE,
|
||||
bool a_noQuestItem = TRUE)
|
||||
{
|
||||
if (!a_refOrList) {
|
||||
a_vm->TraceStack("a_refOrList in AddItemsOfTypeAndKeywordToList is None", a_stackID);
|
||||
return 0;
|
||||
}
|
||||
if (!a_targetList) {
|
||||
a_vm->TraceStack("a_targetList in AddItemsOfTypeAndKeywordToList is None", a_stackID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a_refOrList->Is(RE::FormType::FormList)) {
|
||||
a_refOrList->As<RE::BGSListForm>()->ForEachForm([&](RE::TESForm& a_exform) {
|
||||
const auto refrItem = a_exform.As<RE::TESObjectREFR>();
|
||||
if (refrItem) {
|
||||
AddItemsOfTypeAndKeywordToList(a_vm, a_stackID, {}, refrItem, a_targetList, a_formType, a_keywordOrList, a_excludeForm, a_noEquipped, a_noFavourited, a_noQuestItem);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return a_targetList->forms.size();
|
||||
}
|
||||
|
||||
const auto containerRef = a_refOrList->As<RE::TESObjectREFR>();
|
||||
|
||||
if (!containerRef) {
|
||||
a_vm->TraceStack("containerRef in AddItemsOfTypeAndKeywordToList is not a reference", a_stackID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto formType = static_cast<RE::FormType>(a_formType);
|
||||
const bool bNoType = formType == RE::FormType::None;
|
||||
|
||||
const auto keyword = a_keywordOrList ? a_keywordOrList->As<RE::BGSKeyword>() : nullptr;
|
||||
const auto keywordList = a_keywordOrList ? a_keywordOrList->As<RE::BGSListForm>() : nullptr;
|
||||
|
||||
auto inv = containerRef->GetInventory([&](RE::TESBoundObject& a_exform) {
|
||||
return (bNoType || a_exform.formType == formType)
|
||||
&& (
|
||||
(!keyword && !keywordList)
|
||||
|| (keyword && a_exform.As<RE::BGSKeywordForm>()->HasKeyword(keyword))
|
||||
|| (keywordList && a_exform.HasKeywordInList(keywordList, false)))
|
||||
&& (!a_excludeForm || !inv_util::is_excluded(&a_exform, a_excludeForm))
|
||||
&& a_exform.GetPlayable() && a_exform.formID != 0x000001F4;
|
||||
});
|
||||
|
||||
if (containerRef->IsPlayerRef()) {
|
||||
for (const auto& [item, data] : inv) {
|
||||
const auto& [count, entry] = data;
|
||||
if (count > 0 && inv_util::can_be_taken(entry, a_noEquipped, a_noFavourited, a_noQuestItem)) {
|
||||
a_targetList->AddForm(item);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const auto& [item, data] : inv) {
|
||||
const auto& [count, entry] = data;
|
||||
if (count > 0) {
|
||||
a_targetList->AddForm(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return a_targetList->forms.size();
|
||||
}
|
||||
|
||||
inline std::uint32_t GetItemCountInList(RE::StaticFunctionTag*,
|
||||
RE::BGSListForm* a_containerList,
|
||||
RE::TESBoundObject* a_form)
|
||||
@ -256,10 +68,6 @@ namespace Papyrus::ObjectReference
|
||||
|
||||
inline void Bind(VM& a_vm)
|
||||
{
|
||||
BIND(AddAllFormsToList);
|
||||
logger::info("Registered AddAllFormsToList"sv);
|
||||
BIND(AddItemsOfTypeAndKeywordToList);
|
||||
logger::info("Registered AddItemsOfTypeAndKeywordToList"sv);
|
||||
BIND(GetItemCountInList);
|
||||
logger::info("Registered GetItemCountInList"sv);
|
||||
BIND(GetItemCountInActors);
|
||||
|
@ -9,7 +9,7 @@ namespace Papyrus {
|
||||
using StackID = RE::VMStackID;
|
||||
using Severity = RE::BSScript::ErrorLogger::Severity;
|
||||
|
||||
inline constexpr auto script = "EddsArtifactTracker"sv;
|
||||
inline constexpr auto script = "ETR_Functions"sv;
|
||||
|
||||
bool Bind(VM* a_vm);
|
||||
}
|
||||
|
@ -1,12 +1,8 @@
|
||||
Scriptname ETR_Functions Hidden
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; ObjectReference functions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
int function AddAllFormsToList(FormList targetList, int formType, Form excludeForm = None) native global
|
||||
|
||||
int function AddAllFormsToList(FormList targetList, int formType, Form keywordOrList = None, Form excludeForm = None, bool onlyPlayable = true) native global
|
||||
|
||||
int function AddItemsOfTypeAndKeywordToList(Form refOrList, FormList targetList, int formType = 0, Form keywordOrList = None, Form excludeForm = None, bool noEquipped = true, bool noFavourited = true, bool noQuestItem = true) 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
|
||||
|
||||
@ -14,10 +10,6 @@ int function GetItemCountInActors(Actor[] refArray, Form baseForm) native global
|
||||
|
||||
Actor[] function GetPlayerFollowers() native global
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Artifact Tracker
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
ObjectReference function GetCellStorage(ObjectReference ref, FormList refList, Form refToCreate, bool autoCreate = true) native global
|
||||
|
||||
bool function HasRefInCell(Form item, Cell currentCell = None, bool checkContainers = true, FormList excludeList = None) native global
|
||||
|
@ -7,17 +7,20 @@ FormList Property ETR_ItemsFound Auto
|
||||
FormList Property ETR_ItemsStored Auto
|
||||
FormList Property ETR_PersistentStorageList Auto
|
||||
FormList Property ETR_ExcludeFromNew Auto
|
||||
FormList Property ETR_ExcludeFromCellItems Auto
|
||||
FormList Property ETR_ExcludeMisc Auto
|
||||
|
||||
Container Property ETR_CellStorageContainer Auto
|
||||
|
||||
Keyword Property LocTypePlayerHouse Auto
|
||||
|
||||
bool bAtHome = false
|
||||
bool bBusy = false
|
||||
int iFollowerIndex = 0
|
||||
bool bUpdateFollowers = false
|
||||
bool bSyncStorage = false
|
||||
bool bUpdateLists = false
|
||||
bool bAtHome = false
|
||||
bool bRescanHome = false
|
||||
bool bRescanPersistent = false
|
||||
ObjectReference lastDestContainer = None
|
||||
bool lastDestIsPersistent = false
|
||||
int iUpdateCount
|
||||
|
||||
|
||||
event OnInit()
|
||||
@ -27,12 +30,16 @@ endevent
|
||||
|
||||
Event OnPlayerLoadGame()
|
||||
AddInventoryEventFilter(ETR_ItemsFound)
|
||||
Location currentLocation = PlayerRef.GetCurrentLocation()
|
||||
bAtHome = currentLocation && currentLocation.HasKeyword(LocTypePlayerHouse)
|
||||
lastDestContainer = None
|
||||
EndEvent
|
||||
|
||||
|
||||
Event OnLocationChange(Location akOldLoc, Location akNewLoc)
|
||||
|
||||
bAtHome = akNewLoc && akNewLoc.HasKeyword(LocTypePlayerHouse)
|
||||
lastDestContainer = None
|
||||
|
||||
int iCurrentFollowers = 0;
|
||||
Actor[] aFollowers = ETR_Functions.GetPlayerFollowers()
|
||||
@ -43,105 +50,96 @@ Event OnLocationChange(Location akOldLoc, Location akNewLoc)
|
||||
endwhile
|
||||
|
||||
if iCurrentFollowers != iFollowerIndex
|
||||
; If the list of followers has changed, rebuild ETR_ItemsFound and ETR_ItemsNew
|
||||
iFollowerIndex = iCurrentFollowers
|
||||
bUpdateFollowers = true
|
||||
bRescanHome = false
|
||||
bRescanPersistent = false
|
||||
RegisterForSingleUpdate(3.0) ; wait until followers load into the location
|
||||
endif
|
||||
|
||||
endEvent
|
||||
|
||||
|
||||
Event OnMenuClose(String MenuName)
|
||||
UnregisterForUpdate()
|
||||
OnUpdate()
|
||||
EndEvent
|
||||
|
||||
|
||||
Event OnUpdate()
|
||||
|
||||
Actor[] aFollowers
|
||||
int i
|
||||
if UI.IsMenuOpen("ContainerMenu")
|
||||
RegisterForMenu("ContainerMenu")
|
||||
return
|
||||
endif
|
||||
|
||||
if bUpdateLists
|
||||
while bBusy
|
||||
Debug.Notification("Found OnUpdate is busy")
|
||||
Utility.wait(0.5)
|
||||
endwhile
|
||||
|
||||
if Utility.IsInMenuMode()
|
||||
RegisterForSingleUpdate(1.0)
|
||||
bBusy = true
|
||||
|
||||
iUpdateCount += 1
|
||||
Debug.Notification("Running Found OnUpdate " + iUpdateCount)
|
||||
|
||||
if bRescanHome
|
||||
if lastDestContainer && lastDestContainer as Actor && (lastDestContainer as Actor).IsPlayerTeammate()
|
||||
lastDestContainer = None
|
||||
return
|
||||
endif
|
||||
|
||||
bUpdateLists = false
|
||||
bUpdateFollowers = false
|
||||
|
||||
if bSyncStorage
|
||||
bSyncStorage = false
|
||||
ObjectReference cellStorage = ETR_Functions.GetCellStorage(PlayerRef, ETR_PersistentStorageList, ETR_CellStorageContainer)
|
||||
ETR_Functions.SyncCellStorage(cellStorage, ETR_ExcludeFromCellItems)
|
||||
bRescanHome = false
|
||||
ObjectReference cellStorage = ETR_Functions.GetCellStorage(PlayerRef, ETR_PersistentStorageList, ETR_CellStorageContainer)
|
||||
ETR_Functions.SyncCellStorage(cellStorage, ETR_ExcludeMisc)
|
||||
if ! bRescanPersistent
|
||||
ETR_Functions.AddArtifactsToList(cellStorage, ETR_ItemsStored)
|
||||
endif
|
||||
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(ETR_PersistentStorageList, ETR_ItemsStored, 26, None, ETR_ExcludeFromCellItems)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(ETR_PersistentStorageList, ETR_ItemsStored, 41, None, ETR_ExcludeFromCellItems)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(ETR_PersistentStorageList, ETR_ItemsStored, 27, None, ETR_ExcludeFromCellItems)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(ETR_PersistentStorageList, ETR_ItemsStored, 32, None, ETR_ExcludeFromCellItems)
|
||||
|
||||
ETR_ItemsFound.Revert()
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 26, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 41, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 27, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 32, None, ETR_ExcludeFromNew, false, false, false)
|
||||
|
||||
aFollowers = ETR_Functions.GetPlayerFollowers()
|
||||
i = aFollowers.length
|
||||
while i > 0
|
||||
i -= 1
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 26, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 41, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 27, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 32, None, ETR_ExcludeFromNew, false, false, false)
|
||||
endwhile
|
||||
|
||||
ETR_ItemsNew.Revert()
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 26, None, ETR_ExcludeFromNew) ; armor
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 41, None, ETR_ExcludeFromNew) ; weapons
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 27, None, ETR_ExcludeFromNew) ; books
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 32, None, ETR_ExcludeFromNew) ; misc items
|
||||
|
||||
return
|
||||
|
||||
endif
|
||||
|
||||
if bUpdateFollowers
|
||||
bUpdateFollowers = false
|
||||
|
||||
Debug.Notification("Team changed, updating lists")
|
||||
|
||||
ETR_ItemsFound.Revert()
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 26, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 41, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 27, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 32, None, ETR_ExcludeFromNew, false, false, false)
|
||||
|
||||
aFollowers = ETR_Functions.GetPlayerFollowers()
|
||||
i = aFollowers.length
|
||||
while i > 0
|
||||
i -= 1
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 26, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 41, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 27, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 32, None, ETR_ExcludeFromNew, false, false, false)
|
||||
if bRescanPersistent
|
||||
bRescanPersistent = false
|
||||
Form[] aContainers = ETR_PersistentStorageList.ToArray()
|
||||
int n = aContainers.length
|
||||
while n > 0
|
||||
n -= 1
|
||||
ETR_Functions.AddArtifactsToList(aContainers[n], ETR_ItemsStored, ETR_ExcludeMisc, true)
|
||||
endwhile
|
||||
|
||||
ETR_ItemsNew.Revert()
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 26, None, ETR_ExcludeFromNew) ; armor
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 41, None, ETR_ExcludeFromNew) ; weapons
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 27, None, ETR_ExcludeFromNew) ; books
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 32, None, ETR_ExcludeFromNew) ; misc items
|
||||
|
||||
endif
|
||||
|
||||
ETR_ItemsFound.Revert()
|
||||
ETR_Functions.AddArtifactsToList(PlayerRef, ETR_ItemsFound, ETR_ExcludeFromNew)
|
||||
|
||||
Actor[] aFollowers = ETR_Functions.GetPlayerFollowers()
|
||||
int i = aFollowers.length
|
||||
while i > 0
|
||||
i -= 1
|
||||
ETR_Functions.AddArtifactsToList(aFollowers[i], ETR_ItemsFound, ETR_ExcludeFromNew)
|
||||
endwhile
|
||||
|
||||
bBusy = false
|
||||
|
||||
EndEvent
|
||||
|
||||
|
||||
event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
|
||||
|
||||
if akDestContainer
|
||||
bSyncStorage = bAtHome
|
||||
bUpdateLists = true
|
||||
RegisterForSingleUpdate(1.0)
|
||||
if lastDestContainer != akDestContainer
|
||||
lastDestContainer = akDestContainer
|
||||
lastDestIsPersistent = ETR_PersistentStorageList.HasForm(akDestContainer)
|
||||
endif
|
||||
; Moving items without latent functions should help with avoiding stack dumps
|
||||
if lastDestIsPersistent
|
||||
bRescanHome = false
|
||||
bRescanPersistent = true
|
||||
RegisterForSingleUpdate(0.5)
|
||||
elseif bAtHome
|
||||
bRescanHome = true
|
||||
bRescanPersistent = false
|
||||
RegisterForSingleUpdate(0.5)
|
||||
elseif PlayerRef.GetItemCount(akBaseItem) == 0 && ETR_Functions.GetItemCountInActors(ETR_Functions.GetPlayerFollowers(), akBaseItem) == 0
|
||||
ETR_ItemsFound.RemoveAddedForm(akBaseItem)
|
||||
ETR_ItemsNew.AddForm(akBaseItem)
|
||||
endif
|
||||
elseif bAtHome && akItemReference
|
||||
ETR_ItemsFound.RemoveAddedForm(akBaseItem)
|
||||
ETR_ItemsStored.AddForm(akBaseItem)
|
||||
|
@ -7,6 +7,8 @@ FormList Property ETR_ItemsFound Auto
|
||||
FormList Property ETR_ItemsStored Auto
|
||||
FormList Property ETR_ExcludeFromNew Auto
|
||||
FormList Property ETR_PersistentStorageList Auto
|
||||
FormList Property ETR_ExcludeMisc Auto
|
||||
FormList Property ETR_FoundAndStored Auto
|
||||
|
||||
|
||||
event OnInit()
|
||||
@ -36,37 +38,32 @@ event OnPlayerLoadGame()
|
||||
ahzmorehudie.RegisterIconFormList("dbmDisp", ETR_ItemsStored)
|
||||
endif
|
||||
|
||||
If SKSE.GetPluginVersion("QuickLootRE") >= 292
|
||||
QuickLootRE.RegisterNewItemsList(ETR_ItemsNew)
|
||||
QuickLootRE.RegisterDisplayedItemsList(ETR_ItemsStored)
|
||||
QuickLootRE.RegisterFoundItemsList(ETR_ItemsFound)
|
||||
endif
|
||||
|
||||
; Rebuild all lists to avoid discrepancies, stale data, and broken records
|
||||
|
||||
ETR_ItemsStored.Revert()
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(ETR_PersistentStorageList, ETR_ItemsStored, 26, None, ETR_ExcludeFromNew)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(ETR_PersistentStorageList, ETR_ItemsStored, 41, None, ETR_ExcludeFromNew)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(ETR_PersistentStorageList, ETR_ItemsStored, 27, None, ETR_ExcludeFromNew)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(ETR_PersistentStorageList, ETR_ItemsStored, 32, None, ETR_ExcludeFromNew)
|
||||
ETR_Functions.AddArtifactsToList(ETR_PersistentStorageList, ETR_ItemsStored, ETR_ExcludeMisc, true)
|
||||
|
||||
ETR_ItemsFound.Revert()
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 26, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 41, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 27, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(PlayerRef, ETR_ItemsFound, 32, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddArtifactsToList(PlayerRef, ETR_ItemsFound, ETR_ExcludeFromNew)
|
||||
|
||||
Actor[] aFollowers = ETR_Functions.GetPlayerFollowers()
|
||||
int i = aFollowers.length
|
||||
while i > 0
|
||||
i -= 1
|
||||
if ! aFollowers[i].IsDead() && ! aFollowers[i].IsDisabled()
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 26, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 41, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 27, None, ETR_ExcludeFromNew, false, false, false)
|
||||
ETR_Functions.AddItemsOfTypeAndKeywordToList(aFollowers[i], ETR_ItemsFound, 32, None, ETR_ExcludeFromNew, false, false, false)
|
||||
endif
|
||||
ETR_Functions.AddArtifactsToList(aFollowers[i], ETR_ItemsFound, ETR_ExcludeFromNew)
|
||||
endwhile
|
||||
|
||||
ETR_ItemsNew.Revert()
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 26, None, ETR_ExcludeFromNew) ; armor
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 41, None, ETR_ExcludeFromNew) ; weapons
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 27, None, ETR_ExcludeFromNew) ; books
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 32, None, ETR_ExcludeFromNew) ; misc items
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 26, ETR_FoundAndStored)
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 27, ETR_FoundAndStored)
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 32, ETR_ExcludeFromNew)
|
||||
ETR_Functions.AddAllFormsToList(ETR_ItemsNew, 41, ETR_FoundAndStored)
|
||||
|
||||
endevent
|
||||
|
||||
|
@ -6,12 +6,22 @@ FormList Property ETR_ItemsNew Auto
|
||||
FormList Property ETR_ItemsFound Auto
|
||||
FormList Property ETR_ItemsStored Auto
|
||||
FormList Property ETR_PersistentStorageList Auto
|
||||
FormList Property ETR_ExcludeFromNew Auto
|
||||
FormList Property ETR_ExcludeMisc Auto
|
||||
|
||||
Container Property ETR_CellStorageContainer Auto
|
||||
|
||||
Keyword Property LocTypePlayerHouse Auto
|
||||
|
||||
bool bBusy = false
|
||||
bool bAtHome = false
|
||||
bool bRescanHome = false
|
||||
bool bRescanPersistent = false
|
||||
ObjectReference lastDestContainer = None
|
||||
bool lastDestIsPersistent = false
|
||||
ObjectReference lastSourceContainer = None
|
||||
bool lastSourceIsPersistent = false
|
||||
int iUpdateCount
|
||||
|
||||
|
||||
event OnInit()
|
||||
@ -21,69 +31,134 @@ endevent
|
||||
|
||||
Event OnPlayerLoadGame()
|
||||
AddInventoryEventFilter(ETR_ItemsStored)
|
||||
Location currentLocation = PlayerRef.GetCurrentLocation()
|
||||
bAtHome = currentLocation && currentLocation.HasKeyword(LocTypePlayerHouse)
|
||||
if bAtHome
|
||||
GotoState("AtHome")
|
||||
else
|
||||
GotoState("")
|
||||
endif
|
||||
EndEvent
|
||||
|
||||
|
||||
Event OnLocationChange(Location akOldLoc, Location akNewLoc)
|
||||
bAtHome = akNewLoc && akNewLoc.HasKeyword(LocTypePlayerHouse)
|
||||
if bAtHome
|
||||
GotoState("AtHome")
|
||||
else
|
||||
GotoState("")
|
||||
endif
|
||||
endEvent
|
||||
|
||||
|
||||
; The item is already registered as stored, and we just stored more
|
||||
event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
|
||||
Event OnMenuClose(String MenuName)
|
||||
UnregisterForUpdate()
|
||||
OnUpdate()
|
||||
EndEvent
|
||||
|
||||
if ! bAtHome
|
||||
|
||||
Event OnUpdate()
|
||||
|
||||
if UI.IsMenuOpen("ContainerMenu")
|
||||
RegisterForMenu("ContainerMenu")
|
||||
return
|
||||
endif
|
||||
|
||||
if akDestContainer
|
||||
while bBusy
|
||||
Debug.Notification("Stored OnUpdate is busy")
|
||||
Utility.wait(0.5)
|
||||
endwhile
|
||||
|
||||
if !(akDestContainer as Actor)
|
||||
if ETR_PersistentStorageList.HasForm(akDestContainer)
|
||||
return
|
||||
endif
|
||||
elseif (akDestContainer as Actor).IsPlayerTeammate()
|
||||
bBusy = true
|
||||
|
||||
iUpdateCount += 1
|
||||
Debug.Notification("Running Stored OnUpdate " + iUpdateCount)
|
||||
|
||||
if bRescanHome
|
||||
if lastSourceContainer && lastSourceContainer as Actor && (lastSourceContainer as Actor).IsPlayerTeammate()
|
||||
lastSourceContainer = None
|
||||
return
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
if ((akDestContainer && akDestContainer.GetParentCell() == PlayerRef.GetParentCell()) || (! akDestContainer && ETR_Functions.HasRefInCell(akBaseItem, None, true, ETR_PersistentStorageList)))
|
||||
|
||||
ObjectReference cellStorage = ETR_Functions.GetCellStorage(PlayerRef, ETR_PersistentStorageList, ETR_CellStorageContainer)
|
||||
ETR_Functions.SyncCellStorage(cellStorage, ETR_ExcludeMisc)
|
||||
endif
|
||||
|
||||
if cellStorage.GetItemCount(akBaseItem) == 0
|
||||
cellStorage.AddItem(akBaseItem, 1, true)
|
||||
endif
|
||||
if bRescanPersistent
|
||||
|
||||
ETR_ItemsStored.Revert()
|
||||
Form[] aContainers = ETR_PersistentStorageList.ToArray()
|
||||
int n = aContainers.length
|
||||
while n > 0
|
||||
n -= 1
|
||||
ETR_Functions.AddArtifactsToList(aContainers[n], ETR_ItemsStored, ETR_ExcludeMisc, true)
|
||||
endwhile
|
||||
|
||||
ETR_ItemsFound.Revert()
|
||||
ETR_Functions.AddArtifactsToList(PlayerRef, ETR_ItemsFound, ETR_ExcludeFromNew)
|
||||
|
||||
Actor[] aFollowers = ETR_Functions.GetPlayerFollowers()
|
||||
int i = aFollowers.length
|
||||
while i > 0
|
||||
i -= 1
|
||||
ETR_Functions.AddArtifactsToList(aFollowers[i], ETR_ItemsFound, ETR_ExcludeFromNew)
|
||||
endwhile
|
||||
|
||||
endif
|
||||
|
||||
endevent
|
||||
bBusy = false
|
||||
|
||||
EndEvent
|
||||
|
||||
|
||||
; We took a stored item, and we want to find out if it's the last stored item of its kind
|
||||
; We acquired a stored item, and we want to find out if we just have taken the last stored item of its kind
|
||||
event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
|
||||
|
||||
if akSourceContainer && !(akSourceContainer as Actor) && ETR_PersistentStorageList.HasForm(akSourceContainer)
|
||||
if ETR_Functions.GetItemCountInList(ETR_PersistentStorageList, akBaseItem) == 0
|
||||
ETR_ItemsStored.RemoveAddedForm(akBaseItem)
|
||||
ETR_ItemsFound.AddForm(akBaseItem)
|
||||
if akSourceContainer
|
||||
if lastSourceContainer != akSourceContainer
|
||||
lastSourceContainer = akSourceContainer
|
||||
lastSourceIsPersistent = ETR_PersistentStorageList.HasForm(akSourceContainer)
|
||||
endif
|
||||
if bAtHome || lastSourceIsPersistent
|
||||
bRescanHome = bAtHome
|
||||
bRescanPersistent = true
|
||||
RegisterForSingleUpdate(0.5)
|
||||
endif
|
||||
|
||||
elseif bAtHome
|
||||
ObjectReference cellStorage = ETR_Functions.GetCellStorage(PlayerRef, ETR_PersistentStorageList, ETR_CellStorageContainer)
|
||||
int iCount = cellStorage.GetItemCount(akBaseItem)
|
||||
|
||||
if iCount > 0 && ! ETR_Functions.HasRefInCell(akBaseItem, None, true, ETR_PersistentStorageList)
|
||||
cellStorage.RemoveItem(akBaseItem, iCount, true)
|
||||
|
||||
if cellStorage.GetItemCount(akBaseItem)
|
||||
ETR_Functions.SyncCellStorage(cellStorage, ETR_ExcludeMisc)
|
||||
if ETR_Functions.GetItemCountInList(ETR_PersistentStorageList, akBaseItem) == 0
|
||||
ETR_ItemsStored.RemoveAddedForm(akBaseItem)
|
||||
ETR_ItemsFound.AddForm(akBaseItem)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
endevent
|
||||
|
||||
|
||||
state AtHome
|
||||
|
||||
; The item is already registered as stored, and we just stored more
|
||||
event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
|
||||
|
||||
if akDestContainer
|
||||
if lastDestContainer != akDestContainer
|
||||
lastDestContainer = akDestContainer
|
||||
lastDestIsPersistent = ETR_PersistentStorageList.HasForm(akDestContainer)
|
||||
endif
|
||||
if ! lastDestIsPersistent
|
||||
bRescanHome = true
|
||||
bRescanPersistent = false
|
||||
RegisterForSingleUpdate(0.5)
|
||||
endif
|
||||
elseif akItemReference
|
||||
ObjectReference cellStorage = ETR_Functions.GetCellStorage(PlayerRef, ETR_PersistentStorageList, ETR_CellStorageContainer)
|
||||
if cellStorage.GetItemCount(akBaseItem) == 0
|
||||
cellStorage.AddItem(akBaseItem, 1, true)
|
||||
endif
|
||||
endif
|
||||
|
||||
endevent
|
||||
|
||||
endstate
|
||||
|
Loading…
Reference in New Issue
Block a user