From 9798cb44b020cee3335449f7e731159ffe7e687d Mon Sep 17 00:00:00 2001 From: ryan-rsm-mckenzie Date: Sat, 25 Jun 2022 21:01:07 -0700 Subject: [PATCH 01/14] add `PlayerAddItemEvent` event stuff --- cmake/sourcelist.cmake | 2 + include/RE/B/BGSAddToPlayerInventoryEvent.h | 38 +++++++++++++++++ include/RE/B/BGSStoryEventManager.h | 45 +++++++++++++++++++++ include/RE/B/BGSStoryManagerEventNode.h | 2 +- include/RE/P/PlayerCharacter.h | 4 ++ include/RE/Skyrim.h | 2 + include/RE/T/TESObjectREFR.h | 1 + src/RE/P/PlayerCharacter.cpp | 7 ++++ src/RE/T/TESObjectREFR.cpp | 7 ++++ 9 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 include/RE/B/BGSAddToPlayerInventoryEvent.h create mode 100644 include/RE/B/BGSStoryEventManager.h diff --git a/cmake/sourcelist.cmake b/cmake/sourcelist.cmake index 377ecf3bc..92d575021 100644 --- a/cmake/sourcelist.cmake +++ b/cmake/sourcelist.cmake @@ -44,6 +44,7 @@ set(SOURCES include/RE/B/BGSAcousticSpace.h include/RE/B/BGSAction.h include/RE/B/BGSActorEvent.h + include/RE/B/BGSAddToPlayerInventoryEvent.h include/RE/B/BGSAddonNode.h include/RE/B/BGSAnimationSequencer.h include/RE/B/BGSApparatus.h @@ -155,6 +156,7 @@ set(SOURCES include/RE/B/BGSSoundOutput.h include/RE/B/BGSStandardSoundDef.h include/RE/B/BGSStaticCollection.h + include/RE/B/BGSStoryEventManager.h include/RE/B/BGSStoryManagerBranchNode.h include/RE/B/BGSStoryManagerEventNode.h include/RE/B/BGSStoryManagerNodeBase.h diff --git a/include/RE/B/BGSAddToPlayerInventoryEvent.h b/include/RE/B/BGSAddToPlayerInventoryEvent.h new file mode 100644 index 000000000..e3b43ceba --- /dev/null +++ b/include/RE/B/BGSAddToPlayerInventoryEvent.h @@ -0,0 +1,38 @@ +#pragma once + +#include "RE/B/BSPointerHandle.h" + +namespace RE +{ + class BGSLocation; + class TESForm; + + enum class AQUIRE_TYPE + { + kNone = 0, + kSteal = 1, + kBuy = 2, + kPickPocket = 3, + kPickup = 4, + kContainer = 5, + kDeadBody = 6 + }; + + class BGSAddToPlayerInventoryEvent + { + public: + [[nodiscard]] static std::uint32_t& GetIndex() + { + REL::Relocation index{ REL::ID(380074) }; + return *index; + } + + // members + ObjectRefHandle ownerRef; // 0x00 + ObjectRefHandle containerRef; // 0x04 + BGSLocation* location{ nullptr }; // 0x08 + TESForm* itemBase{ nullptr }; // 0x10 + stl::enumeration acquireType{ AQUIRE_TYPE::kNone }; // 0x18 + }; + static_assert(sizeof(BGSAddToPlayerInventoryEvent) == 0x20); +} diff --git a/include/RE/B/BGSStoryEventManager.h b/include/RE/B/BGSStoryEventManager.h new file mode 100644 index 000000000..553ee5110 --- /dev/null +++ b/include/RE/B/BGSStoryEventManager.h @@ -0,0 +1,45 @@ +#pragma once + +#include "RE/B/BSAtomic.h" +#include "RE/B/BSTArray.h" +#include "RE/B/BSTHashMap.h" +#include "RE/B/BSTSingleton.h" + +namespace RE +{ + class BGSRegisteredStoryEvent; + class BGSStoryEvent; + + class BGSStoryEventManager : + public BSTSingletonImplicit // 00 + { + public: + [[nodiscard]] static BGSStoryEventManager* GetSingleton() + { + using func_t = decltype(&BGSStoryEventManager::GetSingleton); + REL::Relocation func{ REL::ID(22790) }; + return func(); + } + + template + std::uint32_t AddEvent(const T& a_event) + { + return AddEvent_Impl(T::GetIndex(), &a_event); + } + + // members + BSTArray registeredEvents; // 00 + BSTHashMap registeredEventIDs; // 18 + BSTArray events; // 48 + mutable BSSpinLock eventArrayLock; // 60 + + private: + std::uint32_t AddEvent_Impl(std::uint32_t a_index, const void* a_event) + { + using func_t = decltype(&BGSStoryEventManager::AddEvent_Impl); + REL::Relocation func{ REL::ID(32359) }; + return func(this, a_index, a_event); + } + }; + static_assert(sizeof(BGSStoryEventManager) == 0x68); +} diff --git a/include/RE/B/BGSStoryManagerEventNode.h b/include/RE/B/BGSStoryManagerEventNode.h index f63245a8b..496239e43 100644 --- a/include/RE/B/BGSStoryManagerEventNode.h +++ b/include/RE/B/BGSStoryManagerEventNode.h @@ -19,7 +19,7 @@ namespace RE }; static_assert(sizeof(BGSStoryEventMember) == 0x18); - struct BGSRegisteredStoryEvent // ENAM + class BGSRegisteredStoryEvent // ENAM { char uniqueID[4]; // 00 std::uint32_t pad04; // 04 diff --git a/include/RE/P/PlayerCharacter.h b/include/RE/P/PlayerCharacter.h index 44d5d21e9..770ea49a6 100644 --- a/include/RE/P/PlayerCharacter.h +++ b/include/RE/P/PlayerCharacter.h @@ -19,6 +19,8 @@ namespace RE { + enum class AQUIRE_TYPE; + class Actor; class BGSInstancedQuestObjective; class BGSLocation; @@ -34,6 +36,7 @@ namespace RE class NiAVObject; class NiNode; class ObjectListItem; + class TESObject; class TESObjectREFR; class TintMask; class UserEventEnabledEvent; @@ -273,6 +276,7 @@ namespace RE static PlayerCharacter* GetSingleton(); void ActivatePickRef(); + void AddPlayerAddItemEvent(TESObject* a_object, TESForm* a_owner, TESObjectREFR* a_container, AQUIRE_TYPE a_type); void AddSkillExperience(ActorValue a_skill, float a_experience); bool AttemptPickpocket(TESObjectREFR* a_containerRef, InventoryEntryData* a_entry, std::int32_t a_number, bool a_fromContainer = true); bool CenterOnCell(const char* a_cellName); diff --git a/include/RE/Skyrim.h b/include/RE/Skyrim.h index 18f4009e8..fc396ab8d 100644 --- a/include/RE/Skyrim.h +++ b/include/RE/Skyrim.h @@ -47,6 +47,7 @@ #include "RE/B/BGSAcousticSpace.h" #include "RE/B/BGSAction.h" #include "RE/B/BGSActorEvent.h" +#include "RE/B/BGSAddToPlayerInventoryEvent.h" #include "RE/B/BGSAddonNode.h" #include "RE/B/BGSAnimationSequencer.h" #include "RE/B/BGSApparatus.h" @@ -158,6 +159,7 @@ #include "RE/B/BGSSoundOutput.h" #include "RE/B/BGSStandardSoundDef.h" #include "RE/B/BGSStaticCollection.h" +#include "RE/B/BGSStoryEventManager.h" #include "RE/B/BGSStoryManagerBranchNode.h" #include "RE/B/BGSStoryManagerEventNode.h" #include "RE/B/BGSStoryManagerNodeBase.h" diff --git a/include/RE/T/TESObjectREFR.h b/include/RE/T/TESObjectREFR.h index 3f5c46fb5..885347280 100644 --- a/include/RE/T/TESObjectREFR.h +++ b/include/RE/T/TESObjectREFR.h @@ -361,6 +361,7 @@ namespace RE const BSTSmartPointer& GetBiped() const; const BSTSmartPointer& GetBiped(bool a_firstPerson) const; TESContainer* GetContainer() const; + BGSLocation* GetCurrentLocation() const; const char* GetDisplayFullName(); InventoryDropMap GetDroppedInventory(); InventoryDropMap GetDroppedInventory(std::function a_filter); diff --git a/src/RE/P/PlayerCharacter.cpp b/src/RE/P/PlayerCharacter.cpp index 33343d959..df6ef6646 100644 --- a/src/RE/P/PlayerCharacter.cpp +++ b/src/RE/P/PlayerCharacter.cpp @@ -24,6 +24,13 @@ namespace RE return func(this); } + void PlayerCharacter::AddPlayerAddItemEvent(TESObject* a_object, TESForm* a_owner, TESObjectREFR* a_container, AQUIRE_TYPE a_type) + { + using func_t = decltype(&PlayerCharacter::AddPlayerAddItemEvent); + REL::Relocation func{ REL::ID(40456) }; + return func(this, a_object, a_owner, a_container, a_type); + } + bool PlayerCharacter::AttemptPickpocket(TESObjectREFR* a_containerRef, InventoryEntryData* a_entry, std::int32_t a_number, bool a_fromContainer) { using func_t = decltype(&PlayerCharacter::AttemptPickpocket); diff --git a/src/RE/T/TESObjectREFR.cpp b/src/RE/T/TESObjectREFR.cpp index 0c8d7e648..ab2bf12df 100644 --- a/src/RE/T/TESObjectREFR.cpp +++ b/src/RE/T/TESObjectREFR.cpp @@ -139,6 +139,13 @@ namespace RE return obj ? obj->As() : nullptr; } + BGSLocation* TESObjectREFR::GetCurrentLocation() const + { + using func_t = decltype(&TESObjectREFR::GetCurrentLocation); + REL::Relocation func{ REL::ID(19812) }; + return func(this); + } + const char* TESObjectREFR::GetDisplayFullName() { using func_t = decltype(&TESObjectREFR::GetDisplayFullName); From 9b63e0c87d741cb2124f3293360cff1007a00ee2 Mon Sep 17 00:00:00 2001 From: ryan-rsm-mckenzie Date: Mon, 27 Jun 2022 11:48:39 -0700 Subject: [PATCH 02/14] simplify GFxValue::DisplayInfo initialization --- include/RE/G/GFxValue.h | 42 ++++++++++---------- src/RE/G/GFxValue.cpp | 85 ++--------------------------------------- 2 files changed, 24 insertions(+), 103 deletions(-) diff --git a/include/RE/G/GFxValue.h b/include/RE/G/GFxValue.h index 91f46a705..aa9bba8f4 100644 --- a/include/RE/G/GFxValue.h +++ b/include/RE/G/GFxValue.h @@ -139,7 +139,7 @@ namespace RE kViewMatrix3D = 1 << 13 }; - DisplayInfo(); // Initializes the DisplayInfo structure. + DisplayInfo() = default; // Initializes the DisplayInfo structure. DisplayInfo(double a_x, double a_y); // Initializes the DisplayInfo structure. DisplayInfo(double a_rotation); // Initializes the DisplayInfo structure. DisplayInfo(bool a_visible); // Initializes the DisplayInfo structure. @@ -185,26 +185,26 @@ namespace RE void ClearFlags(Flag a_flags); // members - double _x; // 00 - double _y; // 08 - double _rotation; // 10 - double _xScale; // 18 - double _yScale; // 20 - double _alpha; // 28 - bool _visible; // 30 - std::uint8_t _pad31; // 31 - std::uint16_t _pad32; // 32 - std::uint32_t _pad34; // 34 - double _z; // 38 - double _xRotation; // 40 - double _yRotation; // 48 - double _zScale; // 50 - double _fov; // 58 - GMatrix3D _viewMatrix3D; // 60 - GMatrix3D _perspMatrix3D; // A0 - stl::enumeration _flags; // E0 - std::uint16_t _padD2; // E2 - std::uint32_t _padD4; // E4 + double _x = 0.0; // 00 + double _y = 0.0; // 08 + double _rotation = 0.0; // 10 + double _xScale = 0.0; // 18 + double _yScale = 0.0; // 20 + double _alpha = 0.0; // 28 + bool _visible = false; // 30 + std::uint8_t _pad31 = 0; // 31 + std::uint16_t _pad32 = 0; // 32 + std::uint32_t _pad34 = 0; // 34 + double _z = 0.0; // 38 + double _xRotation = 0.0; // 40 + double _yRotation = 0.0; // 48 + double _zScale = 0.0; // 50 + double _fov = 0.0; // 58 + GMatrix3D _viewMatrix3D; // 60 + GMatrix3D _perspMatrix3D; // A0 + stl::enumeration _flags = Flag::kNone; // E0 + std::uint16_t _padD2 = 0; // E2 + std::uint32_t _padD4 = 0; // E4 }; static_assert(sizeof(DisplayInfo) == 0xE8); diff --git a/src/RE/G/GFxValue.cpp b/src/RE/G/GFxValue.cpp index e30dd7881..421f05ca3 100644 --- a/src/RE/G/GFxValue.cpp +++ b/src/RE/G/GFxValue.cpp @@ -2,96 +2,17 @@ namespace RE { - GFxValue::DisplayInfo::DisplayInfo() : - _x(0.0), - _y(0.0), - _rotation(0.0), - _xScale(0.0), - _yScale(0.0), - _alpha(0.0), - _visible(false), - _pad31(0), - _pad32(0), - _pad34(0), - _z(0.0), - _xRotation(0.0), - _yRotation(0.0), - _zScale(0.0), - _fov(0.0), - _viewMatrix3D(), - _perspMatrix3D(), - _flags(Flag::kNone), - _padD2(0), - _padD4(0) - {} - GFxValue::DisplayInfo::DisplayInfo(double a_x, double a_y) : _x(a_x), - _y(a_y), - _rotation(0.0), - _xScale(0.0), - _yScale(0.0), - _alpha(0.0), - _visible(false), - _pad31(0), - _pad32(0), - _pad34(0), - _z(0.0), - _xRotation(0.0), - _yRotation(0.0), - _zScale(0.0), - _fov(0.0), - _viewMatrix3D(), - _perspMatrix3D(), - _flags(Flag::kX, Flag::kY), - _padD2(0), - _padD4(0) + _y(a_y) {} GFxValue::DisplayInfo::DisplayInfo(double a_rotation) : - _x(0.0), - _y(0.0), - _rotation(a_rotation), - _xScale(0.0), - _yScale(0.0), - _alpha(0.0), - _visible(false), - _pad31(0), - _pad32(0), - _pad34(0), - _z(0.0), - _xRotation(0.0), - _yRotation(0.0), - _zScale(0.0), - _fov(0.0), - _viewMatrix3D(), - _perspMatrix3D(), - _flags(Flag::kRotation), - _padD2(0), - _padD4(0) + _rotation(a_rotation) {} GFxValue::DisplayInfo::DisplayInfo(bool a_visible) : - _x(0.0), - _y(0.0), - _rotation(0.0), - _xScale(0.0), - _yScale(0.0), - _alpha(0.0), - _visible(a_visible), - _pad31(0), - _pad32(0), - _pad34(0), - _z(0.0), - _xRotation(0.0), - _yRotation(0.0), - _zScale(0.0), - _fov(0.0), - _viewMatrix3D(), - _perspMatrix3D(), - _flags(Flag::kVisible), - _padD2(0), - _padD4(0) + _visible(a_visible) {} void GFxValue::DisplayInfo::Clear() From 33c9f959a5394ddf1caf3d44b64c7fa00073aa92 Mon Sep 17 00:00:00 2001 From: KernalsEgg <52105649+KernalsEgg@users.noreply.github.com> Date: Thu, 14 Jul 2022 03:36:41 +0930 Subject: [PATCH 03/14] Only read and sort the Address Library when creating the file mapping --- include/REL/Relocation.h | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/include/REL/Relocation.h b/include/REL/Relocation.h index 171ec7685..839c45fb3 100644 --- a/include/REL/Relocation.h +++ b/include/REL/Relocation.h @@ -700,19 +700,20 @@ namespace REL auto mapname = L"CommonLibSSEOffsets-v2-"s; mapname += a_version.wstring(); const auto byteSize = static_cast(header.address_count()) * sizeof(mapping_t); - if (!_mmap.open(mapname, byteSize) && - !_mmap.create(mapname, byteSize)) { + if (_mmap.open(mapname, byteSize)) { + _id2offset = { static_cast(_mmap.data()), header.address_count() }; + } else if (_mmap.create(mapname, byteSize)) { + _id2offset = { static_cast(_mmap.data()), header.address_count() }; + unpack_file(in, header); + std::sort( + _id2offset.begin(), + _id2offset.end(), + [](auto&& a_lhs, auto&& a_rhs) { + return a_lhs.id < a_rhs.id; + }); + } else { stl::report_and_fail("failed to create shared mapping"sv); } - - _id2offset = { static_cast(_mmap.data()), header.address_count() }; - unpack_file(in, header); - std::sort( - _id2offset.begin(), - _id2offset.end(), - [](auto&& a_lhs, auto&& a_rhs) { - return a_lhs.id < a_rhs.id; - }); } catch (const std::system_error&) { stl::report_and_fail( fmt::format( From 84070934c639a4c1eb074a29124387f5c29b600e Mon Sep 17 00:00:00 2001 From: ryan-rsm-mckenzie Date: Thu, 15 Sep 2022 15:27:39 -0700 Subject: [PATCH 04/14] stopgap fix for 1.6.629 update hopefully i can publish a more comprehensive solution to this problem in the near future --- include/RE/A/Actor.h | 2 +- include/RE/A/ArrowProjectile.h | 2 +- include/RE/B/BarrierProjectile.h | 2 +- include/RE/B/BeamProjectile.h | 2 +- include/RE/C/Character.h | 2 +- include/RE/C/ConeProjectile.h | 2 +- include/RE/E/ExtraDataList.h | 53 +++++++++-------- include/RE/F/FlameProjectile.h | 2 +- include/RE/G/GrenadeProjectile.h | 2 +- include/RE/H/Hazard.h | 2 +- include/RE/I/Inventory3DManager.h | 2 +- include/RE/M/MissileProjectile.h | 2 +- include/RE/P/PlayerCharacter.h | 2 +- include/RE/P/Projectile.h | 2 +- include/RE/T/TESObjectCELL.h | 2 +- include/RE/T/TESObjectREFR.h | 2 +- src/RE/E/ExtraDataList.cpp | 99 +++++++++++++------------------ 17 files changed, 84 insertions(+), 98 deletions(-) diff --git a/include/RE/A/Actor.h b/include/RE/A/Actor.h index 77e44f04a..0aaa33f78 100644 --- a/include/RE/A/Actor.h +++ b/include/RE/A/Actor.h @@ -598,5 +598,5 @@ namespace RE private: TESFaction* GetCrimeFactionImpl() const; }; - static_assert(sizeof(Actor) == 0x2B0); + static_assert(sizeof(Actor) == 0x2B8); } diff --git a/include/RE/A/ArrowProjectile.h b/include/RE/A/ArrowProjectile.h index f6f7ef42c..684581ab4 100644 --- a/include/RE/A/ArrowProjectile.h +++ b/include/RE/A/ArrowProjectile.h @@ -43,5 +43,5 @@ namespace RE std::uint64_t unk1E0; // 1E0 AlchemyItem* poison; // 1E8 }; - static_assert(sizeof(ArrowProjectile) == 0x1F0); + static_assert(sizeof(ArrowProjectile) == 0x1F8); } diff --git a/include/RE/B/BarrierProjectile.h b/include/RE/B/BarrierProjectile.h index 51dc6b290..f06c90d21 100644 --- a/include/RE/B/BarrierProjectile.h +++ b/include/RE/B/BarrierProjectile.h @@ -46,5 +46,5 @@ namespace RE std::uint32_t pad1DC; // 1DC BSTArray collisionData; // 1E0 }; - static_assert(sizeof(BarrierProjectile) == 0x1F8); + static_assert(sizeof(BarrierProjectile) == 0x200); } diff --git a/include/RE/B/BeamProjectile.h b/include/RE/B/BeamProjectile.h index a1bf63571..cdd343f06 100644 --- a/include/RE/B/BeamProjectile.h +++ b/include/RE/B/BeamProjectile.h @@ -47,5 +47,5 @@ namespace RE // members std::uint64_t unk238; // 238 }; - static_assert(sizeof(BeamProjectile) == 0x240); + static_assert(sizeof(BeamProjectile) == 0x248); } diff --git a/include/RE/C/Character.h b/include/RE/C/Character.h index 0d899a8f0..6e12f121f 100644 --- a/include/RE/C/Character.h +++ b/include/RE/C/Character.h @@ -53,5 +53,5 @@ namespace RE virtual void Unk_128(void); // 128 virtual void Unk_129(void); // 129 - { return 1; } }; - static_assert(sizeof(Character) == 0x2B0); + static_assert(sizeof(Character) == 0x2B8); } diff --git a/include/RE/C/ConeProjectile.h b/include/RE/C/ConeProjectile.h index 3d01344ce..1efdcd927 100644 --- a/include/RE/C/ConeProjectile.h +++ b/include/RE/C/ConeProjectile.h @@ -54,5 +54,5 @@ namespace RE hkRefPtr collisionShape; // 1F8 BSTArray collisions; // 200 }; - static_assert(sizeof(ConeProjectile) == 0x218); + static_assert(sizeof(ConeProjectile) == 0x220); } diff --git a/include/RE/E/ExtraDataList.h b/include/RE/E/ExtraDataList.h index 320a71be1..82c4ba8bc 100644 --- a/include/RE/E/ExtraDataList.h +++ b/include/RE/E/ExtraDataList.h @@ -14,6 +14,28 @@ namespace RE class InventoryChanges; class TESBoundObject; + class BaseExtraList + { + public: + struct PresenceBitfield + { + public: + [[nodiscard]] bool HasType(std::uint32_t a_type) const; + void MarkType(std::uint32_t a_type, bool a_cleared); + + // members + std::uint8_t bits[0x18]; // 00 + }; + static_assert(sizeof(PresenceBitfield) == 0x18); + + virtual ~BaseExtraList(); // 00 + + // members + BSExtraData* data = nullptr; // 08 + PresenceBitfield* presence = nullptr; // 10 + }; + static_assert(sizeof(BaseExtraList) == 0x18); + class ExtraDataList { public: @@ -98,9 +120,6 @@ namespace RE using iterator = iterator_base; using const_iterator = iterator_base; - ExtraDataList(); - ~ExtraDataList(); - TES_HEAP_REDEFINE_NEW(); iterator begin(); @@ -156,28 +175,14 @@ namespace RE void SetInventoryChanges(InventoryChanges* a_changes); void SetOwner(TESForm* a_owner); - protected: - struct PresenceBitfield - { - public: - [[nodiscard]] bool HasType(std::uint32_t a_type) const; - void MarkType(std::uint32_t a_type, bool a_cleared); - - // members - std::uint8_t bits[0x18]; // 00 - }; - static_assert(sizeof(PresenceBitfield) == 0x18); - - void MarkType(std::uint32_t a_type, bool a_cleared); - void MarkType(ExtraDataType a_type, bool a_cleared); - - // members - BSExtraData* _data; // 00 - PresenceBitfield* _presence; // 08 - mutable BSReadWriteLock _lock; // 10 - private: BSExtraData* GetByTypeImpl(ExtraDataType a_type) const; + void MarkType(std::uint32_t a_type, bool a_cleared); + void MarkType(ExtraDataType a_type, bool a_cleared); + + // members + BaseExtraList _extraData; // 00 + mutable BSReadWriteLock _lock; // 18 }; - static_assert(sizeof(ExtraDataList) == 0x18); + static_assert(sizeof(ExtraDataList) == 0x20); } diff --git a/include/RE/F/FlameProjectile.h b/include/RE/F/FlameProjectile.h index 38290918e..17e3f2afd 100644 --- a/include/RE/F/FlameProjectile.h +++ b/include/RE/F/FlameProjectile.h @@ -38,5 +38,5 @@ namespace RE float expirationTimer; // 1D8 float coneAngle; // 1DC }; - static_assert(sizeof(FlameProjectile) == 0x1E0); + static_assert(sizeof(FlameProjectile) == 0x1E8); } diff --git a/include/RE/G/GrenadeProjectile.h b/include/RE/G/GrenadeProjectile.h index e4a5b1434..d9415cb87 100644 --- a/include/RE/G/GrenadeProjectile.h +++ b/include/RE/G/GrenadeProjectile.h @@ -50,5 +50,5 @@ namespace RE std::uint16_t pad1E2; // 1E2 std::uint32_t pad1E4; // 1E4 }; - static_assert(sizeof(GrenadeProjectile) == 0x1E8); + static_assert(sizeof(GrenadeProjectile) == 0x1F0); } diff --git a/include/RE/H/Hazard.h b/include/RE/H/Hazard.h index 0492b1110..9fdfa9941 100644 --- a/include/RE/H/Hazard.h +++ b/include/RE/H/Hazard.h @@ -58,5 +58,5 @@ namespace RE BSSoundHandle sound; // C8 stl::enumeration flags; // D4 }; - static_assert(sizeof(Hazard) == 0xD8); + static_assert(sizeof(Hazard) == 0xE0); } diff --git a/include/RE/I/Inventory3DManager.h b/include/RE/I/Inventory3DManager.h index 78b308a01..ad1f25e80 100644 --- a/include/RE/I/Inventory3DManager.h +++ b/include/RE/I/Inventory3DManager.h @@ -61,5 +61,5 @@ namespace RE std::uint8_t pad15B; // 15B std::uint32_t pad15C; // 15C }; - static_assert(sizeof(Inventory3DManager) == 0x160); + static_assert(sizeof(Inventory3DManager) == 0x168); } diff --git a/include/RE/M/MissileProjectile.h b/include/RE/M/MissileProjectile.h index 806c8096c..9ed88ed34 100644 --- a/include/RE/M/MissileProjectile.h +++ b/include/RE/M/MissileProjectile.h @@ -45,5 +45,5 @@ namespace RE std::uint8_t unk1DD; // 1DD std::uint16_t unk1DE; // 1DE }; - static_assert(sizeof(MissileProjectile) == 0x1E0); + static_assert(sizeof(MissileProjectile) == 0x1E8); } diff --git a/include/RE/P/PlayerCharacter.h b/include/RE/P/PlayerCharacter.h index 770ea49a6..430d1a6e7 100644 --- a/include/RE/P/PlayerCharacter.h +++ b/include/RE/P/PlayerCharacter.h @@ -466,5 +466,5 @@ namespace RE private: bool CenterOnCell_Impl(const char* a_cellName, RE::TESObjectCELL* a_cell); }; - static_assert(sizeof(PlayerCharacter) == 0xBE0); + static_assert(sizeof(PlayerCharacter) == 0xBE8); } diff --git a/include/RE/P/Projectile.h b/include/RE/P/Projectile.h index fe1f14de3..e3132c599 100644 --- a/include/RE/P/Projectile.h +++ b/include/RE/P/Projectile.h @@ -147,5 +147,5 @@ namespace RE std::uint32_t flags; // 1CC std::uint64_t unk1D0; // 1D0 }; - static_assert(sizeof(Projectile) == 0x1D8); + static_assert(sizeof(Projectile) == 0x1E0); } diff --git a/include/RE/T/TESObjectCELL.h b/include/RE/T/TESObjectCELL.h index 55d45d2c0..b350c61aa 100644 --- a/include/RE/T/TESObjectCELL.h +++ b/include/RE/T/TESObjectCELL.h @@ -232,5 +232,5 @@ namespace RE BGSLightingTemplate* lightingTemplate; // 130 - LTMP std::uint64_t unk138; // 138 }; - static_assert(sizeof(TESObjectCELL) == 0x140); + static_assert(sizeof(TESObjectCELL) == 0x148); } diff --git a/include/RE/T/TESObjectREFR.h b/include/RE/T/TESObjectREFR.h index 885347280..9f6e0ffb3 100644 --- a/include/RE/T/TESObjectREFR.h +++ b/include/RE/T/TESObjectREFR.h @@ -438,5 +438,5 @@ namespace RE void MoveTo_Impl(const ObjectRefHandle& a_targetHandle, TESObjectCELL* a_targetCell, TESWorldSpace* a_selfWorldSpace, const NiPoint3& a_position, const NiPoint3& a_rotation); void PlayAnimation_Impl(NiControllerManager* a_manager, NiControllerSequence* a_toSeq, NiControllerSequence* a_fromSeq, bool a_arg4 = false); }; - static_assert(sizeof(TESObjectREFR) == 0x98); + static_assert(sizeof(TESObjectREFR) == 0xA0); }; diff --git a/src/RE/E/ExtraDataList.cpp b/src/RE/E/ExtraDataList.cpp index c182e1350..141b32aa9 100644 --- a/src/RE/E/ExtraDataList.cpp +++ b/src/RE/E/ExtraDataList.cpp @@ -19,33 +19,36 @@ namespace RE { - ExtraDataList::ExtraDataList() : - _data(nullptr), - _presence(nullptr), - _lock() - {} - - ExtraDataList::~ExtraDataList() + bool BaseExtraList::PresenceBitfield::HasType(std::uint32_t a_type) const { - while (_data) { - auto xData = _data; - _data = xData->next; - delete xData; + const std::uint32_t index = (a_type >> 3); + if (index >= 0x18) { + return false; } - _data = nullptr; + const std::uint8_t bitMask = 1 << (a_type % 8); + return (bits[index] & bitMask) != 0; + } - free(_presence); - _presence = nullptr; + void BaseExtraList::PresenceBitfield::MarkType(std::uint32_t a_type, bool a_cleared) + { + const std::uint32_t index = (a_type >> 3); + const std::uint8_t bitMask = 1 << (a_type % 8); + auto& flag = bits[index]; + if (a_cleared) { + flag &= ~bitMask; + } else { + flag |= bitMask; + } } ExtraDataList::iterator ExtraDataList::begin() { - return iterator(_data); + return iterator(_extraData.data); } ExtraDataList::const_iterator ExtraDataList::cbegin() const { - return const_iterator(_data); + return const_iterator(_extraData.data); } ExtraDataList::const_iterator ExtraDataList::begin() const @@ -71,7 +74,7 @@ namespace RE bool ExtraDataList::HasType(ExtraDataType a_type) const { BSReadLockGuard locker(_lock); - return _presence != nullptr && _presence->HasType(static_cast(a_type)); + return _extraData.presence != nullptr && _extraData.presence->HasType(static_cast(a_type)); } BSExtraData* ExtraDataList::GetByType(ExtraDataType a_type) @@ -94,11 +97,11 @@ namespace RE bool removed = false; - if (_data == a_toRemove) { - _data = _data->next; + if (_extraData.data == a_toRemove) { + _extraData.data = _extraData.data->next; removed = true; } else { - for (auto iter = _data; iter; iter = iter->next) { + for (auto iter = _extraData.data; iter; iter = iter->next) { if (iter->next == a_toRemove) { iter->next = a_toRemove->next; removed = true; @@ -118,21 +121,21 @@ namespace RE { BSWriteLockGuard locker(_lock); - if (!_data) { + if (!_extraData.data) { return false; } bool removed = false; - while (_data->GetType() == a_type) { - auto tmp = _data; - _data = _data->next; + while (_extraData.data->GetType() == a_type) { + auto tmp = _extraData.data; + _extraData.data = _extraData.data->next; delete tmp; removed = true; } - auto prev = _data; - for (auto cur = _data->next; cur; cur = cur->next) { + auto prev = _extraData.data; + for (auto cur = _extraData.data->next; cur; cur = cur->next) { if (cur->GetType() == a_type) { prev->next = cur->next; delete cur; @@ -287,38 +290,6 @@ namespace RE } } - bool ExtraDataList::PresenceBitfield::HasType(std::uint32_t a_type) const - { - const std::uint32_t index = (a_type >> 3); - if (index >= 0x18) { - return false; - } - const std::uint8_t bitMask = 1 << (a_type % 8); - return (bits[index] & bitMask) != 0; - } - - void ExtraDataList::PresenceBitfield::MarkType(std::uint32_t a_type, bool a_cleared) - { - const std::uint32_t index = (a_type >> 3); - const std::uint8_t bitMask = 1 << (a_type % 8); - auto& flag = bits[index]; - if (a_cleared) { - flag &= ~bitMask; - } else { - flag |= bitMask; - } - } - - void ExtraDataList::MarkType(std::uint32_t a_type, bool a_cleared) - { - _presence->MarkType(a_type, a_cleared); - } - - void ExtraDataList::MarkType(ExtraDataType a_type, bool a_cleared) - { - MarkType(static_cast(a_type), a_cleared); - } - BSExtraData* ExtraDataList::GetByTypeImpl(ExtraDataType a_type) const { BSReadLockGuard locker(_lock); @@ -327,7 +298,7 @@ namespace RE return nullptr; } - for (auto iter = _data; iter; iter = iter->next) { + for (auto iter = _extraData.data; iter; iter = iter->next) { if (iter->GetType() == a_type) { return iter; } @@ -335,4 +306,14 @@ namespace RE return nullptr; } + + void ExtraDataList::MarkType(std::uint32_t a_type, bool a_cleared) + { + _extraData.presence->MarkType(a_type, a_cleared); + } + + void ExtraDataList::MarkType(ExtraDataType a_type, bool a_cleared) + { + MarkType(static_cast(a_type), a_cleared); + } } From ce57594cb5d0f8892eeec6e5e9d4c54d393b8f5f Mon Sep 17 00:00:00 2001 From: ryan-rsm-mckenzie Date: Thu, 15 Sep 2022 15:28:37 -0700 Subject: [PATCH 05/14] add 1.6.629 to version table --- include/SKSE/Version.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/SKSE/Version.h b/include/SKSE/Version.h index bbd3d3090..0fcde167e 100644 --- a/include/SKSE/Version.h +++ b/include/SKSE/Version.h @@ -24,6 +24,7 @@ namespace SKSE inline constexpr REL::Version RUNTIME_1_6_323(1, 6, 323, 0); inline constexpr REL::Version RUNTIME_1_6_342(1, 6, 342, 0); inline constexpr REL::Version RUNTIME_1_6_353(1, 6, 353, 0); + inline constexpr REL::Version RUNTIME_1_6_629(1, 6, 629, 0); inline constexpr auto RUNTIME_LATEST = RUNTIME_1_6_353; } From 305d721e1782a3b6499b84c591cfa8df7b55aca4 Mon Sep 17 00:00:00 2001 From: ryan-rsm-mckenzie Date: Thu, 15 Sep 2022 15:28:48 -0700 Subject: [PATCH 06/14] set 1.6.629 as latest runtime --- include/SKSE/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SKSE/Version.h b/include/SKSE/Version.h index 0fcde167e..95c1ecec0 100644 --- a/include/SKSE/Version.h +++ b/include/SKSE/Version.h @@ -26,5 +26,5 @@ namespace SKSE inline constexpr REL::Version RUNTIME_1_6_353(1, 6, 353, 0); inline constexpr REL::Version RUNTIME_1_6_629(1, 6, 629, 0); - inline constexpr auto RUNTIME_LATEST = RUNTIME_1_6_353; + inline constexpr auto RUNTIME_LATEST = RUNTIME_1_6_629; } From d85c50c28a39fd1c237faee2a8a9c68210eb357c Mon Sep 17 00:00:00 2001 From: ryan-rsm-mckenzie Date: Thu, 15 Sep 2022 15:34:14 -0700 Subject: [PATCH 07/14] update development info --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cd3853f1a..f8968434b 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,12 @@ [![Main CI](https://img.shields.io/github/workflow/status/Ryan-rsm-McKenzie/CommonLibSSE/Main%20CI?logo=github&logoColor=white)](https://github.com/Ryan-rsm-McKenzie/CommonLibSSE/actions/workflows/main_ci.yml) ## Build Dependencies +* [binary_io](https://github.com/Ryan-rsm-McKenzie/binary_io) * [Boost](https://www.boost.org/) * Stl_interfaces * [spdlog](https://github.com/gabime/spdlog) -* [Visual Studio Community 2019 16.10.0 Preview 3.0](https://visualstudio.microsoft.com/vs/preview/) +* [fmt](https://github.com/fmtlib/fmt) +* [Visual Studio Community 2022](https://visualstudio.microsoft.com/vs/preview/) (or later) * Desktop development with C++ ## End User Dependencies @@ -16,7 +18,7 @@ ## Development * [Address Library for SKSE Plugins](https://www.nexusmods.com/skyrimspecialedition/mods/32444) -* [clang-format 12.0.0](https://github.com/llvm/llvm-project/releases) +* [clang-format 12.0.0](https://github.com/llvm/llvm-project/releases) (or later) * [CMake](https://cmake.org/) * [vcpkg](https://github.com/microsoft/vcpkg) From 6d96994f1a3536be70815a707160f4390686e6e7 Mon Sep 17 00:00:00 2001 From: ryan-rsm-mckenzie Date: Thu, 15 Sep 2022 15:36:27 -0700 Subject: [PATCH 08/14] add tutorial link --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index f8968434b..3d427f341 100644 --- a/README.md +++ b/README.md @@ -24,3 +24,6 @@ ## Notes * CommonLib is incompatible with SKSE and is intended to replace it as a static dependency. However, you will still need the runtime component. + +## Tutorial +Learn how to build your very first SKSE plugin using CommonLib by following [this video tutorial](https://www.youtube.com/watch?v=FLRhsrQ8mqw). From e5ee467ebdafdbffba58907ad583d87fd5a25741 Mon Sep 17 00:00:00 2001 From: MetricExpansion Date: Sat, 17 Sep 2022 13:28:42 -0700 Subject: [PATCH 09/14] Update plugin version info for SKSE 1.6.629 --- include/SKSE/Interfaces.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/include/SKSE/Interfaces.h b/include/SKSE/Interfaces.h index 85ebe8882..f39fc8509 100644 --- a/include/SKSE/Interfaces.h +++ b/include/SKSE/Interfaces.h @@ -374,19 +374,26 @@ namespace SKSE constexpr void MinimumRequiredXSEVersion(REL::Version a_version) noexcept { xseMinimum = a_version.pack(); } constexpr void PluginName(std::string_view a_plugin) noexcept { SetCharBuffer(a_plugin, std::span{ pluginName }); } constexpr void PluginVersion(REL::Version a_version) noexcept { pluginVersion = a_version.pack(); } + constexpr void HasNoStructUse(bool a_value) noexcept { noStructUse = a_value; } constexpr void UsesAddressLibrary(bool a_value) noexcept { addressLibrary = a_value; } constexpr void UsesSigScanning(bool a_value) noexcept { sigScanning = a_value; } + constexpr void UsesStructsPost629(bool a_value) noexcept { structsPost629 = a_value; } const std::uint32_t dataVersion{ kVersion }; std::uint32_t pluginVersion = 0; char pluginName[256] = {}; char author[256] = {}; char supportEmail[256] = {}; - bool addressLibrary: 1 = false; - bool sigScanning: 1 = false; - std::uint8_t padding1: 6 = 0; + bool noStructUse: 1 = false; + std::uint8_t padding1: 7 = 0; std::uint8_t padding2 = 0; std::uint16_t padding3 = 0; + bool addressLibrary: 1 = false; + bool sigScanning: 1 = false; + bool structsPost629: 1 = true; + std::uint8_t padding4: 5 = 0; + std::uint8_t padding5 = 0; + std::uint16_t padding6 = 0; std::uint32_t compatibleVersions[16] = {}; std::uint32_t xseMinimum = 0; @@ -407,7 +414,9 @@ namespace SKSE static_assert(offsetof(PluginVersionData, supportEmail) == 0x208); static_assert(offsetof(PluginVersionData, padding2) == 0x309); static_assert(offsetof(PluginVersionData, padding3) == 0x30A); - static_assert(offsetof(PluginVersionData, compatibleVersions) == 0x30C); - static_assert(offsetof(PluginVersionData, xseMinimum) == 0x34C); - static_assert(sizeof(PluginVersionData) == 0x350); + static_assert(offsetof(PluginVersionData, padding5) == 0x30D); + static_assert(offsetof(PluginVersionData, padding6) == 0x30E); + static_assert(offsetof(PluginVersionData, compatibleVersions) == 0x310); + static_assert(offsetof(PluginVersionData, xseMinimum) == 0x350); + static_assert(sizeof(PluginVersionData) == 0x354); } From 01985b2c7f8d28153633f08201849142fe187eb2 Mon Sep 17 00:00:00 2001 From: MetricExpansion Date: Sat, 17 Sep 2022 14:07:26 -0700 Subject: [PATCH 10/14] Update include/SKSE/Interfaces.h Co-authored-by: Ryan McKenzie --- include/SKSE/Interfaces.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SKSE/Interfaces.h b/include/SKSE/Interfaces.h index f39fc8509..7bd7d33bb 100644 --- a/include/SKSE/Interfaces.h +++ b/include/SKSE/Interfaces.h @@ -383,7 +383,7 @@ namespace SKSE std::uint32_t pluginVersion = 0; char pluginName[256] = {}; char author[256] = {}; - char supportEmail[256] = {}; + char supportEmail[252] = {}; bool noStructUse: 1 = false; std::uint8_t padding1: 7 = 0; std::uint8_t padding2 = 0; From 671752d81d2d28680c6f9166489400d89694053c Mon Sep 17 00:00:00 2001 From: MetricExpansion Date: Sat, 17 Sep 2022 14:07:35 -0700 Subject: [PATCH 11/14] Update include/SKSE/Interfaces.h Co-authored-by: Ryan McKenzie --- include/SKSE/Interfaces.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SKSE/Interfaces.h b/include/SKSE/Interfaces.h index 7bd7d33bb..1f0846fbf 100644 --- a/include/SKSE/Interfaces.h +++ b/include/SKSE/Interfaces.h @@ -418,5 +418,5 @@ namespace SKSE static_assert(offsetof(PluginVersionData, padding6) == 0x30E); static_assert(offsetof(PluginVersionData, compatibleVersions) == 0x310); static_assert(offsetof(PluginVersionData, xseMinimum) == 0x350); - static_assert(sizeof(PluginVersionData) == 0x354); + static_assert(sizeof(PluginVersionData) == 0x350); } From feb3fe990f4b8cc136c5a993eb30fb7924bfc313 Mon Sep 17 00:00:00 2001 From: MetricExpansion Date: Sat, 17 Sep 2022 14:17:07 -0700 Subject: [PATCH 12/14] Fix static asserts --- include/SKSE/Interfaces.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/SKSE/Interfaces.h b/include/SKSE/Interfaces.h index 1f0846fbf..fb1b7e143 100644 --- a/include/SKSE/Interfaces.h +++ b/include/SKSE/Interfaces.h @@ -412,11 +412,11 @@ namespace SKSE static_assert(offsetof(PluginVersionData, pluginName) == 0x008); static_assert(offsetof(PluginVersionData, author) == 0x108); static_assert(offsetof(PluginVersionData, supportEmail) == 0x208); - static_assert(offsetof(PluginVersionData, padding2) == 0x309); - static_assert(offsetof(PluginVersionData, padding3) == 0x30A); - static_assert(offsetof(PluginVersionData, padding5) == 0x30D); - static_assert(offsetof(PluginVersionData, padding6) == 0x30E); - static_assert(offsetof(PluginVersionData, compatibleVersions) == 0x310); - static_assert(offsetof(PluginVersionData, xseMinimum) == 0x350); + static_assert(offsetof(PluginVersionData, padding2) == 0x305); + static_assert(offsetof(PluginVersionData, padding3) == 0x306); + static_assert(offsetof(PluginVersionData, padding5) == 0x309); + static_assert(offsetof(PluginVersionData, padding6) == 0x30A); + static_assert(offsetof(PluginVersionData, compatibleVersions) == 0x30C); + static_assert(offsetof(PluginVersionData, xseMinimum) == 0x34C); static_assert(sizeof(PluginVersionData) == 0x350); } From 2a7919c59a2eb3427fa7f4cb8d12db0e243e8ec5 Mon Sep 17 00:00:00 2001 From: Parapets Date: Sat, 1 Oct 2022 11:03:27 +0100 Subject: [PATCH 13/14] Get log directory from game exe --- src/SKSE/Logger.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SKSE/Logger.cpp b/src/SKSE/Logger.cpp index 41241e02b..db4528163 100644 --- a/src/SKSE/Logger.cpp +++ b/src/SKSE/Logger.cpp @@ -103,7 +103,9 @@ namespace SKSE } std::filesystem::path path = knownPath.get(); - path /= "My Games/Skyrim Special Edition/SKSE"sv; + path /= "My Games"sv; + path /= *REL::Relocation(REL::ID(380738)).get(); + path /= "SKSE"sv; return path; } } From 0e9d380b90950eb3ece1e5b95e3b6a379ee03f8e Mon Sep 17 00:00:00 2001 From: ryan-rsm-mckenzie Date: Fri, 14 Oct 2022 18:52:31 -0700 Subject: [PATCH 14/14] add new exe versions --- include/SKSE/Version.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/SKSE/Version.h b/include/SKSE/Version.h index 95c1ecec0..d63cefeb7 100644 --- a/include/SKSE/Version.h +++ b/include/SKSE/Version.h @@ -25,6 +25,9 @@ namespace SKSE inline constexpr REL::Version RUNTIME_1_6_342(1, 6, 342, 0); inline constexpr REL::Version RUNTIME_1_6_353(1, 6, 353, 0); inline constexpr REL::Version RUNTIME_1_6_629(1, 6, 629, 0); + inline constexpr REL::Version RUNTIME_1_6_640(1, 6, 640, 0); + inline constexpr REL::Version RUNTIME_1_6_659(1, 6, 659, 0); + inline constexpr REL::Version RUNTIME_1_6_678(1, 6, 678, 0); - inline constexpr auto RUNTIME_LATEST = RUNTIME_1_6_629; + inline constexpr auto RUNTIME_LATEST = RUNTIME_1_6_640; // latest for steam }