#pragma once #include "RE/B/BSFixedString.h" #include "RE/B/BSIntrusiveRefCounted.h" #include "RE/B/BSScript_CompiledScriptLoader.h" #include "RE/B/BSScript_ErrorLogger.h" #include "RE/B/BSScript_IClientVM.h" #include "RE/B/BSScript_IHandleReaderWriter.h" #include "RE/B/BSScript_IObjectHandlePolicy.h" #include "RE/B/BSScript_ISavePatcherInterface.h" #include "RE/B/BSScript_IStackCallbackSaveInterface.h" #include "RE/B/BSScript_IVirtualMachine.h" #include "RE/B/BSScript_Internal_IProfilePolicy.h" #include "RE/B/BSScript_MergedBoundScript.h" #include "RE/B/BSScript_ObjectBindPolicy.h" #include "RE/B/BSScript_SimpleAllocMemoryPagePolicy.h" #include "RE/B/BSScript_Variable.h" #include "RE/B/BSSpinLock.h" #include "RE/B/BSTArray.h" #include "RE/B/BSTEvent.h" #include "RE/B/BSTFreeList.h" #include "RE/B/BSTHashMap.h" #include "RE/B/BSTMessageQueue.h" #include "RE/B/BSTSingleton.h" #include "RE/B/BSTSmartPointer.h" #include "RE/B/BSTTuple.h" #include "RE/B/BSTimer.h" #include "RE/M/MemoryManager.h" namespace RE { template using BSTThreadScrapFunction = std::function; namespace BSScript { class IStore; class IVirtualMachine; class IVMDebugInterface; class IVMSaveLoadInterface; class Object; class StatsEvent; } namespace PlayerDifficultySettingChanged { class Event; } namespace RadioManager { class PipboyTransmitterDetectionEvent; } namespace Workshop { class ItemDestroyedEvent; class ItemGrabbedEvent; class ItemMovedEvent; class ItemPlacedEvent; class ItemRepairedEvent; class PowerOffEvent; class PowerOnEvent; class WorkshopModeEvent; } class BGSLocationLoadedEvent; class BGSOnPlayerCompanionDismiss; class BGSOnPlayerCreateRobotEvent; class BGSOnPlayerEnterVertibirdEvent; class BGSOnPlayerFallLongDistances; class BGSOnPlayerFireWeaponEvent; class BGSOnPlayerHealTeammateEvent; class BGSOnPlayerModArmorWeaponEvent; class BGSOnPlayerModRobotEvent; class BGSOnPlayerSwimmingEvent; class BGSOnPlayerUseWorkBenchEvent; class BGSOnSpeechChallengeAvailable; class BGSRadiationDamageEvent; class BSLog; class BSStorage; class InputEnableLayerDestroyedEvent; class PositionPlayerEvent; class TESActivateEvent; class TESActiveEffectApplyRemoveEvent; class TESActorLocationChangeEvent; class TESBookReadEvent; class TESCellAttachDetachEvent; class TESCellFullyLoadedEvent; class TESCombatEvent; class TESCommandModeCompleteCommandEvent; class TESCommandModeEnterEvent; class TESCommandModeExitEvent; class TESCommandModeGiveCommandEvent; class TESConsciousnessEvent; class TESDeathEvent; class TESDeferredKillEvent; class TESDestructionStageChangedEvent; class TESEnterBleedoutEvent; class TESEnterSneakingEvent; class TESEscortWaitStartEvent; class TESEscortWaitStopEvent; class TESExitFurnitureEvent; class TESFile; class TESFormDeleteEvent; class TESFormIDRemapEvent; class TESFurnitureEvent; class TESGrabReleaseEvent; class TESHitEvent; class TESInitScriptEvent; class TESLimbCrippleEvent; class TESLoadGameEvent; class TESLocationClearedEvent; class TESLockChangedEvent; class TESMagicEffectApplyEvent; class TESObjectLoadedEvent; class TESObjectREFRTranslationEvent; class TESOnPCDialogueTargetEvent; class TESOpenCloseEvent; class TESPickpocketFailedEvent; class TESQuestInitEvent; class TESResetEvent; class TESResolveNPCTemplatesEvent; class TESSellEvent; class TESSpellCastEvent; class TESSwitchRaceCompleteEvent; class TESTrapHitEvent; class TESTriggerEnterEvent; class TESTriggerLeaveEvent; class TESUniqueIDChangeEvent; class WorkshopNPCTransferEvent; namespace GameScript { class DelayFunctor; class StatsEvent; namespace Internal { class HitRegistrationList; class MagicEffectApplyRegistrationList; class RadiationDamageRegistrationList; } inline void LogFormError( const TESForm* a_obj, const char* a_error, BSScript::IVirtualMachine* a_vm, std::uint32_t a_stackID, BSScript::ErrorLogger::Severity a_severity = BSScript::ErrorLogger::Severity::kError) { using func_t = decltype(&LogFormError); static REL::Relocation func{ ID::GameScript::LogFormError }; return func(a_obj, a_error, a_vm, a_stackID, a_severity); } class GetWorkshopResourceObjectsLinkedRefChildVisitor { public: enum class OPTIONS : std::uint32_t { kAllObjects = 0x0, kDamagedObjects = 0x1, kUndamagedObjects = 0x2 }; // members BSScrapArray* array; // 00 const ActorValueInfo* filter; // 08 std::uint32_t option; // 10 }; static_assert(sizeof(GetWorkshopResourceObjectsLinkedRefChildVisitor) == 0x18); class __declspec(novtable) DelayFunctor : public BSIntrusiveRefCounted // 08 { public: static constexpr auto RTTI{ RTTI::GameScript__DelayFunctor }; static constexpr auto VTABLE{ VTABLE::GameScript__DelayFunctor }; enum class FunctorType { kMoveTo = 0x0, kMoveToOwnEditorLoc = 0x1, kDamageObject = 0x2, kEnable = 0x3, kDisable = 0x4, kDelete = 0x5, kSetPosition = 0x6, kSetAngle = 0x7, kSetMotionType = 0x8, kNonLatentDelete = 0x9, kMoveToPackLoc = 0xA, kSetScale = 0xB, kDropObject = 0xC, kAttachAshPile = 0xD, kAddRemoveConstraint = 0xE, kAddRemoveRagdoll = 0xF, kApplyHavokImpulse = 0x10, kResetRefr = 0x11, kSendPlayerToJail = 0x12, kAddItem = 0x13, kResurrect = 0x14, kCast = 0x15, kScrollCast = 0x16, kRemoveItem = 0x17, kWaitFor3D = 0x18, kPlayBink = 0x19, kMoveToNearestNavmesh = 0x1A, kClearDestruction = 0x1B, kWaitForResourceRecalc = 0x1C, kRemoveComponent = 0x1D, kDropRe = 0x1Ef }; virtual ~DelayFunctor(); // 00 // add [[nodiscard]] virtual BSScript::Variable operator()() = 0; // 01 [[nodiscard]] virtual bool IsLatent() const = 0; // 02 [[nodiscard]] virtual bool WantsRequeue() const { return false; } // 03 [[nodiscard]] virtual FunctorType GetType() const = 0; // 04 virtual bool SaveImpl(BSStorage& a_storage) const = 0; // 05 virtual bool LoadImpl(const BSStorage& a_storage, std::uint32_t a_scriptSaveVersion, bool& a_dataValid) = 0; // 06 F4_HEAP_REDEFINE_NEW(DelayFunctor); // members std::uint32_t stackID; // 0C }; static_assert(sizeof(DelayFunctor) == 0x10); class __declspec(novtable) Logger : public BSScript::ErrorLogger // 00 { public: static constexpr auto RTTI{ RTTI::GameScript__Logger }; static constexpr auto VTABLE{ VTABLE::GameScript__Logger }; // override (BSScript::ErrorLogger) void PostErrorImpl(const BSScript::ICachedErrorMessage* a_errMsg, Severity a_severity) override; // 01 // members BSFixedString logFolder; // A0 BSLog* log; // A8 }; static_assert(sizeof(Logger) == 0xB0); class __declspec(novtable) HandlePolicy : public BSScript::IObjectHandlePolicy // 00 { public: static constexpr auto RTTI{ RTTI::GameScript__HandlePolicy }; static constexpr auto VTABLE{ VTABLE::GameScript__HandlePolicy }; // override (BSScript::IObjectHandlePolicy) bool HandleIsType(std::uint32_t a_type, std::size_t a_handle) const override; // 01 bool GetHandleType(std::size_t a_handle, std::uint32_t& a_type) const override; // 02 bool IsHandleLoaded(std::size_t a_handle) const override; // 03 bool IsHandleObjectAvailable(std::size_t a_handle) const override; // 04 bool ShouldAttemptToCleanHandle(std::size_t a_handle) const override; // 05 std::size_t EmptyHandle() const override { return 0xFFFF00000000; } // 06 std::size_t GetHandleForObject(std::uint32_t a_type, const void* a_object) const override; // 07 bool HasParent(std::size_t a_childHandle) const override; // 08 std::size_t GetParentHandle(std::size_t a_childHandle) const override; // 09 std::size_t GetHandleScriptsMovedFrom(std::size_t a_newHandle) const override; // 0A std::size_t GetSaveRemappedHandle(std::size_t a_saveHandle) const override; // 0B void* GetObjectForHandle(std::uint32_t a_type, std::size_t a_handle) const override; // 0C void PersistHandle(std::size_t a_handle) override; // 0D void ReleaseHandle(std::size_t a_handle) override; // 0E void ConvertHandleToString(std::size_t a_handle, BSFixedString& a_string) const override; // 0F [[nodiscard]] static std::uint64_t GetHandleForInventoryID(std::uint16_t a_uniqueID, std::uint32_t a_containerFormID) noexcept { return static_cast(static_cast(a_containerFormID)) | (static_cast(a_uniqueID) << 32ull) | (1ull << (32ull + 16ull)); } void DropSaveLoadRemapData() { using func_t = decltype(&HandlePolicy::DropSaveLoadRemapData); static REL::Relocation func{ ID::GameScript::HandlePolicy::DropSaveLoadRemapData }; return func(this); } void GetInventoryObjFromHandle(std::uint64_t a_cobj, TESObjectREFR*& a_container, std::uint16_t& a_uniqueID, TESObjectREFR*& a_inWorldREFR) { using func_t = decltype(&HandlePolicy::GetInventoryObjFromHandle); static REL::Relocation func{ ID::GameScript::HandlePolicy::GetInventoryObjFromHandle }; return func(this, a_cobj, a_container, a_uniqueID, a_inWorldREFR); } void UpdatePersistence() { using func_t = decltype(&HandlePolicy::UpdatePersistence); static REL::Relocation func{ ID::GameScript::HandlePolicy::UpdatePersistence }; return func(this); } // members BSSpinLock persistLock; // 08 BSTHashMap persistRefCount; // 10 BSTHashMap queuedPromotes; // 40 BSSpinLock remapLock; // 70 BSTHashMap changedFormIDs; // 78 }; static_assert(sizeof(HandlePolicy) == 0xA8); class __declspec(novtable) ObjectBindPolicy : public BSScript::ObjectBindPolicy // 00 { public: static constexpr auto RTTI{ RTTI::GameScript__ObjectBindPolicy }; static constexpr auto VTABLE{ VTABLE::GameScript__ObjectBindPolicy }; class QueuedObject { public: // members BSTSmartPointer createdObject; // 00 BSScript::MergedBoundScript boundInfo; // 08 }; static_assert(sizeof(QueuedObject) == 0x18); // override (BSScript::ObjectBindPolicy) void EnsureBaseDataLoaded(std::size_t a_objHandle) override; // 01 void ObjectNoLongerNeeded(std::size_t a_objHandle) override; // 02 void AddBoundInfoImpl(std::size_t a_objHandle) override; // 03 void ClearBoundInfoImpl(std::size_t a_objHandle) override; // 04 void ClearDiskLoadedBoundInfoImpl(std::size_t a_objHandle) override; // 05 void ClearAllBoundInfoImpl() override; // 06 void PostBindObject(std::size_t a_objHandle) override; // 07 std::uint32_t GetExtraInfoSize(std::size_t) const override { return 0; } // 08 void WriteExtraInfo(std::size_t, const BSScript::IHandleReaderWriter&, BSStorage&) const override { return; } // 09 void ReadExtraInfo(std::size_t a_objHandle, std::uint16_t a_handleVersion, const BSScript::IHandleReaderWriter& a_handleReaderWriter, const BSStorage& a_storage) override; // 0A bool IsIgnoringClear() const override; // 0B void ResolveProperties(std::size_t a_objTarget, const BSTSmartPointer& a_object, const BSTSmartPointer& a_boundScript, bool a_postSaveConstOnly) override; // 0D void ResolveProperties(std::size_t a_objTarget, const BSTSmartPointer& a_object, const BSScript::MergedBoundScript& a_boundScript, bool a_postSaveConstOnly) override; // 0C void ConvertProperties(std::size_t a_objTarget, const BSTSmartPointer& a_boundScript, bool a_constOnly, BSTScrapHashMap& a_properties, std::uint32_t& a_nonConvertedProperties) const override; // 0F void ConvertProperties(std::size_t a_objTarget, const BSScript::MergedBoundScript& a_mergedScript, bool a_constOnly, BSTScrapHashMap& a_properties, std::uint32_t& a_nonConvertedProperties) const override; // 0E void EndSaveLoad() { using func_t = decltype(&ObjectBindPolicy::EndSaveLoad); static REL::Relocation func{ ID::GameScript::ObjectBindPolicy::EndSaveLoad }; return func(this); } // members BSSpinLock queueLock; // 50 bool resolveCalled; // 58 bool ignoringClear; // 59 bool initialLoadDone; // 5A BSTHashMap> queuedObjects; // 60 BSTArray queuedAliases; // 90 BSTSet initiallyLoadedObjects; // A8 }; static_assert(sizeof(ObjectBindPolicy) == 0xD8); class FragmentSystem { public: class Fragment : public BSIntrusiveRefCounted // 00 { public: // members BSFixedString objectName; // 08 BSFixedString functionName; // 10 }; static_assert(sizeof(Fragment) == 0x18); class QuestStageFragments : public BSIntrusiveRefCounted // 00 { public: // members BSTHashMap> itemFragments; // 08 }; static_assert(sizeof(QuestStageFragments) == 0x38); class QuestFragments : public BSIntrusiveRefCounted // 00 { public: // members BSTHashMap> stageFragments; // 08 }; static_assert(sizeof(QuestFragments) == 0x38); class BeginEndFragments : public BSIntrusiveRefCounted // 00 { public: // members BSTSmartPointer beginFragment; // 08 BSTSmartPointer endFragment; // 10 }; static_assert(sizeof(BeginEndFragments) == 0x18); class SceneFragments : public BSIntrusiveRefCounted // 00 { public: // members BSTSmartPointer beginFragment; // 08 BSTSmartPointer endFragment; // 10 BSTHashMap> actionFragments; // 18 BSTHashMap> phaseFragments; // 48 }; static_assert(sizeof(SceneFragments) == 0x78); class PackageFragments : public BSIntrusiveRefCounted // 00 { public: // members BSTSmartPointer beginFragment; // 08 BSTSmartPointer endFragment; // 10 BSTSmartPointer changeFragment; // 18 }; static_assert(sizeof(PackageFragments) == 0x20); class PerkFragments : public BSIntrusiveRefCounted // 00 { public: // members BSTHashMap> entryFragments; // 08 }; static_assert(sizeof(PerkFragments) == 0x38); class TerminalFragments : public BSIntrusiveRefCounted // 00 { public: // members BSTHashMap> menuItemFragments; // 08 }; static_assert(sizeof(TerminalFragments) == 0x38); // members BSTHashMap> questFragments; // 000 BSSpinLock kQuestFragmentSpinLock; // 030 BSTHashMap> topicInfoFragments; // 038 BSSpinLock kTopicInfoFragmentSpinLock; // 068 BSTHashMap> sceneFragments; // 070 BSSpinLock kSceneFragmentSpinLock; // 0A0 BSTHashMap> packageFragments; // 0A8 BSSpinLock kPackageFragmentSpinLock; // 0D8 BSTHashMap> perkFragments; // 0E0 BSSpinLock kPerkFragmentSpinLock; // 110 BSTHashMap> terminalFragments; // 118 BSSpinLock kTerminalFragmentSpinLock; // 148 BSTHashMap> boundScripts; // 150 BSSpinLock kBindInfoSpinLock; // 180 }; static_assert(sizeof(FragmentSystem) == 0x188); class __declspec(novtable) Profiler : public BSScript::IProfilePolicy // 000 { public: static constexpr auto RTTI{ RTTI::GameScript__Profiler }; static constexpr auto VTABLE{ VTABLE::GameScript__Profiler }; // override (BSScript::IProfilePolicy) void StackFramePushQueued(std::uint32_t a_stackID, std::uint32_t a_frameNumber, const BSTSmartPointer& a_funcCallQuery) override; // 01 void StackFramePushed(std::uint32_t a_stackID, std::uint32_t a_frameNumber, const BSScript::Variable& a_self, const BSFixedString& a_scriptName, const BSFixedString& a_stateName, const BSFixedString& a_functionName) override; // 02 void StackFramePopQueued(std::uint32_t a_stackID, std::uint32_t a_frameNumber, const BSScript::Variable& a_self, const BSFixedString& a_scriptName, const BSFixedString& a_stateName, const BSFixedString& a_functionName) override; // 03 void StackFramePopped(std::uint32_t a_stackID, std::uint32_t a_frameNumber, const BSScript::Variable& a_self, const BSFixedString& a_scriptName, const BSFixedString& a_stateName, const BSFixedString& a_functionName) override; // 04 // members BSSpinLock dataLock; // 008 BSLog* globalProfilingLog; // 010 BSTHashMap watchedStacks; // 018 BSTHashMap watchedScripts; // 048 BSTHashMap watchedObjects; // 078 BSTArray> watchedStackRoots; // 0A8 BSTimer timer; // 0C0 }; static_assert(sizeof(Profiler) == 0x110); class __declspec(novtable) SavePatcher : public BSScript::ISavePatcherInterface // 0 { public: static constexpr auto RTTI{ RTTI::GameScript__SavePatcher }; static constexpr auto VTABLE{ VTABLE::GameScript__SavePatcher }; // override (BSScript::ISavePatcherInterface) void PatchStackFrame(BSScript::StackFrame&, BSScript::IVirtualMachine&) override { return; } // 01 }; static_assert(sizeof(SavePatcher) == 0x8); } class __declspec(novtable) GameVM : public BSScript::IClientVM, // 0000 public BSScript::IStackCallbackSaveInterface, // 0008 public BSTEventSink, // 0010 public BSTEventSink, // 0018 public BSTEventSink, // 0020 public BSTEventSink, // 0028 public BSTEventSink, // 0030 public BSTEventSink, // 0037 public BSTEventSink, // 0040 public BSTEventSink, // 0048 public BSTSingletonSDM, // 0050 public BSTEventSource // 0058 { public: static constexpr auto RTTI{ RTTI::GameVM }; static constexpr auto VTABLE{ VTABLE::GameVM }; [[nodiscard]] static GameVM* GetSingleton() { static REL::Relocation singleton{ ID::GameScript::GameVM::Singleton }; return *singleton; } [[nodiscard]] BSTSmartPointer GetVM() const noexcept { return impl; } bool QueuePostRenderCall(const BSTSmartPointer& a_functor) { using func_t = decltype(&GameVM::QueuePostRenderCall); static REL::Relocation func{ ID::GameScript::GameVM::QueuePostRenderCall }; return func(this, a_functor); } void RegisterForAllGameEvents() { using func_t = decltype(&GameVM::RegisterForAllGameEvents); static REL::Relocation func{ ID::GameScript::GameVM::RegisterForAllGameEvents }; return func(this); } void SendEventToObjectAndRelated( std::size_t a_object, const BSFixedString& a_eventName, const BSTThreadScrapFunction&)>& a_args, const BSTThreadScrapFunction&)>& a_filter, const BSTSmartPointer& a_callback) { using func_t = decltype(&GameVM::SendEventToObjectAndRelated); static REL::Relocation func{ ID::GameScript::GameVM::SendEventToObjectAndRelated }; return func(this, a_object, a_eventName, a_args, a_filter, a_callback); } // members BSTSmartPointer impl; // 00B0 BSScript::IVMSaveLoadInterface* saveLoadInterface; // 00B8 BSScript::IVMDebugInterface* debugInterface; // 00C0 BSScript::SimpleAllocMemoryPagePolicy memoryPagePolicy; // 00C8 BSScript::CompiledScriptLoader scriptLoader; // 00F8 GameScript::Logger logger; // 0130 GameScript::HandlePolicy handlePolicy; // 01E0 GameScript::ObjectBindPolicy objectBindPolicy; // 0288 BSTSmartPointer scriptStore; // 0360 GameScript::FragmentSystem fragmentSystem; // 0368 GameScript::Profiler profiler; // 04F0 GameScript::SavePatcher savePatcher; // 0600 BSSpinLock freezeLock; // 0608 bool frozen; // 0610 BSSpinLock vmTimeLock; // 0614 std::uint32_t currentTime; // 061C std::uint32_t currentMenuModeTime; // 0620 std::uint32_t currentGameTime; // 0624 bool updateHasBeenRun; // 0628 bool saveLoad; // 0629 BSTStaticFreeList, 512> renderSafeFunctorPool1; // 0630 BSTCommonLLMessageQueue> renderSafeFunctorQueue1; // 2648 BSTStaticFreeList, 512> renderSafeFunctorPool2; // 2670 BSTCommonLLMessageQueue> renderSafeFunctorQueue2; // 4688 BSTStaticFreeList, 512> postRenderFunctorPool1; // 46B0 BSTCommonLLMessageQueue> postRenderFunctorQueue1; // 66C8 BSTStaticFreeList, 512> postRenderFunctorPool2; // 66F0 BSTCommonLLMessageQueue> postRenderFunctorQueue2; // 8708 BSSpinLock renderSafeQueueLock; // 8730 BSTCommonLLMessageQueue>* renderSafeQueueToReadFrom; // 8738 BSTCommonLLMessageQueue>* renderSafeQueueToWriteTo; // 8740 BSSpinLock postRenderQueueLock; // 8748 BSTCommonLLMessageQueue>* postRenderQueueToReadFrom; // 8750 BSTCommonLLMessageQueue>* postRenderQueueToWriteTo; // 8758 BSSpinLock userLogLock; // 8760 BSTHashMap userLogs; // 8768 BSSpinLock statsWarningLock; // 8798 std::uint32_t initialSuspendOverageTime; // 87A0 std::uint32_t initialRunningOverageTime; // 87A4 std::uint32_t initialStackMemoryOverageTime; // 87A8 std::uint32_t lastWarningTime; // 87AC std::uint32_t overflowFlags; // 87B0 }; static_assert(sizeof(GameVM) == 0x87B8); namespace GameScript { class __declspec(novtable) BasicEventHandler : public BSTEventSink, // 000 public BSTEventSink, // 008 public BSTEventSink, // 010 public BSTEventSink, // 018 public BSTEventSink, // 020 public BSTEventSink, // 028 public BSTEventSink, // 030 public BSTEventSink, // 038 public BSTEventSink, // 040 public BSTEventSink, // 048 public BSTEventSink, // 050 public BSTEventSink, // 058 public BSTEventSink, // 060 public BSTEventSink, // 068 public BSTEventSink, // 070 public BSTEventSink, // 078 public BSTEventSink, // 080 public BSTEventSink, // 088 public BSTEventSink, // 090 public BSTEventSink, // 098 public BSTEventSink, // 0A0 public BSTEventSink, // 0A8 public BSTEventSink, // 0B0 public BSTEventSink, // 0B8 public BSTEventSink, // 0C0 public BSTEventSink, // 0C8 public BSTEventSink, // 0D0 public BSTEventSink, // 0D8 public BSTEventSink, // 0E0 public BSTEventSink, // 0E8 public BSTEventSink, // 0F0 public BSTEventSink, // 0F8 public BSTEventSink, // 100 public BSTEventSink, // 108 public BSTEventSink, // 110 public BSTEventSink, // 118 public BSTEventSink, // 120 public BSTEventSink, // 128 public BSTEventSink, // 130 public BSTEventSink, // 138 public BSTEventSink, // 140 public BSTEventSink, // 148 public BSTEventSink, // 150 public BSTEventSink, // 158 public BSTEventSink, // 160 public BSTEventSink, // 168 public BSTEventSink, // 170 public BSTEventSink, // 178 public BSTEventSink, // 180 public BSTEventSink, // 188 public BSTEventSink, // 190 public BSTEventSink, // 198 public BSTEventSink, // 1A0 public BSTEventSink, // 1A8 public BSTEventSink, // 1B0 public BSTEventSink, // 1B8 public BSTEventSink, // 1C0 public BSTEventSink, // 1C8 public BSTEventSink, // 1D0 public BSTEventSink, // 1D8 public BSTEventSink, // 1E0 public BSTEventSink, // 1E8 public BSTSingletonSDM // 1F0 { public: static constexpr auto RTTI{ RTTI::GameScript__BasicEventHandler }; static constexpr auto VTABLE{ VTABLE::GameScript__BasicEventHandler }; // members GameVM* gameVM; // 1F8 FragmentSystem* fragmentSystem; // 200 HandlePolicy* handlePolicy; // 208 ObjectBindPolicy* objectBindPolicy; // 210 BSTSmartPointer vm; // 218 }; static_assert(sizeof(BasicEventHandler) == 0x220); class __declspec(novtable) CombatEventHandler : public BSTEventSink, // 00 public BSTEventSink, // 08 public BSTEventSink, // 10 public BSTSingletonSDM // 18 { public: static constexpr auto RTTI{ RTTI::GameScript__CombatEventHandler }; static constexpr auto VTABLE{ VTABLE::GameScript__CombatEventHandler }; // members BSTSmartPointer vm; // 20 BSSpinLock hitLock; // 28 BSTHashMap> hitEvents; // 30 BSSpinLock magicEffectApplyLock; // 60 BSTHashMap> magicEffectApplyEvents; // 68 BSSpinLock radiationDamageLock; // 98 BSTHashMap> radiationDamageEvents; // A0 }; static_assert(sizeof(CombatEventHandler) == 0xD0); class RefrOrInventoryObj { public: RefrOrInventoryObj() = default; explicit RefrOrInventoryObj(std::uint64_t a_cobj) { const auto vm = GameVM::GetSingleton(); vm->handlePolicy.GetInventoryObjFromHandle(a_cobj, _container, _uniqueID, _ref); } [[nodiscard]] TESObjectREFR* Container() const noexcept { return _container; } [[nodiscard]] TESObjectREFR* Reference() const noexcept { return _ref; } [[nodiscard]] std::uint16_t UniqueID() const noexcept { return _uniqueID; } private: // members TESObjectREFR* _ref{ nullptr }; // 00 TESObjectREFR* _container{ nullptr }; // 08 std::uint16_t _uniqueID{ 0 }; // 10 }; static_assert(sizeof(RefrOrInventoryObj) == 0x18); inline void BindCObject(const BSTSmartPointer& a_scriptObj, const RefrOrInventoryObj& a_cobj, BSScript::IVirtualMachine& a_vm) { using func_t = decltype(&BindCObject); static REL::Relocation func{ ID::GameScript::BindCObject }; return func(a_scriptObj, a_cobj, a_vm); } class __declspec(novtable) BaseHandleReaderWriter : public RE::BSScript::IHandleReaderWriter { public: inline static constexpr auto RTTI = { RTTI::GameScript__BaseHandleReaderWriter }; inline static constexpr auto VTABLE = { VTABLE::GameScript__BaseHandleReaderWriter }; ~BaseHandleReaderWriter() override; // 0 virtual std::uint16_t GetHandleVersion() const override; // 142D8E390 virtual bool WriteHandle(BSStorage& storage, std::uint64_t) const override; // 142D8E398 virtual bool ReadHandle(BSStorage const& storage, std::uint64_t&) const override; // 142D8E3A0 virtual bool ReadHandleNoRemap(BSStorage const& storage, std::uint64_t&) const override; // 142D8E3A8 virtual bool WriteFormID(BSStorage& storage, std::uint32_t) const = 0; // 142D8E3B0 virtual bool ReadFormID(const BSStorage& storage, std::uint32_t&) const = 0; // 142D8E3B8 // members BSScript::IObjectHandlePolicy* objectHandlePolicy; //08 }; static_assert(sizeof(BaseHandleReaderWriter) == 0x10); class DataFileHandleReaderWriter : public BaseHandleReaderWriter { public: inline static constexpr auto RTTI = { RTTI::GameScript__DataFileHandleReaderWriter }; inline static constexpr auto VTABLE = { VTABLE::GameScript__DataFileHandleReaderWriter }; ~DataFileHandleReaderWriter() override; // 0 //DataFileHandleReaderWriter(TESFile *f, BSScript::IObjectHandlePolicy * objectHandlePolicy); virtual bool WriteFormID(BSStorage& storage, std::uint32_t) const override; // 142D8E3B0 virtual bool ReadFormID(const BSStorage& storage, std::uint32_t&) const override; // 142D8E3B8 // members TESFile* file; //10 }; static_assert(sizeof(DataFileHandleReaderWriter) == 0x18); } }