From 293cbde033dc8ae58dd55b94fee2a52efaeb5c5d Mon Sep 17 00:00:00 2001 From: powerof3 <32599957+powerof3@users.noreply.github.com> Date: Tue, 7 Nov 2023 04:08:53 +0530 Subject: [PATCH] feat: add `TESObjectARMO` (#217) --- .../include/RE/B/BGSAttachParentArray.h | 2 +- CommonLibSF/include/RE/B/BGSBlockBashData.h | 26 ++ .../include/RE/B/BGSInstanceNamingRulesForm.h | 24 ++ .../include/RE/B/BGSTypedKeywordValueArray.h | 3 +- CommonLibSF/include/RE/B/BSTOptional.h | 385 ++++++++++++++++++ CommonLibSF/include/RE/IDs.h | 9 +- CommonLibSF/include/RE/T/TBO_InstanceData.h | 32 +- CommonLibSF/include/RE/T/TESBipedModelForm.h | 24 ++ CommonLibSF/include/RE/T/TESEnchantableForm.h | 30 ++ CommonLibSF/include/RE/T/TESNPC.h | 1 - CommonLibSF/include/RE/T/TESObject.h | 20 +- CommonLibSF/include/RE/T/TESObjectARMO.h | 91 ++++- CommonLibSF/include/RE/T/TESRace.h | 1 - 13 files changed, 616 insertions(+), 32 deletions(-) create mode 100644 CommonLibSF/include/RE/B/BGSBlockBashData.h create mode 100644 CommonLibSF/include/RE/B/BGSInstanceNamingRulesForm.h create mode 100644 CommonLibSF/include/RE/B/BSTOptional.h create mode 100644 CommonLibSF/include/RE/T/TESBipedModelForm.h create mode 100644 CommonLibSF/include/RE/T/TESEnchantableForm.h diff --git a/CommonLibSF/include/RE/B/BGSAttachParentArray.h b/CommonLibSF/include/RE/B/BGSAttachParentArray.h index b2dcddad..d28982a9 100644 --- a/CommonLibSF/include/RE/B/BGSAttachParentArray.h +++ b/CommonLibSF/include/RE/B/BGSAttachParentArray.h @@ -17,5 +17,5 @@ namespace RE const BSFixedString& GetFormComponentType() const override; // 01 - { return "BGSAttachParentArray_Component"; } void InitializeDataComponent() override; // 02 - { return; } }; - static_assert(sizeof(BGSAttachParentArray) == 0x18); + static_assert(sizeof(BGSAttachParentArray) == 0x20); } diff --git a/CommonLibSF/include/RE/B/BGSBlockBashData.h b/CommonLibSF/include/RE/B/BGSBlockBashData.h new file mode 100644 index 00000000..91cfe176 --- /dev/null +++ b/CommonLibSF/include/RE/B/BGSBlockBashData.h @@ -0,0 +1,26 @@ +#pragma once + +#include "RE/B/BaseFormComponent.h" + +namespace RE +{ + class BGSImpactDataSet; + class BGSMaterialType; + + class BGSBlockBashData : public BaseFormComponent + { + public: + SF_RTTI_VTABLE(BGSBlockBashData); + + ~BGSBlockBashData() override; // 00 + + // override (BaseFormComponent) + const BSFixedString& GetFormComponentType() const override; // 01 - { return "BGSBlockBashData_Component"; } + void InitializeDataComponent() override; // 02 - { return; } + + // members + BGSImpactDataSet* blockBashImpactDataSet; // 08 + BGSMaterialType* altBlockMaterialType; // 10 + }; + static_assert(sizeof(BGSBlockBashData) == 0x18); +} diff --git a/CommonLibSF/include/RE/B/BGSInstanceNamingRulesForm.h b/CommonLibSF/include/RE/B/BGSInstanceNamingRulesForm.h new file mode 100644 index 00000000..b0915af2 --- /dev/null +++ b/CommonLibSF/include/RE/B/BGSInstanceNamingRulesForm.h @@ -0,0 +1,24 @@ +#pragma once + +#include "RE/B/BaseFormComponent.h" + +namespace RE +{ + class BGSInstanceNamingRules; + + class BGSInstanceNamingRulesForm : public BaseFormComponent + { + public: + SF_RTTI(BGSInstanceNamingRulesForm); + + ~BGSInstanceNamingRulesForm() override; // 00 + + // override (BaseFormComponent) + const BSFixedString& GetFormComponentType() const override; // 01 - { return "BGSInstanceNamingRulesForm_Component"; } + void InitializeDataComponent() override; // 02 - { return; } + + // members + BGSInstanceNamingRules* instanceNamingRules; // 08 + }; + static_assert(sizeof(BGSInstanceNamingRulesForm) == 0x10); +} diff --git a/CommonLibSF/include/RE/B/BGSTypedKeywordValueArray.h b/CommonLibSF/include/RE/B/BGSTypedKeywordValueArray.h index e84574af..ed24923e 100644 --- a/CommonLibSF/include/RE/B/BGSTypedKeywordValueArray.h +++ b/CommonLibSF/include/RE/B/BGSTypedKeywordValueArray.h @@ -60,6 +60,7 @@ namespace RE // members BGSTypedKeywordValue* array; // 00 std::uint32_t size; // 08 + std::uint64_t unk10; // 10 }; - static_assert(sizeof(BGSTypedKeywordValueArray) == 0x10); + static_assert(sizeof(BGSTypedKeywordValueArray) == 0x18); } diff --git a/CommonLibSF/include/RE/B/BSTOptional.h b/CommonLibSF/include/RE/B/BSTOptional.h new file mode 100644 index 00000000..2639434d --- /dev/null +++ b/CommonLibSF/include/RE/B/BSTOptional.h @@ -0,0 +1,385 @@ +#pragma once + +namespace RE +{ + template + class BSTOptional + { + public: + using value_type = T; + + // 1a) + constexpr BSTOptional() noexcept = default; + + // 1b) + constexpr BSTOptional(std::nullopt_t) noexcept {} + + // 2) non-trivial + constexpr BSTOptional(const BSTOptional& a_rhs) // + noexcept(std::is_nothrow_copy_constructible_v) // + requires(std::is_copy_constructible_v && + !std::is_trivially_copy_constructible_v) + { + if (a_rhs.has_value()) { + std::construct_at(std::addressof(_value), a_rhs.value()); + _active = true; + } + } + + // 2) trivial + constexpr BSTOptional(const BSTOptional&) requires(std::is_trivially_copy_constructible_v) = default; + + // 2) trivial + constexpr BSTOptional(BSTOptional&&) requires(std::is_trivially_move_constructible_v) = default; + + // 3) non-trivial + constexpr BSTOptional(BSTOptional&& a_rhs) // + noexcept(std::is_nothrow_move_constructible_v) // + requires(std::is_move_constructible_v && + !std::is_trivially_move_constructible_v) + { + if (a_rhs.has_value()) { + std::construct_at(std::addressof(_value), std::move(a_rhs).value()); + _active = true; + } + } + + // 4) + template + explicit(!std::is_convertible_v) // + BSTOptional(const BSTOptional& a_rhs) // + noexcept(std::is_nothrow_constructible_v) // + requires(std::is_constructible_v && + !std::is_constructible_v&> && + !std::is_constructible_v&> && + !std::is_constructible_v&&> && + !std::is_constructible_v&&> && + !std::is_convertible_v&, value_type> && + !std::is_convertible_v&, value_type> && + !std::is_convertible_v&&, value_type> && + !std::is_convertible_v&&, value_type>) + { + if (a_rhs.has_value()) { + std::construct_at(std::addressof(_value), a_rhs.value()); + _active = true; + } + } + + // 5) + template + explicit(!std::is_convertible_v) // + BSTOptional(BSTOptional&& a_rhs) // + noexcept(std::is_nothrow_constructible_v) // + requires(std::is_constructible_v && + !std::is_constructible_v&> && + !std::is_constructible_v&> && + !std::is_constructible_v&&> && + !std::is_constructible_v&&> && + !std::is_convertible_v&, value_type> && + !std::is_convertible_v&, value_type> && + !std::is_convertible_v&&, value_type> && + !std::is_convertible_v&&, value_type>) + { + if (a_rhs.has_value()) { + std::construct_at(std::addressof(_value), std::move(a_rhs).value()); + _active = true; + } + } + + // 6) + template + constexpr explicit BSTOptional(std::in_place_t, Args&&... a_args) // + noexcept(std::is_nothrow_constructible_v) // + requires(std::is_constructible_v) + { + std::construct_at(std::addressof(_value), std::forward(a_args)...); + _active = true; + } + + // 7) + template + constexpr explicit BSTOptional(std::in_place_t, std::initializer_list a_ilist, Args&&... a_args) // + noexcept(std::is_nothrow_constructible_v&, Args&&...>) // + requires(std::is_constructible_v&, Args&&...>) + { + std::construct_at(std::addressof(_value), a_ilist, std::forward(a_args)...); + _active = true; + } + + // 8) + template + constexpr explicit(!std::is_convertible_v) // + BSTOptional(U&& a_value) // + noexcept(std::is_nothrow_constructible_v) // + requires(std::is_constructible_v && + !std::same_as, std::in_place_t> && + !std::same_as, BSTOptional>) + { + std::construct_at(std::addressof(_value), std::forward(a_value)); + _active = true; + } + + // non-trivial + ~BSTOptional() // + noexcept(std::is_nothrow_destructible_v) // + requires(!std::is_trivially_destructible_v) + { + reset(); + } + + // trivial + ~BSTOptional() requires(std::is_trivially_destructible_v) = default; + + // 1) + BSTOptional& operator=(std::nullopt_t) // + noexcept(noexcept(reset())) + { + reset(); + return *this; + } + + // 2) defined + constexpr BSTOptional& operator=(const BSTOptional& a_rhs) // + noexcept((std::is_nothrow_destructible_v && + std::is_nothrow_copy_constructible_v && + std::is_nothrow_copy_assignable_v)) // + requires((std::is_copy_constructible_v && + std::is_copy_assignable_v)) + { + if (this != std::addressof(a_rhs)) { + if (a_rhs.has_value()) { + if (has_value()) { + _value = a_rhs.value(); + } else { + std::construct_at(std::addressof(_value), a_rhs.value()); + _active = true; + } + } else if (has_value()) { + do_reset(); + } + } + return *this; + } + + // 2) deleted + BSTOptional& operator=(const BSTOptional&) // + requires(!std::is_copy_constructible_v || + !std::is_copy_assignable_v) = delete; + + // 3) defined + constexpr BSTOptional& operator=(BSTOptional&& a_rhs) // + noexcept((std::is_nothrow_destructible_v && + std::is_nothrow_move_constructible_v && + std::is_nothrow_move_assignable_v)) // + requires((std::is_move_constructible_v && + std::is_move_assignable_v)) + { + if (this != std::addressof(a_rhs)) { + if (a_rhs.has_value()) { + if (has_value()) { + _value = std::move(a_rhs).value(); + } else { + std::construct_at(std::addressof(_value), std::move(a_rhs).value()); + _active = true; + } + } else if (has_value()) { + do_reset(); + } + } + return *this; + } + + // 3) deleted + BSTOptional& operator=(BSTOptional&&) // + requires(!std::is_move_constructible_v || + !std::is_move_assignable_v) = delete; + + // 4) + template + BSTOptional& operator=(U&& a_value) // + noexcept((std::is_nothrow_destructible_v && + std::is_nothrow_constructible_v && + std::is_nothrow_assignable_v)) // + requires(!std::same_as, BSTOptional> && + std::is_constructible_v && + std::is_assignable_v && + (!std::is_scalar_v || !std::same_as, T>)) + { + if (has_value()) { + _value = std::forward(a_value); + } else { + std::construct_at(std::addressof(_value), std::forward(a_value)); + _active = true; + } + return *this; + } + + // 5) + template + BSTOptional& operator=(const BSTOptional& a_rhs) // + noexcept((std::is_nothrow_destructible_v && + std::is_nothrow_constructible_v && + std::is_nothrow_assignable_v)) // + requires(!std::is_constructible_v&> && + !std::is_constructible_v&> && + !std::is_constructible_v&&> && + !std::is_constructible_v&&> && + !std::is_convertible_v&, value_type> && + !std::is_convertible_v&, value_type> && + !std::is_convertible_v&&, value_type> && + !std::is_convertible_v&&, value_type> && + !std::is_assignable_v&> && + !std::is_assignable_v&> && + !std::is_assignable_v&&> && + !std::is_assignable_v&&> && + std::is_constructible_v && + std::is_assignable_v) + { + if (a_rhs.has_value()) { + if (has_value()) { + _value = a_rhs.value(); + } else { + std::construct_at(std::addressof(_value), a_rhs.value()); + _active = true; + } + } else if (has_value()) { + reset(); + } + return *this; + } + + // 6) + template + BSTOptional& operator=(BSTOptional&& a_rhs) // + noexcept((std::is_nothrow_destructible_v && + std::is_nothrow_constructible_v && + std::is_nothrow_assignable_v)) // + requires(!std::is_constructible_v&> && + !std::is_constructible_v&> && + !std::is_constructible_v&&> && + !std::is_constructible_v&&> && + !std::is_convertible_v&, value_type> && + !std::is_convertible_v&, value_type> && + !std::is_convertible_v&&, value_type> && + !std::is_convertible_v&&, value_type> && + !std::is_assignable_v&> && + !std::is_assignable_v&> && + !std::is_assignable_v&&> && + !std::is_assignable_v&&> && + std::is_constructible_v && + std::is_assignable_v) + { + if (a_rhs.has_value()) { + if (has_value()) { + _value = std::move(a_rhs).value(); + } else { + std::construct_at(std::addressof(_value), std::move(a_rhs).value()); + _active = true; + } + } else if (has_value()) { + reset(); + } + return *this; + } + + [[nodiscard]] constexpr const value_type* operator->() const noexcept { return std::addressof(value()); } + [[nodiscard]] constexpr value_type* operator->() noexcept { return std::addressof(value()); } + [[nodiscard]] constexpr const value_type& operator*() const& noexcept { return value(); } + [[nodiscard]] constexpr value_type& operator*() & noexcept { return value(); } + [[nodiscard]] constexpr const value_type&& operator*() const&& noexcept { return std::move(*this).value(); } + [[nodiscard]] constexpr value_type&& operator*() && noexcept { return std::move(*this).value(); } + + [[nodiscard]] constexpr explicit operator bool() const noexcept { return has_value(); } + [[nodiscard]] constexpr bool has_value() const noexcept { return _active; } + + [[nodiscard]] constexpr value_type& value() & noexcept + { + assert(has_value()); + return _value; + } + + [[nodiscard]] constexpr const value_type& value() const& noexcept + { + assert(has_value()); + return _value; + } + + [[nodiscard]] constexpr value_type&& value() && noexcept + { + assert(has_value()); + return std::move(_value); + } + + [[nodiscard]] constexpr const value_type&& value() const&& noexcept + { + assert(has_value()); + return std::move(_value); + } + + // 1) + template + [[nodiscard]] constexpr value_type value_or(U&& a_default) const& // + requires((std::is_copy_constructible_v && + std::convertible_to)) + { + return has_value() ? value() : static_cast(std::forward(a_default)); + } + + // 2) + template + [[nodiscard]] constexpr value_type value_or(U&& a_default) && // + requires((std::is_move_constructible_v && + std::convertible_to)) + { + return has_value() ? std::move(*this).value() : static_cast(std::forward(a_default)); + } + + void reset() noexcept(noexcept(do_reset())) { do_reset(); } + + // 1) + template + value_type& emplace(Args&&... a_args) // + noexcept(std::is_nothrow_constructible_v) // + requires(std::is_constructible_v) + { + reset(); + std::construct_at(std::addressof(_value), std::forward(a_args)...); + _active = true; + return value(); + } + + // 2) + template + value_type& emplace(std::initializer_list a_ilist, Args&&... a_args) // + noexcept(std::is_nothrow_constructible_v&, Args&&...>) // + requires(std::is_constructible_v&, Args&&...>) + { + reset(); + std::construct_at(std::addressof(_value), a_ilist, std::forward(a_args)...); + _active = true; + return value(); + } + + private: + constexpr void + do_reset() // + noexcept(std::is_nothrow_destructible_v) + { + if (has_value()) { + std::destroy_at(std::addressof(_value)); + _active = false; + } + } + + // members + union + { + std::remove_const_t _value; + std::byte _buffer[sizeof(value_type)]{}; + }; // 00 + bool _active{ false }; // ?? + }; + + template + BSTOptional(T) -> BSTOptional; +} diff --git a/CommonLibSF/include/RE/IDs.h b/CommonLibSF/include/RE/IDs.h index f73e0242..e6789e65 100644 --- a/CommonLibSF/include/RE/IDs.h +++ b/CommonLibSF/include/RE/IDs.h @@ -320,6 +320,11 @@ namespace RE::ID inline constexpr REL::ID LookupByEditorID{ 86127 }; } + namespace TESObjectARMO + { + inline constexpr REL::ID CanUseArmor{ 103501 }; + } + namespace TESObjectLoadedEvent { inline constexpr REL::ID GetEventSource{ 107177 }; @@ -327,7 +332,9 @@ namespace RE::ID namespace TESObjectREFR { - inline constexpr REL::ID AddLockChange{ 106386 }; + inline constexpr REL::ID ActivateRef{ 106374 }; + inline constexpr REL::ID AddLockChange{ 106386 }; + inline constexpr REL::ID GetCalcLevel{ 107531 }; inline constexpr REL::ID GetCurrentLocation{ 106554 }; inline constexpr REL::ID GetLinkedRef{ 107578 }; inline constexpr REL::ID GetLock{ 107581 }; diff --git a/CommonLibSF/include/RE/T/TBO_InstanceData.h b/CommonLibSF/include/RE/T/TBO_InstanceData.h index 08085e89..2323f73c 100644 --- a/CommonLibSF/include/RE/T/TBO_InstanceData.h +++ b/CommonLibSF/include/RE/T/TBO_InstanceData.h @@ -16,22 +16,22 @@ namespace RE virtual ~TBO_InstanceData(); // 00 // add - virtual BGSKeywordForm* GetKeywordData() const; // 01 - virtual void DeleteKeywordData(); // 02 - virtual void CreateKeywordData(); // 03 - virtual BGSBlockBashData* GetBlockBashData(); // 04 - virtual void DeleteBlockBashData(); // 05 - virtual void CreateBlockBashData(); // 06 - virtual void Unk_07(); // 07 - virtual void Unk_08(); // 08 - virtual void Unk_09(); // 09 - virtual void Unk_0A(); // 0A - virtual void Unk_0B(); // 0B - virtual void Unk_0C(); // 0C - virtual void Unk_0D(); // 0D - virtual void Unk_0E(); // 0E - virtual void Unk_0F(); // 0F - virtual void Unk_10(); // 10 + virtual BGSKeywordForm* GetKeywordData() const; // 01 + virtual void DeleteKeywordData(); // 02 + virtual void CreateKeywordData(); // 03 + virtual BGSBlockBashData* GetBlockBashData(); // 04 + virtual void DeleteBlockBashData(); // 05 + virtual void CreateBlockBashData(); // 06 + virtual float GetWeight(); // 07 + virtual std::int32_t GetValue() const; // 08 + virtual std::uint32_t GetHealth() const; // 09 + virtual float GetColorRemappingIndex() const; // 0A + virtual void Unk_0B(); // 0B + virtual void Unk_0C(); // 0C + virtual void Unk_0D(); // 0D + virtual void Unk_0E(); // 0E + virtual void Unk_0F(); // 0F + virtual void Unk_10(); // 10 // members std::uint64_t unk10; // 10 diff --git a/CommonLibSF/include/RE/T/TESBipedModelForm.h b/CommonLibSF/include/RE/T/TESBipedModelForm.h new file mode 100644 index 00000000..9a0b3254 --- /dev/null +++ b/CommonLibSF/include/RE/T/TESBipedModelForm.h @@ -0,0 +1,24 @@ +#pragma once + +#include "RE/B/BGSModelMaterialSwap.h" +#include "RE/B/BaseFormComponent.h" +#include "RE/S/Sexes.h" + +namespace RE +{ + class TESBipedModelForm : public BaseFormComponent + { + public: + SF_RTTI_VTABLE(TESBipedModelForm); + + ~TESBipedModelForm() override; // 00 + + // override (BaseFormComponent) + const BSFixedString& GetFormComponentType() const override; // 01 - { return "TESBipedModel_Component"; } + void InitializeDataComponent() override; // 02} + + // members + BGSModelMaterialSwap worldModels[SEX::kTotal]; // 08 + }; + static_assert(sizeof(TESBipedModelForm) == 0x58); +} diff --git a/CommonLibSF/include/RE/T/TESEnchantableForm.h b/CommonLibSF/include/RE/T/TESEnchantableForm.h new file mode 100644 index 00000000..d05b74ea --- /dev/null +++ b/CommonLibSF/include/RE/T/TESEnchantableForm.h @@ -0,0 +1,30 @@ +#pragma once + +#include "RE/B/BaseFormComponent.h" +#include "RE/M/MagicSystem.h" + +namespace RE +{ + class EnchantmentItem; + + class TESEnchantableForm : public BaseFormComponent + { + public: + SF_RTTI_VTABLE(TESEnchantableForm); + + ~TESEnchantableForm() override; // 00 + + // override (BaseFormComponent) + const BSFixedString& GetFormComponentType() const override; // 01 - { return "TESEnchantableForm_Component"; } + void InitializeDataComponent() override; // 02 + + // add + [[nodiscard]] virtual MagicSystem::CastingType GetCastingType() const; // 04 - { return castingType; } + + // members + EnchantmentItem* formEnchanting; // 08 + stl::enumeration castingType; // 10 + std::uint16_t amountofEnchantment; // 12 + }; + static_assert(sizeof(TESEnchantableForm) == 0x18); +} diff --git a/CommonLibSF/include/RE/T/TESNPC.h b/CommonLibSF/include/RE/T/TESNPC.h index 7416c988..3882baba 100644 --- a/CommonLibSF/include/RE/T/TESNPC.h +++ b/CommonLibSF/include/RE/T/TESNPC.h @@ -67,7 +67,6 @@ namespace RE // members BGSAttachParentArray attachParents; // 320 - std::uint64_t unk338; // 338 std::uint32_t unk340; // 340 std::uint32_t unk344; // 344 TESClass* npcClass; // 348 diff --git a/CommonLibSF/include/RE/T/TESObject.h b/CommonLibSF/include/RE/T/TESObject.h index 7037f11b..e22e6be5 100644 --- a/CommonLibSF/include/RE/T/TESObject.h +++ b/CommonLibSF/include/RE/T/TESObject.h @@ -12,16 +12,16 @@ namespace RE ~TESObject() override; // add - virtual void Unk_62(); // 62 - virtual void Unk_63(); // 63 - virtual void Unk_64(); // 64 - virtual void Unk_65(); // 65 - virtual void Unk_66(); // 66 - virtual void Unk_67(); // 67 - virtual void Unk_68(); // 68 - virtual void Unk_69(); // 69 - virtual void Unk_6A(); // 6A - virtual void Unk_6B(); // 6B + virtual void Unk_62(); // 62 + virtual void Unk_63(); // 63 + virtual bool IsAutoCalc() const; // 64 + virtual void SetAutoCalc(bool a_autoCalc); // 65 + virtual void Unk_66(); // 66 + virtual void Unk_67(); // 67 + virtual void Unk_68(); // 68 + virtual void Unk_69(); // 69 + virtual void Unk_6A(); // 6A + virtual void Unk_6B(); // 6B }; static_assert(sizeof(TESObject) == 0x38); } diff --git a/CommonLibSF/include/RE/T/TESObjectARMO.h b/CommonLibSF/include/RE/T/TESObjectARMO.h index 522ea14f..b837b0ce 100644 --- a/CommonLibSF/include/RE/T/TESObjectARMO.h +++ b/CommonLibSF/include/RE/T/TESObjectARMO.h @@ -1,14 +1,103 @@ #pragma once +#include "RE/B/BGSAttachParentArray.h" +#include "RE/B/BGSBipedObjectForm.h" +#include "RE/B/BGSBlockBashData.h" +#include "RE/B/BGSDestructibleObjectForm.h" +#include "RE/B/BGSEditorID.h" +#include "RE/B/BGSEquipType.h" +#include "RE/B/BGSInstanceNamingRulesForm.h" +#include "RE/B/BGSKeywordForm.h" +#include "RE/B/BGSPickupPutdownSounds.h" +#include "RE/B/BSTOptional.h" +#include "RE/B/BSTTuple3.h" +#include "RE/T/TBO_InstanceData.h" +#include "RE/T/TESBipedModelForm.h" #include "RE/T/TESBoundObject.h" +#include "RE/T/TESDescription.h" +#include "RE/T/TESEnchantableForm.h" +#include "RE/T/TESFullName.h" +#include "RE/T/TESRaceForm.h" namespace RE { + class TESObjectARMA; + + struct TESObjectARMOInstanceData : public TBO_InstanceData + { + public: + SF_RTTI_VTABLE(TESObjectARMOInstanceData); + + ~TESObjectARMOInstanceData() override; + + // members + BGSBlockBashData* blockBashData; // 18 + BGSKeywordForm* keywords; // 20 + BSTArray>* damageTypes; // 28 + BSTArray>* actorValues; // 30 + float weight; // 38 + float colorRemappingIndex; // 3C + std::int32_t value; // 40 + std::uint32_t health; // 44 + std::uint32_t unk48; // 48 + std::uint32_t unk4C; // 4C + std::uint16_t unk50; // 50 + std::uint16_t unk52; // 52 + BSTArray unk58; // 58 + BSTArray unk68; // 68 + }; + static_assert(sizeof(TESObjectARMOInstanceData) == 0x78); + class TESObjectARMO : - public TESBoundObject + public TESBoundObject, // 000 + public TESFullName, // 118 + public TESRaceForm, // 128 + public TESEnchantableForm, // 138 + public BGSDestructibleObjectForm, // 150 + public BGSPickupPutdownSounds, // 160 + public TESBipedModelForm, // 1C8 + public BGSEquipType, // 220 + public BGSBipedObjectForm, // 230 + public BGSBlockBashData, // 240 + public BGSKeywordForm, // 258 + public TESDescription, // 288 + public BGSInstanceNamingRulesForm // 2A0 { public: SF_RTTI_VTABLE(TESObjectARMO); SF_FORMTYPE(ARMO); + + class ArmorAddon + { + public: + // members + std::uint16_t index; // 00 + TESObjectARMA* armorAddon; // 08 + }; + static_assert(sizeof(ArmorAddon) == 0x10); + + ~TESObjectARMO() override; // 00 + + bool CanUseArmor(TESRace* a_race) const + { + using func_t = decltype(&TESObjectARMO::CanUseArmor); + REL::Relocation func{ ID::TESObjectARMO::CanUseArmor }; + return func(this, a_race); + } + + // members + BGSEditorID formEditorID; // 2B0 + BSTOptional instanceData; // 2C0 + BSTArray modelArray; // 340 + BGSAttachParentArray attachParents; // 350 + std::uint64_t unk370; // 370 + std::uint64_t unk378; // 378 + std::uint64_t unk380; // 380 + std::uint64_t unk388; // 388 + std::uint64_t unk390; // 390 + std::uint64_t unk398; // 398 + std::uint64_t unk3A0; // 3A0 + std::uint64_t unk3A8; // 3A8 }; + static_assert(sizeof(TESObjectARMO) == 0x3B0); } diff --git a/CommonLibSF/include/RE/T/TESRace.h b/CommonLibSF/include/RE/T/TESRace.h index a1603e9d..d84be2fd 100644 --- a/CommonLibSF/include/RE/T/TESRace.h +++ b/CommonLibSF/include/RE/T/TESRace.h @@ -152,7 +152,6 @@ namespace RE BGSVoiceType* defaultVoiceType[SEXES::kTotal]; // 8F8 BGSBodyPartInfo bodyPartInfo; // 908 BGSAttachParentArray attachParents; // 930 - std::uint64_t unk948; // 948 BSTArray unk950; // 950 BGSMovementType* baseMoveTypes[4]; // 960 std::uint64_t unk980; // 980