From 859d5b7e614e55e5ea997fb295e0b9b1f505d37c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Dejerud=20R=C3=A5dstam?= <68670981+FlenarnDev@users.noreply.github.com> Date: Tue, 4 Aug 2026 19:08:15 +0200 Subject: [PATCH 1/2] feat: Misc RE and corrections. (#62) * chore: Library update. * maintenance * chore: Fix compile and missed file. * fix * feat: More ExtraData. * maintenance * fix: Cleanup. * feat: HandlePositionPlayerRequest * chore: Update CommonLib-Shared * chore: Update CommonLib-Shared. * chore: Misc. RE work. * fix: Remove duplicate ID entry. * maintenance * fix: SetLinkedRef declaration. --------- Co-authored-by: Flenarn Co-authored-by: FlenarnDev --- include/RE/B/BGSTerrainManager.h | 79 +++++++++++++++++++++++++++ include/RE/E/EXTRA_DATA_TYPE.h | 8 +-- include/RE/E/ExtraCellSkyRegion.h | 20 +++++++ include/RE/E/ExtraLinkedRef.h | 31 +++++++++++ include/RE/E/ExtraLinkedRefChildren.h | 31 +++++++++++ include/RE/F/FastTravelCommand.h | 19 +++++++ include/RE/Fallout.h | 6 ++ include/RE/IDs.h | 27 +++++++++ include/RE/M/Main.h | 16 +++++- include/RE/M/MapMarker.h | 12 ++++ include/RE/N/NiCullingProcess.h | 9 +++ include/RE/N/NiFrustum.h | 14 ++--- include/RE/P/PipboyMapData.h | 7 +++ include/RE/P/PlayerCharacter.h | 14 +++++ include/RE/T/TES.h | 8 +++ include/RE/T/TESObjectREFR.h | 4 +- include/RE/T/TESWorldSpace.h | 7 +++ 17 files changed, 297 insertions(+), 15 deletions(-) create mode 100644 include/RE/B/BGSTerrainManager.h create mode 100644 include/RE/E/ExtraCellSkyRegion.h create mode 100644 include/RE/E/ExtraLinkedRef.h create mode 100644 include/RE/E/ExtraLinkedRefChildren.h create mode 100644 include/RE/F/FastTravelCommand.h create mode 100644 include/RE/M/MapMarker.h diff --git a/include/RE/B/BGSTerrainManager.h b/include/RE/B/BGSTerrainManager.h new file mode 100644 index 00000000..3122563b --- /dev/null +++ b/include/RE/B/BGSTerrainManager.h @@ -0,0 +1,79 @@ +#pragma once + +#include "RE/B/BSSpinLock.h" +#include "RE/B/BSTArray.h" +#include "RE/N/NiPoint2.h" +#include "RE/N/NiPoint3.h" + +namespace RE +{ + class BGSTerrainNode; + class NiCamera; + class TESWorldSpace; + + class BGSTerrainManager + { + public: + class CullState + { + public: + bool cullRoot; // 00 + bool cullLand; // 01 + bool cullTrees; // 02 + bool cullObjects; // 03 + bool cullInstanced; // 04 + }; + + class QuickCullDAta + { + public: + NiPoint2 frustNearLeft; // 000 + NiPoint2 frustFarLeft; // 008 + NiPoint2 frustNearRight; // 010 + NiPoint2 frustFarRight; // 018 + }; + + void RecomputeQuickCullData(const NiCamera* a_camera) + { + using func_t = decltype(&BGSTerrainManager::RecomputeQuickCullData); + static REL::Relocation func{ ID::BGSTerrainManager::RecomputeQuickCullData }; + return func(this, a_camera); + } + + // members + bool mapMode; // 000 + TESWorldSpace* world; // 008 + BGSTerrainNode* rootNode; // 010 + std::int16_t minCellX; // 018 + std::int16_t minCellY; // 01A + std::uint32_t maxLevel; // 01C + std::uint32_t minLevel; // 020 + std::uint32_t rootLevel; // 024 + std::uint32_t segmentedBlockLevel; // 028 + std::uint32_t treeLevel; // 02C + CullState savedCullState; // 030 + CullState activeCullState; // 035 + bool cullActive; // 03A + bool needsImmediateUpdate; // 03B + bool initialUpdateDone; // 03C + bool hasLOD; // 03D + QuickCullDAta cullData; // 040 + bool staticDataLoaded; // 060 + BSTArray updateUpdates; // 068 + std::uint32_t nextUpdateNode; // 080 + BSTArray immediateUpdates; // 088 + BSSpinLock immediateUpdateLock; // 0A0 + bool lockedLOD; // 0A8 + std::uint32_t lockedTerrainLOD; // 0AC + std::uint32_t lockedObjectLOD; // 0B0 + std::uint32_t totalChildNodes; // 0B4 + std::uint8_t* childNodeBufferStart; // 0B8 + std::uint8_t* childNodeBufferCurr; // 0C0 + std::uint8_t* childNodeBufferEnd; // 0C8 + std::uint32_t nodeCount; // 0D0 + std::uint32_t loadedRectUpdateDelay; // 0D4 + NiPoint3 interiorAdjustedOffset; // 0D8 + BSTArray fadeNodeA; // 0E8 + }; + static_assert(sizeof(BGSTerrainManager) == 0x100); +} diff --git a/include/RE/E/EXTRA_DATA_TYPE.h b/include/RE/E/EXTRA_DATA_TYPE.h index 139ecb2e..3225a818 100644 --- a/include/RE/E/EXTRA_DATA_TYPE.h +++ b/include/RE/E/EXTRA_DATA_TYPE.h @@ -12,7 +12,7 @@ namespace RE kSeenData, // kEditorID, // ExtraEditorID kCellMusicType, // - kSkyRegion, // + kSkyRegion, // ExtraCellSkyRegion kCellMidLowProcess, // kCellDetachTime, // kPersistentCell, // @@ -48,7 +48,7 @@ namespace RE kLight, // ExtraLight kLock, // ExtraLock kTeleport, // ExtraTeleport - kMapMarker, // + kMapMarker, // ExtraMapMarker kLeveledCreature, // ExtraLeveledCreature kLevelItem, // kScale, // @@ -84,8 +84,8 @@ namespace RE kNoRumors, // kSound, // kTerminalState, // - kLinkedRef, // - kLinkedRefChildren, // + kLinkedRef, // ExtraLinkedRef + kLinkedRefChildren, // ExtraLinkedRefChildren kActivateRef, // kActivateRefChildren, // kTalkToPlayer, // diff --git a/include/RE/E/ExtraCellSkyRegion.h b/include/RE/E/ExtraCellSkyRegion.h new file mode 100644 index 00000000..fb1ddda6 --- /dev/null +++ b/include/RE/E/ExtraCellSkyRegion.h @@ -0,0 +1,20 @@ +#pragma once + +#include "RE/B/BSExtraData.h" + +namespace RE +{ + class TESRegion; + + class __declspec(novtable) ExtraCellSkyRegion : + public BSExtraData // 00 + { + static constexpr auto RTTI{ RTTI::ExtraCellSkyRegion }; + static constexpr auto VTABLE{ VTABLE::ExtraCellSkyRegion }; + static constexpr auto TYPE{ EXTRA_DATA_TYPE::kSkyRegion }; + + // members + TESRegion* skyRegion; // 18 + }; + static_assert(sizeof(ExtraCellSkyRegion) == 0x20); +} diff --git a/include/RE/E/ExtraLinkedRef.h b/include/RE/E/ExtraLinkedRef.h new file mode 100644 index 00000000..142e3168 --- /dev/null +++ b/include/RE/E/ExtraLinkedRef.h @@ -0,0 +1,31 @@ +#pragma once + +#include "RE/B/BSExtraData.h" +#include "RE/B/BSTArray.h" + +namespace RE +{ + class BGSKeyword; + class TESObjectREFR; + + class __declspec(novtable) ExtraLinkedRef : + public BSExtraData // 00 + { + public: + static constexpr auto RTTI{ RTTI::ExtraLinkedRef }; + static constexpr auto VTABLE{ VTABLE::ExtraLinkedRef }; + static constexpr auto TYPE{ EXTRA_DATA_TYPE::kLinkedRef }; + + class LinkedRef + { + public: + BGSKeyword* keyword; // 00 + TESObjectREFR* REFR; // 08 + }; + + // members + BSTSmallArray linkedRefs; // 018 + bool transientRefs; // 038 + }; + static_assert(sizeof(ExtraLinkedRef) == 0x40); +} diff --git a/include/RE/E/ExtraLinkedRefChildren.h b/include/RE/E/ExtraLinkedRefChildren.h new file mode 100644 index 00000000..1e1e30f2 --- /dev/null +++ b/include/RE/E/ExtraLinkedRefChildren.h @@ -0,0 +1,31 @@ +#pragma once + +#include "RE/B/BSExtraData.h" +#include "RE/B/BSPointerHandle.h" +#include "RE/B/BSTArray.h" + +namespace RE +{ + class BGSKeyword; + class TESObjectREFR; + + class __declspec(novtable) ExtraLinkedRefChildren : + public BSExtraData // 00 + { + public: + static constexpr auto RTTI{ RTTI::ExtraLinkedRefChildren }; + static constexpr auto VTABLE{ VTABLE::ExtraLinkedRefChildren }; + static constexpr auto TYPE{ EXTRA_DATA_TYPE::kLinkedRefChildren }; + + class LinkedRefChild + { + public: + BGSKeyword* keyword; // 00 + ObjectRefHandle REFR; // 08 + }; + + // members + BSTSmallArray linkedChildren; // 018 + }; + static_assert(sizeof(ExtraLinkedRefChildren) == 0x38); +} diff --git a/include/RE/F/FastTravelCommand.h b/include/RE/F/FastTravelCommand.h new file mode 100644 index 00000000..dab9addf --- /dev/null +++ b/include/RE/F/FastTravelCommand.h @@ -0,0 +1,19 @@ +#pragma once + +#include "RE/P/PipboyCommand.h" + +namespace RE +{ + class __declspec(novtable) FastTravelCommand : + public PipboyCommand // 000 + { + public: + static constexpr auto RTTI{ RTTI::FastTravelCommand }; + static constexpr auto VTABLE{ VTABLE::FastTravelCommand }; + + // members + uint32_t markerId; // 028 + }; + static_assert(sizeof(FastTravelCommand) == 0x30); + +} diff --git a/include/RE/Fallout.h b/include/RE/Fallout.h index 76ef6a54..7681dd3e 100644 --- a/include/RE/Fallout.h +++ b/include/RE/Fallout.h @@ -230,6 +230,7 @@ #include "RE/B/BGSSynchronizedAnimationManager.h" #include "RE/B/BGSTalkingActivator.h" #include "RE/B/BGSTerminal.h" +#include "RE/B/BGSTerrainManager.h" #include "RE/B/BGSTextureModel.h" #include "RE/B/BGSTextureSet.h" #include "RE/B/BGSTopicSubtypeUnion.h" @@ -664,6 +665,7 @@ #include "RE/E/ExtraAliasInstanceArray.h" #include "RE/E/ExtraAmmo.h" #include "RE/E/ExtraBendableSplineParams.h" +#include "RE/E/ExtraCellSkyRegion.h" #include "RE/E/ExtraCellWaterType.h" #include "RE/E/ExtraCharge.h" #include "RE/E/ExtraDataList.h" @@ -674,6 +676,8 @@ #include "RE/E/ExtraInstanceData.h" #include "RE/E/ExtraLeveledCreature.h" #include "RE/E/ExtraLight.h" +#include "RE/E/ExtraLinkedRef.h" +#include "RE/E/ExtraLinkedRefChildren.h" #include "RE/E/ExtraLocation.h" #include "RE/E/ExtraLock.h" #include "RE/E/ExtraMapMarker.h" @@ -701,6 +705,7 @@ #include "RE/F/FORM.h" #include "RE/F/FORM_ENUM_STRING.h" #include "RE/F/FUNCTION_DATA.h" +#include "RE/F/FastTravelCommand.h" #include "RE/F/FatmanDeaths.h" #include "RE/F/FavoriteMgr_Events.h" #include "RE/F/FavoritesManager.h" @@ -959,6 +964,7 @@ #include "RE/M/MagicTarget.h" #include "RE/M/Main.h" #include "RE/M/MainMenu.h" +#include "RE/M/MapMarker.h" #include "RE/M/MapMarkerData.h" #include "RE/M/MarkerIconTypes.h" #include "RE/M/MeleeThrowHandler.h" diff --git a/include/RE/IDs.h b/include/RE/IDs.h index 9591fb7b..5a5fd067 100644 --- a/include/RE/IDs.h +++ b/include/RE/IDs.h @@ -432,6 +432,11 @@ namespace RE::ID inline constexpr REL::ID Activate{ 2197778 }; } + namespace BGSTerrainManager + { + inline constexpr REL::ID RecomputeQuickCullData{ 2213622 }; + } + namespace bhkCharacterController { inline constexpr REL::ID Jump{ 2278191 }; @@ -517,6 +522,12 @@ namespace RE::ID inline constexpr REL::ID Singleton{ 2255115 }; } + namespace BSCullingProcess + { + inline constexpr REL::ID Process1{ 2275931 }; + inline constexpr REL::ID Process2{ 2275932 }; + } + namespace BSGFxDisplayObject { inline constexpr REL::ID RemoveChild{ 2287327 }; @@ -1460,6 +1471,8 @@ namespace RE::ID inline constexpr REL::ID QGameSystemsShouldUpdate{ 2698031 }; inline constexpr REL::ID QGameDataLoaded{ 2698032 }; inline constexpr REL::ID SetCameraFOV{ 2228973 }; + inline constexpr REL::ID LandLODRoot{ 2698035 }; + inline constexpr REL::ID ObjectLODRoot{ 2698036 }; } namespace MapMarkerData @@ -1557,6 +1570,11 @@ namespace RE::ID inline constexpr REL::ID Activate{ 2271861 }; } + namespace NiCullingProcess + { + inline constexpr REL::ID SetFrustum{ 2270782 }; + } + namespace NiMatrix3 { inline constexpr REL::ID ToEulerAnglesXYZ{ 2269806 }; @@ -1696,6 +1714,11 @@ namespace RE::ID inline constexpr REL::ID UpdateCursorConstraint{ 2225488 }; } + namespace PipboyMapData + { + inline constexpr REL::ID GetTravelLocationRefr{ 2225515 }; + } + namespace PipboyMapMenu { inline constexpr REL::ID UpdateData{ 2224074 }; @@ -1820,6 +1843,8 @@ namespace RE::ID inline constexpr REL::ID HasLOSToTarget{ 2233004 }; inline constexpr REL::ID TryUnlockObject{ 2233040 }; inline constexpr REL::ID EnableRadio{ 2233211 }; + inline constexpr REL::ID UpdateAnimation{ 2233005 }; + inline constexpr REL::ID HandlePositionPlayerRequest{ 2232905 }; } namespace PlayerControls @@ -2008,6 +2033,7 @@ namespace RE::ID namespace TES { inline constexpr REL::ID Singleton{ 2698044 }; + inline constexpr REL::ID UpdateMultiBoundVisibility{ 2192134 }; } namespace TESActivateEvent @@ -2345,6 +2371,7 @@ namespace RE::ID { inline constexpr REL::ID DefaultWater{ 4799138 }; inline constexpr REL::ID GetSkyCell{ 2202924 }; + inline constexpr REL::ID AdjustMapMarkerCoord{ 2202880 }; } namespace UI diff --git a/include/RE/M/Main.h b/include/RE/M/Main.h index 82eaa50a..b77bb971 100644 --- a/include/RE/M/Main.h +++ b/include/RE/M/Main.h @@ -38,9 +38,9 @@ namespace RE return func(); } - [[nodiscard]] static SceneGraph* WorldRootNode() + [[nodiscard]] static SceneGraph* GetWorldRootNode() { - static REL::Relocation*> nodePtr{ ID::Main::WorldRootCamera }; + static REL::Relocation*> nodePtr{ ID::Main::WorldRootNode }; return nodePtr->get(); } @@ -63,6 +63,18 @@ namespace RE return func(this, a_fov); } + inline static NiNode* GetLandLODRoot() + { + static REL::Relocation value{ ID::Main::LandLODRoot }; + return value.get(); + } + + inline static NiNode* GetObjectLODRoot() + { + static REL::Relocation value{ ID::Main::ObjectLODRoot }; + return value.get(); + } + // members BSTArray> sortedVisibleHighActors; // 08 std::uint32_t localMapRenderDelay; // 20 diff --git a/include/RE/M/MapMarker.h b/include/RE/M/MapMarker.h new file mode 100644 index 00000000..cd39f657 --- /dev/null +++ b/include/RE/M/MapMarker.h @@ -0,0 +1,12 @@ +#pragma once +namespace RE +{ + namespace MapMarker + { + enum class MARKER_SCOPE + { + kWorld = 0x0, + kLocal = 0x1 + }; + } +} diff --git a/include/RE/N/NiCullingProcess.h b/include/RE/N/NiCullingProcess.h index a73a457f..1c553f04 100644 --- a/include/RE/N/NiCullingProcess.h +++ b/include/RE/N/NiCullingProcess.h @@ -4,6 +4,8 @@ namespace RE { + class NiFrustum; + class __declspec(novtable) NiCullingProcess { public: @@ -41,6 +43,13 @@ namespace RE virtual void Process(const NiCamera* a_camera, NiAVObject* a_scene, NiVisibleArray* a_visibleSet); // 1A virtual void AppendVirtual(BSGeometry* a_visible); // 1B + void SetFrustum(const NiFrustum* a_frustum) + { + using func_t = decltype(&NiCullingProcess::SetFrustum); + static REL::Relocation func{ ID::NiCullingProcess::SetFrustum }; + return func(this, a_frustum); + } + // members bool useVirtualAppend; // 08 NiVisibleArray* visibleSet; // 10 diff --git a/include/RE/N/NiFrustum.h b/include/RE/N/NiFrustum.h index 59bce857..20f2a4f1 100644 --- a/include/RE/N/NiFrustum.h +++ b/include/RE/N/NiFrustum.h @@ -5,13 +5,13 @@ namespace RE class NiFrustum { public: - float left; // 00 - float right; // 04 - float top; // 08 - float bottom; // 0C - float near; // 10 - float far; // 14 - bool ortho; // 18 + float fLeft; // 00 + float fRight; // 04 + float fTop; // 08 + float fBottom; // 0C + float fNear; // 10 + float fFar; // 14 + bool ortho; // 18 }; static_assert(sizeof(NiFrustum) == 0x1C); } diff --git a/include/RE/P/PipboyMapData.h b/include/RE/P/PipboyMapData.h index 0eeb634a..c171568f 100644 --- a/include/RE/P/PipboyMapData.h +++ b/include/RE/P/PipboyMapData.h @@ -84,6 +84,13 @@ namespace RE virtual void DoClearData() override; // 0C virtual void DoClearSink() override; // 0D + ObjectRefHandle GetTravelLocationRefr(ObjectRefHandle* a_result, std::uint32_t a_markerId) + { + using func_t = decltype(&PipboyMapData::GetTravelLocationRefr); + static REL::Relocation func{ ID::PipboyMapData::GetTravelLocationRefr }; + return func(this, a_result, a_markerId); + } + // members PipboyObject* mapObject; // E8 BSTHashMap travelLocationsMarkers; // F0 diff --git a/include/RE/P/PlayerCharacter.h b/include/RE/P/PlayerCharacter.h index 5b29c1b7..b04ee798 100644 --- a/include/RE/P/PlayerCharacter.h +++ b/include/RE/P/PlayerCharacter.h @@ -320,6 +320,20 @@ namespace RE return func(this, a_enable); } + void UpdateAnimation(float a_delta) + { + using func_t = decltype(&PlayerCharacter::UpdateAnimation); + static REL::Relocation func{ ID::PlayerCharacter::UpdateAnimation }; + return func(this, a_delta); + } + + char HandlePositionPlayerRequest() + { + using func_t = decltype(&PlayerCharacter::HandlePositionPlayerRequest); + static REL::Relocation func{ ID::PlayerCharacter::HandlePositionPlayerRequest }; + return func(this); + } + // members BSSpinLock actorToDisplayOnHUDLock; // 628 BSSpinLock questTargetLock; // 630 diff --git a/include/RE/T/TES.h b/include/RE/T/TES.h index 9993fa99..710e370d 100644 --- a/include/RE/T/TES.h +++ b/include/RE/T/TES.h @@ -9,6 +9,7 @@ namespace RE { + class BSCullingProcess; class GridCellArray; class GridDistantArray; class ImageSpaceModifierInstance; @@ -107,6 +108,13 @@ namespace RE void ForEachReferenceInRange(const NiPoint3& a_origin, const float a_radius, std::function a_callback); void ForEachReferenceInRange(const TESObjectREFR* a_ref, const float a_radius, std::function a_callback); + void UpdateMultiBoundVisibility(BSCullingProcess* a_cullingProcess) + { + using func_t = decltype(&TES::UpdateMultiBoundVisibility); + static REL::Relocation func{ ID::TES::UpdateMultiBoundVisibility }; + return func(this, a_cullingProcess); + } + // members GridDistantArray* gridDistant; // 010 GridCellArray* gridCells; // 018 diff --git a/include/RE/T/TESObjectREFR.h b/include/RE/T/TESObjectREFR.h index 2baab003..fefea4c6 100644 --- a/include/RE/T/TESObjectREFR.h +++ b/include/RE/T/TESObjectREFR.h @@ -494,11 +494,11 @@ namespace RE return func(this, a_point); } - void SetLinkedRef(Actor* a_actor, BGSKeyword* a_keyword) + void SetLinkedRef(TESObjectREFR* a_ref, BGSKeyword* a_keyword) { using func_t = decltype(&TESObjectREFR::SetLinkedRef); static REL::Relocation func{ ID::TESObjectREFR::SetLinkedRef }; - return func(this, a_actor, a_keyword); + return func(this, a_ref, a_keyword); } void SetLocationOnReference(const NiPoint3& a_point) diff --git a/include/RE/T/TESWorldSpace.h b/include/RE/T/TESWorldSpace.h index 9c63ac81..b899cce5 100644 --- a/include/RE/T/TESWorldSpace.h +++ b/include/RE/T/TESWorldSpace.h @@ -91,6 +91,13 @@ namespace RE } } + void AdjustMapMarkerCoord(NiPoint3* a_mapCoord, bool a_inverse) + { + using func_t = decltype(&TESWorldSpace::AdjustMapMarkerCoord); + static REL::Relocation func{ ID::TESWorldSpace::AdjustMapMarkerCoord }; + return func(this, a_mapCoord, a_inverse); + } + // members BSTHashMap cellMap; // 0x040 TESObjectCELL* persistentCell; // 0x070 From 3625330f6b1692bd138e30aa6f5136f84809cdde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Dejerud=20R=C3=A5dstam?= <68670981+FlenarnDev@users.noreply.github.com> Date: Wed, 5 Aug 2026 14:20:01 +0200 Subject: [PATCH 2/2] fix: Corrections from review. (#63) --- include/RE/M/MapMarker.h | 1 + include/RE/P/PlayerCharacter.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/RE/M/MapMarker.h b/include/RE/M/MapMarker.h index cd39f657..996a5822 100644 --- a/include/RE/M/MapMarker.h +++ b/include/RE/M/MapMarker.h @@ -1,4 +1,5 @@ #pragma once + namespace RE { namespace MapMarker diff --git a/include/RE/P/PlayerCharacter.h b/include/RE/P/PlayerCharacter.h index b04ee798..38b84763 100644 --- a/include/RE/P/PlayerCharacter.h +++ b/include/RE/P/PlayerCharacter.h @@ -327,7 +327,7 @@ namespace RE return func(this, a_delta); } - char HandlePositionPlayerRequest() + bool HandlePositionPlayerRequest() { using func_t = decltype(&PlayerCharacter::HandlePositionPlayerRequest); static REL::Relocation func{ ID::PlayerCharacter::HandlePositionPlayerRequest };