From 85c1a2049897a292547d5026619c70bdce2ee260 Mon Sep 17 00:00:00 2001 From: nikitalita <69168929+nikitalita@users.noreply.github.com> Date: Thu, 19 Oct 2023 16:30:45 -0700 Subject: [PATCH 1/6] feat: add IVMObjectBindInterface.h --- .../include/RE/I/IVMObjectBindInterface.h | 32 +++++++++++++++++++ CommonLibSF/include/RE/Starfield.h | 1 + 2 files changed, 33 insertions(+) create mode 100644 CommonLibSF/include/RE/I/IVMObjectBindInterface.h diff --git a/CommonLibSF/include/RE/I/IVMObjectBindInterface.h b/CommonLibSF/include/RE/I/IVMObjectBindInterface.h new file mode 100644 index 00000000..e19bcf7d --- /dev/null +++ b/CommonLibSF/include/RE/I/IVMObjectBindInterface.h @@ -0,0 +1,32 @@ +#pragma once + +#include "RE/B/BSFixedString.h" +#include "RE/B/BSTSmartPointer.h" + +namespace RE +{ + namespace BSScript + { + class Object; + + struct __declspec(novtable) IVMObjectBindInterface + { + public: + SF_RTTI_VTABLE(BSScript__IVMObjectBindInterface); + virtual ~IVMObjectBindInterface(); // 00 + + // add + [[nodiscard]] virtual std::uint64_t GetBoundHandle(const BSTSmartPointer& a_objPtr) const = 0; // 01 + virtual void TypeCanBeBound(const BSFixedString& a_className, std::uint64_t a_handle) = 0; // 02 + virtual void BindObject(BSTSmartPointer& a_objPtr, std::uint64_t a_handle, bool a_conditional) = 0; // 03 + virtual void HandleLoadedBinding(BSTSmartPointer& a_objPtr, std::uint64_t a_handle, bool a_conditional) = 0; // 04 + virtual void RemoveAllBoundObjects(std::uint64_t a_handle) = 0; // 05 + virtual void RemoveAllDiskLoadedBoundObjects(std::uint64_t a_handle) = 0; // 06 + virtual void HandleCObjectDeletion(std::uint64_t a_handle) = 0; // 07 + virtual void UnbindObject(const BSTSmartPointer& a_objPtr) = 0; // 08 + virtual bool CreateObjectWithProperties(const BSFixedString& a_className, std::uint32_t a_numProperties, BSTSmartPointer& a_objPtr) = 0; // 09 + virtual bool InitObjectProperties(BSTSmartPointer& a_objPtr, void* a_property, bool a_arg3) = 0; // 0A + }; + static_assert(sizeof(IVMObjectBindInterface) == 0x8); + } +} diff --git a/CommonLibSF/include/RE/Starfield.h b/CommonLibSF/include/RE/Starfield.h index f5cb7a66..5eefd413 100644 --- a/CommonLibSF/include/RE/Starfield.h +++ b/CommonLibSF/include/RE/Starfield.h @@ -86,6 +86,7 @@ #include "RE/I/IPostAnimationChannelUpdateFunctor.h" #include "RE/I/IStoreAnimationActions.h" #include "RE/IDs.h" +#include "RE/I/IVMObjectBindInterface.h" #include "RE/M/MagicTarget.h" #include "RE/M/MemoryManager.h" #include "RE/M/MenuOpenCloseEvent.h" From c5606c8f4eee858a1d57a7c4d5a90efc7e7e31c0 Mon Sep 17 00:00:00 2001 From: nikitalita <69168929+nikitalita@users.noreply.github.com> Date: Thu, 19 Oct 2023 17:56:55 -0700 Subject: [PATCH 2/6] feat: Add ObjectBindPolicy --- CommonLibSF/include/RE/IDs.h | 5 + CommonLibSF/include/RE/O/ObjectBindPolicy.h | 144 ++++++++++++++++++++ CommonLibSF/include/RE/Starfield.h | 1 + 3 files changed, 150 insertions(+) create mode 100644 CommonLibSF/include/RE/O/ObjectBindPolicy.h diff --git a/CommonLibSF/include/RE/IDs.h b/CommonLibSF/include/RE/IDs.h index 415037ce..576bff6c 100644 --- a/CommonLibSF/include/RE/IDs.h +++ b/CommonLibSF/include/RE/IDs.h @@ -124,6 +124,11 @@ namespace RE::ID inline constexpr REL::ID PlayMenuSound{ 167344 }; } + namespace ObjectBindPolicy + { + inline constexpr REL::ID BindObject{ 195981 }; + } + namespace PlayerCamera { inline constexpr REL::ID singleton{ 878523 }; diff --git a/CommonLibSF/include/RE/O/ObjectBindPolicy.h b/CommonLibSF/include/RE/O/ObjectBindPolicy.h new file mode 100644 index 00000000..1ee60b8e --- /dev/null +++ b/CommonLibSF/include/RE/O/ObjectBindPolicy.h @@ -0,0 +1,144 @@ +#pragma once + +#include "RE/B/BSContainer.h" +#include "RE/B/BSFixedString.h" +#include "RE/B/BSLock.h" +#include "RE/B/BSTArray.h" +#include "RE/B/BSTEvent.h" +#include "RE/B/BSTSmartPointer.h" +#include "RE/IDs.h" + +namespace RE +{ + class BSStorage; + + namespace BSScript + { + class BoundScript; // stub + class IVirtualMachine; + class Object; + class Variable; + class MergedBoundScript + { + public: + // members + BSTSmartPointer childScript; // 00 + BSTSmartPointer parentScript; // 08 + }; + static_assert(sizeof(MergedBoundScript) == 0x10); + + struct IHandleReaderWriter; + struct IVMObjectBindInterface; + + namespace UnlinkedTypes + { + struct Object; // stub + } + + class ObjectBindPolicy + { + public: + SF_RTTI_VTABLE(BSScript__ObjectBindPolicy); + + virtual ~ObjectBindPolicy(); // 00 + + // add + virtual void EnsureBaseDataLoaded(std::size_t a_objHandle) = 0; // 01 + virtual void ObjectNoLongerNeeded(std::size_t a_objHandle) = 0; // 02 + virtual void AddBoundInfoImpl(std::size_t a_objHandle) = 0; // 03 + virtual void ClearBoundInfoImpl(std::size_t a_objHandle) = 0; // 04 + virtual void ClearDiskLoadedBoundInfoImpl(std::size_t a_objHandle) = 0; // 05 + virtual void ClearAllBoundInfoImpl() = 0; // 06 + virtual void PostBindObject(std::size_t a_objHandle) = 0; // 07 + virtual std::uint32_t GetExtraInfoSize(std::size_t) const = 0; // 08 + virtual void WriteExtraInfo(std::size_t, const IHandleReaderWriter&, BSStorage&) const = 0; // 09 + virtual void ReadExtraInfo(std::size_t a_objHandle, std::uint16_t a_handleVersion, const IHandleReaderWriter& a_handleReaderWriter, const BSStorage& a_storage) = 0; // 0A + virtual bool IsIgnoringClear() const = 0; // 0B + virtual void ResolveProperties(std::size_t a_objTarget, const BSTSmartPointer& a_object, const MergedBoundScript& a_boundScript, bool a_postSaveConstOnly) = 0; // 0C + virtual void ResolveProperties(std::size_t a_objTarget, const BSTSmartPointer& a_object, const BSTSmartPointer& a_boundScript, bool a_postSaveConstOnly) = 0; // 0D + virtual void ConvertProperties(std::size_t a_objTarget, const MergedBoundScript& a_mergedScript, bool a_constOnly, /*BSTScrapHashMap&*/ void* a_properties, std::uint32_t& a_nonConvertedProperties) const = 0; // 0E + virtual void ConvertProperties(std::size_t a_objTarget, const BSTSmartPointer& a_boundScript, bool a_constOnly, /*BSTScrapHashMap&*/ void* a_properties, std::uint32_t& a_nonConvertedProperties) const = 0; // 0F + + void BindObject(const BSTSmartPointer& a_obj, std::size_t a_objHandle) + { + using func_t = decltype(&ObjectBindPolicy::BindObject); + REL::Relocation func{ ID::ObjectBindPolicy::BindObject }; + return func(this, a_obj, a_objHandle); + } + + // TODO: Need to find UnbindObject(), all usages may be inlined + + // members + IVirtualMachine* vm; // 08 + IVMObjectBindInterface* bindInterface; // 10 + BSSpinLock attachedScriptsLock; // 18 + uint64_t unk20; // 20 + std::byte unk28[0x30]; // 28 + std::uint64_t unk58; // 58 + + // TODO: unk28 is likely `BSTHashMap>> attachedScripts`, but unsure where exactly it starts + }; + static_assert(sizeof(ObjectBindPolicy) == 0x60); + + } + + namespace GameScript + { + class ObjectBindPolicy : + public BSScript::ObjectBindPolicy // 00 + { + public: + SF_RTTI_VTABLE(GameScript__ObjectBindPolicy); + + struct 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 BSScript::MergedBoundScript& a_mergedScript, bool a_constOnly, /*BSTScrapHashMap&*/ void* a_properties, std::uint32_t& a_nonConvertedProperties) const override; // 0E + void ConvertProperties(std::size_t a_objTarget, const BSTSmartPointer& a_boundScript, bool a_constOnly, /*BSTScrapHashMap&*/ void* a_properties, std::uint32_t& a_nonConvertedProperties) const override; // 0F + + // members + BSSpinLock queueLock; // 60 + bool resolveCalled; // 68 + bool ignoringClear; // 69 + bool initialLoadDone; // 6A + std::uint8_t pad6B; // 6B + std::uint32_t pad6C; // 6C + /*BSTHashMap>*/ char queuedObjects[0x30]; // 70 + std::uint64_t unkA0; // A0 + std::uint64_t unkA8; // A8 + std::uint64_t unkB0; // B0 + std::uint64_t unkB8; // B8 + std::uint64_t unkC0; // C0 + std::uint64_t unkC8; // C8 + std::uint64_t unkD0; // D0 + std::uint64_t unkD8; // D8 + std::uint64_t unkE0; // E0 + std::uint64_t unkE8; // E8 + std::uint64_t unkF0; // F0 + std::uint64_t unkF8; // F8 + + //TODO:BSTArray queuedAliases and BSTSet initiallyLoadedObjects is somewhere up there... + }; + static_assert(sizeof(ObjectBindPolicy) == 0x100); + } +} diff --git a/CommonLibSF/include/RE/Starfield.h b/CommonLibSF/include/RE/Starfield.h index 5eefd413..e6193bb6 100644 --- a/CommonLibSF/include/RE/Starfield.h +++ b/CommonLibSF/include/RE/Starfield.h @@ -95,6 +95,7 @@ #include "RE/N/NativeFunctionBase.h" #include "RE/N/NiPoint3.h" #include "RE/N/NiSmartPointer.h" +#include "RE/O/ObjectBindPolicy.h" #include "RE/Offsets_NiRTTI.h" #include "RE/Offsets_RTTI.h" #include "RE/Offsets_VTABLE.h" From cce38f907e8c7a9ea9791b7e91d888333f8e77bd Mon Sep 17 00:00:00 2001 From: nikitalita <69168929+nikitalita@users.noreply.github.com> Date: Thu, 19 Oct 2023 19:03:27 -0700 Subject: [PATCH 3/6] feat: add TypeInfo, IComplexType --- CommonLibSF/include/RE/I/IComplexType.h | 28 +++++ CommonLibSF/include/RE/Starfield.h | 2 + CommonLibSF/include/RE/T/TypeInfo.h | 148 ++++++++++++++++++++++++ CommonLibSF/src/RE/T/TypeInfo.cpp | 23 ++++ 4 files changed, 201 insertions(+) create mode 100644 CommonLibSF/include/RE/I/IComplexType.h create mode 100644 CommonLibSF/include/RE/T/TypeInfo.h create mode 100644 CommonLibSF/src/RE/T/TypeInfo.cpp diff --git a/CommonLibSF/include/RE/I/IComplexType.h b/CommonLibSF/include/RE/I/IComplexType.h new file mode 100644 index 00000000..45f54f17 --- /dev/null +++ b/CommonLibSF/include/RE/I/IComplexType.h @@ -0,0 +1,28 @@ +#pragma once + +#include "RE/B/BSIntrusiveRefCounted.h" +#include "RE/T/TypeInfo.h" + +namespace RE +{ + namespace BSScript + { + class TypeInfo; + + class __declspec(novtable) IComplexType : + public BSIntrusiveRefCounted // 08 + { + public: + SF_RTTI_VTABLE(BSScript__IComplexType); + + // TODO: Verify that setting this to default doesn't fuck everything up + virtual ~IComplexType() = default; // 00 + + // add + virtual TypeInfo::RawType GetRawType() const = 0; // 01 + + [[nodiscard]] bool IsObject() const { return GetRawType() == TypeInfo::RawType::kObject; } + }; + static_assert(sizeof(IComplexType) == 0x10); + } +} diff --git a/CommonLibSF/include/RE/Starfield.h b/CommonLibSF/include/RE/Starfield.h index e6193bb6..56321b01 100644 --- a/CommonLibSF/include/RE/Starfield.h +++ b/CommonLibSF/include/RE/Starfield.h @@ -73,6 +73,7 @@ #include "RE/G/GameMenuBase.h" #include "RE/H/HandlePolicy.h" #include "RE/I/IAnimationGraphManagerHolder.h" +#include "RE/I/IComplexType.h" #include "RE/I/IFunction.h" #include "RE/I/IKeywordFormBase.h" #include "RE/I/IMenu.h" @@ -153,4 +154,5 @@ #include "RE/T/TESTexture.h" #include "RE/T/TESTopicInfo.h" #include "RE/T/TESWorldSpace.h" +#include "RE/T/TypeInfo.h" #include "RE/U/UI.h" diff --git a/CommonLibSF/include/RE/T/TypeInfo.h b/CommonLibSF/include/RE/T/TypeInfo.h new file mode 100644 index 00000000..e931d311 --- /dev/null +++ b/CommonLibSF/include/RE/T/TypeInfo.h @@ -0,0 +1,148 @@ +#pragma once + +namespace RE +{ + namespace BSScript + { + class IComplexType; + class ObjectTypeInfo; + class StructTypeInfo; + + class TypeInfo + { + public: + enum class RawType : std::uint32_t + { + kNone, + kObject, + kString, + kInt, + kFloat, + kBool, + kVar, + kStruct, + + kArrayStart = 10, + kArrayObject, + kArrayString, + kArrayInt, + kArrayFloat, + kArrayBool, + kArrayVar, + kArrayStruct, + kArrayEnd + }; + + TypeInfo() noexcept = default; + TypeInfo(const TypeInfo& a_rhs) noexcept { data.complexTypeInfo = a_rhs.data.complexTypeInfo; } + TypeInfo(TypeInfo&& a_rhs) noexcept { data.complexTypeInfo = std::exchange(a_rhs.data.complexTypeInfo, nullptr); } + TypeInfo(RawType a_type) noexcept { data.rawType = a_type; } + TypeInfo(IComplexType* a_type) noexcept { data.complexTypeInfo = a_type; } + + TypeInfo& operator=(const TypeInfo& a_rhs) noexcept + { + if (this != std::addressof(a_rhs)) { + data.complexTypeInfo = a_rhs.data.complexTypeInfo; + } + return *this; + } + + TypeInfo& operator=(TypeInfo&& a_rhs) noexcept + { + if (this != std::addressof(a_rhs)) { + data.complexTypeInfo = std::exchange(a_rhs.data.complexTypeInfo, nullptr); + } + return *this; + } + + TypeInfo& operator=(RawType a_type) noexcept + { + data.rawType = a_type; + return *this; + } + + TypeInfo& operator=(IComplexType* a_type) noexcept + { + data.complexTypeInfo = a_type; + return *this; + } + + [[nodiscard]] RawType GetRawType() const; + + [[nodiscard]] bool IsArray() const noexcept + { + if (IsComplex()) { + return data.rawType.all(static_cast(1u)); + } else { + return RawType::kArrayStart < data.rawType && data.rawType < RawType::kArrayEnd; + } + } + + [[nodiscard]] bool IsComplex() const noexcept { return data.rawType >= RawType::kArrayEnd; } + + [[nodiscard]] bool IsObjectArray() const noexcept + { + return GetRawType() == RawType::kArrayObject; + } + [[nodiscard]] bool IsStructArray() const noexcept + { + return GetRawType() == RawType::kArrayStruct; + } + [[nodiscard]] bool IsComplexTypeArray() const noexcept + { + return (IsComplex() && IsArray()); + } + [[nodiscard]] bool IsObject() const { return GetRawType() == RawType::kObject; } + [[nodiscard]] bool IsStruct() const { return GetRawType() == RawType::kStruct; } + IComplexType* GetComplexType() const + { + return IsComplex() ? reinterpret_cast( + reinterpret_cast(data.complexTypeInfo) & + ~static_cast(1)) : + nullptr; + } + ObjectTypeInfo* GetObjectTypeInfo() const + { + return IsObject() || IsObjectArray() ? reinterpret_cast(GetComplexType()) : nullptr; + } + StructTypeInfo* GetStructTypeInfo() const + { + return IsStruct() || IsStructArray() ? reinterpret_cast(GetComplexType()) : nullptr; + } + void SetArray(bool a_set) noexcept + { + if (IsComplex()) { + if (a_set) { + assert(!IsArray()); + data.rawType.set(static_cast(1u)); + } else { + assert(IsArray()); + data.rawType.reset(static_cast(1u)); + } + } else { + if (a_set) { + assert(!IsArray()); + data.rawType += RawType::kArrayStart; + } else { + assert(IsArray()); + data.rawType -= RawType::kArrayEnd; + } + } + } + + // members + union D + { + D() noexcept : + complexTypeInfo(nullptr) + {} + + ~D() noexcept { complexTypeInfo = nullptr; } + + stl::enumeration rawType; + IComplexType* complexTypeInfo; + } data; // 0 + }; + static_assert(sizeof(TypeInfo) == 0x8); + } +} diff --git a/CommonLibSF/src/RE/T/TypeInfo.cpp b/CommonLibSF/src/RE/T/TypeInfo.cpp new file mode 100644 index 00000000..2c8ec0c7 --- /dev/null +++ b/CommonLibSF/src/RE/T/TypeInfo.cpp @@ -0,0 +1,23 @@ + +#include "RE/T/TypeInfo.h" +#include "RE/I/IComplexType.h" +namespace RE::BSScript +{ + auto TypeInfo::GetRawType() const + -> RawType + { + if (IsComplex()) { + const auto complex = + reinterpret_cast( + reinterpret_cast(data.complexTypeInfo) & + ~static_cast(1)); + uint32_t rtype = (uint32_t)complex->GetRawType(); + if (IsArray()) { + rtype += 10; + } + return (RawType)rtype; + } else { + return *data.rawType; + } + } +} \ No newline at end of file From 749fbb9115fa172660889ffe94e38d615d642fb8 Mon Sep 17 00:00:00 2001 From: nikitalita <69168929+nikitalita@users.noreply.github.com> Date: Fri, 20 Oct 2023 02:10:46 -0700 Subject: [PATCH 4/6] feat: Add BSScript Types --- CommonLibSF/include/RE/A/Array.h | 90 ++++++ CommonLibSF/include/RE/IDs.h | 25 ++ CommonLibSF/include/RE/O/Object.h | 97 ++++++ CommonLibSF/include/RE/O/ObjectTypeInfo.h | 82 +++++ CommonLibSF/include/RE/P/PropertyGroupInfo.h | 23 ++ CommonLibSF/include/RE/P/PropertyTypeInfo.h | 35 ++ CommonLibSF/include/RE/S/Struct.h | 35 ++ CommonLibSF/include/RE/S/StructTypeInfo.h | 65 ++++ CommonLibSF/include/RE/Starfield.h | 8 + CommonLibSF/include/RE/V/Variable.h | 323 +++++++++++++++++++ CommonLibSF/src/RE/A/Array.cpp | 196 +++++++++++ CommonLibSF/src/RE/S/Struct.cpp | 17 + CommonLibSF/src/RE/V/Variable.cpp | 141 ++++++++ 13 files changed, 1137 insertions(+) create mode 100644 CommonLibSF/include/RE/A/Array.h create mode 100644 CommonLibSF/include/RE/O/Object.h create mode 100644 CommonLibSF/include/RE/O/ObjectTypeInfo.h create mode 100644 CommonLibSF/include/RE/P/PropertyGroupInfo.h create mode 100644 CommonLibSF/include/RE/P/PropertyTypeInfo.h create mode 100644 CommonLibSF/include/RE/S/Struct.h create mode 100644 CommonLibSF/include/RE/S/StructTypeInfo.h create mode 100644 CommonLibSF/include/RE/V/Variable.h create mode 100644 CommonLibSF/src/RE/A/Array.cpp create mode 100644 CommonLibSF/src/RE/S/Struct.cpp create mode 100644 CommonLibSF/src/RE/V/Variable.cpp diff --git a/CommonLibSF/include/RE/A/Array.h b/CommonLibSF/include/RE/A/Array.h new file mode 100644 index 00000000..10e01a60 --- /dev/null +++ b/CommonLibSF/include/RE/A/Array.h @@ -0,0 +1,90 @@ +#pragma once + +#include "RE/B/BSContainer.h" +#include "RE/B/BSFixedString.h" +#include "RE/B/BSIntrusiveRefCounted.h" +#include "RE/B/BSLock.h" +#include "RE/B/BSTArray.h" +#include "RE/B/BSTEvent.h" +#include "RE/B/BSTSmartPointer.h" +#include "RE/M/MemoryManager.h" +#include "RE/T/TypeInfo.h" +#include "RE/V/Variable.h" + +namespace RE +{ + namespace BSScript + { + class TypeInfo; + class Variable; + + class Array : + public BSIntrusiveRefCounted // 00 + { + private: + Array* ctor(const TypeInfo* type_info, std::uint32_t initial_size = 0); + void dtor(); + + public: + using value_type = Variable; + using size_type = std::uint32_t; + using difference_type = std::int32_t; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; + using iterator = value_type*; + using const_iterator = const value_type*; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + Array(const TypeInfo* type_info, std::uint32_t initial_size = 0); + ~Array(); + + [[nodiscard]] reference operator[](size_type a_pos); + [[nodiscard]] const_reference operator[](size_type a_pos) const; + + [[nodiscard]] reference front(); + [[nodiscard]] const_reference front() const; + + [[nodiscard]] reference back(); + [[nodiscard]] const_reference back() const; + + [[nodiscard]] pointer data() noexcept; + [[nodiscard]] const_pointer data() const noexcept; + + [[nodiscard]] iterator begin() noexcept; + [[nodiscard]] const_iterator begin() const noexcept; + [[nodiscard]] const_iterator cbegin() const noexcept; + + [[nodiscard]] iterator end() noexcept; + [[nodiscard]] const_iterator end() const noexcept; + [[nodiscard]] const_iterator cend() const noexcept; + + [[nodiscard]] reverse_iterator rbegin() noexcept; + [[nodiscard]] const_reverse_iterator rbegin() const noexcept; + [[nodiscard]] const_reverse_iterator crbegin() const noexcept; + + [[nodiscard]] reverse_iterator rend() noexcept; + [[nodiscard]] const_reverse_iterator rend() const noexcept; + [[nodiscard]] const_reverse_iterator crend() const noexcept; + + [[nodiscard]] bool empty() const noexcept; + + [[nodiscard]] size_type size() const noexcept; + + [[nodiscard]] size_type max_size() const noexcept; + + [[nodiscard]] TypeInfo& type_info(); + [[nodiscard]] const TypeInfo& type_info() const; + + [[nodiscard]] TypeInfo::RawType type() const; + + // members + TypeInfo elementType; // 08 + BSSpinLock elementsLock; // 10 + BSTArray elements; // 18 + }; + static_assert(sizeof(Array) == 0x28); + } +} diff --git a/CommonLibSF/include/RE/IDs.h b/CommonLibSF/include/RE/IDs.h index 576bff6c..5bdb9562 100644 --- a/CommonLibSF/include/RE/IDs.h +++ b/CommonLibSF/include/RE/IDs.h @@ -48,6 +48,31 @@ namespace RE::ID namespace BSScript { + namespace Array + { + inline constexpr REL::ID ctor{ 196577 }; + inline constexpr REL::ID dtor{ 196579 }; + } + + namespace Object + { + inline constexpr REL::ID ctor{ 196025 }; + inline constexpr REL::ID dtor{ 196032 }; + inline constexpr REL::ID GetHandle{ 196069 }; + inline constexpr REL::ID SetHandle{ 196079 }; + inline constexpr REL::ID IncRef{ 37879 }; + inline constexpr REL::ID DecRef{ 196057 }; + } + + namespace ObjectTypeInfo + { + inline constexpr REL::ID ctor{ 197047 }; + inline constexpr REL::ID dtor{ 196202 }; + inline constexpr REL::ID Clear{ 196218 }; + inline constexpr REL::ID CopyFromLinkedData{ 196219 }; + inline constexpr REL::ID GetProperty{ 196241 }; + } + namespace Internal { namespace NF_util diff --git a/CommonLibSF/include/RE/O/Object.h b/CommonLibSF/include/RE/O/Object.h new file mode 100644 index 00000000..618c0ea5 --- /dev/null +++ b/CommonLibSF/include/RE/O/Object.h @@ -0,0 +1,97 @@ +#pragma once + +#include "RE/B/BSContainer.h" +#include "RE/B/BSFixedString.h" +#include "RE/B/BSLock.h" +#include "RE/B/BSTArray.h" +#include "RE/B/BSTEvent.h" +#include "RE/B/BSTSmartPointer.h" +#include "RE/I/IObjectHandlePolicy.h" +#include "RE/M/MemoryManager.h" +#include "RE/O/ObjectTypeInfo.h" + +namespace RE +{ + namespace BSScript + { + class ObjectTypeInfo; + class Variable; + + class Object + { + public: + void dtor() + { + using func_t = decltype(&Object::dtor); + REL::Relocation func{ ID::BSScript::Object::dtor }; + return func(this); + } + + ~Object() + { + dtor(); + } + + Object* ctor(const BSTSmartPointer& a_type, const IObjectHandlePolicy& a_handlePolicy, std::uint32_t a_numProperties) + { + using func_t = decltype(&Object::ctor); + REL::Relocation func{ ID::BSScript::Object::ctor }; + return func(this, a_type, a_handlePolicy, a_numProperties); + } + + Object(const BSTSmartPointer& a_type, const IObjectHandlePolicy& a_handlePolicy, std::uint32_t a_numProperties) + { + ctor(a_type, a_handlePolicy, a_numProperties); + } + + Object() = delete; + + [[nodiscard]] constexpr bool IsConstructed() const noexcept { return static_cast(constructed); } + [[nodiscard]] constexpr bool IsInitialized() const noexcept { return static_cast(initialized); } + [[nodiscard]] constexpr bool IsValid() const noexcept { return static_cast(valid); } + + [[nodiscard]] std::uint32_t DecRef() const + { + using func_t = decltype(&Object::DecRef); + REL::Relocation func{ ID::BSScript::Object::DecRef }; + return func(this); + } + + [[nodiscard]] std::size_t GetHandle() const + { + using func_t = decltype(&Object::GetHandle); + REL::Relocation func{ ID::BSScript::Object::GetHandle }; + return func(this); + } + + void IncRef() const + { + using func_t = decltype(&Object::IncRef); + REL::Relocation func{ ID::BSScript::Object::IncRef }; + return func(this); + } + + SF_HEAP_REDEFINE_NEW(); + + // members + std::uint16_t unk00; // 00 + std::uint16_t unk02; // 02 + std::uint32_t unk04; // 04 + std::uint64_t unk08; // 08 + std::uint32_t constructed: 1; // 10:00 + std::uint32_t initialized: 1; // 10:01 + std::uint32_t valid: 1; // 10:02 + std::uint32_t remainingPropsToInit: 29; // 10:03 + std::uint32_t unk14; // 14 + std::uint32_t unk18; // 18 + std::uint32_t unk1C; // 1C + BSTSmartPointer type; // 20 + BSFixedString currentState; // 28 + void* lockStructure; // 30 + IObjectHandlePolicy* handlePolicy; // 38 + std::size_t handle; // 40 + std::uint32_t refCountAndHandleLock; // 48 + }; + static_assert(sizeof(Object) == 0x50); + } +} diff --git a/CommonLibSF/include/RE/O/ObjectTypeInfo.h b/CommonLibSF/include/RE/O/ObjectTypeInfo.h new file mode 100644 index 00000000..f2d50873 --- /dev/null +++ b/CommonLibSF/include/RE/O/ObjectTypeInfo.h @@ -0,0 +1,82 @@ +#pragma once + +#include "RE/B/BSContainer.h" +#include "RE/B/BSFixedString.h" +#include "RE/B/BSLock.h" +#include "RE/B/BSTArray.h" +#include "RE/B/BSTSmartPointer.h" +#include "RE/I/IComplexType.h" +#include "RE/I/IFunction.h" +#include "RE/P/PropertyGroupInfo.h" +#include "RE/V/Variable.h" + +namespace RE +{ + namespace BSScript + { + class IFunction; + + class ObjectTypeInfo : + public IComplexType // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSScript__ObjectTypeInfo }; + static constexpr auto VTABLE{ VTABLE::BSScript__ObjectTypeInfo }; + + enum class LinkValidState : std::uint8_t + { + kNotLinked, + kCurrentlyLinking, + kLinkedInvalid, + kLinkedValid + }; + + // TODO: the rest of this + // CopyFromLinkedData() is located at REL::ID(196219) if someone wants to figure this out + /*** + * This likely has: + * userFlagCount + * variableCount + * guardCount + * propertyCount + * staticFunctionCount + * emptyStateMemberFunctionCount + * namedStateCount + * initialValueCount + * + * But it's not clear which is which. + * Also it's not clear if they keep track of variableUserFlagCount or initialState anymore. + */ + struct CountData + { + uint16_t unk00; + uint16_t variableCount; + uint16_t unk04; + uint16_t unk06; + uint16_t unk08; + uint16_t unk0A; + uint16_t unk0C; + uint16_t unk0E; + }; + + // override (IComplexType) + virtual TypeInfo::RawType GetRawType() const override { return TypeInfo::RawType::kObject; } // 01 + + // members + BSFixedString name; // 10 + BSTSmartPointer parentTypeInfo; // 18 + BSFixedString docString; // 20 + BSTArray> propertyGroups; // 28 + CountData countData; // 38 + uint64_t unk48; // 48 + void* data; // 50 + uint32_t unk58; // 58 + uint16_t unk5C; // 5C + LinkValidState linkedValid; // 5E + uint8_t unk5F; // 5F + bool loaded; // 60 + }; + + static_assert(sizeof(ObjectTypeInfo) == 0x68); + } +} diff --git a/CommonLibSF/include/RE/P/PropertyGroupInfo.h b/CommonLibSF/include/RE/P/PropertyGroupInfo.h new file mode 100644 index 00000000..0c986be2 --- /dev/null +++ b/CommonLibSF/include/RE/P/PropertyGroupInfo.h @@ -0,0 +1,23 @@ +#pragma once + +#include "RE/B/BSFixedString.h" +#include "RE/B/BSIntrusiveRefCounted.h" +#include "RE/B/BSTArray.h" + +namespace RE +{ + namespace BSScript + { + class PropertyGroupInfo : + public BSIntrusiveRefCounted // 00 + { + public: + // members + BSFixedString groupName; // 08 + BSFixedString docString; // 10 + std::uint32_t userFlags; // 18 + BSTArray propertyNames; // 20 + }; + static_assert(sizeof(PropertyGroupInfo) == 0x30); + } +} diff --git a/CommonLibSF/include/RE/P/PropertyTypeInfo.h b/CommonLibSF/include/RE/P/PropertyTypeInfo.h new file mode 100644 index 00000000..ad7a664a --- /dev/null +++ b/CommonLibSF/include/RE/P/PropertyTypeInfo.h @@ -0,0 +1,35 @@ +#pragma once + +#include "RE/B/BSFixedString.h" +#include "RE/B/BSTSmartPointer.h" +#include "RE/I/IFunction.h" +#include "RE/T/TypeInfo.h" + +namespace RE +{ + namespace BSScript + { + class IFunction; + + struct PropertyTypeInfo + { + public: + enum class Permissions + { + }; + + // members + BSFixedString parentObjName; // 00 + BSFixedString propertyName; // 08 + TypeInfo type; // 10 + stl::enumeration permissions; // 18 + std::uint32_t pad1C; // 1C + BSTSmartPointer getFunction; // 20 + BSTSmartPointer setFunction; // 28 + std::uint32_t autoVarIndex; // 30 + std::uint32_t userFlags; // 34 + BSFixedString docString; // 38 + }; + static_assert(sizeof(PropertyTypeInfo) == 0x40); + } +} diff --git a/CommonLibSF/include/RE/S/Struct.h b/CommonLibSF/include/RE/S/Struct.h new file mode 100644 index 00000000..15aa5ccd --- /dev/null +++ b/CommonLibSF/include/RE/S/Struct.h @@ -0,0 +1,35 @@ +#pragma once + +#include "RE/B/BSContainer.h" +#include "RE/B/BSFixedString.h" +#include "RE/B/BSLock.h" +#include "RE/B/BSTArray.h" +#include "RE/B/BSTEvent.h" +#include "RE/B/BSTSmartPointer.h" +#include "RE/M/MemoryManager.h" +#include "RE/S/StructTypeInfo.h" +#include "RE/V/Variable.h" + +namespace RE +{ + namespace BSScript + { + class StructTypeInfo; + class Variable; + + class Struct : + public BSIntrusiveRefCounted // 00 + { + public: + ~Struct(); + + // members + BSSpinLock structLock; // 04 + BSTSmartPointer type; // 10 + bool constructed{ true }; // 18 + bool valid{ false }; // 19 + Variable variables[0]; // 20 + }; + static_assert(sizeof(Struct) == 0x20); + } +} diff --git a/CommonLibSF/include/RE/S/StructTypeInfo.h b/CommonLibSF/include/RE/S/StructTypeInfo.h new file mode 100644 index 00000000..5898062a --- /dev/null +++ b/CommonLibSF/include/RE/S/StructTypeInfo.h @@ -0,0 +1,65 @@ +#pragma once + +#include "RE/B/BSFixedString.h" +#include "RE/B/BSLock.h" +#include "RE/B/BSTArray.h" +#include "RE/B/BSTSmartPointer.h" +#include "RE/I/IComplexType.h" +#include "RE/M/MemoryManager.h" +#include "RE/T/TypeInfo.h" +#include "RE/V/Variable.h" + +namespace RE +{ + namespace BSScript + { + class IComplexType; + class ObjectTypeInfo; + class TypeInfo; + class Variable; + + class __declspec(novtable) StructTypeInfo : + public IComplexType // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSScript__StructTypeInfo }; + static constexpr auto VTABLE{ VTABLE::BSScript__StructTypeInfo }; + + enum class LinkValidState + { + kNotLinked, + kCurrentlyLinking, + kLinkedInvalid, + kLinkedValid + }; + + struct StructVar + { + public: + // members + Variable initialValue; // 00 + TypeInfo varType; // 10 + BSFixedString docString; // 18 + std::uint32_t userFlags; // 20 + bool isConst; // 24 + }; + static_assert(sizeof(StructVar) == 0x28); + + const char* GetName() const + { + return name.c_str(); + } + + // override (IComplexType) + virtual TypeInfo::RawType GetRawType() const override { return TypeInfo::RawType::kStruct; } // 01 + + // members + BSFixedString name; // 10 + BSTSmartPointer containingObjTypeInfo; // 18 + BSTArray variables; // 20 + /*BSTHashMap*/ char varNameIndexMap[0x38]; // 30 + stl::enumeration linkedValid; // 68 + }; + static_assert(sizeof(StructTypeInfo) == 0x70); + } +} diff --git a/CommonLibSF/include/RE/Starfield.h b/CommonLibSF/include/RE/Starfield.h index 56321b01..1e484ddf 100644 --- a/CommonLibSF/include/RE/Starfield.h +++ b/CommonLibSF/include/RE/Starfield.h @@ -11,6 +11,7 @@ #include "RE/A/ActorValueOwner.h" #include "RE/A/ActorValueStorage.h" #include "RE/A/ActorValues.h" +#include "RE/A/Array.h" #include "RE/B/BGSAnimationGraphComponent.h" #include "RE/B/BGSAttachParentArray.h" #include "RE/B/BGSAttackDataForm.h" @@ -96,13 +97,17 @@ #include "RE/N/NativeFunctionBase.h" #include "RE/N/NiPoint3.h" #include "RE/N/NiSmartPointer.h" +#include "RE/O/Object.h" #include "RE/O/ObjectBindPolicy.h" +#include "RE/O/ObjectTypeInfo.h" #include "RE/Offsets_NiRTTI.h" #include "RE/Offsets_RTTI.h" #include "RE/Offsets_VTABLE.h" #include "RE/P/PerkRankData.h" #include "RE/P/PlayerCamera.h" #include "RE/P/PlayerCharacter.h" +#include "RE/P/PropertyGroupInfo.h" +#include "RE/P/PropertyTypeInfo.h" #include "RE/R/RegSettingCollection.h" #include "RE/RTTI.h" #include "RE/S/SWFToCodeFunctionHandler.h" @@ -121,6 +126,8 @@ #include "RE/S/SettingCollectionList.h" #include "RE/S/SettingCollectionMap.h" #include "RE/S/Sexes.h" +#include "RE/S/Struct.h" +#include "RE/S/StructTypeInfo.h" #include "RE/T/TBO_InstanceData.h" #include "RE/T/TESAIForm.h" #include "RE/T/TESActorBase.h" @@ -156,3 +163,4 @@ #include "RE/T/TESWorldSpace.h" #include "RE/T/TypeInfo.h" #include "RE/U/UI.h" +#include "RE/V/Variable.h" diff --git a/CommonLibSF/include/RE/V/Variable.h b/CommonLibSF/include/RE/V/Variable.h new file mode 100644 index 00000000..982b42f6 --- /dev/null +++ b/CommonLibSF/include/RE/V/Variable.h @@ -0,0 +1,323 @@ +#pragma once + +#include "RE/B/BSFixedString.h" +#include "RE/B/BSTSmartPointer.h" +#include "RE/M/MemoryManager.h" +#include "RE/T/TypeInfo.h" + +namespace RE +{ + namespace BSScript + { + class Array; + class Object; + class Struct; + class TypeInfo; + class Variable; + + namespace detail + { + struct variable_raw_accessor; + } + + namespace UnlinkedTypes + { + struct Object; // stub + } + + class Variable + { + public: + Variable() noexcept = default; + Variable(const Variable& a_rhs) { copy(a_rhs); } + Variable(Variable&&) noexcept = default; + + ~Variable() { reset(); } + + Variable& operator=(const Variable& a_rhs) + { + if (this != std::addressof(a_rhs)) { + reset(); + copy(a_rhs); + } + return *this; + } + + Variable& operator=(Variable&&) noexcept = default; + + Variable& operator=(std::nullptr_t) + { + reset(); + assert(is()); + return *this; + } + + Variable& operator=(BSTSmartPointer a_object); + + Variable& operator=(BSFixedString a_string) + { + reset(); + value.s = std::move(a_string); + varType = RawType::kString; + + assert(is()); + return *this; + } + + Variable& operator=(std::uint32_t a_unsigned) + { + reset(); + value.u = a_unsigned; + varType = RawType::kInt; + + assert(is()); + return *this; + } + + Variable& operator=(std::int32_t a_signed) + { + reset(); + value.i = a_signed; + varType = RawType::kInt; + + assert(is()); + return *this; + } + + Variable& operator=(float a_float) + { + reset(); + value.f = a_float; + varType = RawType::kFloat; + + assert(is()); + return *this; + } + + Variable& operator=(bool a_boolean) + { + reset(); + value.b = a_boolean; + varType = RawType::kBool; + + assert(is()); + return *this; + } + + Variable& operator=(stl::owner a_variable) + { + assert(a_variable != nullptr); + assert(a_variable->varType.GetRawType() != RawType::kVar); + + reset(); + value.v = a_variable; + varType = RawType::kVar; + return *this; + } + + Variable& operator=(BSTSmartPointer a_struct); + Variable& operator=(BSTSmartPointer a_array); + + SF_HEAP_REDEFINE_NEW(Variable); + + template + [[nodiscard]] bool is() const // + requires(std::same_as) + { + return varType.GetRawType() == RawType::kNone; + } + + template + [[nodiscard]] bool is() const // + requires(std::same_as) + { + return varType.GetRawType() == RawType::kObject; + } + + template + [[nodiscard]] bool is() const // + requires(std::same_as) + { + return varType.GetRawType() == RawType::kString; + } + + template + [[nodiscard]] bool is() const // + requires(std::same_as || + std::same_as) + { + return varType.GetRawType() == RawType::kInt; + } + + template + [[nodiscard]] bool is() const // + requires(std::same_as) + { + return varType.GetRawType() == RawType::kFloat; + } + + template + [[nodiscard]] bool is() const // + requires(std::same_as) + { + return varType.GetRawType() == RawType::kBool; + } + + template + [[nodiscard]] bool is() const // + requires(std::same_as) + { + return varType.GetRawType() == RawType::kVar; + } + + template + [[nodiscard]] bool is() const // + requires(std::same_as) + { + return varType.GetRawType() == RawType::kStruct; + } + + template + [[nodiscard]] bool is() const // + requires(std::same_as) + { + return varType.IsArray(); + } + + TypeInfo GetType() const + { + return varType; + } + + void reset(); + + private: + friend detail::variable_raw_accessor; + + using RawType = TypeInfo::RawType; + + void copy(const Variable& a_rhs); + + // members + TypeInfo varType; // 00 + union V + { + // NOLINTNEXTLINE(modernize-use-equals-default) + V() : + v(nullptr) + {} + + V(V&& a_rhs) noexcept : + v(std::exchange(a_rhs.v, nullptr)) + {} + + ~V() {} // NOLINT(modernize-use-equals-default) + + V& operator=(V&& a_rhs) noexcept + { + if (this != std::addressof(a_rhs)) { + v = std::exchange(a_rhs.v, nullptr); + } + return *this; + } + + BSTSmartPointer o; + BSFixedString s; + std::uint32_t u; + std::int32_t i; + float f; + bool b; + stl::owner v; + BSTSmartPointer t; + BSTSmartPointer a; + } value; // 08 + }; + static_assert(sizeof(Variable) == 0x10); + + namespace detail + { + struct variable_raw_accessor + { + public: + template + [[nodiscard]] static auto&& get_raw(T&& a_var) // + requires(std::same_as, Variable>) + { + return std::forward(a_var).value; + } + }; + } + + template + [[nodiscard]] BSTSmartPointer get(const Variable& a_var) // + requires(std::same_as) + { + assert(a_var.is()); + return detail::variable_raw_accessor::get_raw(a_var).o; + } + + template + [[nodiscard]] BSFixedString get(const Variable& a_var) // + requires(std::same_as) + { + assert(a_var.is()); + return detail::variable_raw_accessor::get_raw(a_var).s; + } + + template + [[nodiscard]] std::uint32_t get(const Variable& a_var) // + requires(std::same_as) + { + assert(a_var.is()); + return detail::variable_raw_accessor::get_raw(a_var).u; + } + + template + [[nodiscard]] std::int32_t get(const Variable& a_var) // + requires(std::same_as) + { + assert(a_var.is()); + return detail::variable_raw_accessor::get_raw(a_var).i; + } + + template + [[nodiscard]] float get(const Variable& a_var) // + requires(std::same_as) + { + assert(a_var.is()); + return detail::variable_raw_accessor::get_raw(a_var).f; + } + + template + [[nodiscard]] bool get(const Variable& a_var) // + requires(std::same_as) + { + assert(a_var.is()); + return detail::variable_raw_accessor::get_raw(a_var).b; + } + + template + [[nodiscard]] stl::observer get(const Variable& a_var) // + requires(std::same_as) + { + assert(a_var.is()); + return detail::variable_raw_accessor::get_raw(a_var).v; + } + + template + [[nodiscard]] BSTSmartPointer get(const Variable& a_var) // + requires(std::same_as) + { + assert(a_var.is()); + return detail::variable_raw_accessor::get_raw(a_var).t; + } + + template + [[nodiscard]] BSTSmartPointer get(const Variable& a_var) // + requires(std::same_as) + { + assert(a_var.is()); + return detail::variable_raw_accessor::get_raw(a_var).a; + } + } +} diff --git a/CommonLibSF/src/RE/A/Array.cpp b/CommonLibSF/src/RE/A/Array.cpp new file mode 100644 index 00000000..8b4be128 --- /dev/null +++ b/CommonLibSF/src/RE/A/Array.cpp @@ -0,0 +1,196 @@ +#include "RE/A/Array.h" + +namespace RE +{ + namespace BSScript + { + Array::~Array() + { + dtor(); + } + + Array::Array(const TypeInfo* type_info, std::uint32_t initial_size) + { + ctor(type_info, initial_size); + } + + Array* Array::ctor(const TypeInfo* type_info, std::uint32_t initial_size) + { + using func_t = decltype(&Array::ctor); + REL::Relocation func{ ID::BSScript::Array::ctor }; + return func(this, type_info, initial_size); + } + + void Array::dtor() + { + using func_t = decltype(&Array::dtor); + REL::Relocation func{ ID::BSScript::Array::dtor }; + return func(this); + } + + [[nodiscard]] auto Array::operator[](size_type a_pos) + -> reference + { + assert(a_pos < size()); + return *(elements.data() + static_cast(a_pos)); // TODO: add operator[] to BSTArray + } + + [[nodiscard]] auto Array::operator[](size_type a_pos) const + -> const_reference + { + assert(a_pos < size()); + return *(elements.data() + static_cast(a_pos)); + } + + [[nodiscard]] auto Array::front() + -> reference + { + return operator[](0); + } + + [[nodiscard]] auto Array::front() const + -> const_reference + { + return operator[](0); + } + + [[nodiscard]] auto Array::back() + -> reference + { + return operator[](size() - 1); + } + + [[nodiscard]] auto Array::back() const + -> const_reference + { + return operator[](size() - 1); + } + + [[nodiscard]] auto Array::data() noexcept + -> pointer + { + return size() > 0 ? elements.data() : nullptr; + } + + [[nodiscard]] auto Array::data() const noexcept + -> const_pointer + { + return size() > 0 ? elements.data() : nullptr; + } + + [[nodiscard]] auto Array::begin() noexcept + -> iterator + { + return elements.begin(); + } + + [[nodiscard]] auto Array::begin() const noexcept + -> const_iterator + { + return elements.begin(); + } + + [[nodiscard]] auto Array::cbegin() const noexcept + -> const_iterator + { + return elements.begin(); + } + + [[nodiscard]] auto Array::end() noexcept + -> iterator + { + return size() > 0 ? elements.end() : nullptr; + } + + [[nodiscard]] auto Array::end() const noexcept + -> const_iterator + { + return size() > 0 ? elements.end() : nullptr; + } + + [[nodiscard]] auto Array::cend() const noexcept + -> const_iterator + { + return elements.end(); + } + + [[nodiscard]] auto Array::rbegin() noexcept + -> reverse_iterator + { + return reverse_iterator(end()); + } + + [[nodiscard]] auto Array::rbegin() const noexcept + -> const_reverse_iterator + { + return const_reverse_iterator(end()); + } + + [[nodiscard]] auto Array::crbegin() const noexcept + -> const_reverse_iterator + { + return rbegin(); + } + + [[nodiscard]] auto Array::rend() noexcept + -> reverse_iterator + { + return reverse_iterator(begin()); + } + + [[nodiscard]] auto Array::rend() const noexcept + -> const_reverse_iterator + { + return const_reverse_iterator(begin()); + } + + [[nodiscard]] auto Array::crend() const noexcept + -> const_reverse_iterator + { + return rend(); + } + + [[nodiscard]] bool Array::empty() const noexcept + { + return size() > 0; + } + + [[nodiscard]] auto Array::size() const noexcept + -> size_type + { + return elements.size(); + } + + [[nodiscard]] auto Array::max_size() const noexcept + -> size_type + { + return std::numeric_limits::max(); + } + + [[nodiscard]] TypeInfo& Array::type_info() + { + return elementType; + } + + [[nodiscard]] const TypeInfo& Array::type_info() const + { + return elementType; + } + + [[nodiscard]] TypeInfo::RawType Array::type() const + { + const stl::enumeration typeID = elementType.GetRawType(); + switch (*typeID) { + case TypeInfo::RawType::kNone: + case TypeInfo::RawType::kObject: + case TypeInfo::RawType::kString: + case TypeInfo::RawType::kInt: + case TypeInfo::RawType::kFloat: + case TypeInfo::RawType::kBool: + return *(typeID + TypeInfo::RawType::kArrayStart); + default: + return *(typeID + TypeInfo::RawType::kObject); + } + } + } +} diff --git a/CommonLibSF/src/RE/S/Struct.cpp b/CommonLibSF/src/RE/S/Struct.cpp new file mode 100644 index 00000000..91e5ad98 --- /dev/null +++ b/CommonLibSF/src/RE/S/Struct.cpp @@ -0,0 +1,17 @@ +#include "RE/S/Struct.h" +#include "RE/V/Variable.h" + +namespace RE::BSScript +{ + Struct::~Struct() + { + if (constructed) { + const std::uint32_t size = type ? type->variables.size() : 0; + for (std::uint32_t i = 0; i < size; ++i) { + variables[i].reset(); + } + + constructed = false; + } + } +} \ No newline at end of file diff --git a/CommonLibSF/src/RE/V/Variable.cpp b/CommonLibSF/src/RE/V/Variable.cpp new file mode 100644 index 00000000..79f61af7 --- /dev/null +++ b/CommonLibSF/src/RE/V/Variable.cpp @@ -0,0 +1,141 @@ +#include "RE/V/Variable.h" +#include "RE/A/Array.h" +#include "RE/O/Object.h" +#include "RE/O/ObjectTypeInfo.h" +#include "RE/S/Struct.h" +#include "RE/T/TypeInfo.h" + +namespace RE::BSScript +{ + Variable& Variable::operator=(BSTSmartPointer a_object) + { + reset(); + if (a_object) { + value.o = std::move(a_object); + varType = value.o->type.get(); + } else { + assert(false); + } + + assert(is()); + return *this; + } + + Variable& Variable::operator=(BSTSmartPointer a_struct) + { + reset(); + if (a_struct) { + value.t = std::move(a_struct); + varType = value.t->type.get(); + } else { + assert(false); + } + + assert(is()); + return *this; + } + + Variable& Variable::operator=(BSTSmartPointer a_array) + { + reset(); + if (a_array) { + value.a = std::move(a_array); + varType = value.a->elementType; + varType.SetArray(true); + } else { + assert(false); + } + + assert(is()); + return *this; + } + + void Variable::reset() + { + switch (varType.GetRawType()) { + case RawType::kObject: + value.o.reset(); + break; + case RawType::kString: + value.s.~BSFixedString(); + break; + case RawType::kVar: + delete value.v; + break; + case RawType::kStruct: + value.t.reset(); + break; + case RawType::kArrayObject: + case RawType::kArrayString: + case RawType::kArrayInt: + case RawType::kArrayFloat: + case RawType::kArrayBool: + case RawType::kArrayVar: + case RawType::kArrayStruct: + value.a.reset(); + break; + case RawType::kNone: + case RawType::kInt: + case RawType::kFloat: + case RawType::kBool: + break; + default: + assert(false); // unhandled type + break; + } + + varType = RawType::kNone; + value.v = nullptr; + assert(is()); + } + + // NOLINTNEXTLINE(misc-no-recursion) + void Variable::copy(const Variable& a_rhs) + { + assert(varType.GetRawType() == RawType::kNone); + assert(value.v == nullptr); + + switch (a_rhs.varType.GetRawType()) { + case RawType::kObject: + value.o = a_rhs.value.o; + break; + case RawType::kString: + value.s = a_rhs.value.s; + break; + case RawType::kVar: + if (a_rhs.value.v) { + value.v = new Variable(*a_rhs.value.v); + } + break; + case RawType::kStruct: + value.t = a_rhs.value.t; + break; + case RawType::kArrayObject: + case RawType::kArrayString: + case RawType::kArrayInt: + case RawType::kArrayFloat: + case RawType::kArrayBool: + case RawType::kArrayVar: + case RawType::kArrayStruct: + value.a = a_rhs.value.a; + break; + case RawType::kNone: + break; + case RawType::kInt: + value.u = a_rhs.value.u; + break; + case RawType::kFloat: + value.f = a_rhs.value.f; + break; + case RawType::kBool: + value.b = a_rhs.value.b; + break; + default: + assert(false); // unhandled type + break; + } + + varType = a_rhs.varType; + } + +} \ No newline at end of file From 0459bdc435bbcc8844c5198c69b24e19e6eaa30d Mon Sep 17 00:00:00 2001 From: nikitalita <69168929+nikitalita@users.noreply.github.com> Date: Fri, 20 Oct 2023 02:26:56 -0700 Subject: [PATCH 5/6] chore: fix missed Offset -> ID renames --- CommonLibSF/include/RE/B/BGSObjectInstance.h | 2 +- CommonLibSF/include/RE/C/ConsoleLog.h | 4 +- CommonLibSF/include/RE/N/NativeFunctionBase.h | 10 ++--- .../include/RE/R/RegSettingCollection.h | 2 +- CommonLibSF/include/RE/RTTI.h | 2 +- CommonLibSF/include/RE/S/ScaleformGFxValue.h | 44 +++++++++---------- CommonLibSF/include/RE/S/Script.h | 4 +- .../include/RE/T/TESCellFullyLoadedEvent.h | 2 +- .../include/RE/T/TESContainerChangedEvent.h | 2 +- CommonLibSF/include/RE/T/TESDataHandler.h | 2 +- CommonLibSF/include/RE/T/TESDeathEvent.h | 2 +- .../include/RE/T/TESObjectLoadedEvent.h | 2 +- CommonLibSF/include/RE/U/UI.h | 4 +- 13 files changed, 41 insertions(+), 41 deletions(-) diff --git a/CommonLibSF/include/RE/B/BGSObjectInstance.h b/CommonLibSF/include/RE/B/BGSObjectInstance.h index ef53c84f..d9df35d0 100644 --- a/CommonLibSF/include/RE/B/BGSObjectInstance.h +++ b/CommonLibSF/include/RE/B/BGSObjectInstance.h @@ -23,7 +23,7 @@ namespace RE BGSObjectInstance* ctor(TESForm* a_object, TBO_InstanceData* a_instanceData) { using func_t = decltype(&BGSObjectInstance::ctor); - REL::Relocation func{ Offset::BGSObjectInstance::ctor }; + REL::Relocation func{ ID::BGSObjectInstance::ctor }; return func(this, a_object, a_instanceData); } }; diff --git a/CommonLibSF/include/RE/C/ConsoleLog.h b/CommonLibSF/include/RE/C/ConsoleLog.h index 890a2d99..df9be9a8 100644 --- a/CommonLibSF/include/RE/C/ConsoleLog.h +++ b/CommonLibSF/include/RE/C/ConsoleLog.h @@ -10,14 +10,14 @@ namespace RE // BSTSDM [[nodiscard]] static ConsoleLog* GetSingleton() { - static REL::Relocation singleton{ Offset::ConsoleLog::singleton }; + static REL::Relocation singleton{ ID::ConsoleLog::singleton }; return *singleton; } void VPrint(const char* a_fmt, std::va_list a_args) { using func_t = decltype(&ConsoleLog::VPrint); - REL::Relocation func{ Offset::ConsoleLog::VPrint }; + REL::Relocation func{ ID::ConsoleLog::VPrint }; func(this, a_fmt, a_args); } diff --git a/CommonLibSF/include/RE/N/NativeFunctionBase.h b/CommonLibSF/include/RE/N/NativeFunctionBase.h index a5eb4620..19a9a038 100644 --- a/CommonLibSF/include/RE/N/NativeFunctionBase.h +++ b/CommonLibSF/include/RE/N/NativeFunctionBase.h @@ -59,7 +59,7 @@ namespace RE virtual std::uint64_t* GetParam(std::uint32_t a_idx, BSFixedString* a_nameOut, std::uint64_t* a_typeOut) { using func_t = std::add_pointer_t; - REL::Relocation func{ Offset::BSScript::Internal::NF_util::NativeFunctionBase::GetParam }; + REL::Relocation func{ ID::BSScript::Internal::NF_util::NativeFunctionBase::GetParam }; return func(&_params, a_idx, a_nameOut, a_typeOut); } virtual std::uint64_t GetNumParams2(void) override { return _params.unk0A; } @@ -73,13 +73,13 @@ namespace RE virtual std::uint32_t Invoke(std::uint64_t a_unk0, std::uint64_t a_unk1, VMClassRegistry* a_registry, VMState* a_unk3) override { using func_t = decltype(&NativeFunctionBase::Invoke); - REL::Relocation func{ Offset::BSScript::Internal::NF_util::NativeFunctionBase::Invoke }; + REL::Relocation func{ ID::BSScript::Internal::NF_util::NativeFunctionBase::Invoke }; return func(this, a_unk0, a_unk1, a_registry, a_unk3); } virtual BSFixedString* Unk_10(void) override { using func_t = decltype(&NativeFunctionBase::Unk_10); - REL::Relocation func{ Offset::BSScript::Internal::NF_util::NativeFunctionBase::Unk_10 }; + REL::Relocation func{ ID::BSScript::Internal::NF_util::NativeFunctionBase::Unk_10 }; return func(this); } virtual bool Unk_11(std::uint32_t a_unk0, std::uint32_t* a_unk1) override @@ -104,13 +104,13 @@ namespace RE virtual bool GetParamInfo(std::uint32_t a_idx, void* a_out) override { using func_t = decltype(&NativeFunctionBase::GetParamInfo); - REL::Relocation func{ Offset::BSScript::Internal::NF_util::NativeFunctionBase::GetParamInfo }; + REL::Relocation func{ ID::BSScript::Internal::NF_util::NativeFunctionBase::GetParamInfo }; return func(this, a_idx, a_out); } virtual void* Unk_15(std::uint64_t a_arg0, std::uint64_t a_arg1) { using func_t = decltype(&NativeFunctionBase::Unk_15); - REL::Relocation func{ Offset::BSScript::Internal::NF_util::NativeFunctionBase::Unk_15 }; + REL::Relocation func{ ID::BSScript::Internal::NF_util::NativeFunctionBase::Unk_15 }; return func(this, a_arg0, a_arg1); } virtual bool GetUnk41(void) override { return _isCallableFromTasklet; } diff --git a/CommonLibSF/include/RE/R/RegSettingCollection.h b/CommonLibSF/include/RE/R/RegSettingCollection.h index 4b3aeb77..88cfde8f 100644 --- a/CommonLibSF/include/RE/R/RegSettingCollection.h +++ b/CommonLibSF/include/RE/R/RegSettingCollection.h @@ -15,7 +15,7 @@ namespace RE [[nodiscard]] static RegSettingCollection* GetSingleton() { - REL::Relocation singleton{ Offset::RegSettingCollection::singleton }; + REL::Relocation singleton{ ID::RegSettingCollection::singleton }; return *singleton; } diff --git a/CommonLibSF/include/RE/RTTI.h b/CommonLibSF/include/RE/RTTI.h index aebc25e3..2e929646 100644 --- a/CommonLibSF/include/RE/RTTI.h +++ b/CommonLibSF/include/RE/RTTI.h @@ -138,7 +138,7 @@ namespace RE inline void* RTDynamicCast(void* a_inptr, std::int32_t a_vfDelta, void* a_srcType, void* a_targetType, std::int32_t a_isReference) { using func_t = decltype(&RTDynamicCast); - REL::Relocation func{ Offset::RTDynamicCast }; + REL::Relocation func{ ID::RTDynamicCast }; return func(a_inptr, a_vfDelta, a_srcType, a_targetType, a_isReference); } diff --git a/CommonLibSF/include/RE/S/ScaleformGFxValue.h b/CommonLibSF/include/RE/S/ScaleformGFxValue.h index 0d9eb91f..e3e76980 100644 --- a/CommonLibSF/include/RE/S/ScaleformGFxValue.h +++ b/CommonLibSF/include/RE/S/ScaleformGFxValue.h @@ -169,154 +169,154 @@ namespace RE::Scaleform::GFx void ObjectAddRef(Value* a_val, void* a_obj) { using func_t = decltype(&ObjectInterface::ObjectAddRef); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::ObjectAddRef }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::ObjectAddRef }; return func(this, a_val, a_obj); } void ObjectRelease(Value* a_val, void* a_obj) { using func_t = decltype(&ObjectInterface::ObjectRelease); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::ObjectRelease }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::ObjectRelease }; return func(this, a_val, a_obj); } bool HasMember(void* a_data, const char* a_name, bool a_isdobj) const { using func_t = decltype(&ObjectInterface::HasMember); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::HasMember }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::HasMember }; return func(this, a_data, a_name, a_isdobj); } bool GetMember(void* a_data, const char* a_name, Value* a_val, bool a_isdobj) const { using func_t = decltype(&ObjectInterface::GetMember); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::GetMember }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::GetMember }; return func(this, a_data, a_name, a_val, a_isdobj); } bool SetMember(void* a_data, const char* a_name, const Value& a_value, bool a_isdobj) { using func_t = decltype(&ObjectInterface::SetMember); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::SetMember }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::SetMember }; return func(this, a_data, a_name, a_value, a_isdobj); } bool Invoke(void* a_data, Value* a_result, const char* a_name, const Value* a_args, std::size_t a_numArgs, bool a_isdobj) { using func_t = decltype(&ObjectInterface::Invoke); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::Invoke }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::Invoke }; return func(this, a_data, a_result, a_name, a_args, a_numArgs, a_isdobj); } void VisitMembers(void* a_data, ObjVisitor* a_visitor, bool a_isdobj) { using func_t = decltype(&ObjectInterface::VisitMembers); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::VisitMembers }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::VisitMembers }; return func(this, a_data, a_visitor, a_isdobj); } std::uint32_t GetArraySize(void* a_data) { using func_t = decltype(&ObjectInterface::GetArraySize); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::GetArraySize }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::GetArraySize }; return func(this, a_data); } bool SetArraySize(void* a_data, std::uint32_t a_size) { using func_t = decltype(&ObjectInterface::SetArraySize); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::SetArraySize }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::SetArraySize }; return func(this, a_data, a_size); } bool GetElement(void* a_data, std::uint32_t a_index, Value* a_value) { using func_t = decltype(&ObjectInterface::GetElement); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::GetElement }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::GetElement }; return func(this, a_data, a_index, a_value); } bool SetElement(void* a_data, std::uint32_t a_index, const Value& a_value) { using func_t = decltype(&ObjectInterface::SetElement); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::SetElement }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::SetElement }; return func(this, a_data, a_index, a_value); } void VisitElements(void* a_data, ArrVisitor* a_visitor, std::uint32_t a_index, std::int32_t a_count) { using func_t = decltype(&ObjectInterface::VisitElements); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::VisitElements }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::VisitElements }; return func(this, a_data, a_visitor, a_index, a_count); } bool PushBack(void* a_data, const Value& a_value) { using func_t = decltype(&ObjectInterface::PushBack); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::PushBack }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::PushBack }; return func(this, a_data, a_value); } bool PopBack(void* a_data, Value* a_value) { using func_t = decltype(&ObjectInterface::PopBack); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::PopBack }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::PopBack }; return func(this, a_data, a_value); } bool RemoveElements(void* a_data, std::uint32_t a_index, std::int32_t a_count) { using func_t = decltype(&ObjectInterface::RemoveElements); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::RemoveElements }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::RemoveElements }; return func(this, a_data, a_index, a_count); } bool GetParent(void* a_data, Value* a_value) { using func_t = decltype(&ObjectInterface::GetParent); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::GetParent }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::GetParent }; return func(this, a_data, a_value); } bool GetText(void* a_data, Value* a_value, bool a_html) { using func_t = decltype(&ObjectInterface::GetText); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::GetText }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::GetText }; return func(this, a_data, a_value, a_html); } bool SetText(void* a_data, const char* a_text, bool a_html) { using func_t = decltype(&ObjectInterface::SetText); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::SetText }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::SetText }; return func(this, a_data, a_text, a_html); } bool SetTextW(void* a_data, const wchar_t* a_text, bool a_html) { using func_t = decltype(&ObjectInterface::SetTextW); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::SetTextW }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::SetTextW }; return func(this, a_data, a_text, a_html); } bool CreateEmptyMovieClip(void* a_data, Value* a_value, const char* a_name, std::int32_t a_depth) { using func_t = decltype(&ObjectInterface::CreateEmptyMovieClip); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::CreateEmptyMovieClip }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::CreateEmptyMovieClip }; return func(this, a_data, a_value, a_name, a_depth); } bool GotoAndPlayL(void* a_data, const char* a_frame, bool a_stop) { using func_t = decltype(&ObjectInterface::GotoAndPlayL); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::GotoAndPlayL }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::GotoAndPlayL }; return func(this, a_data, a_frame, a_stop); } bool GotoAndPlay(void* a_data, std::uint32_t a_frame, bool a_stop) { using func_t = decltype(&ObjectInterface::GotoAndPlay); - REL::Relocation func{ Offset::Scaleform::ObjectInterface::GotoAndPlay }; + REL::Relocation func{ ID::Scaleform::ObjectInterface::GotoAndPlay }; return func(this, a_data, a_frame, a_stop); } diff --git a/CommonLibSF/include/RE/S/Script.h b/CommonLibSF/include/RE/S/Script.h index dad4c551..158cc0d2 100644 --- a/CommonLibSF/include/RE/S/Script.h +++ b/CommonLibSF/include/RE/S/Script.h @@ -158,13 +158,13 @@ namespace RE inline static const auto GetConsoleCommands() { - static REL::Relocation chunk{ Offset::Script::GetConsoleCommands }; + static REL::Relocation chunk{ ID::Script::GetConsoleCommands }; return std::span{ *chunk }; } inline static const auto GetScriptCommands() { - static REL::Relocation chunk{ Offset::Script::GetScriptCommands }; + static REL::Relocation chunk{ ID::Script::GetScriptCommands }; return std::span{ *chunk }; } diff --git a/CommonLibSF/include/RE/T/TESCellFullyLoadedEvent.h b/CommonLibSF/include/RE/T/TESCellFullyLoadedEvent.h index e82bd191..3d3200c3 100644 --- a/CommonLibSF/include/RE/T/TESCellFullyLoadedEvent.h +++ b/CommonLibSF/include/RE/T/TESCellFullyLoadedEvent.h @@ -12,7 +12,7 @@ namespace RE [[nodiscard]] static BSTEventSource* GetEventSource() { using func_t = decltype(&TESCellFullyLoadedEvent::GetEventSource); - REL::Relocation func{ Offset::TESCellFullyLoadedEvent::GetEventSource }; + REL::Relocation func{ ID::TESCellFullyLoadedEvent::GetEventSource }; return func(); } diff --git a/CommonLibSF/include/RE/T/TESContainerChangedEvent.h b/CommonLibSF/include/RE/T/TESContainerChangedEvent.h index ba059c70..735ace93 100644 --- a/CommonLibSF/include/RE/T/TESContainerChangedEvent.h +++ b/CommonLibSF/include/RE/T/TESContainerChangedEvent.h @@ -10,7 +10,7 @@ namespace RE [[nodiscard]] static BSTEventSource* GetEventSource() { using func_t = decltype(&TESContainerChangedEvent::GetEventSource); - REL::Relocation func{ Offset::TESContainerChangedEvent::GetEventSource }; + REL::Relocation func{ ID::TESContainerChangedEvent::GetEventSource }; return func(); } diff --git a/CommonLibSF/include/RE/T/TESDataHandler.h b/CommonLibSF/include/RE/T/TESDataHandler.h index f3189c3a..1886074b 100644 --- a/CommonLibSF/include/RE/T/TESDataHandler.h +++ b/CommonLibSF/include/RE/T/TESDataHandler.h @@ -40,7 +40,7 @@ namespace RE [[nodiscard]] static TESDataHandler* GetSingleton() { - REL::Relocation singleton{ Offset::TESDataHandler::singleton }; + REL::Relocation singleton{ ID::TESDataHandler::singleton }; return *singleton; } diff --git a/CommonLibSF/include/RE/T/TESDeathEvent.h b/CommonLibSF/include/RE/T/TESDeathEvent.h index 6773e691..0d8b2d2b 100644 --- a/CommonLibSF/include/RE/T/TESDeathEvent.h +++ b/CommonLibSF/include/RE/T/TESDeathEvent.h @@ -13,7 +13,7 @@ namespace RE [[nodiscard]] static BSTEventSource* GetEventSource() { using func_t = decltype(&TESDeathEvent::GetEventSource); - REL::Relocation func{ Offset::TESDeathEvent::GetEventSource }; + REL::Relocation func{ ID::TESDeathEvent::GetEventSource }; return func(); } diff --git a/CommonLibSF/include/RE/T/TESObjectLoadedEvent.h b/CommonLibSF/include/RE/T/TESObjectLoadedEvent.h index 76bb0485..329fb86c 100644 --- a/CommonLibSF/include/RE/T/TESObjectLoadedEvent.h +++ b/CommonLibSF/include/RE/T/TESObjectLoadedEvent.h @@ -10,7 +10,7 @@ namespace RE [[nodiscard]] static BSTEventSource* GetEventSource() { using func_t = decltype(&TESObjectLoadedEvent::GetEventSource); - REL::Relocation func{ Offset::TESObjectLoadedEvent::GetEventSource }; + REL::Relocation func{ ID::TESObjectLoadedEvent::GetEventSource }; return func(); } diff --git a/CommonLibSF/include/RE/U/UI.h b/CommonLibSF/include/RE/U/UI.h index 50d57f76..6cb6f2b6 100644 --- a/CommonLibSF/include/RE/U/UI.h +++ b/CommonLibSF/include/RE/U/UI.h @@ -42,14 +42,14 @@ namespace RE inline static UI* GetSingleton() { - static REL::Relocation singleton{ Offset::UI::singleton }; + static REL::Relocation singleton{ ID::UI::singleton }; return *singleton; } bool IsMenuOpen(const BSFixedString& a_name) { using func_t = decltype(&UI::IsMenuOpen); - REL::Relocation func{ Offset::UI::IsMenuOpen }; + REL::Relocation func{ ID::UI::IsMenuOpen }; return func(this, a_name); } From e17f086ae69a53c7700583ee04c6346ea74d84fb Mon Sep 17 00:00:00 2001 From: nikitalita <69168929+nikitalita@users.noreply.github.com> Date: Fri, 20 Oct 2023 17:21:38 -0700 Subject: [PATCH 6/6] fix: fix compile on clang --- CommonLibSF/include/RE/S/StructTypeInfo.h | 1 + 1 file changed, 1 insertion(+) diff --git a/CommonLibSF/include/RE/S/StructTypeInfo.h b/CommonLibSF/include/RE/S/StructTypeInfo.h index 5898062a..23d6f6ff 100644 --- a/CommonLibSF/include/RE/S/StructTypeInfo.h +++ b/CommonLibSF/include/RE/S/StructTypeInfo.h @@ -6,6 +6,7 @@ #include "RE/B/BSTSmartPointer.h" #include "RE/I/IComplexType.h" #include "RE/M/MemoryManager.h" +#include "RE/O/ObjectTypeInfo.h" #include "RE/T/TypeInfo.h" #include "RE/V/Variable.h"