From c1db74812d40ca7086f4d421e4be21c45fc0c08e Mon Sep 17 00:00:00 2001 From: powerof3 <32599957+powerof3@users.noreply.github.com> Date: Thu, 19 Oct 2023 07:56:57 +0530 Subject: [PATCH 1/2] feat!: add `ExtraDataList`, `BSExtraData` --- CommonLibSF/include/RE/B/BSExtraData.h | 29 ++++++++ CommonLibSF/include/RE/E/ExtraDataList.h | 85 +++++++++++++++++++++++ CommonLibSF/include/RE/E/ExtraDataTypes.h | 5 +- 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 CommonLibSF/include/RE/B/BSExtraData.h create mode 100644 CommonLibSF/include/RE/E/ExtraDataList.h diff --git a/CommonLibSF/include/RE/B/BSExtraData.h b/CommonLibSF/include/RE/B/BSExtraData.h new file mode 100644 index 00000000..24e566e9 --- /dev/null +++ b/CommonLibSF/include/RE/B/BSExtraData.h @@ -0,0 +1,29 @@ +#pragma once + +#include "RE/E/ExtraDataTypes.h" + +namespace RE +{ + class BSExtraData + { + public: + SF_RTTI_VTABLE(BSExtraData); + SF_EXTRADATATYPE(None); + + virtual ~BSExtraData(); // 00 + + // add + virtual void Unk_01(); // 01 + virtual void Unk_02(); // 02 + virtual void Unk_03(); // 03 + virtual void Unk_04(); // 04 + virtual void Unk_05(); // 05 + virtual void Unk_06(); // 06 + + // members + BSExtraData* next; // 08 + std::uint16_t flags; // 10 + stl::enumeration type; // 12 + }; + static_assert(sizeof(BSExtraData) == 0x18); +} diff --git a/CommonLibSF/include/RE/E/ExtraDataList.h b/CommonLibSF/include/RE/E/ExtraDataList.h new file mode 100644 index 00000000..e6418d2c --- /dev/null +++ b/CommonLibSF/include/RE/E/ExtraDataList.h @@ -0,0 +1,85 @@ +#pragma once + +#include "RE/B/BSExtraData.h" +#include "RE/B/BSIntrusiveRefCounted.h" +#include "RE/B/BSLock.h" +#include "RE/E/ExtraDataTypes.h" + +namespace RE +{ + class BaseExtraList + { + public: + void AddExtra(BSExtraData* a_extra) + { + using func_t = decltype(&BaseExtraList::AddExtra); + REL::Relocation func{ REL::ID(83084) }; + return func(this, a_extra); + } + + [[nodiscard]] BSExtraData* GetByType(ExtraDataType a_type) const noexcept + { + using func_t = decltype(&BaseExtraList::GetByType); + REL::Relocation func{ REL::ID(83208) }; + return func(this, a_type); + } + + private: + // members + BSExtraData* _head{ nullptr }; // 00 + BSExtraData** _tail{ std::addressof(_head) }; // 08 + std::uint8_t* _flags{ nullptr }; // 10 + }; + static_assert(sizeof(BaseExtraList) == 0x18); + + namespace detail + { + template + concept ExtraDataListConstraint = + std::derived_from && + !std::is_pointer_v && + !std::is_reference_v; + } + + class ExtraDataList : + public BSIntrusiveRefCounted // 00 + { + public: + void AddExtra(BSExtraData* a_extra) + { + const BSAutoWriteLock l{ _extraRWLock }; + _extraData.AddExtra(a_extra); + } + + [[nodiscard]] BSExtraData* GetByType(ExtraDataType a_type) const noexcept + { + const BSAutoReadLock l{ _extraRWLock }; + return _extraData.GetByType(a_type); + } + + template + [[nodiscard]] T* GetByType() const noexcept + { + return static_cast(GetByType(T::EXTRADATATYPE)); + } + + [[nodiscard]] bool HasType(ExtraDataType a_type) const noexcept + { + using func_t = bool(*)(const ExtraDataList*, ExtraDataType); + REL::Relocation func{ REL::ID(83208) }; + return func(this, a_type); + } + + template + [[nodiscard]] bool HasType() const noexcept + { + return HasType(T::EXTRADATATYPE); + } + + private: + // members + BaseExtraList _extraData; // 08 + mutable BSReadWriteLock _extraRWLock; // 20 + }; + static_assert(sizeof(ExtraDataList) == 0x28); +} diff --git a/CommonLibSF/include/RE/E/ExtraDataTypes.h b/CommonLibSF/include/RE/E/ExtraDataTypes.h index 4d7db26b..30b6f5c1 100644 --- a/CommonLibSF/include/RE/E/ExtraDataTypes.h +++ b/CommonLibSF/include/RE/E/ExtraDataTypes.h @@ -2,7 +2,7 @@ namespace RE { - enum class EXTRA_DATA_TYPE + enum class ExtraDataType { kNone, // 0x00 kHavok, // 0x01 - ExtraHavok @@ -260,3 +260,6 @@ namespace RE kPlacedPlanetContent, // 0xFD - ExtraPlacedPlanetContent }; } + +#define SF_EXTRADATATYPE(TYPE) \ + inline static constexpr auto EXTRADATATYPE = RE::ExtraDataType::k##TYPE From 95c60fb97a0a7407dbc99dc6c85ea0aa89b880ff Mon Sep 17 00:00:00 2001 From: powerof3 <32599957+powerof3@users.noreply.github.com> Date: Thu, 19 Oct 2023 08:12:18 +0530 Subject: [PATCH 2/2] chore: add `TESObjectREFR` and `TESObjectCELL` definitions --- CommonLibSF/include/RE/T/TESObjectCELL.h | 4 +++- CommonLibSF/include/RE/T/TESObjectREFR.h | 24 +++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/CommonLibSF/include/RE/T/TESObjectCELL.h b/CommonLibSF/include/RE/T/TESObjectCELL.h index a2255551..bb1b0749 100644 --- a/CommonLibSF/include/RE/T/TESObjectCELL.h +++ b/CommonLibSF/include/RE/T/TESObjectCELL.h @@ -3,6 +3,8 @@ #include "RE/B/BSContainer.h" #include "RE/B/BSLock.h" #include "RE/B/BSTArray.h" +#include "RE/B/BSTSmartPointer.h" +#include "RE/E/ExtraDataList.h" #include "RE/N/NiPoint3.h" #include "RE/N/NiSmartPointer.h" #include "RE/T/TESFullName.h" @@ -133,7 +135,7 @@ namespace RE std::uint8_t unk4E; // 04E stl::enumeration cellState; // 04F std::uint64_t unk50; // 050 - void* extraDataList; // 058 - smart ptr + BSTSmartPointer extraDataList; // 058 CellData cellData; // 060 std::uint32_t unk068; // 068 float unk06C; // 06C diff --git a/CommonLibSF/include/RE/T/TESObjectREFR.h b/CommonLibSF/include/RE/T/TESObjectREFR.h index 6da51ece..20041a8d 100644 --- a/CommonLibSF/include/RE/T/TESObjectREFR.h +++ b/CommonLibSF/include/RE/T/TESObjectREFR.h @@ -4,6 +4,8 @@ #include "RE/B/BGSInventoryList.h" #include "RE/B/BSLock.h" #include "RE/B/BSTEvent.h" +#include "RE/B/BSTSmartPointer.h" +#include "RE/E/ExtraDataList.h" #include "RE/I/IAnimationGraphManagerHolder.h" #include "RE/I/IKeywordFormBase.h" #include "RE/I/IMovementInterface.h" @@ -318,17 +320,17 @@ namespace RE [[nodiscard]] bool IsSpaceshipLanded(); // members - OBJ_REFR data; // 0A0 - BGSInventoryList* inventoryList; // 0D0 - this + lock is one struct? - mutable BSReadWriteLock inventoryListLock; // 0D8 - TESObjectCELL* parentCell; // 0E0 - LOADED_REF_DATA* loadedData; // 0E8 - same as above - mutable BSReadWriteLock loadedDataLock; // 0F0 - std::uint64_t extraDataList; // 0F8 - BGSLocalizedString unk100; // 100 - empty? - std::uint16_t scale; // 108 - bool unk10A; // 10A - std::uint8_t flags; // 10B + OBJ_REFR data; // 0A0 + BGSInventoryList* inventoryList; // 0D0 - this + lock is one struct? + mutable BSReadWriteLock inventoryListLock; // 0D8 + TESObjectCELL* parentCell; // 0E0 + LOADED_REF_DATA* loadedData; // 0E8 - same as above + mutable BSReadWriteLock loadedDataLock; // 0F0 + BSTSmartPointer extraDataList; // 0F8 + BGSLocalizedString unk100; // 100 - empty? + std::uint16_t scale; // 108 + bool unk10A; // 10A + std::uint8_t flags; // 10B }; static_assert(sizeof(TESObjectREFR) == 0x110); }