#pragma once void RemoveListItem(RE::BGSListForm* a_List, RE::TESForm* a_form) { using func_t = decltype(&RemoveListItem); REL::Relocation func{ REL::RelocationID(20471, 20914) }; return func(a_List, a_form); } void RevertList(RE::TESForm* a_form) { using func_t = decltype(&RevertList); REL::Relocation func{ REL::RelocationID(20469, 20912) }; return func(a_form); } inline bool RefHasItem(RE::TESObjectREFR* a_ref, RE::TESForm* a_item) { if (!a_ref || !a_item) { SKSE::log::warn("Invalid arguments in RefHasItem"); return false; } auto invChanges = a_ref->GetInventoryChanges(); if (invChanges && invChanges->entryList) { for (auto& entry : *invChanges->entryList) { if (entry && entry->object && entry->object->formID == a_item->formID) { return entry->countDelta > 0; } } } return false; } inline std::uint32_t GetItemCountInList(RE::BGSListForm* a_containerList, RE::TESBoundObject* a_form) { if (!a_containerList || !a_form) { SKSE::log::warn("Invalid arguments in GetItemCountInList"); return 0; } std::uint32_t iResult = 0; a_containerList->ForEachForm([&](RE::TESForm& a_container) { const auto refrItem = a_container.As(); if (refrItem) { const auto inv = refrItem->GetInventory([&](RE::TESBoundObject& a_object) -> bool { return a_form->formID == a_object.formID; }); const auto it = inv.find(a_form); iResult += it != inv.end() ? it->second.first : 0; } return true; }); return iResult; } inline bool FollowersHaveItem(RE::TESBoundObject* a_form) { if (const auto processLists = RE::ProcessLists::GetSingleton(); processLists) { for (auto& actorHandle : processLists->highActorHandles) { if (auto actor = actorHandle.get(); actor && actor->IsPlayerTeammate()) { const auto inv = actor->GetInventory([&](RE::TESBoundObject& a_object) -> bool { return a_form->formID == a_object.formID; }); const auto it = inv.find(a_form); const auto iCount = it != inv.end() ? it->second.first : 0; if (iCount > 0) { return true; } } } } return false; }