diff --git a/CommonLibSF/include/RE/B/BGSAttachParentArray.h b/CommonLibSF/include/RE/B/BGSAttachParentArray.h new file mode 100644 index 00000000..cb15f1bc --- /dev/null +++ b/CommonLibSF/include/RE/B/BGSAttachParentArray.h @@ -0,0 +1,17 @@ +#pragma once + +#include "RE/B/BGSTypedKeywordValueArray.h" + +namespace RE +{ + class BGSAttachParentArray : + public BaseFormComponent, // 00 + public BGSTypedKeywordValueArray // 08 + { + public: + SF_RTTI_VTABLE(BGSAttachParentArray); + + ~BGSAttachParentArray() override; + }; + static_assert(sizeof(BGSAttachParentArray) == 0x18); +} diff --git a/CommonLibSF/include/RE/B/BGSAttackDataForm.h b/CommonLibSF/include/RE/B/BGSAttackDataForm.h index 378f7b97..3de1f45a 100644 --- a/CommonLibSF/include/RE/B/BGSAttackDataForm.h +++ b/CommonLibSF/include/RE/B/BGSAttackDataForm.h @@ -12,7 +12,7 @@ namespace RE public: SF_RTTI_VTABLE(BGSAttackDataForm); - virtual ~BGSAttackDataForm(); // 00 + ~BGSAttackDataForm() override; // 00 // members NiPointer attackDataMap; // 08 diff --git a/CommonLibSF/include/RE/B/BGSDestructibleObjectForm.h b/CommonLibSF/include/RE/B/BGSDestructibleObjectForm.h index 3672df68..398be90f 100644 --- a/CommonLibSF/include/RE/B/BGSDestructibleObjectForm.h +++ b/CommonLibSF/include/RE/B/BGSDestructibleObjectForm.h @@ -13,6 +13,8 @@ namespace RE public: SF_RTTI_VTABLE(BGSDestructibleObjectForm); + ~BGSDestructibleObjectForm() override; + // members DestructibleObjectData* data; // 08 }; diff --git a/CommonLibSF/include/RE/B/BGSForcedLocRefType.h b/CommonLibSF/include/RE/B/BGSForcedLocRefType.h index 681e3ed2..b87238f3 100644 --- a/CommonLibSF/include/RE/B/BGSForcedLocRefType.h +++ b/CommonLibSF/include/RE/B/BGSForcedLocRefType.h @@ -9,6 +9,8 @@ namespace RE public: SF_RTTI_VTABLE(BGSForcedLocRefType); + ~BGSForcedLocRefType() override; + // members std::uint64_t unk08; // 08 std::uint64_t unk10; // 10 diff --git a/CommonLibSF/include/RE/B/BGSKeywordForm.h b/CommonLibSF/include/RE/B/BGSKeywordForm.h index 5bab5910..999bd2ae 100644 --- a/CommonLibSF/include/RE/B/BGSKeywordForm.h +++ b/CommonLibSF/include/RE/B/BGSKeywordForm.h @@ -12,6 +12,8 @@ namespace RE public: SF_RTTI_VTABLE(BGSKeywordForm); + ~BGSKeywordForm() override; + // members std::uint32_t unk10; std::uint32_t unk14; diff --git a/CommonLibSF/include/RE/B/BGSMod.h b/CommonLibSF/include/RE/B/BGSMod.h index a777e604..f3f591c1 100644 --- a/CommonLibSF/include/RE/B/BGSMod.h +++ b/CommonLibSF/include/RE/B/BGSMod.h @@ -1,5 +1,6 @@ #pragma once +#include "RE/B/BSFixedString.h" #include "RE/B/BaseFormComponent.h" namespace RE @@ -8,13 +9,12 @@ namespace RE { namespace Template { - class Items : - public BaseFormComponent // 00 + class Items : public BaseFormComponent { public: SF_RTTI_VTABLE(BGSMod__Template__Items); - virtual ~Items(); + virtual ~Items() override; // add virtual void Unk_0B(); // 0B @@ -22,9 +22,9 @@ namespace RE virtual void Unk_0D(); // 0D // members - void* unk08; // 08 - void* unk10; // 10 - void* unk18; // 18 + void* unk08; // 08 + void* unk10; // 10 + BSFixedString unk18; // 18 }; static_assert(sizeof(Items) == 0x20); } diff --git a/CommonLibSF/include/RE/B/BGSNativeTerminalForm.h b/CommonLibSF/include/RE/B/BGSNativeTerminalForm.h index af5c2c5d..51223cbf 100644 --- a/CommonLibSF/include/RE/B/BGSNativeTerminalForm.h +++ b/CommonLibSF/include/RE/B/BGSNativeTerminalForm.h @@ -1,13 +1,19 @@ #pragma once -#include "RE/B/BGSTerminal.h" #include "RE/B/BaseFormComponent.h" namespace RE { + class BGSTerminal; + class BGSNativeTerminalForm : public BaseFormComponent { public: + SF_RTTI(BGSNativeTerminalForm); + + ~BGSNativeTerminalForm() override; + + // members BGSTerminal* terminal; // 08 }; static_assert(sizeof(BGSNativeTerminalForm) == 0x10); diff --git a/CommonLibSF/include/RE/B/BGSObjectPlacementDefaults.h b/CommonLibSF/include/RE/B/BGSObjectPlacementDefaults.h index 52c5cee8..7a0718ad 100644 --- a/CommonLibSF/include/RE/B/BGSObjectPlacementDefaults.h +++ b/CommonLibSF/include/RE/B/BGSObjectPlacementDefaults.h @@ -4,10 +4,13 @@ namespace RE { - class BGSObjectPlacementDefaults : - public BaseFormComponent + class BGSObjectPlacementDefaults : public BaseFormComponent { public: + SF_RTTI_VTABLE(BGSObjectPlacementDefaults); + + ~BGSObjectPlacementDefaults() override; + // members std::uint64_t unk08; // 08 std::uint32_t unk10; // 10 diff --git a/CommonLibSF/include/RE/B/BGSOverridePackCollection.h b/CommonLibSF/include/RE/B/BGSOverridePackCollection.h index 0ee387ee..e17cd9df 100644 --- a/CommonLibSF/include/RE/B/BGSOverridePackCollection.h +++ b/CommonLibSF/include/RE/B/BGSOverridePackCollection.h @@ -10,15 +10,17 @@ namespace RE public: SF_RTTI_VTABLE(BGSOverridePackCollection); + ~BGSOverridePackCollection() override; + // members - BGSListForm* unk08; - BGSListForm* unk10; - BGSListForm* unk18; - BGSListForm* unk20; - BGSListForm* unk28; - BGSListForm* unk30; - BGSListForm* unk38; - BGSListForm* unk40; + BGSListForm* unk08; // 08 + BGSListForm* unk10; // 10 + BGSListForm* unk18; // 18 + BGSListForm* unk20; // 20 + BGSListForm* unk28; // 28 + BGSListForm* unk30; // 30 + BGSListForm* unk38; // 38 + BGSListForm* unk40; // 40 }; static_assert(sizeof(BGSOverridePackCollection) == 0x48); } diff --git a/CommonLibSF/include/RE/B/BGSPerkRankArray.h b/CommonLibSF/include/RE/B/BGSPerkRankArray.h index b83c458a..7d5a6926 100644 --- a/CommonLibSF/include/RE/B/BGSPerkRankArray.h +++ b/CommonLibSF/include/RE/B/BGSPerkRankArray.h @@ -19,6 +19,8 @@ namespace RE public: SF_RTTI(BGSPerkRankArray); + ~BGSPerkRankArray() override; + // members PerkRankData* perks; // 08 std::uint32_t perkCount; // 10 diff --git a/CommonLibSF/include/RE/B/BGSPropertySheet.h b/CommonLibSF/include/RE/B/BGSPropertySheet.h index 748cda3b..9b0ed73b 100644 --- a/CommonLibSF/include/RE/B/BGSPropertySheet.h +++ b/CommonLibSF/include/RE/B/BGSPropertySheet.h @@ -9,6 +9,8 @@ namespace RE public: SF_RTTI_VTABLE(BGSPropertySheet); + ~BGSPropertySheet() override; + // members std::uint64_t /* BSTArray>* */ unk08; }; diff --git a/CommonLibSF/include/RE/B/BGSSkinForm.h b/CommonLibSF/include/RE/B/BGSSkinForm.h index dad9bf20..64c16b8a 100644 --- a/CommonLibSF/include/RE/B/BGSSkinForm.h +++ b/CommonLibSF/include/RE/B/BGSSkinForm.h @@ -10,6 +10,8 @@ namespace RE public: SF_RTTI_VTABLE(BGSSkinForm); + ~BGSSkinForm() override; + // members TESObjectARMO* formSkin; // 08 }; diff --git a/CommonLibSF/include/RE/B/BGSTypedKeywordValueArray.h b/CommonLibSF/include/RE/B/BGSTypedKeywordValueArray.h new file mode 100644 index 00000000..e84574af --- /dev/null +++ b/CommonLibSF/include/RE/B/BGSTypedKeywordValueArray.h @@ -0,0 +1,65 @@ +#pragma once + +#include "RE/B/BGSKeyword.h" + +namespace RE +{ + enum class KeywordType + { + kNone, + kComponentTechLevel, + kAttachPoint, + kComponentProperty, + kInstantiationFilter, + kModAssociation, + kSound, + kAnimArchetype, + kFunctionCall, + kRecipeFilter, + kAttractionType, + kDialogueSubtype, + kQuestTarget, + kAnimFlavor, + kAnimGender, + kAnimFaceArchetype, + kQuestGroup, + kAnimInjured, + kDispelEffect, + + kTotal + }; + + template + class BGSTypedKeywordValue + { + public: + // members + std::uint16_t keywordIndex; // 0 + }; + + namespace detail + { + [[nodiscard]] BGSKeyword* BGSKeywordGetTypedKeywordByIndex(KeywordType a_type, std::uint16_t a_index); + } + + template + class BGSTypedKeywordValueArray + { + public: + [[nodiscard]] bool HasKeyword(BGSKeyword* a_keyword) + { + for (std::uint32_t i = 0; i < size; ++i) { + const auto kywd = detail::BGSKeywordGetTypedKeywordByIndex(TYPE, array[i].keywordIndex); + if (kywd == a_keyword) { + return true; + } + } + return false; + } + + // members + BGSTypedKeywordValue* array; // 00 + std::uint32_t size; // 08 + }; + static_assert(sizeof(BGSTypedKeywordValueArray) == 0x10); +} diff --git a/CommonLibSF/include/RE/C/Color.h b/CommonLibSF/include/RE/C/Color.h new file mode 100644 index 00000000..e6f8ea86 --- /dev/null +++ b/CommonLibSF/include/RE/C/Color.h @@ -0,0 +1,277 @@ +#pragma once + +namespace RE +{ + struct Color + { + public: + enum : std::size_t + { + kRed, + kGreen, + kBlue, + kAlpha, + + kTotal + }; + + constexpr Color() noexcept : + red(0), + green(0), + blue(0), + alpha(0) + {} + + constexpr Color(const Color& a_rhs) noexcept : + red(a_rhs.red), + green(a_rhs.green), + blue(a_rhs.blue), + alpha(a_rhs.alpha) + {} + + constexpr Color(Color&& a_rhs) noexcept : + red(std::move(a_rhs.red)), + green(std::move(a_rhs.green)), + blue(std::move(a_rhs.blue)), + alpha(std::move(a_rhs.alpha)) + {} + + constexpr Color(std::uint8_t a_red, std::uint8_t a_green, std::uint8_t a_blue, std::uint8_t a_alpha) noexcept : + red(a_red), + green(a_green), + blue(a_blue), + alpha(a_alpha) + {} + + constexpr Color(std::uint32_t a_hexValue) noexcept : + red((a_hexValue >> 16) & 0xFF), + green((a_hexValue >> 8) & 0xFF), + blue((a_hexValue)&0xFF), + alpha(0) + {} + + ~Color() noexcept = default; + + constexpr Color& operator=(const Color& a_rhs) noexcept + { + if (this != std::addressof(a_rhs)) { + red = a_rhs.red; + green = a_rhs.green; + blue = a_rhs.blue; + alpha = a_rhs.alpha; + } + return *this; + } + + constexpr Color& operator=(Color&& a_rhs) noexcept + { + if (this != std::addressof(a_rhs)) { + red = std::move(a_rhs.red); + green = std::move(a_rhs.green); + blue = std::move(a_rhs.blue); + alpha = std::move(a_rhs.alpha); + } + return *this; + } + + [[nodiscard]] friend constexpr bool operator==(const Color& a_lhs, const Color& a_rhs) noexcept + { + for (std::size_t i = 0; i < kTotal; ++i) { + if (a_lhs[i] != a_rhs[i]) { + return false; + } + } + return true; + } + + [[nodiscard]] friend constexpr bool operator!=(const Color& a_lhs, const Color& a_rhs) noexcept + { + return !(a_lhs == a_rhs); + } + + [[nodiscard]] constexpr std::uint8_t& operator[](std::size_t a_idx) noexcept + { + assert(a_idx < kTotal); + return std::addressof(red)[a_idx]; + } + + [[nodiscard]] constexpr const std::uint8_t& operator[](std::size_t a_idx) const noexcept + { + assert(a_idx < kTotal); + return std::addressof(red)[a_idx]; + } + + [[nodiscard]] Color operator+(const Color& a_rhs) const noexcept + { + Color tmp = *this; + for (std::size_t i = 0; i < kTotal; ++i) { + tmp[i] += a_rhs[i]; + } + return tmp; + } + + Color& operator+=(const Color& a_rhs) noexcept + { + for (std::size_t i = 0; i < kTotal; ++i) { + operator[](i) += a_rhs[i]; + } + return *this; + } + + [[nodiscard]] Color operator-(const Color& a_rhs) const noexcept + { + Color tmp = *this; + for (std::size_t i = 0; i < kTotal; ++i) { + tmp[i] -= a_rhs[i]; + } + return tmp; + } + + Color& operator-=(const Color& a_rhs) noexcept + { + for (std::size_t i = 0; i < kTotal; ++i) { + operator[](i) -= a_rhs[i]; + } + return *this; + } + + friend Color operator-(std::uint8_t a_lhs, const Color& a_rhs) + { + return Color( + a_lhs - a_rhs.red, + a_lhs - a_rhs.green, + a_lhs - a_rhs.blue, + a_lhs - a_rhs.alpha); + } + + [[nodiscard]] Color operator*(const Color& a_rhs) const noexcept + { + Color tmp = *this; + for (std::size_t i = 0; i < kTotal; ++i) { + tmp[i] *= a_rhs[i]; + } + return tmp; + } + + Color& operator*=(const Color& a_rhs) noexcept + { + for (std::size_t i = 0; i < kTotal; ++i) { + operator[](i) *= a_rhs[i]; + } + return *this; + } + + friend Color operator*(std::uint8_t a_lhs, const Color& a_rhs) + { + return Color( + a_lhs * a_rhs.red, + a_lhs * a_rhs.green, + a_lhs * a_rhs.blue, + a_lhs * a_rhs.alpha); + } + + [[nodiscard]] Color operator/(const Color& a_rhs) const noexcept + { + Color tmp = *this; + for (std::size_t i = 0; i < kTotal; ++i) { + tmp[i] /= a_rhs[i]; + } + return tmp; + } + + Color& operator/=(const Color& a_rhs) noexcept + { + for (std::size_t i = 0; i < kTotal; ++i) { + operator[](i) /= a_rhs[i]; + } + return *this; + } + + friend Color operator/(std::uint8_t a_lhs, const Color& a_rhs) + { + return Color( + a_lhs / a_rhs.red, + a_lhs / a_rhs.green, + a_lhs / a_rhs.blue, + a_lhs / a_rhs.alpha); + } + + [[nodiscard]] Color operator+(std::uint8_t a_value) const noexcept + { + Color tmp = *this; + for (std::size_t i = 0; i < kTotal; ++i) { + tmp[i] += a_value; + } + return tmp; + } + + Color& operator+=(std::uint8_t a_value) noexcept + { + for (std::size_t i = 0; i < kTotal; ++i) { + operator[](i) += a_value; + } + return *this; + } + + [[nodiscard]] Color operator-(std::uint8_t a_value) const noexcept + { + Color tmp = *this; + for (std::size_t i = 0; i < kTotal; ++i) { + tmp[i] -= a_value; + } + return tmp; + } + + Color& operator-=(std::uint8_t a_value) noexcept + { + for (std::size_t i = 0; i < kTotal; ++i) { + operator[](i) -= a_value; + } + return *this; + } + + [[nodiscard]] Color operator*(std::uint8_t a_value) const noexcept + { + Color tmp = *this; + for (std::size_t i = 0; i < kTotal; ++i) { + tmp[i] *= a_value; + } + return tmp; + } + + Color& operator*=(std::uint8_t a_value) noexcept + { + for (std::size_t i = 0; i < kTotal; ++i) { + operator[](i) *= a_value; + } + return *this; + } + + [[nodiscard]] Color operator/(std::uint8_t a_value) const noexcept + { + Color tmp = *this; + for (std::size_t i = 0; i < kTotal; ++i) { + tmp[i] /= a_value; + } + return tmp; + } + + Color& operator/=(std::uint8_t a_value) noexcept + { + for (std::size_t i = 0; i < kTotal; ++i) { + operator[](i) /= a_value; + } + return *this; + } + + std::uint32_t ToInt() const; + std::string ToHex() const; + + // members + std::uint8_t red; // 0 + std::uint8_t green; // 1 + std::uint8_t blue; // 2 + std::uint8_t alpha; // 3 + }; + static_assert(sizeof(Color) == 0x4); +} diff --git a/CommonLibSF/include/RE/T/TESAIForm.h b/CommonLibSF/include/RE/T/TESAIForm.h index 17de5136..eeae19ef 100644 --- a/CommonLibSF/include/RE/T/TESAIForm.h +++ b/CommonLibSF/include/RE/T/TESAIForm.h @@ -9,7 +9,7 @@ namespace RE public: SF_RTTI_VTABLE(PackageList); - virtual void Unk_00(); + virtual ~PackageList(); // members std::uint64_t unk08; // 08 @@ -34,6 +34,11 @@ namespace RE class TESAIForm : public BaseFormComponent { public: + SF_RTTI_VTABLE(TESAIForm); + + ~TESAIForm() override; + + // members AIDATA_GAME aiData; // 08 PackageList aiPackList; // 18 }; diff --git a/CommonLibSF/include/RE/T/TESActorBase.h b/CommonLibSF/include/RE/T/TESActorBase.h index aefef8a7..dcf7d556 100644 --- a/CommonLibSF/include/RE/T/TESActorBase.h +++ b/CommonLibSF/include/RE/T/TESActorBase.h @@ -17,7 +17,7 @@ namespace RE { class TESActorBase : - public TESBoundAnimObject, + public TESBoundAnimObject, // 000 public TESActorBaseData, // 118 public TESContainer, // 188 public TESSpellList, // 1A0 @@ -34,24 +34,13 @@ namespace RE public: SF_RTTI_VTABLE(TESActorBase); - enum class Pronoun_Type - { - kNotSet, - kHeHim, - kSheHer, - kTheyThem - }; + ~TESActorBase() override; // add virtual void Unk_82(); // 82 virtual void Unk_83(); // 83 virtual void Unk_84(); // 84 virtual void Unk_85(); // 85 - - // members - std::uint8_t pad298[488]; // 298 - stl::enumeration pronoun; // 480 - // }; - -} // namespace RE + static_assert(sizeof(TESActorBase) == 0x298); +} diff --git a/CommonLibSF/include/RE/T/TESActorBaseData.h b/CommonLibSF/include/RE/T/TESActorBaseData.h index c454d2bc..f31e9d28 100644 --- a/CommonLibSF/include/RE/T/TESActorBaseData.h +++ b/CommonLibSF/include/RE/T/TESActorBaseData.h @@ -9,6 +9,25 @@ namespace RE enum class Flag { kNone = 0, + kFemale = 1 << 0, + kEssential = 1 << 1, + kIsChargenFacePreset = 1 << 2, + kRespawn = 1 << 3, + kAutoCalcStats = 1 << 4, + kUnique = 1 << 5, + kDoesntAffectStealthMeter = 1 << 6, + kPCLevelMult = 1 << 7, + kUsesTemplate = 1 << 8, + kProtected = 1 << 11, + kSummonable = 1 << 14, + kDoesntBleed = 1 << 16, + kBleedoutOverride = 1 << 18, + kOppositeGenderanims = 1 << 19, + kSimpleActor = 1 << 20, + kLoopedScript = 1 << 21, // ? + kLoopedAudio = 1 << 28, // ? + kIsGhost = 1 << 29, + kInvulnerable = 1 << 31 }; enum class TEMPLATE_USE_FLAG @@ -28,20 +47,21 @@ namespace RE }; static_assert(sizeof(ACTOR_BASE_DATA) == 0x14); - class TESActorBaseData : - public BaseFormComponent // ACBS + class TESActorBaseData : public BaseFormComponent { public: SF_RTTI_VTABLE(TESActorBaseData); + ~TESActorBaseData() override; + // add - virtual void Unk_10(); // 10 - virtual void Unk_11(); // 11 - virtual void Unk_12(); // 12 - virtual void Unk_13(); // 13 + virtual void Unk_0B(); // 0B + virtual void Unk_0C(); // 0C + virtual void Unk_0D(); // 0D + virtual void Unk_0E(); // 0E // members - ACTOR_BASE_DATA actorData; // 18 + ACTOR_BASE_DATA actorData; // 08 std::int32_t changeFlags; // 1C std::uint64_t unk20; // 20 std::uint64_t unk28; // 28 diff --git a/CommonLibSF/include/RE/T/TESBoundAnimObject.h b/CommonLibSF/include/RE/T/TESBoundAnimObject.h index 3b5b8a5e..9b5a6f0e 100644 --- a/CommonLibSF/include/RE/T/TESBoundAnimObject.h +++ b/CommonLibSF/include/RE/T/TESBoundAnimObject.h @@ -16,8 +16,7 @@ namespace RE virtual void Unk_81(); // 81 // members - std::uint64_t unkF0; // F0 - std::uint64_t unkF8; // F8 + std::uint64_t unk0F8; // 0F8 std::uint64_t unk100; // 100 std::uint64_t unk108; // 108 std::uint64_t unk110; // 110 diff --git a/CommonLibSF/include/RE/T/TESBoundObject.h b/CommonLibSF/include/RE/T/TESBoundObject.h index 122e2c81..07e96801 100644 --- a/CommonLibSF/include/RE/T/TESBoundObject.h +++ b/CommonLibSF/include/RE/T/TESBoundObject.h @@ -8,12 +8,13 @@ namespace RE { - class TESBoundObject : - public TESObject // 00 + class TESBoundObject : public TESObject { public: SF_RTTI_VTABLE(TESBoundObject); + ~TESBoundObject() override; + // add virtual void Unk_6C(); // 6C virtual void Unk_6D(); // 6D @@ -45,9 +46,7 @@ namespace RE BGSMod::Template::Items templateItems; // 68 BGSPreviewTransform previewTransform; // 88 BGSObjectPlacementDefaults placementDefaults; // D0 + std::uint32_t unkF0; // F0 }; - static_assert(offsetof(TESBoundObject, templateItems) == 0x68); - static_assert(offsetof(TESBoundObject, previewTransform) == 0x88); - static_assert(offsetof(TESBoundObject, placementDefaults) == 0xD0); - static_assert(sizeof(TESBoundObject) == 0xF0); + static_assert(sizeof(TESBoundObject) == 0xF8); } diff --git a/CommonLibSF/include/RE/T/TESContainer.h b/CommonLibSF/include/RE/T/TESContainer.h index 2afd1cce..7944a93d 100644 --- a/CommonLibSF/include/RE/T/TESContainer.h +++ b/CommonLibSF/include/RE/T/TESContainer.h @@ -11,6 +11,8 @@ namespace RE public: SF_RTTI_VTABLE(TESContainer); + ~TESContainer() override; + // members ContainerObject** containerObjects; // 08 std::uint32_t numContainerObjects; // 10 diff --git a/CommonLibSF/include/RE/T/TESNPC.h b/CommonLibSF/include/RE/T/TESNPC.h index 227f96fb..98ebe0ad 100644 --- a/CommonLibSF/include/RE/T/TESNPC.h +++ b/CommonLibSF/include/RE/T/TESNPC.h @@ -1,37 +1,106 @@ #pragma once +#include "RE/B/BGSAttachParentArray.h" #include "RE/B/BGSForcedLocRefType.h" #include "RE/B/BGSNativeTerminalForm.h" #include "RE/B/BGSOverridePackCollection.h" +#include "RE/B/BSTArray.h" +#include "RE/B/BSTEvent.h" +#include "RE/C/Color.h" +#include "RE/N/NiPoint3.h" #include "RE/T/TESActorBase.h" #include "RE/T/TESRaceForm.h" namespace RE { + class BGSHeadPart; + class BGSListForm; + class BGSOutfit; + class MenuOpenCloseEvent; + class TESClass; + class TESCombatStyle; + class TESFaction; + class TESNPC : - public TESActorBase, - public TESRaceForm, // 298 - public BGSOverridePackCollection, // 2A8 - public BGSForcedLocRefType, // 2F0 - public BGSNativeTerminalForm // 308 + public TESActorBase, // 000 + public TESRaceForm, // 298 + public BGSOverridePackCollection, // 2A8 + public BGSForcedLocRefType, // 2F0 + public BGSNativeTerminalForm, // 308 + public BSTEventSink // 318 { public: SF_RTTI_VTABLE(TESNPC); SF_FORMTYPE(NPC_); + enum class PRONOUN_TYPE + { + kNone, + kHeHim, + kSheHer, + kTheyThem + }; + + struct HeadPartData + { + std::uint32_t type; // 00 + std::uint32_t unk04; // 04 + BSFixedString category; // 08 + BSFixedString material; // 10 + BSFixedString texturePath; // 18 + Color color; // 20 + std::uint32_t intensity; // 24 + }; + static_assert(sizeof(HeadPartData) == 0x28); + + ~TESNPC() override; + // members - /* - TESRaceForm raceForm; // 298 - BGSOverridePackCollection overridePackCollection; // 2A8 - BGSForcedLocRefType forcedLocRefType; // 2F0 - BGSNativeTerminalForm terminalForm; // 308 - */ - // More here, havent decoded this yet + BGSAttachParentArray attachParents; // 320 + std::uint64_t unk338; // 338 + std::uint32_t unk340; // 340 + std::uint32_t unk344; // 344 + TESClass* npcClass; // 348 + std::uint64_t unk350; // 350 + BGSListForm* giftFilter; // 358 + TESCombatStyle* combatStyle; // 360 + std::uint32_t fileOffset; // 368 + std::uint32_t unk36C; // 36C + TESRace* originalRace; // 370 + TESNPC* faceNPC; // 378 + NiPoint3 morphWeight; // 380 + float height; // 38C + float heightMax; // 390 + std::uint32_t unk394; // 394 + std::uint64_t unk398; // 398 + std::uint64_t unk3A0; // 3A0 + std::uint64_t unk3A8; // 3A8 + BGSLocalizedString shortName; // 3B0 + std::uint64_t unk3B8; // 3B8 + std::uint64_t unk3C0; // 3C0 + BGSOutfit* defaultOutfit; // 3C8 + BGSOutfit* sleepOutfit; // 3D0 + BGSListForm* defaultPackList; // 3D8 + TESFaction* crimeFaction; // 3E0 + std::uint64_t unk3E8; // 3E8 + BSTArray headparts; // 3F0 + std::uint64_t unk400; // 400 + std::uint64_t unk408; // 408 + std::uint64_t unk410; // 410 + std::uint64_t unk418; // 418 + BSTArray headpartData; // 420 + std::uint32_t skinTone; // 430 + std::uint32_t unk434; // 434 + BSFixedString teeth; // 438 + BSFixedString jewelryColor; // 440 + BSFixedString eyeColor; // 448 + BSFixedString hairColor; // 450 + BSFixedString facialColor; // 458 + BSFixedString eyebrowColor; // 460 + std::uint64_t unk468; // 468 + BGSLocalizedString organization; // 470 - faction? + std::uint64_t unk478; // 478 + stl::enumeration pronoun; // 480 }; - /* - static_assert(offsetof(TESNPC, raceForm) == 0x298); - static_assert(offsetof(TESNPC, overridePackCollection) == 0x2A8); - static_assert(offsetof(TESNPC, forcedLocRefType) == 0x2F0); - static_assert(offsetof(TESNPC, terminalForm) == 0x308); - */ + static_assert(sizeof(TESNPC) == 0x488); } diff --git a/CommonLibSF/include/RE/T/TESObject.h b/CommonLibSF/include/RE/T/TESObject.h index d743ec95..7037f11b 100644 --- a/CommonLibSF/include/RE/T/TESObject.h +++ b/CommonLibSF/include/RE/T/TESObject.h @@ -4,12 +4,13 @@ namespace RE { - class TESObject : - public TESForm // 00 + class TESObject : public TESForm { public: SF_RTTI_VTABLE(TESObject); + ~TESObject() override; + // add virtual void Unk_62(); // 62 virtual void Unk_63(); // 63 @@ -22,4 +23,5 @@ namespace RE virtual void Unk_6A(); // 6A virtual void Unk_6B(); // 6B }; + static_assert(sizeof(TESObject) == 0x38); } diff --git a/CommonLibSF/include/RE/T/TESRaceForm.h b/CommonLibSF/include/RE/T/TESRaceForm.h index 1725d6e3..c4cf2d20 100644 --- a/CommonLibSF/include/RE/T/TESRaceForm.h +++ b/CommonLibSF/include/RE/T/TESRaceForm.h @@ -11,6 +11,8 @@ namespace RE public: SF_RTTI_VTABLE(TESRaceForm); + ~TESRaceForm() override; + // members TESRace* formRace; // 08 }; diff --git a/CommonLibSF/include/RE/T/TESSpellList.h b/CommonLibSF/include/RE/T/TESSpellList.h index 38c6ca44..6ebc70a4 100644 --- a/CommonLibSF/include/RE/T/TESSpellList.h +++ b/CommonLibSF/include/RE/T/TESSpellList.h @@ -9,6 +9,8 @@ namespace RE public: SF_RTTI_VTABLE(TESSpellList); + ~TESSpellList() override; + // members std::uint32_t unk08; // 08 std::uint32_t unk0C; // 0C diff --git a/CommonLibSF/src/RE/C/Color.cpp b/CommonLibSF/src/RE/C/Color.cpp new file mode 100644 index 00000000..b9c1f32c --- /dev/null +++ b/CommonLibSF/src/RE/C/Color.cpp @@ -0,0 +1,14 @@ +#include "RE/C/Color.h" + +namespace RE +{ + std::uint32_t Color::ToInt() const + { + return ((red & 0xFF) << 24) + ((green & 0xFF) << 16) + ((blue & 0xFF) << 8) + (alpha & 0xFF); + } + + std::string Color::ToHex() const + { + return std::format("{:X}{:X}{:X}{:X}", red, green, blue, alpha); + } +}