docs: add plugin setup guide

This commit is contained in:
2026-05-30 18:33:24 +12:00
parent f3db41c402
commit b61043a3fe
1776 changed files with 122386 additions and 2 deletions
@@ -0,0 +1,42 @@
#pragma once
#include "RE/B/BSIntrusiveRefCounted.h"
#include "RE/B/BSTArray.h"
namespace RE
{
class BGSBlockBashData;
class BGSKeywordForm;
class NiAVObject;
class __declspec(novtable) TBO_InstanceData :
public BSIntrusiveRefCounted // 08
{
public:
static constexpr auto RTTI{ RTTI::TBO_InstanceData };
static constexpr auto VTABLE{ VTABLE::TBO_InstanceData };
virtual ~TBO_InstanceData() = default; // 00
// add
virtual BGSKeywordForm* GetKeywordData() const { return nullptr; } // 01
virtual void DeleteKeywordData() { return; } // 02
virtual void CreateKeywordData() { return; } // 03
virtual BGSBlockBashData* GetBlockBashData() const { return nullptr; } // 04
virtual void DeleteBlockBashData() { return; } // 05
virtual void CreateBlockBashData() { return; } // 06
virtual BSTArray<EnchantmentItem*>* GetEnchantmentArray() const { return nullptr; } // 07
virtual void DeleteEnchantmentArray() { return; } // 08
virtual void CreateEnchantmentArray() { return; } // 09
virtual BSTArray<BGSMaterialSwap*>* GetMaterialSwapArray() const { return nullptr; } // 0A
virtual void DeleteMaterialSwapArray() { return; } // 0B
virtual void CreateMaterialSwapArray() { return; } // 0C
virtual float GetWeight() const { return -1.0F; } // 0D
virtual std::int32_t GetValue() const { return -1; } // 0E
virtual std::uint32_t GetHealth() const { return 0; } // 0F
virtual float GetColorRemappingIndex() const { return std::numeric_limits<float>::max(); } // 10
virtual void PostAttach3D(NiAVObject* a_obj3D, TESObjectREFR* a_ref) const; // 11
virtual void PostApplyMods(const TESBoundObject*) { return; } // 12
};
static_assert(sizeof(TBO_InstanceData) == 0x10);
}
@@ -0,0 +1,20 @@
#pragma once
namespace RE
{
enum class TEMP_EFFECT_TYPE : std::int32_t
{
kTerrain = 0x0,
kWeaponBlood = 0x1,
kDecal = 0x2,
kGeometryDecal = 0x3,
kParticle = 0x4,
kDebris = 0x5,
kSPG = 0x6,
kDefault = 0x7,
kRefDefault = 0x8,
kRefModel = 0x9,
kRefShader = 0xA,
kMagicSummon = 0xB
};
}
+162
View File
@@ -0,0 +1,162 @@
#pragma once
#include "RE/B/BSContainer.h"
#include "RE/B/BSSimpleList.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTEvent.h"
#include "RE/B/BSTTuple.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class GridCellArray;
class GridDistantArray;
class ImageSpaceModifierInstance;
class LoadedAreaBound;
class NavMeshInfoMap;
class NiAVObject;
class NiDirectionalLight;
class NiFogProperty;
class NiNode;
class NiPoint3;
class NiTexture;
class PositionPlayerEvent;
class QueuedFile;
class Sky;
class TESObjectCELL;
class TESObjectREFR;
class TESRegion;
class TESWorldSpace;
namespace BSResource::Archive2
{
class StreamOpenedEvent;
}
class TES :
public BSTEventSink<BSResource::Archive2::StreamOpenedEvent>, // 000
public BSTEventSink<PositionPlayerEvent> // 008
{
public:
static constexpr auto RTTI{ RTTI::TES };
static constexpr auto VTABLE{ VTABLE::TES };
using TACCallbackFunc_t = void(TESObjectCELL*, void*, void*);
enum class PICKWORLD_NODE
{
kActors = 0x1,
kMarkers = 0x2,
kLand = 0x4,
kStatic = 0x8,
kActive = 0x10,
kAll = 0x1F,
};
enum class TACMode
{
kAll = 0x0,
kMainWorldOnly = 0x1,
kOtherWorldsOnly = 0x2,
kInteriorsOnly = 0x3,
kSpecifiedWorldOnly = 0x4
};
enum class TAC_CONTROL : std::uint32_t
{
kStop = 0xFFFFFFFF,
kContinue = 0x0,
kAllStandard = 0x1,
kInteriorsStandard = 0x2,
kStartInCurrentCell = 0x3,
kAllSaves = 0x4,
kAllSavesAfterChangingObjects = 0x5,
kAllRenderTest = 0x6,
kInteriorsRenderTest = 0x7,
kRegionFilter = 0x8,
kAllFileUsage = 0x9,
kAllGraphicsTest = 0xA,
kAllGraphicsTestLimited = 0xB
};
class ParticleObjectCache
{
public:
// members
NiPointer<NiAVObject> model; // 00
NiPointer<NiAVObject>* clones; // 08
ParticleObjectCache* next; // 10
};
static_assert(sizeof(ParticleObjectCache) == 0x18);
virtual ~TES(); // 00
// override (BSTEventSink<BSResource::ArchiveStreamOpenedEvent>)
BSEventNotifyControl ProcessEvent(const BSResource::Archive2::StreamOpenedEvent& a_event, BSTEventSource<BSResource::Archive2::StreamOpenedEvent>* a_eventSource) override; // 01 - { return BSEventNotifyControl::kContinue; }
// override (BSTEventSink<PositionPlayerEvent>)
BSEventNotifyControl ProcessEvent(const PositionPlayerEvent& a_event, BSTEventSource<PositionPlayerEvent>* a_eventSource) override; // 01
[[nodiscard]] static TES* GetSingleton()
{
static REL::Relocation<TES**> singleton{ ID::TES::Singleton };
return *singleton;
}
void ForEachReference(std::function<BSContainer::ForEachResult(TESObjectREFR* a_ref)> a_callback);
void ForEachReferenceInRange(const NiPoint3& a_origin, const float a_radius, std::function<BSContainer::ForEachResult(TESObjectREFR* a_ref)> a_callback);
void ForEachReferenceInRange(const TESObjectREFR* a_ref, const float a_radius, std::function<BSContainer::ForEachResult(TESObjectREFR* a_ref)> a_callback);
// members
GridDistantArray* gridDistant; // 010
GridCellArray* gridCells; // 018
NiNode* objRoot; // 020
NiNode* lodLandRoot; // 028
NiNode* objLODWaterRoot; // 030
NiDirectionalLight* objLight; // 038
NiFogProperty* objFog; // 040
std::int32_t currentGridX; // 044
std::int32_t currentGridY; // 048
std::int32_t currentQueuedX; // 04C
std::int32_t currentQueuedY; // 050
TESObjectCELL* interiorCell; // 058
TESObjectCELL** interiorBuffer; // 060
TESObjectCELL** exteriorBuffer; // 068
std::uint32_t tempInteriorBufferSize; // 070
std::uint32_t tempExteriorBufferSize; // 074
std::int32_t saveGridX; // 078
std::int32_t saveGridY; // 07C
TACCallbackFunc_t* tacCallbackFunc; // 080
void* tacCallbackData; // 088
TESRegion* tacRegionFilter; // 090
Sky* sky; // 098
BSSimpleList<NiPointer<ImageSpaceModifierInstance>> activeImageSpaceModifiers; // 0A0
std::uint32_t totalToLoad; // 0B0
std::uint32_t loaded; // 0B4
std::uint64_t cellCaptureStartTime; // 0B8
bool disablePercentageUpdate; // 0C0
bool showLANDborders; // 0C1
bool fadeWhenLoading; // 0C2
bool forceUpdateMultiBoundExterior; // 0C3
bool collisionBoxes; // 0C4
bool runningCellTests; // 0C5
bool runningCellTests2; // 0C6
bool runningGraphicsTests; // 0C7
bool runningCellListGraphicsTests; // 0C8
bool runningSubmergedObjectTest; // 0C9
bool allowUnusedPurge; // 0CA
float cellDeltaX; // 0D0
float cellDeltaY; // 0D4
TESWorldSpace* worldSpace; // 0D8
BSTArray<BSTTuple<TESActorBase*, std::uint16_t>> deadCount; // 0E0
NiPointer<QueuedFile> preloadedAddonNodes; // 0F8
NiPointer<NiTexture> bloodDecalPreload1; // 100
NiPointer<QueuedFile> preloadedForms; // 108
NiPointer<QueuedFile> preloadedDefaultModels; // 110
ParticleObjectCache* particleCacheHead; // 118
std::uint32_t placeableWaterCount; // 120
NavMeshInfoMap* navMeshInfoMap; // 128
NiPointer<LoadedAreaBound> loadedAreaBound; // 130
};
static_assert(sizeof(TES) == 0x138);
}
@@ -0,0 +1,21 @@
#pragma once
#include "RE/A/AIDATA_GAME.h"
#include "RE/B/BaseFormComponent.h"
#include "RE/P/PackageList.h"
namespace RE
{
class __declspec(novtable) TESAIForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESAIForm };
static constexpr auto VTABLE{ VTABLE::TESAIForm };
// members
AIDATA_GAME aiData; // 08
PackageList aiPackList; // 18
};
static_assert(sizeof(TESAIForm) == 0x28);
}
@@ -0,0 +1,23 @@
#pragma once
#include "RE/B/BSTEvent.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class TESActivateEvent
{
public:
[[nodiscard]] static BSTEventSource<TESActivateEvent>* GetEventSource()
{
using func_t = decltype(&TESActivateEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESActivateEvent::GetEventSource };
return func();
}
// members
NiPointer<TESObjectREFR> objectActivated; // 00
NiPointer<TESObjectREFR> actionRef; // 08
};
static_assert(sizeof(TESActivateEvent) == 0x10);
}
@@ -0,0 +1,46 @@
#pragma once
#include "RE/A/ActorValueOwner.h"
#include "RE/B/BGSAttackDataForm.h"
#include "RE/B/BGSDestructibleObjectForm.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSPerkRankArray.h"
#include "RE/B/BGSPropertySheet.h"
#include "RE/B/BGSSkinForm.h"
#include "RE/T/TESAIForm.h"
#include "RE/T/TESActorBaseData.h"
#include "RE/T/TESBoundAnimObject.h"
#include "RE/T/TESContainer.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESSpellList.h"
namespace RE
{
class __declspec(novtable) TESActorBase :
public TESBoundAnimObject, // 000
public TESActorBaseData, // 068
public TESContainer, // 0D0
public TESSpellList, // 0E8
public TESAIForm, // 0F8
public TESFullName, // 120
public ActorValueOwner, // 130
public BGSDestructibleObjectForm, // 138
public BGSSkinForm, // 148
public BGSKeywordForm, // 158
public BGSAttackDataForm, // 178
public BGSPerkRankArray, // 188
public BGSPropertySheet // 1A0
{
public:
static constexpr auto RTTI{ RTTI::TESActorBase };
static constexpr auto VTABLE{ VTABLE::TESActorBase };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kNONE };
// add
virtual bool GetHasPLSpecTex() const { return false; } // 67
virtual TESCombatStyle* GetCombatStyle() { return nullptr; } // 68
virtual void SetCombatStyle(TESCombatStyle*) { return; } // 69
virtual TESForm* GetAsForm() { return nullptr; } // 6A
};
static_assert(sizeof(TESActorBase) == 0x1B0);
}
@@ -0,0 +1,68 @@
#pragma once
#include "RE/A/ACTOR_BASE_DATA.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BaseFormComponent.h"
#include "RE/F/FACTION_RANK.h"
namespace RE
{
class __declspec(novtable) TESActorBaseData :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESActorBaseData };
static constexpr auto VTABLE{ VTABLE::TESActorBaseData };
enum class ALIGNMENT : std::uint32_t
{
kGood = 0x0,
kNeutral = 0x1,
kEvil = 0x2,
kVeryGood = 0x3,
kVeryEvil = 0x4
};
// add
virtual void CopyFromTemplateForms([[maybe_unused]] TESActorBase** a_forceTemplates) { return; } // 07
virtual bool GetIsGhost() const; // 08
virtual bool GetInvulnerable() const; // 09
[[nodiscard]] constexpr bool AffectsStealthMeter() const noexcept { return actorData.actorBaseFlags.none(ACTOR_BASE_DATA::Flag::kDoesntAffectStealthMeter); }
[[nodiscard]] constexpr bool Bleeds() const noexcept { return actorData.actorBaseFlags.none(ACTOR_BASE_DATA::Flag::kDoesntBleed); }
[[nodiscard]] constexpr bool IsEssential() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kEssential); }
[[nodiscard]] constexpr bool IsFemale() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kFemale); }
[[nodiscard]] inline bool IsGhost() const { return GetIsGhost(); }
[[nodiscard]] constexpr bool IsPreset() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kIsChargenFacePreset); }
[[nodiscard]] constexpr bool IsProtected() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kProtected); }
[[nodiscard]] constexpr bool IsSimpleActor() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kSimpleActor); }
[[nodiscard]] constexpr bool IsSummonable() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kSummonable); }
[[nodiscard]] constexpr bool IsUnique() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kUnique); }
[[nodiscard]] inline bool IsInvulnerable() const { return GetInvulnerable(); }
[[nodiscard]] constexpr bool HasAutoCalcStats() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kAutoCalcStats); }
[[nodiscard]] constexpr bool HasBleedoutOverride() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kBleedoutOverride); }
[[nodiscard]] constexpr bool HasPCLevelMult() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kPCLevelMult); }
[[nodiscard]] constexpr bool Respawns() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kRespawn); }
[[nodiscard]] constexpr bool UsesOppositeGenderAnims() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kOppositeGenderanims); }
[[nodiscard]] constexpr bool UsesTemplate() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kUsesTemplate); }
std::uint16_t GetLevel() const
{
using func_t = decltype(&TESActorBaseData::GetLevel);
static REL::Relocation<func_t> func{ ID::TESActorBaseData::GetLevel };
return func(this);
}
// members
ACTOR_BASE_DATA actorData; // 08
std::int32_t changeFlags; // 1C
TESLevItem* deathItem; // 20
BGSVoiceType* voiceType; // 28
TESForm* baseTemplateForm; // 30
TESForm** templateForms; // 38
TESGlobal* legendChance; // 40
TESForm* legendTemplate; // 48
BSTArray<FACTION_RANK> factions; // 50
};
static_assert(sizeof(TESActorBaseData) == 0x68);
}
@@ -0,0 +1,51 @@
#pragma once
#include "RE/A/AMMO_DATA.h"
#include "RE/B/BGSDestructibleObjectForm.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BGSMessageIcon.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BGSPickupPutdownSounds.h"
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESDescription.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESIcon.h"
#include "RE/T/TESModel.h"
#include "RE/T/TESValueForm.h"
#include "RE/T/TESWeightForm.h"
namespace RE
{
class __declspec(novtable) TESAmmo :
public TESBoundObject, // 000
public TESFullName, // 068
public BGSModelMaterialSwap, // 078
public TESIcon, // 0B8
public BGSMessageIcon, // 0C8
public TESValueForm, // 0E0
public BGSDestructibleObjectForm, // 0F0
public BGSPickupPutdownSounds, // 100
public TESDescription, // 118
public BGSKeywordForm, // 130
public TESWeightForm // 150
{
public:
static constexpr auto RTTI{ RTTI::TESAmmo };
static constexpr auto VTABLE{ VTABLE::TESAmmo };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kAMMO };
[[nodiscard]] static bool GetReloadsWithAmmoRef(const TESAmmo* a_ammo)
{
using func_t = decltype(&TESAmmo::GetReloadsWithAmmoRef);
static REL::Relocation<func_t> func{ ID::TESAmmo::GetReloadsWithAmmoRef };
return func(a_ammo);
}
// members
AMMO_DATA data; // 160
BGSLocalizedString shortDesc; // 178
TESModel shellCasing; // 180
};
static_assert(sizeof(TESAmmo) == 0x1B0);
}
@@ -0,0 +1,71 @@
#pragma once
#include "RE/B/BSIntrusiveRefCounted.h"
namespace RE
{
namespace TESAudio
{
enum class CategoryDuckingType : std::int32_t
{
kHolotapeProgram = 0x0,
kHolotapeScene = 0x1,
kDialogueMenu = 0x2,
kSemiDialogue = 0x3,
kDialogueCamera = 0x4,
kInterestingNonDialogue = 0x5,
kHighlightNearby = 0x6
};
class __declspec(novtable) alignas(0x08) RepeaterData :
public BSIntrusiveRefCounted // 00
{
public:
// members
BSSoundHandle currSound; // 04
const TESSound* soundBase; // 10
float countdown; // 18
};
static_assert(sizeof(RepeaterData) == 0x20);
class __declspec(novtable) ScriptedMusicState :
public BSTEventSink<TESLoadGameEvent>, // 00
public BSTSingletonSDM<ScriptedMusicState> // 08
{
public:
[[nodiscard]] static ScriptedMusicState* GetSingleton()
{
static REL::Relocation<ScriptedMusicState**> singleton{ ID::TESAudio::ScriptedMusicState::Singleton };
return *singleton;
}
void Remove(BGSMusicType* a_toRemove)
{
using func_t = decltype(&ScriptedMusicState::Remove);
static REL::Relocation<func_t> func{ ID::TESAudio::ScriptedMusicState::Remove };
return func(this, a_toRemove);
}
// members
BSTSmallArray<BGSMusicType*, 2> currentTypes;
};
static_assert(sizeof(ScriptedMusicState) == 0x30);
class __declspec(novtable) SnapTransitionData
{
public:
// members
float transitionQuantum; // 00
float desiredMult; // 04
};
class __declspec(novtable) alignas(0x08) SnapshotEntry
{
public:
// members
const BGSSoundCategorySnapshot* snapForm; // 00
float transitionSecs; // 08
};
static_assert(sizeof(SnapshotEntry) == 0x10);
}
}
@@ -0,0 +1,25 @@
#pragma once
#include "RE/B/BGSMessageIcon.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BaseFormComponent.h"
#include "RE/T/TESIcon.h"
#include "RE/T/TESModelRDT.h"
namespace RE
{
class __declspec(novtable) TESBipedModelForm :
public BaseFormComponent // 000
{
public:
static constexpr auto RTTI{ RTTI::TESBipedModelForm };
static constexpr auto VTABLE{ VTABLE::TESBipedModelForm };
// members
BGSModelMaterialSwap worldModel[2]; // 008
TESIcon inventoryIcon[2]; // 088
BGSMessageIcon messageIcon[2]; // 0A8
TESModelRDT constraintTemplate; // 0D8
};
static_assert(sizeof(TESBipedModelForm) == 0x108);
}
@@ -0,0 +1,16 @@
#pragma once
#include "RE/T/TESBoundObject.h"
namespace RE
{
class __declspec(novtable) TESBoundAnimObject :
public TESBoundObject // 00
{
public:
static constexpr auto RTTI{ RTTI::TESBoundAnimObject };
static constexpr auto VTABLE{ VTABLE::TESBoundAnimObject };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kNONE };
};
static_assert(sizeof(TESBoundAnimObject) == 0x68);
}
@@ -0,0 +1,68 @@
#pragma once
#include "RE/B/BGSMod.h"
#include "RE/B/BGSPreviewTransform.h"
#include "RE/B/BGSSoundTagComponent.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTSmartPointer.h"
#include "RE/N/NiNPShortPoint3.h"
#include "RE/N/NiPointer.h"
#include "RE/T/TBO_InstanceData.h"
#include "RE/T/TESObject.h"
namespace RE
{
enum class COMMAND_REFUSAL_TYPE;
class BGSObjectInstanceExtra;
class __declspec(novtable) TESBoundObject :
public TESObject // 00
{
public:
static constexpr auto RTTI{ RTTI::TESBoundObject };
static constexpr auto VTABLE{ VTABLE::TESBoundObject };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kNONE };
class BOUND_DATA
{
public:
// members
NiNPShortPoint3 boundMin; // 00
NiNPShortPoint3 boundMax; // 06
};
static_assert(sizeof(BOUND_DATA) == 0xC);
// add
virtual TBO_InstanceData* CreateInstanceData(const TBO_InstanceData*) const { return nullptr; } // 56
virtual const TBO_InstanceData* GetBaseInstanceData() const { return nullptr; } // 57
virtual bool GetAttachedMarkersVisible(NiAVObject*) const { return false; } // 58
virtual void SetAttachedMarkersVisible(NiAVObject*, bool) const { return; } // 59
virtual bool QSupportsCountPerInstance() const { return false; } // 5A
virtual void SetObjectVoiceType(BGSVoiceType*) { return; } // 5B
virtual BGSVoiceType* GetObjectVoiceType() const { return nullptr; } // 5C
virtual BGSSoundDescriptorForm* GetSoundForTag(const BSFixedString& a_tag) const; // 5D
virtual void Clone3D(TESObjectREFR* a_requester, NiPointer<NiAVObject>& a_obj3D) { TESObject::Clone3D(a_requester, a_obj3D, false); } // 5E
virtual bool ReplaceModel(const char* a_filename); // 5F
virtual bool GetActivateText(TESObjectREFR* a_itemActivated, BSString& a_resultString); // 60
virtual COMMAND_REFUSAL_TYPE CalculateDoFavor(Actor* a_actor, bool a_owned, TESObjectREFR*, float a_moralityMult) const; // 61
virtual void HandleRemoveItemFromContainer(TESObjectREFR*) { return; } // 62
virtual void OnRemove3D(NiAVObject*) { return; } // 63
virtual void OnCheckModels() { return; } // 64
virtual void OnCopyReference() { return; } // 65
virtual void OnFinishScale() { return; } // 66
void ApplyMods(BSTSmartPointer<TBO_InstanceData>& a_dest, const BGSObjectInstanceExtra* a_extra) const
{
using func_t = decltype(&TESBoundObject::ApplyMods);
static REL::Relocation<func_t> func{ ID::TESBoundObject::ApplyMods };
return func(this, a_dest, a_extra);
}
// members
BOUND_DATA boundData; // 20
BGSMod::Template::Items objectTemplate; // 30
BGSPreviewTransform previewTransform; // 50
BGSSoundTagComponent soundTagComponent; // 60
};
static_assert(sizeof(TESBoundObject) == 0x68);
}
@@ -0,0 +1,34 @@
#pragma once
#include "RE/B/BSTPoint.h"
#include "RE/B/BSTSmartPointer.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class NiNode;
class TESCameraState;
class __declspec(novtable) TESCamera
{
public:
static constexpr auto RTTI{ RTTI::TESCamera };
static constexpr auto VTABLE{ VTABLE::TESCamera };
virtual ~TESCamera(); // 00
// add
virtual void SetCameraRoot(NiNode* a_cameraRoot); // 01
virtual void SetEnabled(bool a_enabled) { enabled = a_enabled; } // 02
virtual void Update(); // 03
// members
BSTPoint2<float> rotationInput; // 08
BSTPoint3<float> translationInput; // 10
float zoomInput; // 1C
NiPointer<NiNode> cameraRoot; // 20
BSTSmartPointer<TESCameraState> currentState; // 28
bool enabled; // 30
};
static_assert(sizeof(TESCamera) == 0x38);
}
@@ -0,0 +1,41 @@
#pragma once
#include "RE/B/BSInputEventUser.h"
#include "RE/B/BSIntrusiveRefCounted.h"
#include "RE/B/BSTSmartPointer.h"
#include "RE/C/CameraStates.h"
#include "RE/N/NiQuaternion.h"
namespace RE
{
class BGSLoadFormBuffer;
class BGSSaveFormBuffer;
class NiPoint3;
class TESCamera;
class __declspec(novtable) TESCameraState :
public BSIntrusiveRefCounted, // 10
public BSInputEventUser // 00
{
public:
static constexpr auto RTTI{ RTTI::TESCameraState };
static constexpr auto VTABLE{ VTABLE::TESCameraState };
virtual ~TESCameraState(); // 00
// add
virtual void Begin() { return; } // 09
virtual void End() { return; } // 0A
virtual void Update(BSTSmartPointer<TESCameraState>& a_nextState); // 0B
virtual void GetRotation(NiQuaternion& a_rotation) const; // 0C
virtual void GetTranslation(NiPoint3& a_translation) const; // 0D
virtual void SaveGame([[maybe_unused]] BGSSaveFormBuffer* a_saveGameBuffer) { return; } // 0E
virtual void LoadGame([[maybe_unused]] BGSLoadFormBuffer* a_loadGameBuffer) { return; } // 0F
virtual void Revert([[maybe_unused]] BGSLoadFormBuffer* a_loadGameBuffer) { return; } // 10
// members
TESCamera* camera; // 18
REX::TEnum<CameraState, std::uint32_t> id; // 20
};
static_assert(sizeof(TESCameraState) == 0x28);
}
@@ -0,0 +1,23 @@
#pragma once
#include "RE/B/BSTEvent.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class TESCellAttachDetachEvent
{
public:
[[nodiscard]] static BSTEventSource<TESCellAttachDetachEvent>* GetEventSource()
{
using func_t = decltype(&TESCellAttachDetachEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESCellAttachDetachEvent::GetEventSource };
return func();
}
// members
NiPointer<TESObjectREFR> refr;
bool isAttaching;
};
static_assert(sizeof(TESCellAttachDetachEvent) == 0x10);
}
@@ -0,0 +1,21 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class TESCellFullyLoadedEvent
{
public:
[[nodiscard]] static BSTEventSource<TESCellFullyLoadedEvent>* GetEventSource()
{
using func_t = decltype(&TESCellFullyLoadedEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESCellFullyLoadedEvent::GetEventSource };
return func();
}
// members
TESObjectCELL* cell;
};
static_assert(sizeof(TESCellFullyLoadedEvent) == 0x8);
}
@@ -0,0 +1,17 @@
#pragma once
namespace RE
{
class __declspec(novtable) TESChildCell
{
public:
static constexpr auto RTTI{ RTTI::TESChildCell };
static constexpr auto VTABLE{ VTABLE::TESChildCell };
virtual ~TESChildCell() = default; // 00
// add
virtual TESObjectCELL* GetSaveParentCell() const = 0; // 01
};
static_assert(sizeof(TESChildCell) == 0x8);
}
@@ -0,0 +1,28 @@
#pragma once
#include "RE/B/BGSPropertySheet.h"
#include "RE/C/CLASS_DATA.h"
#include "RE/T/TESDescription.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESTexture.h"
namespace RE
{
class __declspec(novtable) TESClass :
public TESForm, // 00
public TESFullName, // 20
public TESDescription, // 30
public TESTexture, // 48
public BGSPropertySheet // 58
{
public:
static constexpr auto RTTI{ RTTI::TESClass };
static constexpr auto VTABLE{ VTABLE::TESClass };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kCLAS };
// members
CLASS_DATA data; // 68
};
static_assert(sizeof(TESClass) == 0x70);
}
@@ -0,0 +1,48 @@
#pragma once
#include "RE/T/TESForm.h"
#include "RE/T/TESModel.h"
#include "RE/T/TESTexture.h"
#include "RE/T/TESWeatherList.h"
namespace RE
{
class __declspec(novtable) TESClimate :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::TESClimate };
static constexpr auto VTABLE{ VTABLE::TESClimate };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kCLMT };
enum class MiscData
{
kVolatility = 0x4,
kMoonData = 0x5,
kNumSliders = 0x6
};
enum class TextureType
{
kSun = 0x0,
kGlare = 0x1,
kCount = 0x2
};
enum class TransTime
{
kSunriseBegin = 0x0,
kSunriseEnd = 0x1,
kSunsetBegin = 0x2,
kSunsetEnd = 0x3,
kCount = 0x4
};
// members
TESModel nightSky; // 20
TESWeatherList weatherList; // 50
TESTexture skyObjects[2]; // 60
std::int8_t data[6]; // 80
};
static_assert(sizeof(TESClimate) == 0x88);
}
@@ -0,0 +1,42 @@
#pragma once
#include "RE/C/CombatStyleCloseRangeData.h"
#include "RE/C/CombatStyleCoverData.h"
#include "RE/C/CombatStyleFlightData.h"
#include "RE/C/CombatStyleGeneralData.h"
#include "RE/C/CombatStyleLongRangeData.h"
#include "RE/C/CombatStyleMeleeData.h"
#include "RE/C/CombatStyleRangedData.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) TESCombatStyle :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::TESCombatStyle };
static constexpr auto VTABLE{ VTABLE::TESCombatStyle };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kCSTY };
enum class FLAG : std::uint32_t
{
kDuelingStyle = 0x1,
kFlankingStyle = 0x2,
kAllowDualWeilding = 0x4,
kChargingStyle = 0x8,
kAllowMeleeRetarget = 0x10
};
// members
CombatStyleGeneralData generalData; // 20
CombatStyleMeleeData meleeData; // 50
CombatStyleRangedData rangedData; // 78
CombatStyleCloseRangeData closeRangeData; // 7C
CombatStyleLongRangeData longRangeData; // A8
CombatStyleCoverData coverData; // BC
CombatStyleFlightData flightData; // C0
FLAG flags; // E0
};
static_assert(sizeof(TESCombatStyle) == 0xE8);
}
@@ -0,0 +1,44 @@
#pragma once
namespace RE
{
enum class SCRIPT_OUTPUT;
class ConditionCheckParams;
class TESConditionItem;
class TESCondition
{
public:
[[nodiscard]] explicit operator bool() const noexcept { return head != nullptr; }
[[nodiscard]] bool operator()(TESObjectREFR* a_actionRef, TESObjectREFR* a_targetRef) const
{
return IsTrue(a_actionRef, a_targetRef);
}
[[nodiscard]] bool IsTrue(TESObjectREFR* a_actionRef, TESObjectREFR* a_targetRef) const
{
using func_t = decltype(&TESCondition::IsTrue);
static REL::Relocation<func_t> func{ ID::TESCondition::IsTrue };
return func(this, a_actionRef, a_targetRef);
}
[[nodiscard]] bool IsTrueForAllButFunction(ConditionCheckParams& a_paramData, SCRIPT_OUTPUT a_function) const
{
using func_t = decltype(&TESCondition::IsTrueForAllButFunction);
static REL::Relocation<func_t> func{ ID::TESCondition::IsTrueForAllButFunction };
return func(this, a_paramData, a_function);
}
void ClearAllConditionItems() const
{
using func_t = decltype(&TESCondition::ClearAllConditionItems);
static REL::Relocation<func_t> func{ ID::TESCondition::ClearAllConditionItems };
return func(this);
}
// members
TESConditionItem* head; // 0
};
static_assert(sizeof(TESCondition) == 0x8);
}
@@ -0,0 +1,37 @@
#pragma once
#include "RE/C/CONDITION_ITEM_DATA.h"
#include "RE/C/ConditionCheckParams.h"
namespace RE
{
class TESConditionItem
{
public:
[[nodiscard]] float GetComparisonValue()
{
using func_t = decltype(&TESConditionItem::GetComparisonValue);
static REL::Relocation<func_t> func{ ID::TESConditionItem::GetComparisonValue };
return func(this);
}
[[nodiscard]] bool IsTrue(TESObjectREFR* a_actionRef, TESObjectREFR* a_targetRef)
{
using func_t = bool (*)(TESConditionItem*, TESObjectREFR*, TESObjectREFR*);
static REL::Relocation<func_t> func{ ID::TESConditionItem::IsTrue1 };
return func(this, a_actionRef, a_targetRef);
}
[[nodiscard]] bool IsTrue(ConditionCheckParams& a_params)
{
using func_t = bool (*)(TESConditionItem*, ConditionCheckParams&);
static REL::Relocation<func_t> func{ ID::TESConditionItem::IsTrue2 };
return func(this, a_params);
}
// members
TESConditionItem* next; // 00
CONDITION_ITEM_DATA data; // 08
};
static_assert(sizeof(TESConditionItem) == 0x38);
}
@@ -0,0 +1,87 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
#include "RE/C/ContainerObject.h"
namespace RE
{
class __declspec(novtable) TESContainer :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESContainer };
static constexpr auto VTABLE{ VTABLE::TESContainer };
void CopyObjectList(const std::vector<ContainerObject*>& a_copiedData)
{
const auto oldData = containerObjects;
const auto newSize = a_copiedData.size();
const auto newData = calloc<ContainerObject*>(newSize);
std::ranges::copy(a_copiedData, newData);
numContainerObjects = static_cast<std::uint32_t>(newSize);
containerObjects = newData;
free(oldData);
}
void ForEachContainerObject(std::function<bool(ContainerObject&)> a_fn) const
{
for (std::uint32_t i = 0; i < numContainerObjects; ++i) {
auto entry = containerObjects[i];
if (entry) {
if (!a_fn(*entry)) {
break;
}
}
}
}
bool AddObject(TESBoundObject* a_object, std::int32_t a_count, TESForm* a_owner)
{
bool added = false;
for (std::uint32_t i = 0; i < numContainerObjects; ++i) {
if (const auto entry = containerObjects[i]; entry && entry->obj == a_object) {
entry->count += a_count;
added = true;
break;
}
}
if (!added) {
std::vector<ContainerObject*> copiedData{ containerObjects, containerObjects + numContainerObjects };
const auto newObj = new ContainerObject(a_object, a_count, a_owner);
copiedData.push_back(newObj);
CopyObjectList(copiedData);
return true;
}
return added;
}
bool AddObjectsToContainer(std::map<TESBoundObject*, std::int32_t>& a_objects, TESForm* a_owner)
{
for (std::uint32_t i = 0; i < numContainerObjects; ++i) {
if (const auto entry = containerObjects[i]; entry && entry->obj) {
if (auto it = a_objects.find(entry->obj); it != a_objects.end()) {
entry->count += it->second;
a_objects.erase(it);
}
}
}
if (!a_objects.empty()) {
std::vector<ContainerObject*> copiedData{ containerObjects, containerObjects + numContainerObjects };
for (auto& [object, count] : a_objects) {
const auto newObj = new ContainerObject(object, count, a_owner);
copiedData.push_back(newObj);
}
CopyObjectList(copiedData);
}
return true;
}
// members
ContainerObject** containerObjects; // 08
std::uint32_t numContainerObjects; // 10
};
static_assert(sizeof(TESContainer) == 0x18);
}
@@ -0,0 +1,26 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class TESContainerChangedEvent
{
public:
[[nodiscard]] static BSTEventSource<TESContainerChangedEvent>* GetEventSource()
{
using func_t = decltype(&TESContainerChangedEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESContainerChangedEvent::GetEventSource };
return func();
}
// members
std::uint32_t oldContainerFormID; // 00
std::uint32_t newContainerFormID; // 04
std::uint32_t baseObjectFormID; // 08
std::int32_t itemCount; // 0C
std::uint32_t referenceFormID; // 10
std::uint16_t uniqueID; // 14
};
static_assert(sizeof(TESContainerChangedEvent) == 0x18);
}
@@ -0,0 +1,200 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSSimpleList.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTEvent.h"
#include "RE/B/BSTSingleton.h"
#include "RE/E/ENUM_FORM_ID.h"
#include "RE/N/NiTArray.h"
#include "RE/N/NiTList.h"
#include "RE/T/TESFileCollection.h"
#include "RE/T/TESForm.h"
namespace RE
{
class BGSHotloadCompletedEvent;
class NEW_REFR_DATA;
class TESFile;
class TESObjectList;
class TESRegionDataManager;
class TESRegionList;
class TESDataHandler :
public BSTEventSource<BGSHotloadCompletedEvent>, // 0000
public BSTSingletonSDM<TESDataHandler> // 0058
{
public:
[[nodiscard]] static TESDataHandler* GetSingleton()
{
static REL::Relocation<TESDataHandler**> singleton{ ID::TESDataHandler::Singleton };
return *singleton;
}
[[nodiscard]] bool AddFormToDataHandler(TESForm* a_form)
{
using func_t = decltype(&TESDataHandler::AddFormToDataHandler);
static REL::Relocation<func_t> func{ ID::TESDataHandler::AddFormToDataHandler };
return func(this, a_form);
}
[[nodiscard]] bool CheckModsLoaded(bool a_everModded)
{
using func_t = decltype(&TESDataHandler::CheckModsLoaded);
static REL::Relocation<func_t> func{ ID::TESDataHandler::CheckModsLoaded };
return func(this, a_everModded);
}
[[nodiscard]] ObjectRefHandle CreateReferenceAtLocation(NEW_REFR_DATA& a_data)
{
using func_t = decltype(&TESDataHandler::CreateReferenceAtLocation);
static REL::Relocation<func_t> func{ ID::TESDataHandler::CreateReferenceAtLocation };
return func(this, a_data);
}
template <class T>
[[nodiscard]] BSTArray<T*>& GetFormArray() noexcept //
requires(std::derived_from<T, TESForm> &&
!std::is_pointer_v<T> &&
!std::is_reference_v<T>)
{
assert(T::FORM_ID < ENUM_FORM_ID::kTotal);
return reinterpret_cast<BSTArray<T*>&>(formArrays[std::to_underlying(T::FORM_ID)]);
}
TESFormID LookupFormID(TESFormID a_rawFormID, std::string_view a_modName)
{
auto file = LookupModByName(a_modName);
if (!file || file->compileIndex == 0xFF) {
return 0;
}
TESFormID formID = file->compileIndex << 24;
formID += file->smallFileCompileIndex << 12;
formID += a_rawFormID;
return formID;
}
TESForm* LookupForm(TESFormID a_rawFormID, std::string_view a_modName)
{
auto formID = LookupFormID(a_rawFormID, a_modName);
return formID != 0 ? TESForm::GetFormByID(formID) : nullptr;
}
template <class T>
T* LookupForm(TESFormID a_rawFormID, std::string_view a_modName)
{
auto form = LookupForm(a_rawFormID, a_modName);
if (!form) {
return nullptr;
}
return form->Is(T::FORM_ID) ? form->As<T>() : nullptr;
}
const TESFile* LookupModByName(std::string_view a_modName)
{
for (auto& file : files) {
if (a_modName.size() == strlen(file->filename) &&
_strnicmp(file->filename, a_modName.data(), a_modName.size()) == 0) {
return file;
}
}
return nullptr;
}
std::optional<std::uint8_t> GetModIndex(std::string_view a_modName)
{
auto mod = LookupModByName(a_modName);
return mod ? std::make_optional(mod->compileIndex) : std::nullopt;
}
const TESFile* LookupLoadedModByName(std::string_view a_modName)
{
for (auto& file : compiledFileCollection.files) {
if (a_modName.size() == strlen(file->filename) &&
_strnicmp(file->filename, a_modName.data(), a_modName.size()) == 0) {
return file;
}
}
return nullptr;
}
const TESFile* LookupLoadedModByIndex(std::uint8_t a_index)
{
for (auto& file : compiledFileCollection.files) {
if (file->compileIndex == a_index) {
return file;
}
}
return nullptr;
}
std::optional<std::uint8_t> GetLoadedModIndex(std::string_view a_modName)
{
auto mod = LookupLoadedModByName(a_modName);
return mod ? std::make_optional(mod->compileIndex) : std::nullopt;
}
const TESFile* LookupLoadedLightModByName(std::string_view a_modName)
{
for (auto& smallFile : compiledFileCollection.smallFiles) {
if (a_modName.size() == strlen(smallFile->filename) &&
_strnicmp(smallFile->filename, a_modName.data(), a_modName.size()) == 0) {
return smallFile;
}
}
return nullptr;
}
const TESFile* LookupLoadedLightModByIndex(std::uint16_t a_index)
{
for (auto& smallFile : compiledFileCollection.smallFiles) {
if (smallFile->smallFileCompileIndex == a_index) {
return smallFile;
}
}
return nullptr;
}
std::optional<std::uint16_t> GetLoadedLightModIndex(std::string_view a_modName)
{
auto mod = LookupLoadedLightModByName(a_modName);
return mod ? std::make_optional(mod->smallFileCompileIndex) : std::nullopt;
}
bool IsFormIDInuse(TESFormID a_formID)
{
using func_t = decltype(&TESDataHandler::IsFormIDInuse);
static REL::Relocation<func_t> func{ ID::TESDataHandler::IsFormIDInuse };
return func(this, a_formID);
}
// members
TESObjectList* objectList; // 0060
BSTArray<TESForm*> formArrays[std::to_underlying(ENUM_FORM_ID::kTotal)]; // 0068
TESRegionList* regionList; // 0F50
NiTPrimitiveArray<TESObjectCELL*> interiorCells; // 0F58
NiTPrimitiveArray<BGSAddonNode*> addonNodes; // 0F70
NiTList<TESForm*> badForms; // 0F88
std::uint32_t nextID; // 0FA0
TESFile* activeFile; // 0FA8
BSSimpleList<TESFile*> files; // 0FB0
TESFileCollection compiledFileCollection; // 0FC0
BSTArray<std::uint32_t> releasedFormIDArray; // 0FF0
bool masterSave; // 1008
bool blockSave; // 1009
bool saveLoadGame; // 100A
bool autoSaving; // 100B
bool exportingPlugin; // 100C
bool clearingData; // 100D
bool hasDesiredFiles; // 100E
bool checkingModels; // 100F
bool loadingFiles; // 1010
bool dontRemoveIDs; // 1011
char gameSettingsLoadState; // 1012
TESRegionDataManager* regionDataManager; // 1018
};
static_assert(sizeof(TESDataHandler) == 0x1020);
}
@@ -0,0 +1,24 @@
#pragma once
#include "RE/B/BSTEvent.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class TESDeathEvent
{
public:
[[nodiscard]] static BSTEventSource<TESDeathEvent>* GetEventSource()
{
using func_t = decltype(&TESDeathEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESDeathEvent::GetEventSource };
return func();
}
// members
NiPointer<TESObjectREFR> actorDying; // 00
NiPointer<TESObjectREFR> actorKiller; // 08
bool dead; // 10
};
static_assert(sizeof(TESDeathEvent) == 0x18);
}
@@ -0,0 +1,39 @@
#pragma once
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BSStringT.h"
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) TESDescription :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESDescription };
static constexpr auto VTABLE{ VTABLE::TESDescription };
// override (BaseFormComponent)
void InitializeDataComponent() override // 02
{
fileOffset = 0;
chunkOffset = 0;
}
void ClearDataComponent() override { return; } // 03
void CopyComponent(BaseFormComponent*) override; // 06
void GetDescription(BSString& a_outString, const TESForm* a_form = nullptr)
{
using func_t = decltype(&TESDescription::GetDescription);
static REL::Relocation<func_t> func{ ID::TESDescription::GetDescription };
return func(this, a_outString, a_form);
}
// members
std::uint32_t fileOffset; // 08
std::uint32_t chunkOffset; // 0C
BGSLocalizedStringDL descriptionText; // 10
};
static_assert(sizeof(TESDescription) == 0x18);
}
@@ -0,0 +1,30 @@
#pragma once
#include "RE/E/EffectShaderData.h"
#include "RE/N/NiPointer.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESModel.h"
#include "RE/T/TESTexture.h"
namespace RE
{
class BSGeometry;
class __declspec(novtable) TESEffectShader :
public TESForm, // 000
public TESModel // 020
{
public:
static constexpr auto RTTI{ RTTI::TESEffectShader };
static constexpr auto VTABLE{ VTABLE::TESEffectShader };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kEFSH };
// members
EffectShaderData data; // 050
TESTexture textureShaderTexture; // 0F8
TESTexture blockOutTexture; // 108
TESTexture paletteTexture; // 118
NiPointer<BSGeometry> shareableGeometry; // 128
};
static_assert(sizeof(TESEffectShader) == 0x130);
}
@@ -0,0 +1,32 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
namespace MagicSystem
{
enum class CastingType;
}
class __declspec(novtable) TESEnchantableForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESEnchantableForm };
static constexpr auto VTABLE{ VTABLE::TESEnchantableForm };
virtual MagicSystem::CastingType GetCastingType() const { return *castingType; } // 07
[[nodiscard]] std::uint16_t GetBaseCharge() const noexcept { return amountOfEnchantment; }
[[nodiscard]] EnchantmentItem* GetBaseEnchanting() const noexcept { return formEnchanting; }
void SetBaseCharge(std::uint16_t a_amount) noexcept { amountOfEnchantment = a_amount; }
void SetBaseEnchanting(EnchantmentItem* a_ench) noexcept { formEnchanting = a_ench; }
// members
EnchantmentItem* formEnchanting; // 08
REX::TEnumSet<MagicSystem::CastingType, std::uint16_t> castingType; // 10
std::uint16_t amountOfEnchantment; // 12
};
static_assert(sizeof(TESEnchantableForm) == 0x18);
}
@@ -0,0 +1,22 @@
#pragma once
#include "RE/B/BSTEvent.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class TESEnterSneakingEvent
{
public:
[[nodiscard]] static BSTEventSource<TESEnterSneakingEvent>* GetEventSource()
{
using func_t = decltype(&TESEnterSneakingEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESEnterSneakingEvent::GetEventSource };
return func();
}
// members
NiPointer<TESObjectREFR> actor; // 00
};
static_assert(sizeof(TESEnterSneakingEvent) == 0x8);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/N/NiPointer.h"
namespace RE
{
class TESEquipEvent
{
public:
// members
NiPointer<TESObjectREFR> actor; // 00
std::uint32_t baseObject; // 08
std::uint32_t originalRefr; // 0C
std::uint16_t uniqueID; // 10
bool equipped; // 12
};
static_assert(sizeof(TESEquipEvent) == 0x18);
}
@@ -0,0 +1,30 @@
#pragma once
#include "RE/T/TESForm.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESTexture.h"
namespace RE
{
class __declspec(novtable) TESEyes :
public TESForm, // 00
public TESFullName, // 20
public TESTexture // 30
{
public:
static constexpr auto RTTI{ RTTI::TESEyes };
static constexpr auto VTABLE{ VTABLE::TESEyes };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kEYES };
enum class Flags : std::int8_t
{
kPlayable = 0x1,
kMale = 0x2,
kFemale = 0x4,
};
// members
std::int8_t flags; // 40
};
static_assert(sizeof(TESEyes) == 0x48);
}
@@ -0,0 +1,39 @@
#pragma once
#include "RE/A/AITimeStamp.h"
#include "RE/B/BSSimpleList.h"
#include "RE/B/BSTHashMap.h"
#include "RE/F/FACTION_CRIME_DATA.h"
#include "RE/F/FACTION_DATA.h"
#include "RE/F/FACTION_VENDOR_DATA.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESReactionForm.h"
namespace RE
{
class RANK_DATA;
class __declspec(novtable) TESFaction :
public TESForm, // 000
public TESFullName, // 020
public TESReactionForm // 030
{
public:
static constexpr auto RTTI{ RTTI::TESFaction };
static constexpr auto VTABLE{ VTABLE::TESFaction };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kFACT };
// members
BSTHashMap<const TESNPC*, std::uint32_t>* crimeGoldMap; // 50
FACTION_DATA data; // 58
FACTION_CRIME_DATA crimeData; // 60
FACTION_VENDOR_DATA vendorData; // A8
BSSimpleList<RANK_DATA*> rankDataList; // E0
std::int32_t majorCrime; // F0
std::int32_t minorCrime; // F4
AITimeStamp resistArrestTimeStamp; // F8
float enemyFlagTimeStamp; // FC
};
static_assert(sizeof(TESFaction) == 0x100);
}
@@ -0,0 +1,166 @@
#pragma once
#include "RE/B/BSFile.h"
#include "RE/B/BSSimpleList.h"
#include "RE/B/BSStringT.h"
#include "RE/B/BSSystemFile.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTHashMap.h"
#include "RE/B/BSTSmartPointer.h"
#include "RE/F/FILE_HEADER.h"
#include "RE/F/FORM.h"
#include "RE/N/NiFile.h"
namespace RE
{
enum class CHUNK_ID;
enum class TES_RETURN_CODE;
class _ULARGE_INTEGER;
class FORM_GROUP;
class TESBitArrayFile;
class TESFile
{
public:
class InteriorCellOffsetDataStruct;
enum class RecordFlag
{
kNone = 0,
kMaster = 1 << 0,
kAltered = 1 << 1,
kChecked = 1 << 2,
kActive = 1 << 3,
kOptimizedFile = 1 << 4,
kTempIDOwner = 1 << 5,
kDelocalized = 1 << 7,
kPrecalcDataOnly = 1 << 8,
kSmallFile = 1 << 9
};
[[nodiscard]] std::uint8_t GetCompileIndex() const noexcept { return compileIndex; }
[[nodiscard]] std::string_view GetFilename() const noexcept { return { filename }; }
[[nodiscard]] std::uint16_t GetSmallFileCompileIndex() const noexcept { return smallFileCompileIndex; }
[[nodiscard]] bool IsActive() const noexcept { return GetCompileIndex() != 0xFF; }
[[nodiscard]] bool IsLight() const noexcept { return flags.all(RecordFlag::kSmallFile); };
[[nodiscard]] bool CloseTES(bool a_forceClose)
{
using func_t = decltype(&TESFile::CloseTES);
static REL::Relocation<func_t> func{ ID::TESFile::CloseTES };
return func(this, a_forceClose);
}
[[nodiscard]] bool GetChunkData(void* a_data, std::uint32_t a_maxSize)
{
using func_t = bool (TESFile::*)(void*, uint32_t);
static REL::Relocation<func_t> func{ ID::TESFile::GetChunkData };
return func(this, a_data, a_maxSize);
}
[[nodiscard]] bool GetChunkData(char* a_data)
{
return GetChunkData(a_data, 0);
}
[[nodiscard]] bool IsFormInMod(TESFormID a_formID) const
{
if (!IsLight() && (a_formID >> 24) == compileIndex) {
return true;
}
if (IsLight() && (a_formID >> 24) == 0xFE && ((a_formID & 0x00FFF000) >> 12) == smallFileCompileIndex) {
return true;
}
return false;
}
[[nodiscard]] std::uint32_t GetTESChunk()
{
using func_t = decltype(&TESFile::GetTESChunk);
static REL::Relocation<func_t> func{ ID::TESFile::GetTESChunk };
return func(this);
}
[[nodiscard]] bool NextChunk()
{
using func_t = decltype(&TESFile::NextChunk);
static REL::Relocation<func_t> func{ ID::TESFile::NextChunk };
return func(this);
}
[[nodiscard]] bool NextForm(bool a_skipIgnored)
{
using func_t = decltype(&TESFile::NextForm);
static REL::Relocation<func_t> func{ ID::TESFile::NextForm };
return func(this, a_skipIgnored);
}
[[nodiscard]] bool NextGroup()
{
using func_t = decltype(&TESFile::NextGroup);
static REL::Relocation<func_t> func{ ID::TESFile::NextGroup };
return func(this);
}
[[nodiscard]] bool OpenTES(char* a_path, const char* a_filename, NiFile::OpenMode a_accessMode, bool a_lock)
{
using func_t = bool (TESFile::*)(char*, const char*, NiFile::OpenMode, bool);
static REL::Relocation<func_t> func{ ID::TESFile::OpenTES };
return func(this, a_path, a_filename, a_accessMode, a_lock);
}
[[nodiscard]] bool OpenTES(NiFile::OpenMode a_accessMode, bool a_lock)
{
return OpenTES(path, filename, a_accessMode, a_lock);
}
// members
REX::TEnumSet<TES_RETURN_CODE, std::int32_t> lastError; // 000
TESFile* threadSafeParent; // 008
BSTHashMap<std::uint32_t, TESFile*> threadSafeFileMap; // 010
BSTSmartPointer<BSFile::PageCache> pageCache; // 040
BSFile* lockedFile; // 048
BSFile* file; // 050
TESBitArrayFile* formUserDataBitArray; // 058
TESBitArrayFile* formVersionBitArray; // 060
TESBitArrayFile* formIDBitArray; // 068
char filename[REX::W32::MAX_PATH]; // 070
char path[REX::W32::MAX_PATH]; // 174
char* buffer; // 278
std::uint32_t bufferAllocSize; // 280
std::uint32_t firstCellOffset; // 284
std::uint32_t currCellOffset; // 288
TESObjectCELL* currCell; // 290
std::uint32_t currRefOffset; // 298
FORM currentform; // 29C
REX::TEnumSet<CHUNK_ID, std::int32_t> currentchunkID; // 2B4
std::uint32_t actualChunkSize; // 2B8
std::uint32_t filesize; // 2BC
std::uint32_t fileoffset; // 2C0
std::uint32_t formoffset; // 2C4
std::uint32_t chunkoffset; // 2C8
FORM saveform; // 2CC
std::uint32_t saveformoffset; // 2E4
std::uint32_t savechunkoffset; // 2E8
BSSimpleList<FORM_GROUP*> groups; // 2F0
bool hasGroups; // 300
BSSystemFile::Info fileInfo; // 308
FILE_HEADER fileHeaderInfo; // 328
REX::TEnumSet<RecordFlag, std::uint32_t> flags; // 334
BSSimpleList<char*> masters; // 338
BSSimpleList<_ULARGE_INTEGER*> mastersData; // 348
std::uint32_t masterCount; // 358
TESFile** masterPtrs; // 360
REX::W32::FILETIME deletedFormTime; // 368
std::uint8_t compileIndex; // 370
std::uint16_t smallFileCompileIndex; // 372
BSString createdBy; // 378
BSString summary; // 388
char* decompressedFormBuffer; // 398
std::uint32_t decompressedFormBufferSize; // 3A0
void* reservedDecompressionBuffer; // 3A8
std::uint32_t reservedDecompressionBufferSize; // 3B0
BSTArray<InteriorCellOffsetDataStruct>* interiorCellOffsetData; // 3B8
};
static_assert(sizeof(TESFile) == 0x3C0);
}
@@ -0,0 +1,15 @@
#pragma once
#include "RE/B/BSTArray.h"
namespace RE
{
class TESFile;
class TESFileArray :
public BSStaticArray<TESFile*> // 00
{
public:
};
static_assert(sizeof(TESFileArray) == 0x10);
}
@@ -0,0 +1,17 @@
#pragma once
#include "RE/B/BSTArray.h"
namespace RE
{
class TESFile;
class TESFileCollection
{
public:
// members
BSTArray<TESFile*> files; // 00
BSTArray<TESFile*> smallFiles; // 18
};
static_assert(sizeof(TESFileCollection) == 0x30);
}
@@ -0,0 +1,14 @@
#pragma once
namespace RE
{
class TESFileArray;
class TESFileContainer
{
public:
// members
const TESFileArray* array; // 0
};
static_assert(sizeof(TESFileContainer) == 0x8);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/T/TESObjectACTI.h"
#include "RE/T/TESProduceForm.h"
namespace RE
{
class __declspec(novtable) TESFlora :
public TESObjectACTI, // 000
public TESProduceForm // 148
{
public:
static constexpr auto RTTI{ RTTI::TESFlora };
static constexpr auto VTABLE{ VTABLE::TESFlora };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kFLOR };
};
static_assert(sizeof(TESFlora) == 0x168);
}
@@ -0,0 +1,376 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSSpinLock.h"
#include "RE/B/BSTHashMap.h"
#include "RE/B/BaseFormComponent.h"
#include "RE/E/ENUM_FORM_ID.h"
#include "RE/F/FORM_ENUM_STRING.h"
#include "RE/T/TESFile.h"
#include "RE/T/TESFileContainer.h"
namespace RE
{
class BGSLoadFormBuffer;
class BGSPreviewTransform;
class BGSSaveFormBuffer;
class BGSSoundTagComponent;
class __declspec(novtable) TESForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESForm };
static constexpr auto VTABLE{ VTABLE::TESForm };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kNONE };
class FormSortFunc
{
public:
std::int32_t operator()(const TESForm* a_arg1, const TESForm* a_arg2)
{
using func_t = decltype(&FormSortFunc::operator());
static REL::Relocation<func_t> func{ ID::TESForm::FormSortFunc };
return func(this, a_arg1, a_arg2);
}
};
static_assert(std::is_empty_v<FormSortFunc>);
// override (BaseFormComponent)
void InitializeDataComponent() override { return; } // 02
void ClearDataComponent() override { SetFormEditorID(""); } // 03
void CopyComponent(BaseFormComponent*) override { return; } // 06
// add
virtual void InitializeData() { return; } // 07
virtual void ClearData() { return; } // 08
virtual bool Load([[maybe_unused]] TESFile* a_file) { return true; } // 09
virtual bool LoadPartial([[maybe_unused]] TESFile* a_file) { return true; } // 0A
virtual bool LoadEdit(TESFile* a_file) { return Load(a_file); } // 0B
virtual TESForm* CreateDuplicateForm(bool a_createEditorID, BSTHashMap<TESForm*, TESForm*>* a_copyMap); // 0C
virtual bool AddChange(std::uint32_t a_changeFlags); // 0D
virtual void RemoveChange(std::uint32_t a_changeFlags); // 0E
virtual bool FindInFileFast([[maybe_unused]] TESFile* a_file) { return false; } // 0F
virtual bool CheckSaveGame([[maybe_unused]] BGSSaveFormBuffer* a_saveGameBuffer) const { return true; } // 10
virtual void SaveGame(BGSSaveFormBuffer* a_saveGameBuffer); // 11
virtual void LoadGame(BGSLoadFormBuffer* a_loadGameBuffer); // 12
virtual void InitLoadGame([[maybe_unused]] BGSLoadFormBuffer* a_loadGameBuffer) { return; } // 13
virtual void FinishLoadGame([[maybe_unused]] BGSLoadFormBuffer* a_loadGameBuffer) { return; } // 14
virtual void Revert([[maybe_unused]] BGSLoadFormBuffer* a_loadGameBuffer) { return; } // 15
virtual void InitItemImpl() { return; } // 16
virtual TESFile* GetRevertFile() const; // 17
virtual TESFile* GetDescriptionOwnerFile() const; // 18
virtual ENUM_FORM_ID GetSavedFormType() const { return *formType; } // 19
virtual void GetFormDetailedString(char* a_dest, std::uint32_t a_size) const; // 1A
virtual bool GetKnown() const { return (formFlags >> 6) & 1; } // 1B
virtual bool GetRandomAnim() const { return (formFlags >> 16) & 1; } // 1C
virtual bool GetPlayable([[maybe_unused]] const TBO_InstanceData* a_data) const { return (formFlags >> 2) & 1; } // 1D
virtual bool IsHeadingMarker() const { return false; } // 1E
virtual bool IsHeadtrackMarker() const { return false; } // 1F
virtual bool GetDangerous() const { return (formFlags >> 17) & 1; } // 20
virtual bool QHasCurrents() const { return (formFlags >> 19) & 1; } // 21
virtual bool GetObstacle() const { return (formFlags >> 25) & 1; } // 22
virtual bool QIsLODLandObject() const { return false; } // 23
virtual bool GetOnLocalMap() const { return (formFlags >> 9) & 1; } // 24
virtual bool GetMustUpdate() const { return (formFlags >> 8) & 1; } // 25
virtual void SetOnLocalMap(bool a_val); // 26
virtual bool GetIgnoredBySandbox() const { return false; } // 27
virtual void SetDelete(bool a_deleted); // 28
virtual void SetAltered(bool a_altered); // 29
virtual void SaveObjectBound() { return; } // 2A
virtual void LoadObjectBound([[maybe_unused]] TESFile* a_file) { return; } // 2B
virtual void SavePreviewTransform(CHUNK_ID) { return; } // 2C
virtual void LoadPreviewTransform([[maybe_unused]] TESFile* a_file) { return; } // 2D
virtual bool IsBoundObject() const { return false; } // 2E
virtual bool IsObject() const { return false; } // 2F
virtual bool IsMagicItem() const { return false; } // 30
virtual bool IsWater() const { return false; } // 31
virtual TESObjectREFR* IsReference() { return nullptr; } // 33
virtual const TESObjectREFR* IsReference() const { return nullptr; } // 32
virtual std::uint32_t GetRefCount() const { return 0; } // 34
virtual const char* GetTextForParsedSubTag(const BSFixedString& a_subTag) const; // 35
virtual void Copy([[maybe_unused]] TESForm* a_copy) { return; } // 36
virtual bool BelongsInGroup(FORM* a_groupFORM, bool a_allowParentGroups, bool a_currentOnly); // 37
virtual void CreateGroupData(FORM* a_outGroupFORM, FORM_GROUP* a_parentGroup); // 38
virtual std::uint32_t GetFormEditorIDLength() const; // 39
virtual const char* GetFormEditorID() const { return ""; } // 3A
virtual bool SetFormEditorID([[maybe_unused]] const char* a_editorID) { return true; } // 3B
virtual bool IsParentForm() { return false; } // 3C
virtual bool IsParentFormTree() { return false; } // 3D
virtual bool IsFormTypeChild([[maybe_unused]] std::uint8_t a_type) { return false; } // 3E
virtual bool LoopingActivate(TESObjectREFR* a_itemActivated, TESObjectREFR* a_actionRef) { return Activate(a_itemActivated, a_actionRef, nullptr, 1); } // 3F
virtual bool Activate([[maybe_unused]] TESObjectREFR* a_itemActivated, [[maybe_unused]] TESObjectREFR* a_actionRef, [[maybe_unused]] TESBoundObject* a_objectToGet, [[maybe_unused]] std::int32_t a_count) { return false; } // 40
virtual void SetFormID(TESFormID a_formID, bool a_updateFile); // 41
virtual const char* GetObjectTypeName() const { return ""; } // 42
virtual bool QAvailableInGame() const { return true; } // 43
virtual BGSMod::Template::Items* GetObjectTemplate() { return nullptr; } // 44
virtual BGSPreviewTransform* GetPreviewTransform() { return nullptr; } // 45
virtual BGSSoundTagComponent* GetSoundTagComponent() { return nullptr; } // 46
virtual std::uint32_t GetFilledSlots() const; // 47
virtual std::uint32_t GetFilledSlotsImpl() const { return static_cast<std::uint32_t>(-1); } // 48
virtual float GetDesirability([[maybe_unused]] TBO_InstanceData* a_instanceData, [[maybe_unused]] const TESForm* a_user) const { return 0.0F; } // 49
static void AddCompileIndex(std::uint32_t& a_id, TESFile* a_file)
{
using func_t = decltype(&TESForm::AddCompileIndex);
static REL::Relocation<func_t> func{ ID::TESForm::AddCompileIndex };
return func(a_id, a_file);
}
[[nodiscard]] static auto GetAllForms()
-> std::pair<
BSTHashMap<std::uint32_t, TESForm*>*,
std::reference_wrapper<BSReadWriteLock>>
{
static REL::Relocation<BSTHashMap<std::uint32_t, TESForm*>**> allForms{ ID::TESForm::AllForms };
static REL::Relocation<BSReadWriteLock*> allFormsMapLock{ ID::TESForm::AllFormsMapLock };
return { *allForms, *allFormsMapLock };
}
[[nodiscard]] static auto GetAllFormsByEditorID()
-> std::pair<
BSTHashMap<BSFixedString, TESForm*>*,
std::reference_wrapper<BSReadWriteLock>>
{
static REL::Relocation<BSTHashMap<BSFixedString, TESForm*>**> allFormsByEditorID{ ID::TESForm::AllFormsByEditorID };
static REL::Relocation<BSReadWriteLock*> allFormsEditorIDMapLock{ ID::TESForm::AllFormsEditorIDMapLock };
return { *allFormsByEditorID, *allFormsEditorIDMapLock };
}
[[nodiscard]] bool GetDelete()
{
return (formFlags & 0x20);
}
[[nodiscard]] TESFile* GetFile(std::int32_t a_index = -1) const
{
using func_t = decltype(&TESForm::GetFile);
static REL::Relocation<func_t> func{ ID::TESForm::GetFile };
return func(this, a_index);
}
[[nodiscard]] static TESForm* GetFormByID(TESFormID a_formID)
{
const auto& [map, lock] = GetAllForms();
BSAutoReadLock l{ lock };
if (map) {
const auto it = map->find(a_formID);
return it != map->end() ? it->second : nullptr;
} else {
return nullptr;
}
}
template <class T>
[[nodiscard]] static T* GetFormByID(TESFormID a_formID)
{
const auto form = GetFormByID(a_formID);
return form ? form->As<T>() : nullptr;
}
[[nodiscard]] static TESForm* GetFormByEditorID(const BSFixedString& a_editorID)
{
const auto& [map, lock] = GetAllFormsByEditorID();
BSAutoReadLock l{ lock };
if (map) {
const auto it = map->find(a_editorID);
return it != map->end() ? it->second : nullptr;
} else {
return nullptr;
}
}
template <class T>
[[nodiscard]] static T* GetFormByEditorID(const BSFixedString& a_editorID)
{
const auto form = GetFormByEditorID(a_editorID);
return form ? form->As<T>() : nullptr;
}
[[nodiscard]] static std::uint32_t GetFormCode(ENUM_FORM_ID a_formType)
{
auto formEnumString = GetFormEnumString();
return formEnumString[std::to_underlying(a_formType)].formCode;
}
[[nodiscard]] std::uint32_t GetFormCode() const
{
return GetFormCode(GetFormType());
}
[[nodiscard]] static std::span<FORM_ENUM_STRING, 159> GetFormEnumString()
{
static REL::Relocation<FORM_ENUM_STRING(*)[159]> functions{ ID::TESForm::GetFormEnumString };
return { *functions };
}
[[nodiscard]] static ENUM_FORM_ID GetFormTypeFromString(const char* a_formTypeString)
{
using func_t = decltype(&TESForm::GetFormTypeFromString);
static REL::Relocation<func_t> func{ ID::TESForm::GetFormTypeFromString };
return func(a_formTypeString);
}
[[nodiscard]] static const char* GetFormTypeString(ENUM_FORM_ID a_formType)
{
auto formEnumString = GetFormEnumString();
return formEnumString[std::to_underlying(a_formType)].formString;
}
[[nodiscard]] const char* GetFormTypeString() const
{
return GetFormTypeString(GetFormType());
}
[[nodiscard]] std::uint32_t GetFormFlags() const noexcept { return formFlags; }
[[nodiscard]] TESFormID GetFormID() const noexcept { return formID; }
[[nodiscard]] ENUM_FORM_ID GetFormType() const noexcept { return *formType; }
[[nodiscard]] TESFormID GetLocalFormID()
{
auto file = GetFile(0);
std::uint32_t fileIndex = file->compileIndex << (3 * 8);
fileIndex += file->smallFileCompileIndex << ((1 * 8) + 4);
return formID & ~fileIndex;
}
[[nodiscard]] bool Is(ENUM_FORM_ID a_type) const noexcept { return GetFormType() == a_type; }
template <class... Args>
[[nodiscard]] bool Is(Args... a_args) const noexcept //
requires(std::same_as<Args, ENUM_FORM_ID> && ...)
{
return (Is(a_args) || ...);
}
template <class T>
[[nodiscard]] bool Is() const noexcept //
requires(std::derived_from<T, TESForm> &&
!std::is_pointer_v<T> &&
!std::is_reference_v<T>)
{
return Is(T::FORM_ID);
}
[[nodiscard]] bool IsActor() const noexcept { return Is(ENUM_FORM_ID::kACHR); }
[[nodiscard]] bool IsAlchemyItem() const noexcept { return Is(ENUM_FORM_ID::kALCH); }
[[nodiscard]] bool IsCreated() const noexcept { return (formID >> (8 * 3)) == 0xFF; }
[[nodiscard]] bool IsDeleted() noexcept { return (formFlags & (1u << 5)) != 0; }
[[nodiscard]] bool IsDisabled() noexcept { return (formFlags & (1u << 11)) != 0; }
[[nodiscard]] bool IsInitialized() const noexcept { return (formFlags & (1u << 3)) != 0; }
[[nodiscard]] bool IsNot(ENUM_FORM_ID a_type) const noexcept { return !Is(a_type); }
template <class... Args>
[[nodiscard]] bool IsNot(Args... a_args) const noexcept //
requires(std::same_as<Args, ENUM_FORM_ID> && ...)
{
return (IsNot(a_args) && ...);
}
[[nodiscard]] bool IsPlayer() const noexcept { return GetFormID() == 0x00000007; }
[[nodiscard]] bool IsPlayerRef() const noexcept { return GetFormID() == 0x00000014; }
[[nodiscard]] bool IsWeapon() const noexcept { return Is(ENUM_FORM_ID::kWEAP); }
void SetInGameFormFlags(std::uint16_t a_flags, bool a_value)
{
if (a_value) {
inGameFormFlags |= a_flags;
AddChange(1);
} else {
inGameFormFlags &= ~a_flags;
AddChange(1);
}
}
void SetTemporary()
{
using func_t = decltype(&TESForm::SetTemporary);
static REL::Relocation<func_t> func{ ID::TESForm::SetTemporary };
return func(this);
}
static TESForm* GetFormByNumericID(std::uint32_t a_searchID)
{
using func_t = decltype(&TESForm::GetFormByNumericID);
static REL::Relocation<func_t> func{ ID::TESForm::GetFormByNumericID };
return func(a_searchID);
}
template <
class T,
class = std::enable_if_t<
std::negation_v<
std::disjunction<
std::is_pointer<T>,
std::is_reference<T>,
std::is_const<T>,
std::is_volatile<T>>>>>
[[nodiscard]] T* As() noexcept;
template <
class T,
class = std::enable_if_t<
std::negation_v<
std::disjunction<
std::is_pointer<T>,
std::is_reference<T>,
std::is_const<T>,
std::is_volatile<T>>>>>
[[nodiscard]] const T* As() const noexcept;
// members
TESFileContainer sourceFiles; // 08
std::uint32_t formFlags; // 10
TESFormID formID; // 14
std::uint16_t inGameFormFlags; // 18
REX::TEnumSet<ENUM_FORM_ID, std::uint8_t> formType; // 1A
};
static_assert(sizeof(TESForm) == 0x20);
}
namespace std
{
[[nodiscard]] inline std::string to_string(RE::ENUM_FORM_ID a_formType)
{
return RE::TESForm::GetFormTypeString(a_formType);
}
}
#ifdef FMT_VERSION
namespace fmt
{
template <>
struct formatter<RE::ENUM_FORM_ID>
{
template <class ParseContext>
constexpr auto parse(ParseContext& a_ctx)
{
return a_ctx.begin();
}
template <class FormatContext>
auto format(const RE::ENUM_FORM_ID& a_formType, FormatContext& a_ctx)
{
return fmt::format_to(a_ctx.out(), "{}", RE::TESForm::GetFormTypeString(a_formType));
}
};
}
#endif
#ifdef __cpp_lib_format
namespace std
{
template <class CharT>
struct formatter<RE::ENUM_FORM_ID, CharT> : std::formatter<std::string_view, CharT>
{
template <class FormatContext>
auto format(RE::ENUM_FORM_ID a_formType, FormatContext& a_ctx)
{
return formatter<std::string_view, CharT>::format(RE::TESForm::GetFormTypeString(a_formType), a_ctx);
}
};
}
#endif
@@ -0,0 +1,21 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class TESFormDeleteEvent
{
public:
[[nodiscard]] static BSTEventSource<TESFormDeleteEvent>* GetEventSource()
{
using func_t = decltype(&TESFormDeleteEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESFormDeleteEvent::GetEventSource };
return func();
}
// members
TESFormID formID; // 00
};
static_assert(sizeof(TESFormDeleteEvent) == 0x04);
}
@@ -0,0 +1,321 @@
#pragma once
#include "RE/A/Actor.h"
#include "RE/A/ActorValueInfo.h"
#include "RE/A/AlchemyItem.h"
#include "RE/A/ArrowProjectile.h"
#include "RE/B/BGSAcousticSpace.h"
#include "RE/B/BGSAction.h"
#include "RE/B/BGSAddonNode.h"
#include "RE/B/BGSAimModel.h"
#include "RE/B/BGSArtObject.h"
#include "RE/B/BGSAssociationType.h"
#include "RE/B/BGSAttractionRule.h"
#include "RE/B/BGSAudioEffectChain.h"
#include "RE/B/BGSBendableSpline.h"
#include "RE/B/BGSBodyPartData.h"
#include "RE/B/BGSCameraPath.h"
#include "RE/B/BGSCameraShot.h"
#include "RE/B/BGSCollisionLayer.h"
#include "RE/B/BGSColorForm.h"
#include "RE/B/BGSComponent.h"
#include "RE/B/BGSConstructibleObject.h"
#include "RE/B/BGSDamageType.h"
#include "RE/B/BGSDebris.h"
#include "RE/B/BGSDefaultObject.h"
#include "RE/B/BGSDefaultObjectManager.h"
#include "RE/B/BGSDialogueBranch.h"
#include "RE/B/BGSDualCastData.h"
#include "RE/B/BGSEncounterZone.h"
#include "RE/B/BGSEquipSlot.h"
#include "RE/B/BGSExplosion.h"
#include "RE/B/BGSFootstep.h"
#include "RE/B/BGSFootstepSet.h"
#include "RE/B/BGSGodRays.h"
#include "RE/B/BGSHazard.h"
#include "RE/B/BGSHeadPart.h"
#include "RE/B/BGSIdleMarker.h"
#include "RE/B/BGSImpactData.h"
#include "RE/B/BGSImpactDataSet.h"
#include "RE/B/BGSInstanceNamingRules.h"
#include "RE/B/BGSKeyword.h"
#include "RE/B/BGSLensFlare.h"
#include "RE/B/BGSLightingTemplate.h"
#include "RE/B/BGSListForm.h"
#include "RE/B/BGSLocation.h"
#include "RE/B/BGSLocationRefType.h"
#include "RE/B/BGSMaterialObject.h"
#include "RE/B/BGSMaterialSwap.h"
#include "RE/B/BGSMaterialType.h"
#include "RE/B/BGSMenuIcon.h"
#include "RE/B/BGSMessage.h"
#include "RE/B/BGSMod.h"
#include "RE/B/BGSMovableStatic.h"
#include "RE/B/BGSMovementType.h"
#include "RE/B/BGSMusicTrackFormWrapper.h"
#include "RE/B/BGSMusicType.h"
#include "RE/B/BGSNote.h"
#include "RE/B/BGSOutfit.h"
#include "RE/B/BGSPackIn.h"
#include "RE/B/BGSPerk.h"
#include "RE/B/BGSProjectile.h"
#include "RE/B/BGSReferenceEffect.h"
#include "RE/B/BGSRelationship.h"
#include "RE/B/BGSReverbParameters.h"
#include "RE/B/BGSScene.h"
#include "RE/B/BGSShaderParticleGeometryData.h"
#include "RE/B/BGSSoundCategory.h"
#include "RE/B/BGSSoundCategorySnapshot.h"
#include "RE/B/BGSSoundDescriptorForm.h"
#include "RE/B/BGSSoundKeywordMapping.h"
#include "RE/B/BGSSoundOutput.h"
#include "RE/B/BGSSoundTagSet.h"
#include "RE/B/BGSStaticCollection.h"
#include "RE/B/BGSStoryManagerBranchNode.h"
#include "RE/B/BGSStoryManagerEventNode.h"
#include "RE/B/BGSStoryManagerQuestNode.h"
#include "RE/B/BGSTalkingActivator.h"
#include "RE/B/BGSTerminal.h"
#include "RE/B/BGSTextureSet.h"
#include "RE/B/BGSTransform.h"
#include "RE/B/BGSVoiceType.h"
#include "RE/B/BGSZoomData.h"
#include "RE/B/BarrierProjectile.h"
#include "RE/B/BeamProjectile.h"
#include "RE/C/ConeProjectile.h"
#include "RE/E/EffectSetting.h"
#include "RE/E/EnchantmentItem.h"
#include "RE/F/FlameProjectile.h"
#include "RE/G/GrenadeProjectile.h"
#include "RE/H/Hazard.h"
#include "RE/I/IngredientItem.h"
#include "RE/M/MissileProjectile.h"
#include "RE/N/NavMesh.h"
#include "RE/N/NavMeshInfoMap.h"
#include "RE/S/Script.h"
#include "RE/S/ScrollItem.h"
#include "RE/S/SpellItem.h"
#include "RE/T/TESAmmo.h"
#include "RE/T/TESClass.h"
#include "RE/T/TESClimate.h"
#include "RE/T/TESCombatStyle.h"
#include "RE/T/TESEffectShader.h"
#include "RE/T/TESEyes.h"
#include "RE/T/TESFaction.h"
#include "RE/T/TESFlora.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESFurniture.h"
#include "RE/T/TESGlobal.h"
#include "RE/T/TESGrass.h"
#include "RE/T/TESIdleForm.h"
#include "RE/T/TESImageSpace.h"
#include "RE/T/TESImageSpaceModifier.h"
#include "RE/T/TESKey.h"
#include "RE/T/TESLandTexture.h"
#include "RE/T/TESLevCharacter.h"
#include "RE/T/TESLevItem.h"
#include "RE/T/TESLevSpell.h"
#include "RE/T/TESLoadScreen.h"
#include "RE/T/TESNPC.h"
#include "RE/T/TESObjectACTI.h"
#include "RE/T/TESObjectANIO.h"
#include "RE/T/TESObjectARMA.h"
#include "RE/T/TESObjectARMO.h"
#include "RE/T/TESObjectBOOK.h"
#include "RE/T/TESObjectCELL.h"
#include "RE/T/TESObjectCONT.h"
#include "RE/T/TESObjectDOOR.h"
#include "RE/T/TESObjectLAND.h"
#include "RE/T/TESObjectLIGH.h"
#include "RE/T/TESObjectMISC.h"
#include "RE/T/TESObjectREFR.h"
#include "RE/T/TESObjectSTAT.h"
#include "RE/T/TESObjectTREE.h"
#include "RE/T/TESObjectWEAP.h"
#include "RE/T/TESPackage.h"
#include "RE/T/TESQuest.h"
#include "RE/T/TESRace.h"
#include "RE/T/TESRegion.h"
#include "RE/T/TESShout.h"
#include "RE/T/TESSoulGem.h"
#include "RE/T/TESSound.h"
#include "RE/T/TESTopic.h"
#include "RE/T/TESTopicInfo.h"
#include "RE/T/TESWaterForm.h"
#include "RE/T/TESWeather.h"
#include "RE/T/TESWordOfPower.h"
#include "RE/T/TESWorldSpace.h"
#define F4SE_FORMUTIL(a_elem) \
case a_elem::FORM_ID: \
if constexpr (std::is_convertible_v<const a_elem*, const T*>) { \
return static_cast<const a_elem*>(this); \
} \
break
namespace RE
{
template <class T, class>
[[nodiscard]] T* TESForm::As() noexcept
{
return const_cast<T*>(static_cast<const TESForm*>(this)->As<T>());
}
template <class T, class>
[[nodiscard]] const T* TESForm::As() const noexcept
{
switch (GetFormType()) {
F4SE_FORMUTIL(TESForm);
F4SE_FORMUTIL(BGSKeyword);
F4SE_FORMUTIL(BGSLocationRefType);
F4SE_FORMUTIL(BGSAction);
F4SE_FORMUTIL(BGSTransform);
F4SE_FORMUTIL(BGSComponent);
F4SE_FORMUTIL(BGSTextureSet);
F4SE_FORMUTIL(BGSMenuIcon);
F4SE_FORMUTIL(TESGlobal);
F4SE_FORMUTIL(BGSDamageType);
F4SE_FORMUTIL(TESClass);
F4SE_FORMUTIL(TESFaction);
F4SE_FORMUTIL(BGSHeadPart);
F4SE_FORMUTIL(TESEyes);
F4SE_FORMUTIL(TESRace);
F4SE_FORMUTIL(TESSound);
F4SE_FORMUTIL(BGSAcousticSpace);
F4SE_FORMUTIL(EffectSetting);
F4SE_FORMUTIL(Script);
F4SE_FORMUTIL(TESLandTexture);
F4SE_FORMUTIL(EnchantmentItem);
F4SE_FORMUTIL(SpellItem);
F4SE_FORMUTIL(ScrollItem);
F4SE_FORMUTIL(TESObjectACTI);
F4SE_FORMUTIL(BGSTalkingActivator);
F4SE_FORMUTIL(TESObjectARMO);
F4SE_FORMUTIL(TESObjectBOOK);
F4SE_FORMUTIL(TESObjectCONT);
F4SE_FORMUTIL(TESObjectDOOR);
F4SE_FORMUTIL(IngredientItem);
F4SE_FORMUTIL(TESObjectLIGH);
F4SE_FORMUTIL(TESObjectMISC);
F4SE_FORMUTIL(TESObjectSTAT);
F4SE_FORMUTIL(BGSStaticCollection);
F4SE_FORMUTIL(BGSMovableStatic);
F4SE_FORMUTIL(TESGrass);
F4SE_FORMUTIL(TESObjectTREE);
F4SE_FORMUTIL(TESFlora);
F4SE_FORMUTIL(TESFurniture);
F4SE_FORMUTIL(TESObjectWEAP);
F4SE_FORMUTIL(TESAmmo);
F4SE_FORMUTIL(TESNPC);
F4SE_FORMUTIL(TESLevCharacter);
F4SE_FORMUTIL(TESKey);
F4SE_FORMUTIL(AlchemyItem);
F4SE_FORMUTIL(BGSIdleMarker);
F4SE_FORMUTIL(BGSNote);
F4SE_FORMUTIL(BGSProjectile);
F4SE_FORMUTIL(BGSHazard);
F4SE_FORMUTIL(BGSBendableSpline);
F4SE_FORMUTIL(TESSoulGem);
F4SE_FORMUTIL(BGSTerminal);
F4SE_FORMUTIL(TESLevItem);
F4SE_FORMUTIL(TESWeather);
F4SE_FORMUTIL(TESClimate);
F4SE_FORMUTIL(BGSShaderParticleGeometryData);
F4SE_FORMUTIL(BGSReferenceEffect);
F4SE_FORMUTIL(TESRegion);
F4SE_FORMUTIL(NavMeshInfoMap);
F4SE_FORMUTIL(TESObjectCELL);
F4SE_FORMUTIL(TESObjectREFR);
F4SE_FORMUTIL(Actor);
F4SE_FORMUTIL(MissileProjectile);
F4SE_FORMUTIL(ArrowProjectile);
F4SE_FORMUTIL(GrenadeProjectile);
F4SE_FORMUTIL(BeamProjectile);
F4SE_FORMUTIL(FlameProjectile);
F4SE_FORMUTIL(ConeProjectile);
F4SE_FORMUTIL(BarrierProjectile);
F4SE_FORMUTIL(Hazard);
F4SE_FORMUTIL(TESWorldSpace);
F4SE_FORMUTIL(TESObjectLAND);
F4SE_FORMUTIL(NavMesh);
F4SE_FORMUTIL(TESTopic);
F4SE_FORMUTIL(TESTopicInfo);
F4SE_FORMUTIL(TESQuest);
F4SE_FORMUTIL(TESIdleForm);
F4SE_FORMUTIL(TESPackage);
F4SE_FORMUTIL(TESCombatStyle);
F4SE_FORMUTIL(TESLoadScreen);
F4SE_FORMUTIL(TESLevSpell);
F4SE_FORMUTIL(TESObjectANIO);
F4SE_FORMUTIL(TESWaterForm);
F4SE_FORMUTIL(TESEffectShader);
F4SE_FORMUTIL(BGSExplosion);
F4SE_FORMUTIL(BGSDebris);
F4SE_FORMUTIL(TESImageSpace);
F4SE_FORMUTIL(TESImageSpaceModifier);
F4SE_FORMUTIL(BGSListForm);
F4SE_FORMUTIL(BGSPerk);
F4SE_FORMUTIL(BGSBodyPartData);
F4SE_FORMUTIL(BGSAddonNode);
F4SE_FORMUTIL(ActorValueInfo);
F4SE_FORMUTIL(BGSCameraShot);
F4SE_FORMUTIL(BGSCameraPath);
F4SE_FORMUTIL(BGSVoiceType);
F4SE_FORMUTIL(BGSMaterialType);
F4SE_FORMUTIL(BGSImpactData);
F4SE_FORMUTIL(BGSImpactDataSet);
F4SE_FORMUTIL(TESObjectARMA);
F4SE_FORMUTIL(BGSEncounterZone);
F4SE_FORMUTIL(BGSLocation);
F4SE_FORMUTIL(BGSMessage);
F4SE_FORMUTIL(BGSDefaultObjectManager);
F4SE_FORMUTIL(BGSDefaultObject);
F4SE_FORMUTIL(BGSLightingTemplate);
F4SE_FORMUTIL(BGSMusicType);
F4SE_FORMUTIL(BGSFootstep);
F4SE_FORMUTIL(BGSFootstepSet);
F4SE_FORMUTIL(BGSStoryManagerBranchNode);
F4SE_FORMUTIL(BGSStoryManagerQuestNode);
F4SE_FORMUTIL(BGSStoryManagerEventNode);
F4SE_FORMUTIL(BGSDialogueBranch);
F4SE_FORMUTIL(BGSMusicTrackFormWrapper);
F4SE_FORMUTIL(TESWordOfPower);
F4SE_FORMUTIL(TESShout);
F4SE_FORMUTIL(BGSEquipSlot);
F4SE_FORMUTIL(BGSRelationship);
F4SE_FORMUTIL(BGSScene);
F4SE_FORMUTIL(BGSAssociationType);
F4SE_FORMUTIL(BGSOutfit);
F4SE_FORMUTIL(BGSArtObject);
F4SE_FORMUTIL(BGSMaterialObject);
F4SE_FORMUTIL(BGSMovementType);
F4SE_FORMUTIL(BGSSoundDescriptorForm);
F4SE_FORMUTIL(BGSDualCastData);
F4SE_FORMUTIL(BGSSoundCategory);
F4SE_FORMUTIL(BGSSoundOutput);
F4SE_FORMUTIL(BGSCollisionLayer);
F4SE_FORMUTIL(BGSColorForm);
F4SE_FORMUTIL(BGSReverbParameters);
F4SE_FORMUTIL(BGSPackIn);
F4SE_FORMUTIL(BGSAimModel);
F4SE_FORMUTIL(BGSConstructibleObject);
F4SE_FORMUTIL(BGSMod::Attachment::Mod);
F4SE_FORMUTIL(BGSMaterialSwap);
F4SE_FORMUTIL(BGSZoomData);
F4SE_FORMUTIL(BGSInstanceNamingRules);
F4SE_FORMUTIL(BGSSoundKeywordMapping);
F4SE_FORMUTIL(BGSAudioEffectChain);
F4SE_FORMUTIL(BGSAttractionRule);
F4SE_FORMUTIL(BGSSoundCategorySnapshot);
F4SE_FORMUTIL(BGSSoundTagSet);
F4SE_FORMUTIL(BGSLensFlare);
F4SE_FORMUTIL(BGSGodRays);
default:
break;
}
return nullptr;
}
}
#undef F4SE_FORMUTIL
@@ -0,0 +1,35 @@
#pragma once
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BSTHashMap.h"
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) TESFullName :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESFullName };
static constexpr auto VTABLE{ VTABLE::TESFullName };
// add
virtual std::uint32_t GetFullNameLength() const { return fullName.length(); } // 07
virtual const char* GetFullName() const { return fullName.c_str(); } // 08
[[nodiscard]] static std::string_view GetFullName(const TESForm& a_form, bool a_strict = false);
[[nodiscard]] static auto GetSparseFullNameMap()
-> BSTHashMap<const TESForm*, BGSLocalizedString>&
{
static REL::Relocation<BSTHashMap<const TESForm*, BGSLocalizedString>*> sparseFullNameMap{ ID::TESFullName::SparseFullNameMap, -0x8 };
return *sparseFullNameMap;
}
static void SetFullName(TESForm& a_form, std::string_view a_fullName);
// members
BGSLocalizedString fullName; // 08
};
static_assert(sizeof(TESFullName) == 0x10);
}
@@ -0,0 +1,46 @@
#pragma once
#include "RE/B/BGSAttachParentArray.h"
#include "RE/B/BSTArray.h"
#include "RE/T/TESObjectACTI.h"
#include "RE/W/WorkbenchData.h"
namespace RE
{
class BSFurnitureMarker;
class TESContainer;
class __declspec(novtable) TESFurniture :
public TESObjectACTI // 000
{
public:
static constexpr auto RTTI{ RTTI::TESFurniture };
static constexpr auto VTABLE{ VTABLE::TESFurniture };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kFURN };
class EntryPointData
{
public:
// members
std::uint32_t entryPoint; // 0
std::uint32_t flags; // 4
};
static_assert(sizeof(EntryPointData) == 0x8);
[[nodiscard]] TESContainer* GetContainer()
{
using func_t = decltype(&TESFurniture::GetContainer);
static REL::Relocation<func_t> func{ ID::TESFurniture::GetContainer };
return func(this);
}
// members
BSTArray<EntryPointData> entryPointDataArray; // 148
BGSAttachParentArray attachParents; // 160
WorkbenchData wbData; // 178
std::uint32_t furnFlags; // 17C
TESForm* associatedForm; // 180
BSTArray<BSFurnitureMarker> markersArray; // 188
};
static_assert(sizeof(TESFurniture) == 0x1A0);
}
@@ -0,0 +1,33 @@
#pragma once
#include "RE/B/BSTEvent.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class TESFurnitureEvent
{
public:
enum class FurnitureEventType : std::int32_t
{
kEnter = 0x0,
kExit = 0x1
};
[[nodiscard]] static BSTEventSource<TESFurnitureEvent>* GetEventSource()
{
using func_t = decltype(&TESFurnitureEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESFurnitureEvent::GetEventSource };
return func();
}
[[nodiscard]] constexpr bool IsEnter() const noexcept { return type.all(FurnitureEventType::kEnter); }
[[nodiscard]] constexpr bool IsExit() const noexcept { return type.all(FurnitureEventType::kExit); }
// members
NiPointer<TESObjectREFR> actor; // 00
NiPointer<TESObjectREFR> targetFurniture; // 08
REX::TEnumSet<FurnitureEventType, std::int32_t> type; // 10
};
static_assert(sizeof(TESFurnitureEvent) == 0x18);
}
@@ -0,0 +1,23 @@
#pragma once
#include "RE/B/BSStringT.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) TESGlobal :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::TESGlobal };
static constexpr auto VTABLE{ VTABLE::TESGlobal };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kGLOB };
[[nodiscard]] float GetValue() const noexcept { return value; }
// members
BSString formEditorID; // 20
float value; // 30
};
static_assert(sizeof(TESGlobal) == 0x38);
}
@@ -0,0 +1,86 @@
#pragma once
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESModel.h"
namespace RE
{
class __declspec(novtable) TESGrass :
public TESBoundObject, // 00
public TESModel // 68
{
public:
static constexpr auto RTTI{ RTTI::TESGrass };
static constexpr auto VTABLE{ VTABLE::TESGrass };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kGRAS };
enum class GRASS_WATER_STATE
{
kAboveOnlyAtleast = 0x0,
kAboveOnlyAtmost = 0x1,
kBelowOnlyAtleast = 0x2,
kBelowOnlyAtmost = 0x3,
kBothAtlest = 0x4,
kBothAtmost = 0x5,
kBothAtmostAbove = 0x6,
kBothAtmostBelow = 0x7,
kTotal = 0x8
};
class GRASS_DATA
{
public:
enum class Flags : std::int8_t
{
kVertexLighting = 0x1,
kUniformScaling = 0x2,
kFitToSlope = 0x4
};
// members
std::int8_t density; // 00
std::int8_t minSlopeDegrees; // 01
std::int8_t maxSlopeDegrees; // 02
std::uint16_t distanceFromWaterLevel; // 04
REX::TEnumSet<GRASS_WATER_STATE, std::int32_t> underwater; // 08
float positionRange; // 0C
float heightRange; // 10
float colorRange; // 14
float wavePeriod; // 18
std::int8_t flags; // 1C
};
static_assert(sizeof(GRASS_DATA) == 0x20);
// add
virtual std::int8_t GetDensity() const { return data.density; } // 67
virtual bool SetDensity(std::int8_t a_density); // 68
virtual std::int8_t GetMinSlopeDegrees() const { return data.minSlopeDegrees; } // 69
virtual bool SetMinSlopeDegrees(std::int8_t a_minSlopeDegrees); // 6A
virtual std::int8_t GetMaxSlopeDegrees() const { return data.maxSlopeDegrees; } // 6B
virtual bool SetMaxSlopeDegrees(std::int8_t a_maxSlopeDegrees); // 6C
virtual float GetMinSlope() const; // 6D
virtual float GetMaxSlope() const; // 6E
virtual std::uint16_t GetDistanceFromWaterLevel() const { return data.distanceFromWaterLevel; } // 6F
virtual void SetDistanceFromWaterLevel(const std::uint16_t a_distanceFromWaterLevel) { data.distanceFromWaterLevel = a_distanceFromWaterLevel; } // 70
virtual GRASS_WATER_STATE GetUnderwaterState() const { return *data.underwater; } // 71
virtual void SetUnderwaterState(const GRASS_WATER_STATE a_underwater) { data.underwater = a_underwater; } // 72
virtual float GetPositionRange() const { return data.positionRange; } // 73
virtual bool SetPositionRange(float a_range); // 74
virtual float GetHeightRange() const { return data.heightRange; } // 75
virtual bool SetHeightRange(float a_range); // 76
virtual float GetColorRange() const { return data.colorRange; } // 77
virtual bool SetColorRange(float a_range); // 78
virtual float GetWavePeriod() const { return data.wavePeriod; } // 79
virtual bool SetWavePeriod(float a_period); // 7A
virtual bool GetVertexLighting() const; // 7B
virtual void SetVertexLighting(bool a_flag); // 7C
virtual bool GetUniformScaling() const; // 7D
virtual void SetUniformScaling(bool a_flag); // 7E
virtual bool GetFitToSlope() const; // 7F
virtual void SetFitToSlope(bool a_flag) const; // 80
// members
GRASS_DATA data; // 98
};
static_assert(sizeof(TESGrass) == 0xB8);
}
@@ -0,0 +1,13 @@
#pragma once
#include "RE/G/GrassParam.h"
namespace RE
{
class TESGrassAreaParam
{
public:
GrassParam grassParam; // 00
float density[9]; // 28
};
static_assert(sizeof(TESGrassAreaParam) == 0x50);
}
@@ -0,0 +1,26 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
namespace TESHarvestEvent
{
class ItemHarvested
{
public:
[[nodiscard]] static BSTEventSource<ItemHarvested>* GetEventSource()
{
using func_t = decltype(&ItemHarvested::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESHarvestEvent::GetEventSource };
return func();
}
// members
const TESBoundObject* itemHarvested; // 00
TESObjectREFR* referenceHarvested; // 08
const Actor* harvestedBy; // 10
};
static_assert(sizeof(ItemHarvested) == 0x18);
}
}
@@ -0,0 +1,30 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) TESHealthForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESHealthForm };
static constexpr auto VTABLE{ VTABLE::TESHealthForm };
// override (BaseFormComponent)
void InitializeDataComponent() override; // 02
void ClearDataComponent() override; // 03
void CopyComponent(BaseFormComponent*) override; // 06
[[nodiscard]] static std::uint32_t GetFormHealth(const TESForm* a_form, const TBO_InstanceData* a_data)
{
using func_t = decltype(&TESHealthForm::GetFormHealth);
static REL::Relocation<func_t> func{ ID::TESHealthForm::GetFormHealth };
return func(a_form, a_data);
}
// members
std::uint32_t health; // 08
};
static_assert(sizeof(TESHealthForm) == 0x10);
}
@@ -0,0 +1,30 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTEvent.h"
#include "RE/H/HitData.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class TESHitEvent
{
public:
[[nodiscard]] static BSTEventSource<TESHitEvent>* GetEventSource()
{
using func_t = decltype(&TESHitEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESHitEvent::GetEventSource };
return func();
}
// members
HitData hitData; // 000
NiPointer<TESObjectREFR> target; // 0E0
NiPointer<TESObjectREFR> cause; // 0E8
BSFixedString material; // 0F0
std::uint32_t sourceFormID; // 0F8
std::uint32_t projectileFormID; // 0FC
bool usesHitData; // 100
};
static_assert(sizeof(TESHitEvent) == 0x110);
}
@@ -0,0 +1,15 @@
#pragma once
#include "RE/T/TESTexture.h"
namespace RE
{
class __declspec(novtable) TESIcon :
public TESTexture // 00
{
public:
static constexpr auto RTTI{ RTTI::TESIcon };
static constexpr auto VTABLE{ VTABLE::TESIcon };
};
static_assert(sizeof(TESIcon) == 0x10);
}
@@ -0,0 +1,48 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSStringT.h"
#include "RE/I/IDLE_DATA.h"
#include "RE/T/TESCondition.h"
#include "RE/T/TESForm.h"
namespace RE
{
class NiFormArray;
class __declspec(novtable) TESIdleForm :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::TESIdleForm };
static constexpr auto VTABLE{ VTABLE::TESIdleForm };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kIDLE };
bool CheckConditions(TESObjectREFR* a_actionRef, TESObjectREFR* a_targetRef, bool a_recurseUp)
{
if (!conditions.IsTrue(a_actionRef, a_targetRef)) {
return false;
}
if (a_recurseUp) {
if (parentIdle) {
return parentIdle->CheckConditions(a_actionRef, a_targetRef, a_recurseUp);
}
}
return true;
}
// members
TESCondition conditions; // 20
IDLE_DATA data; // 28
NiFormArray* childIdles; // 30
TESIdleForm* parentIdle; // 38
TESIdleForm* prevIdle; // 40
BSFixedString behaviorGraphName; // 48
BSFixedString animEventName; // 50
BSFixedString animFileName; // 58
BSString formEditorID; // 60
};
static_assert(sizeof(TESIdleForm) == 0x70);
}
@@ -0,0 +1,26 @@
#pragma once
#include "RE/I/ImageSpaceBaseData.h"
#include "RE/N/NiPointer.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESTexture.h"
namespace RE
{
class NiTexture;
class __declspec(novtable) TESImageSpace :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::TESImageSpace };
static constexpr auto VTABLE{ VTABLE::TESImageSpace };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kIMGS };
// members
ImageSpaceBaseData data; // 20
TESTexture lutTexture; // 78
NiPointer<NiTexture> niLutTexture; // 88
};
static_assert(sizeof(TESImageSpace) == 0x90);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) TESImageSpaceModifiableForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESImageSpaceModifiableForm };
static constexpr auto VTABLE{ VTABLE::TESImageSpaceModifiableForm };
// members
TESImageSpaceModifier* formImageSpaceModifying; // 08
};
static_assert(sizeof(TESImageSpaceModifiableForm) == 0x10);
}
@@ -0,0 +1,77 @@
#pragma once
#include "RE/B/BSStringT.h"
#include "RE/N/NiPoint2.h"
#include "RE/N/NiPointer.h"
#include "RE/T/TESForm.h"
namespace RE
{
class NiColorInterpolator;
class NiFloatInterpolator;
class __declspec(novtable) TESImageSpaceModifier :
public TESForm // 000
{
public:
static constexpr auto RTTI{ RTTI::TESImageSpaceModifier };
static constexpr auto VTABLE{ VTABLE::TESImageSpaceModifier };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kIMAD };
enum class ImageSpaceModifierOperations
{
kMult = 0x0,
kAdd = 0x1,
};
class ImageSpaceModifierData
{
public:
// members
bool animatable; // 00
float duration; // 04
std::uint32_t keySize[21][2]; // 08
std::uint32_t tintColorKeySize; // B0
std::uint32_t blurKeySize; // B4
std::uint32_t doubleKeySize; // B8
std::uint32_t radialBlurStrengthKeySize; // BC
std::uint32_t radialBlurRampupKeySize; // C0
std::uint32_t radialBlurStartKeySize; // C4
bool useTargetForRadialBlur; // C8
NiPoint2 radialBlurCenter; // CC
std::uint32_t depthOfFieldStrengthKeySize; // D4
std::uint32_t depthOfFieldDistanceKeySize; // D8
std::uint32_t depthOfFieldRangeKeySize; // DC
bool useTargetForDepthOfField; // E0
std::int8_t depthOfFieldMode; // E1
std::uint32_t radialBlurRampDownKeySize; // E4
std::uint32_t radialBlurDownStartKeySize; // E8
std::uint32_t fadeColorKeySize; // EC
std::uint32_t motionBlurStrengthKeySize; // F0
std::uint32_t depthOfFieldVignetteRadiusKeySize; // F4
std::uint32_t depthOfFieldVignetteStrengthKeySize; // F8
};
static_assert(sizeof(ImageSpaceModifierData) == 0xFC);
// members
ImageSpaceModifierData data; // 020
NiPointer<NiFloatInterpolator> interpolator[21][2]; // 120
NiPointer<NiFloatInterpolator> blurInterpolator; // 270
NiPointer<NiFloatInterpolator> doubleInterpolator; // 278
NiPointer<NiColorInterpolator> tintColorInterpolator; // 280
NiPointer<NiColorInterpolator> fadeColorInterpolator; // 288
NiPointer<NiFloatInterpolator> radialBlurStrengthInterpolator; // 290
NiPointer<NiFloatInterpolator> radialBlurRampupInterpolator; // 298
NiPointer<NiFloatInterpolator> radialBlurStartInterpolator; // 2A0
NiPointer<NiFloatInterpolator> radialBlurRampDownInterpolator; // 2A8
NiPointer<NiFloatInterpolator> radialBlurDownStartInterpolator; // 2B0
NiPointer<NiFloatInterpolator> depthOfFieldStrengthInterpolator; // 2B8
NiPointer<NiFloatInterpolator> depthOfFieldDistanceInterpolator; // 2C0
NiPointer<NiFloatInterpolator> depthOfFieldRangeInterpolator; // 2C8
NiPointer<NiFloatInterpolator> depthOfFieldVignetteRadiusInterpolator; // 2D0
NiPointer<NiFloatInterpolator> depthOfFieldVignetteStrengthInterpolator; // 2D8
NiPointer<NiFloatInterpolator> motionBlurStrengthInterpolator; // 2E0
BSString formEditorID; // 2E8
};
static_assert(sizeof(TESImageSpaceModifier) == 0x2F8);
}
@@ -0,0 +1,21 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class TESInitScriptEvent
{
public:
[[nodiscard]] static BSTEventSource<TESInitScriptEvent>* GetEventSource()
{
using func_t = decltype(&TESInitScriptEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESInitScriptEvent::GetEventSource };
return func();
}
// members
TESObjectREFR* hObjectInitialized; // 00
};
static_assert(sizeof(TESInitScriptEvent) == 0x8);
}
@@ -0,0 +1,16 @@
#pragma once
#include "RE/T/TESObjectMISC.h"
namespace RE
{
class __declspec(novtable) TESKey :
public TESObjectMISC // 000
{
public:
static constexpr auto RTTI{ RTTI::TESKey };
static constexpr auto VTABLE{ VTABLE::TESKey };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kKEYM };
};
static_assert(sizeof(TESKey) == 0x168);
}
@@ -0,0 +1,26 @@
#pragma once
#include "RE/B/BSSimpleList.h"
#include "RE/T/TESForm.h"
#include "RE/T/TEXTURE_HAVOK_DATA.h"
namespace RE
{
class __declspec(novtable) TESLandTexture :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::TESLandTexture };
static constexpr auto VTABLE{ VTABLE::TESLandTexture };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kLTEX };
// members
BGSTextureSet* textureSet; // 20
TEXTURE_HAVOK_DATA havokData; // 28
BGSMaterialType* materialType; // 30
std::int8_t specularExponent; // 38
std::int32_t shaderTextureIndex; // 3C
BSSimpleList<TESGrass*> textureGrassList; // 40
};
static_assert(sizeof(TESLandTexture) == 0x50);
}
@@ -0,0 +1,20 @@
#pragma once
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/T/TESBoundAnimObject.h"
#include "RE/T/TESLeveledList.h"
namespace RE
{
class __declspec(novtable) TESLevCharacter :
public TESBoundAnimObject, // 00
public TESLeveledList, // 68
public BGSModelMaterialSwap // 98
{
public:
static constexpr auto RTTI{ RTTI::TESLevCharacter };
static constexpr auto VTABLE{ VTABLE::TESLevCharacter };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kLVLN };
};
static_assert(sizeof(TESLevCharacter) == 0xD8);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESLeveledList.h"
namespace RE
{
class __declspec(novtable) TESLevItem :
public TESBoundObject, // 00
public TESLeveledList // 68
{
public:
static constexpr auto RTTI{ RTTI::TESLevItem };
static constexpr auto VTABLE{ VTABLE::TESLevItem };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kLVLI };
};
static_assert(sizeof(TESLevItem) == 0x98);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESLeveledList.h"
namespace RE
{
class __declspec(novtable) TESLevSpell :
public TESBoundObject, // 00
public TESLeveledList // 68
{
public:
static constexpr auto RTTI{ RTTI::TESLevSpell };
static constexpr auto VTABLE{ VTABLE::TESLevSpell };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kLVSP };
};
static_assert(sizeof(TESLevSpell) == 0x98);
}
@@ -0,0 +1,85 @@
#pragma once
#include "RE/B/BGSTypedFormValuePair.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTTuple.h"
#include "RE/B/BaseFormComponent.h"
namespace RE
{
enum class ENUM_FORM_ID;
class CALCED_OBJECT;
class ContainerItemExtra;
class LEVELED_OBJECT;
class INSTANCE_FILTER;
class __declspec(novtable) TESLeveledList :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESLeveledList };
static constexpr auto VTABLE{ VTABLE::TESLeveledList };
enum class LeveledListAllBelowForce
{
kNever = -1,
kDefault = 0,
kAlways = 1,
kShiftUp = 2,
};
// add
virtual std::int8_t GetChanceNone(); // 07
virtual bool GetMultCalc(); // 08
virtual std::int32_t GetMaxLevelDifference() { return 0; } // 09
virtual const char* GetOverrideName() { return nullptr; } // 0A
virtual bool GetCanContainFormsOfType(ENUM_FORM_ID a_type) const = 0; // 0B
LEVELED_OBJECT* AddLeveledObject(std::uint16_t a_level, std::uint16_t a_count, std::int8_t a_chanceNone, TESForm* a_item, ContainerItemExtra* a_itemExtra)
{
using func_t = decltype(&TESLeveledList::AddLeveledObject);
static REL::Relocation<func_t> func{ ID::TESLeveledList::AddLeveledObject };
return func(this, a_level, a_count, a_chanceNone, a_item, a_itemExtra);
}
void CalculateCurrentFormList(
std::uint16_t a_level,
std::uint16_t a_count,
BSScrapArray<CALCED_OBJECT>& a_outCont,
LeveledListAllBelowForce a_allBelowForce = LeveledListAllBelowForce::kDefault,
bool a_clampToPlayer = false,
INSTANCE_FILTER* a_instanceFilter = nullptr,
const char* a_overrideName = nullptr)
{
using func_t = decltype(&TESLeveledList::CalculateCurrentFormList);
static REL::Relocation<func_t> func{ ID::TESLeveledList::CalculateCurrentFormList };
return func(this, a_level, a_count, a_outCont, a_allBelowForce, a_clampToPlayer, a_instanceFilter, a_overrideName);
}
void CalculateCurrentFormListForRef(TESObjectREFR* a_ref, BSScrapArray<CALCED_OBJECT>& a_outCont, bool a_legendary)
{
using func_t = decltype(&TESLeveledList::CalculateCurrentFormListForRef);
static REL::Relocation<func_t> func{ ID::TESLeveledList::CalculateCurrentFormListForRef };
return func(this, a_ref, a_outCont, a_legendary);
}
bool GetUseAll()
{
using func_t = decltype(&TESLeveledList::GetUseAll);
static REL::Relocation<func_t> func{ ID::TESLeveledList::GetUseAll };
return func(this);
}
// members
TESGlobal* chanceGlobal; // 08
BSTArray<BSTTuple<TESForm*, BGSTypedFormValuePair::SharedVal>>* keywordChances; // 10
LEVELED_OBJECT* leveledLists; // 18
LEVELED_OBJECT** scriptAddedLists; // 20
std::int8_t scriptListCount; // 28
std::int8_t baseListCount; // 29
std::int8_t chanceNone; // 2A
std::int8_t llFlags; // 2B
std::int8_t maxUseAllCount; // 2C
};
static_assert(sizeof(TESLeveledList) == 0x30);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class TESLoadGameEvent
{
public:
[[nodiscard]] static BSTEventSource<TESLoadGameEvent>* GetEventSource()
{
using func_t = decltype(&TESLoadGameEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESLoadGameEvent::GetEventSource };
return func();
}
};
static_assert(sizeof(TESLoadGameEvent) == 0x1);
}
@@ -0,0 +1,39 @@
#pragma once
#include "RE/B/BGSLocalizedString.h"
#include "RE/T/TESCondition.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESModel.h"
namespace RE
{
class BGSTransform;
class TESBoundObject;
class __declspec(novtable) TESLoadScreen :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::TESLoadScreen };
static constexpr auto VTABLE{ VTABLE::TESLoadScreen };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kLSCR };
class LoadNIFData
{
public:
// members
TESBoundObject* loadNif; // 00
std::int16_t rotationConstraints[2]; // 08
TESModel cameraPath; // 10
BGSTransform* transform; // 40
float zoomConstraints[2]; // 48
};
static_assert(sizeof(LoadNIFData) == 0x50);
// members
TESCondition conditions; // 20
LoadNIFData* loadNIFData; // 28
BGSLocalizedString loadingText; // 30
};
static_assert(sizeof(TESLoadScreen) == 0x38);
}
@@ -0,0 +1,19 @@
#pragma once
namespace RE
{
class TESLocationClearedEvent
{
public:
[[nodiscard]] static BSTEventSource<TESLocationClearedEvent>* GetEventSource()
{
using func_t = decltype(&TESLocationClearedEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESLocationClearedEvent::GetEventSource };
return func();
}
// members
const BGSLocation* location; // 00
};
static_assert(sizeof(TESLocationClearedEvent) == 0x08);
}
@@ -0,0 +1,11 @@
#pragma once
namespace RE
{
class TESMagicCasterForm
{
public:
static constexpr auto RTTI{ RTTI::TESMagicCasterForm };
};
static_assert(std::is_empty_v<TESMagicCasterForm>);
}
@@ -0,0 +1,24 @@
#pragma once
#include "RE/B/BSTEvent.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class TESMagicEffectApplyEvent
{
public:
[[nodiscard]] static BSTEventSource<TESMagicEffectApplyEvent>* GetEventSource()
{
using func_t = decltype(&TESMagicEffectApplyEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESMagicEffectApplyEvent::GetEventSource };
return func();
}
// members
NiPointer<TESObjectREFR> target; // 00
NiPointer<TESObjectREFR> caster; // 08
std::uint32_t magicEffectFormID; // 10
};
static_assert(sizeof(TESMagicEffectApplyEvent) == 0x18);
}
@@ -0,0 +1,11 @@
#pragma once
namespace RE
{
class TESMagicTargetForm
{
public:
static constexpr auto RTTI{ RTTI::TESMagicTargetForm };
};
static_assert(std::is_empty_v<TESMagicTargetForm>);
}
@@ -0,0 +1,44 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class BGSModelMaterialSwap;
namespace BSResource
{
class ID;
}
class __declspec(novtable) TESModel :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESModel };
static constexpr auto VTABLE{ VTABLE::TESModel };
// override (BaseFormComponent)
void InitializeDataComponent() override; // 02
void ClearDataComponent() override; // 03
void CopyComponent(BaseFormComponent*) override; // 06
// add
virtual const char* GetModel() const { return model.c_str(); } // 07
virtual void SetModel(const char* a_model) { model = a_model; } // 08
virtual BGSModelMaterialSwap* GetAsModelMaterialSwap() { return nullptr; } // 09
// members
BSFixedString model; // 08
BSResource::ID* textures; // 10
BSResource::ID* materials; // 18
std::uint32_t* addons; // 20
std::int8_t numTextures; // 28
std::int8_t numTexturesSRGB; // 29
std::int8_t numAddons; // 2A
std::int8_t numMaterials; // 2B
std::int8_t flags; // 2C
};
static_assert(sizeof(TESModel) == 0x30);
}
@@ -0,0 +1,15 @@
#pragma once
#include "RE/T/TESModel.h"
namespace RE
{
class __declspec(novtable) TESModelRDT :
public TESModel // 00
{
public:
static constexpr auto RTTI{ RTTI::TESModelRDT };
static constexpr auto VTABLE{ VTABLE::TESModelRDT };
};
static_assert(sizeof(TESModelRDT) == 0x30);
}
@@ -0,0 +1,15 @@
#pragma once
#include "RE/T/TESModel.h"
namespace RE
{
class __declspec(novtable) TESModelTri :
public TESModel // 00
{
public:
static constexpr auto RTTI{ RTTI::TESModelTri };
static constexpr auto VTABLE{ VTABLE::TESModelTri };
};
static_assert(sizeof(TESModelTri) == 0x30);
}
@@ -0,0 +1,212 @@
#pragma once
#include "RE/B/BGSAttachParentArray.h"
#include "RE/B/BGSCharacterMorph.h"
#include "RE/B/BGSCharacterTint.h"
#include "RE/B/BGSForcedLocRefType.h"
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BGSNativeTerminalForm.h"
#include "RE/B/BGSOverridePackCollection.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTEvent.h"
#include "RE/B/BSTHashMap.h"
#include "RE/N/NPC_DATA.h"
#include "RE/N/NiPoint3.h"
#include "RE/P/PerkRankData.h"
#include "RE/S/SEX.h"
#include "RE/T/TESActorBase.h"
#include "RE/T/TESRaceForm.h"
#include "RE/T/TESSpellList.h"
namespace RE
{
class BGSRelationship;
class CreatureSounds;
class MenuOpenCloseEvent;
class __declspec(novtable) TESNPC :
public TESActorBase, // 000
public TESRaceForm, // 1B0
public BGSOverridePackCollection, // 1C0
public BGSForcedLocRefType, // 1F8
public BGSNativeTerminalForm, // 208
public BSTEventSink<MenuOpenCloseEvent> // 218
{
public:
static constexpr auto RTTI{ RTTI::TESActorBase };
static constexpr auto VTABLE{ VTABLE::TESActorBase };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kNPC_ };
class HeadRelatedData
{
public:
// members
BGSColorForm* hairColor; // 00
BGSColorForm* facialHairColor; // 08
BGSTextureSet* faceDetails; // 10
};
static_assert(sizeof(HeadRelatedData) == 0x18);
void CopyPerkRankArray(const std::vector<PerkRankData>& a_copiedData);
bool AddPerk(BGSPerk* a_perk, std::int8_t a_rank)
{
if (!GetPerkIndex(a_perk)) {
std::vector<PerkRankData> storage{ &perks[0], &perks[perkCount] };
auto perk = new PerkRankData(a_perk, a_rank);
storage.push_back(*perk);
AllocatePerkRankArray(static_cast<std::uint32_t>(storage.size()));
std::ranges::copy(storage, perks);
return true;
}
return false;
}
bool AddPerks(const std::vector<BGSPerk*>& a_perks, std::int8_t a_rank);
[[nodiscard]] bool ContainsKeyword(std::string_view a_editorID) const;
[[nodiscard]] static BSTHashMap<const TESNPC*, BSTArray<BGSHeadPart*>>& GetAlternateHeadPartListMap()
{
static REL::Relocation<BSTHashMap<const TESNPC*, BSTArray<BGSHeadPart*>>*> map{ ID::TESNPC::AlternateHeadPartListMap, -0x8 };
return *map;
}
[[nodiscard]] std::span<BGSHeadPart*> GetHeadParts(bool a_alternate = true) const
{
if (a_alternate && UsingAlternateHeadPartList()) {
auto& map = GetAlternateHeadPartListMap();
const auto it = map.find(this);
if (it != map.end()) {
return { it->second.data(), it->second.size() };
} else {
return {};
}
} else {
return { headParts, static_cast<std::size_t>(numHeadParts) };
}
}
[[nodiscard]] std::optional<std::uint32_t> GetPerkIndex(BGSPerk* a_perk) const
{
if (perks) {
for (std::uint32_t i = 0; i < perkCount; i++) {
if (perks[i].perk == a_perk) {
return i;
}
}
}
return std::nullopt;
}
[[nodiscard]] TESNPC* GetRootFaceNPC() noexcept
{
return const_cast<TESNPC*>(static_cast<const TESNPC*>(this)->GetRootFaceNPC());
}
[[nodiscard]] const TESNPC* GetRootFaceNPC() const noexcept
{
auto root = this;
while (root->faceNPC) {
root = root->faceNPC;
}
return root;
}
[[nodiscard]] SEX GetSex() noexcept
{
using func_t = decltype(&TESNPC::GetSex);
static REL::Relocation<func_t> func{ ID::TESNPC::GetSex };
return func(this);
}
[[nodiscard]] TESSpellList::SpellData* GetSpellList()
{
if (!spellData) {
spellData = new TESSpellList::SpellData();
}
return spellData;
}
[[nodiscard]] bool HasApplicableKeywordString(std::string_view a_editorID) const;
bool RemovePerks(const std::vector<BGSPerk*>& a_perks);
[[nodiscard]] bool IsInFaction(const TESFaction* a_faction)
{
for (const auto& faction : factions) {
if (faction.faction == a_faction && faction.rank > -1) {
return true;
}
}
return false;
}
[[nodiscard]] bool UsingAlternateHeadPartList() const;
float GetFacialBoneMorphIntensity()
{
using func_t = decltype(&TESNPC::GetFacialBoneMorphIntensity);
static REL::Relocation<func_t> func{ ID::TESNPC::GetFacialBoneMorphIntensity };
return func(this);
}
void SetHairColor(BGSColorForm* a_col)
{
using func_t = decltype(&TESNPC::SetHairColor);
static REL::Relocation<func_t> func{ ID::TESNPC::SetHairColor };
return func(this, a_col);
}
[[nodiscard]] const char* GetShortName() noexcept
{
using func_t = decltype(&TESNPC::GetShortName);
static REL::Relocation<func_t> func{ ID::TESNPC::GetShortName };
return func(this);
}
// members
BGSAttachParentArray attachParents; // 220
NPC_DATA data; // 238
TESClass* cl; // 240
HeadRelatedData* headRelatedData; // 248
BGSListForm* giftFilter; // 250
TESCombatStyle* combatStyle; // 258
std::uint32_t fileOffset; // 260
TESRace* originalRace; // 268
TESNPC* faceNPC; // 270
NiPoint3 morphWeight; // 278
float height; // 284
float heightMax; // 288
union
{
TESNPC* soundCreature;
CreatureSounds* creatureSounds;
}; // 290
BGSLocalizedString shortName; // 298
TESObjectARMO* farSkin; // 2A0
TESFurniture* powerArmorFurn; // 2A8
BGSOutfit* defOutfit; // 2B0
BGSOutfit* sleepOutfit; // 2B8
BGSListForm* defaultPackList; // 2C0
TESFaction* crimeFaction; // 2C8
BGSHeadPart** headParts; // 2D0
BSTArray<float>* morphRegionSliderValues; // 2D8
BSTHashMap<std::uint32_t, BGSCharacterMorph::Transform>* facialBoneRegionSliderValues; // 2E0
std::int8_t numHeadParts; // 2E8
std::int8_t soundLevel; // 2E9
std::int8_t bodyTintColorR; // 2EA
std::int8_t bodyTintColorG; // 2EN
std::int8_t bodyTintColorB; // 2EC
std::int8_t bodyTintColorA; // 2ED
BSTArray<BGSRelationship*>* relationships; // 2F0
BSTHashMap<std::uint32_t, float>* morphSliderValues; // 2F8
BGSCharacterTint::Entries* tintingData; // 300
};
static_assert(sizeof(TESNPC) == 0x308);
}
@@ -0,0 +1,33 @@
#pragma once
#include "RE/N/NiPointer.h"
#include "RE/T/TESForm.h"
namespace RE
{
class NiAVObject;
class __declspec(novtable) TESObject :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::TESObject };
static constexpr auto VTABLE{ VTABLE::TESObject };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kNONE };
// add
virtual bool IsBoundAnimObject() { return false; } // 4A
virtual TESWaterForm* GetWaterType() const { return nullptr; } // 4B
virtual bool IsAutoCalc() const { return false; } // 4C
virtual void SetAutoCalc(bool) { return; } // 4D
virtual void Clone3D(TESObjectREFR*, NiPointer<NiAVObject>&, bool) { return; } // 4E
virtual void UnClone3D(TESObjectREFR* a_requester); // 4F
virtual bool IsMarker(); // 50
virtual bool IsOcclusionMarker(); // 51
virtual bool ReplaceModel(); // 52
virtual std::uint32_t IncRef() { return 0; } // 53
virtual std::uint32_t DecRef() { return 0; } // 54
virtual NiAVObject* LoadGraphics(TESObjectREFR* a_ref); // 55
};
static_assert(sizeof(TESObject) == 0x20);
}
@@ -0,0 +1,51 @@
#pragma once
#include "RE/B/BGSDestructibleObjectForm.h"
#include "RE/B/BGSForcedLocRefType.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BGSNativeTerminalForm.h"
#include "RE/B/BGSNavmeshableObject.h"
#include "RE/B/BGSOpenCloseForm.h"
#include "RE/B/BGSPropertySheet.h"
#include "RE/T/TESBoundAnimObject.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESMagicTargetForm.h"
namespace RE
{
class __declspec(novtable) TESObjectACTI :
public TESBoundAnimObject, // 000
public TESFullName, // 068
public BGSModelMaterialSwap, // 078
public TESMagicTargetForm, // 120
public BGSDestructibleObjectForm, // 0B8
public BGSOpenCloseForm, // 0C8
public BGSKeywordForm, // 0D0
public BGSPropertySheet, // 0F0
public BGSForcedLocRefType, // 100
public BGSNativeTerminalForm, // 110
public BGSNavmeshableObject // 120
{
public:
static constexpr auto RTTI{ RTTI::TESObjectACTI };
static constexpr auto VTABLE{ VTABLE::TESObjectACTI };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kACTI };
enum class ActiFlags
{
kNoDisplacement = 0x1,
kNoSandbox = 0x2,
kIsProceduralWater = 0x4,
kIsLODWater = 0x8,
kIsRadio = 0x10
};
// members
BGSSoundDescriptorForm* soundLoop; // 128
BGSSoundDescriptorForm* soundActivate; // 130
TESWaterForm* waterForm; // 138
std::uint16_t flags; // 140
};
static_assert(sizeof(TESObjectACTI) == 0x148);
}
@@ -0,0 +1,18 @@
#pragma once
namespace RE
{
namespace TESObjectACTIDefs
{
struct alignas(0x08) RadioReceiverData
{
public:
BGSSoundOutput* outputOverride; // 00
float frequency; // 08
float volume; // 0C
bool active; // 10
bool noStatic; // 11
};
static_assert(sizeof(RadioReceiverData) == 0x18);
}
}
@@ -0,0 +1,23 @@
#pragma once
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BSFixedString.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) TESObjectANIO :
public TESForm, // 00
public BGSModelMaterialSwap // 20
{
public:
static constexpr auto RTTI{ RTTI::TESObjectANIO };
static constexpr auto VTABLE{ VTABLE::TESObjectANIO };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kANIO };
// members
BSFixedString formEditorID; // 60
BSFixedString unloadEventName; // 68
};
static_assert(sizeof(TESObjectANIO) == 0x70);
}
@@ -0,0 +1,38 @@
#pragma once
#include "RE/B/BGSBipedObjectForm.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTHashMap.h"
#include "RE/N/NiPoint3.h"
#include "RE/O/OBJ_ARMA.h"
#include "RE/T/TESObject.h"
#include "RE/T/TESRaceForm.h"
namespace RE
{
class __declspec(novtable) TESObjectARMA :
public TESObject, // 000
public TESRaceForm, // 020
public BGSBipedObjectForm // 030
{
public:
static constexpr auto RTTI{ RTTI::TESObjectARMA };
static constexpr auto VTABLE{ VTABLE::TESObjectARMA };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kARMA };
// members
OBJ_ARMA data; // 040
BGSModelMaterialSwap bipedModel[2]; // 050
BGSModelMaterialSwap bipedModelFacebones[2]; // 0D0
BGSModelMaterialSwap bipedModel1stPerson[2]; // 150
BGSTextureSet* skinTextures[2]; // 1D0
BGSListForm* skinTextureSwapLists[2]; // 1E0
BSTArray<TESRace*> additionalRaces; // 1F0
BGSFootstepSet* footstepSet; // 208
BGSArtObject* artObject; // 210
BSTHashMap<BSFixedString, NiPoint3>* scaleModifiers[2]; // 218
};
static_assert(sizeof(TESObjectARMA) == 0x228);
}
@@ -0,0 +1,92 @@
#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/BGSEquipType.h"
#include "RE/B/BGSInstanceNamingRulesForm.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSPickupPutdownSounds.h"
#include "RE/B/BGSTypedFormValuePair.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTTuple.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
{
enum class STAGGER_MAGNITUDE;
class __declspec(novtable) TESObjectARMO :
public TESBoundObject, // 000
public TESFullName, // 068
public TESRaceForm, // 078
public TESEnchantableForm, // 088
public BGSDestructibleObjectForm, // 0A0
public BGSPickupPutdownSounds, // 0B0
public TESBipedModelForm, // 0C8
public BGSEquipType, // 1D0
public BGSBipedObjectForm, // 1E0
public BGSBlockBashData, // 1F0
public BGSKeywordForm, // 208
public TESDescription, // 228
public BGSInstanceNamingRulesForm // 240
{
public:
static constexpr auto RTTI{ RTTI::TESObjectARMO };
static constexpr auto VTABLE{ VTABLE::TESObjectARMO };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kARMO };
class __declspec(novtable) InstanceData :
public TBO_InstanceData // 00
{
public:
static constexpr auto RTTI{ RTTI::TESObjectARMO__InstanceData };
static constexpr auto VTABLE{ VTABLE::TESObjectARMO__InstanceData };
// members
BSTArray<EnchantmentItem*>* enchantments; // 10
BSTArray<BGSMaterialSwap*>* materialSwaps; // 18
BGSBlockBashData* blockBashData; // 20
BGSKeywordForm* keywords; // 28
BSTArray<BSTTuple<TESForm*, BGSTypedFormValuePair::SharedVal>>* damageTypes; // 30
BSTArray<BSTTuple<TESForm*, BGSTypedFormValuePair::SharedVal>>* actorValues; // 38
float weight; // 40
float colorRemappingIndex; // 44
std::uint32_t value; // 48
std::uint32_t health; // 4C
REX::TEnumSet<STAGGER_MAGNITUDE, std::int32_t> staggerRating; // 50
std::uint16_t rating; // 54
std::uint16_t index; // 56
};
static_assert(sizeof(InstanceData) == 0x58);
class ArmorAddon
{
public:
// members
std::uint16_t index; // 00
TESObjectARMA* armorAddon; // 08
};
static_assert(sizeof(ArmorAddon) == 0x10);
bool Protects(const ActorValueInfo* a_condition, bool a_only)
{
using func_t = decltype(&TESObjectARMO::Protects);
static REL::Relocation<func_t> func{ ID::TESObjectARMO::Protects };
return func(this, a_condition, a_only);
}
// members
InstanceData armorData; // 250
BSTArray<ArmorAddon> modelArray; // 2A8
TESObjectARMO* armorTemplate; // 2C0
BGSAttachParentArray attachParents; // 2C8
};
static_assert(sizeof(TESObjectARMO) == 0x2E0);
}
@@ -0,0 +1,44 @@
#pragma once
#include "RE/B/BGSDestructibleObjectForm.h"
#include "RE/B/BGSFeaturedItemMessage.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSMessageIcon.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BGSPickupPutdownSounds.h"
#include "RE/O/OBJ_BOOK.h"
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESDescription.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESIcon.h"
#include "RE/T/TESValueForm.h"
#include "RE/T/TESWeightForm.h"
namespace RE
{
class __declspec(novtable) TESObjectBOOK :
public TESBoundObject, // 000
public TESFullName, // 068
public BGSModelMaterialSwap, // 078
public TESIcon, // 0B8
public TESValueForm, // 0C8
public TESWeightForm, // 0D8
public TESDescription, // 0E8
public BGSDestructibleObjectForm, // 100
public BGSMessageIcon, // 110
public BGSPickupPutdownSounds, // 128
public BGSKeywordForm, // 140
public BGSFeaturedItemMessage // 160
{
public:
static constexpr auto RTTI{ RTTI::TESObjectBOOK };
static constexpr auto VTABLE{ VTABLE::TESObjectBOOK };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kBOOK };
// members
OBJ_BOOK data; // 170
TESObjectSTAT* inventoryModel; // 188
TESDescription itemCardDescription; // 190
};
static_assert(sizeof(TESObjectBOOK) == 0x1A8);
}
@@ -0,0 +1,262 @@
#pragma once
#include "RE/B/BSContainer.h"
#include "RE/B/BSSpinLock.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTHashMap.h"
#include "RE/B/BSTSmartPointer.h"
#include "RE/N/NiPointer.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESFullName.h"
namespace RE
{
class bhkPickData;
class bhkWorldM;
class EXTERIOR_DATA;
class ExtraDataList;
class INTERIOR_DATA;
class LOADED_CELL_DATA;
class NavMeshArray;
class NiAVObject;
class NiPoint3;
class TESRegionList;
namespace BGSWaterCollisionManager
{
class AutoWater;
class BGSWaterUpdateI;
}
class __declspec(novtable) TESObjectCELL :
public TESForm, // 0x00
public TESFullName // 0x20
{
public:
static constexpr auto RTTI{ RTTI::TESObjectCELL };
static constexpr auto VTABLE{ VTABLE::TESObjectCELL };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kCELL };
enum class CELL_STATE : std::uint8_t
{
kNotLoaded = 0x0,
kUnloading = 0x1,
kLoadingData = 0x2,
kLoading = 0x3,
kLoaded = 0x4,
kDetaching = 0x5,
kAttachQueued = 0x6,
kAttaching = 0x7,
kAttached = 0x8
};
enum class CELLNODE
{
kActor = 0x0,
kMarker = 0x1,
kLand = 0x2,
kStatic = 0x3,
kDynamic = 0x4,
kOcclusionPlane = 0x5,
kPortal = 0x6,
kMultibound = 0x7,
kCollision = 0x8,
kSmallObjects = 0x9,
kLightMarker = 0xA,
kSoundMarker = 0xB
};
enum class CELL_CULL_NODE
{
kActor = 0x0,
kMarker = 0x1,
kLand = 0x2,
kStatic = 0x3,
kDynamic = 0x4,
kOcclusionPlane = 0x5,
kPortal = 0x6,
kMultibound = 0x7,
kCollision = 0x8,
kLightMarker = 0x9,
kSoundMarker = 0xA,
kWater = 0xB
};
enum class Flag
{
kInterior = 1u << 0,
kHasWater = 1u << 1,
kWarnToLeave = 1u << 9,
};
enum class QUAD_HIDE_STATE
{
kNormal = 0x0,
kCulled = 0x1,
kMissing = 0x2
};
enum class MARKERNODECHILD
{
kLightMarker = 0x0,
kSoundMarker = 0x1
};
union CELL_DATA
{
EXTERIOR_DATA* exterior; // XCLC
INTERIOR_DATA* interior; // XCLL
};
class RENDER_DATA
{
public:
// members
std::uint32_t geometryCount; // 00
std::uint32_t triangleCount; // 04
std::uint32_t newRenderPassCoutn; // 08
std::uint32_t activeLights; // 0C
std::uint64_t totalTime; // 10
std::uint32_t accumulateTime; // 18
};
static_assert(sizeof(RENDER_DATA) == 0x20);
[[nodiscard]] bhkWorldM* GetbhkWorld() const
{
using func_t = decltype(&TESObjectCELL::GetbhkWorld);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::GetbhkWorld };
return func(this);
}
[[nodiscard]] bool GetCantWaitHere()
{
using func_t = decltype(&TESObjectCELL::GetCantWaitHere);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::GetCantWaitHere };
return func(this);
}
[[nodiscard]] std::int32_t GetDataX()
{
using func_t = decltype(&TESObjectCELL::GetDataX);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::GetDataX };
return func(this);
}
[[nodiscard]] std::int32_t GetDataY()
{
using func_t = decltype(&TESObjectCELL::GetDataY);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::GetDataY };
return func(this);
}
[[nodiscard]] BGSEncounterZone* GetEncounterZone() const
{
using func_t = decltype(&TESObjectCELL::GetEncounterZone);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::GetEncounterZone };
return func(this);
}
[[nodiscard]] BGSLocation* GetLocation() const
{
using func_t = decltype(&TESObjectCELL::GetLocation);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::GetLocation };
return func(this);
}
[[nodiscard]] TESForm* GetOwner()
{
using func_t = decltype(&TESObjectCELL::GetOwner);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::GetOwner };
return func(this);
}
[[nodiscard]] TESRegionList* GetRegionList(bool a_createIfMissing)
{
using func_t = decltype(&TESObjectCELL::GetRegionList);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::GetRegionList };
return func(this, a_createIfMissing);
}
[[nodiscard]] NiAVObject* Pick(bhkPickData& pd)
{
using func_t = decltype(&TESObjectCELL::Pick);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::Pick };
return func(this, pd);
}
void SetCullCellMarkers(bool a_cull)
{
using func_t = decltype(&TESObjectCELL::SetCullCellMarkers);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::SetCullCellMarkers };
return func(this, a_cull);
}
void UpdateAllRefsLoaded()
{
using func_t = decltype(&TESObjectCELL::UpdateAllRefsLoaded);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::UpdateAllRefsLoaded };
return func(this);
}
void AttatchReference3D(TESObjectREFR* a_ref, bool a_onTop, bool a_queueAttatch)
{
using func_t = decltype(&TESObjectCELL::AttatchReference3D);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::AttatchReference3D };
return func(this, a_ref, a_onTop, a_queueAttatch);
}
void RemoveReference(TESObjectREFR* a_ref)
{
using func_t = decltype(&TESObjectCELL::RemoveReference);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::RemoveReference };
return func(this, a_ref);
}
void UpdateAllDecals()
{
using func_t = decltype(&TESObjectCELL::UpdateAllDecals);
static REL::Relocation<func_t> func{ ID::TESObjectCELL::UpdateAllDecals };
return func(this);
}
EXTERIOR_DATA* GetCoordinates() const;
[[nodiscard]] TESWaterForm* GetWaterType() const noexcept;
[[nodiscard]] bool HasWater() const noexcept { return cellFlags.all(Flag::kHasWater); }
[[nodiscard]] bool IsAttached() const noexcept { return cellState == CELL_STATE::kAttached; }
[[nodiscard]] bool IsExterior() const noexcept { return !IsInterior(); }
[[nodiscard]] bool IsInterior() const noexcept { return cellFlags.all(Flag::kInterior); }
void ForEachReference(std::function<BSContainer::ForEachResult(TESObjectREFR*)> a_callback);
void ForEachReferenceInRange(const NiPoint3& a_origin, float a_radius, std::function<BSContainer::ForEachResult(TESObjectREFR*)> a_callback);
// members
BSSpinLock grassCreateLock; // 0x30
BSSpinLock grassTaskLock; // 0x38
REX::TEnumSet<Flag, std::uint16_t> cellFlags; // 0x40
std::uint16_t cellGameFlags; // 0x42
CELL_STATE cellState; // 0x44
bool autoWaterLoaded; // 0x45
bool cellDetached; // 0x46
BSTSmartPointer<ExtraDataList> extraList; // 0x48
CELL_DATA cellData; // 0x50
TESObjectLAND* cellLand; // 0x58
float waterHeight; // 0x60
NavMeshArray* navMeshes; // 0x68
BSTArray<NiPointer<TESObjectREFR>> references; // 0x70
BSTSmartPointer<BGSWaterCollisionManager::AutoWater> autoWater; // 0x77
BSTSet<BSTSmartPointer<BGSWaterCollisionManager::BGSWaterUpdateI>> waterSet; // 0x80
BSSpinLock spinLock; // 0xC0
union
{
TESWorldSpace* worldSpace;
std::uint32_t tempDataOffset;
}; // 0xC8
LOADED_CELL_DATA* loadedData; // 0xD0
BGSLightingTemplate* lightingTemplate; // 0xD8
void* visibilityData; // 0xE0 - TODO
std::uint32_t rootVisibilityCellID; // 0xE8
std::uint16_t visCalcDate; // 0xEC
std::uint16_t preCombineDate; // 0xF0
};
static_assert(sizeof(TESObjectCELL) == 0xF0);
}
@@ -0,0 +1,54 @@
#pragma once
#include "RE/B/BGSDestructibleObjectForm.h"
#include "RE/B/BGSForcedLocRefType.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BGSNativeTerminalForm.h"
#include "RE/B/BGSOpenCloseForm.h"
#include "RE/B/BGSPropertySheet.h"
#include "RE/C/CONT_DATA.h"
#include "RE/T/TESBoundAnimObject.h"
#include "RE/T/TESContainer.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESMagicCasterForm.h"
#include "RE/T/TESMagicTargetForm.h"
#include "RE/T/TESWeightForm.h"
namespace RE
{
class __declspec(novtable) TESObjectCONT :
public TESBoundAnimObject, // 000
public TESContainer, // 068
public TESFullName, // 080
public BGSModelMaterialSwap, // 090
public TESWeightForm, // 0D0
public TESMagicCasterForm, // 148
public TESMagicTargetForm, // 148
public BGSDestructibleObjectForm, // 0E0
public BGSOpenCloseForm, // 0F0
public BGSKeywordForm, // 0F8
public BGSForcedLocRefType, // 118
public BGSPropertySheet, // 128
public BGSNativeTerminalForm // 138
{
public:
static constexpr auto RTTI{ RTTI::TESObjectCONT };
static constexpr auto VTABLE{ VTABLE::TESObjectCONT };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kCONT };
enum class Flags : std::int8_t
{
kRespawn = 0x2,
kShowOwner = 0x4
};
// members
CONT_DATA data; // 149
BGSSoundDescriptorForm* openSound; // 150
BGSSoundDescriptorForm* closeSound; // 158
BGSSoundDescriptorForm* takeAllSound; // 160
BGSListForm* containsOnlyList; // 168
};
static_assert(sizeof(TESObjectCONT) == 0x170);
}
@@ -0,0 +1,43 @@
#pragma once
#include "RE/B/BGSDestructibleObjectForm.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BGSNativeTerminalForm.h"
#include "RE/B/BGSOpenCloseForm.h"
#include "RE/B/BSTArray.h"
#include "RE/T/TESBoundAnimObject.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESMagicCasterForm.h"
#include "RE/T/TESMagicTargetForm.h"
namespace RE
{
class __declspec(novtable) TESObjectDOOR :
public TESBoundAnimObject, // 000
public TESFullName, // 068
public BGSModelMaterialSwap, // 078
public TESMagicCasterForm, // 100
public TESMagicTargetForm, // 100
public BGSDestructibleObjectForm, // 0B8
public BGSOpenCloseForm, // 0C8
public BGSKeywordForm, // 0D0
public BGSNativeTerminalForm // 0F0
{
public:
static constexpr auto RTTI{ RTTI::TESObjectDOOR };
static constexpr auto VTABLE{ VTABLE::TESObjectDOOR };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kDOOR };
// members
BGSLocalizedString altOpenText; // 108
BGSLocalizedString altCloseText; // 110
BGSSoundDescriptorForm* openSound; // 118
BGSSoundDescriptorForm* closeSound; // 120
BGSSoundDescriptorForm* loopSound; // 128
std::int8_t flags; // 130
BSTArray<TESForm*> randomTeleports; // 138
};
static_assert(sizeof(TESObjectDOOR) == 0x150);
}
@@ -0,0 +1,62 @@
#pragma once
#include "RE/B/BSTArray.h"
#include "RE/C/CHAR_NORM.h"
#include "RE/H/hkRefPtr.h"
#include "RE/N/NiPointer.h"
#include "RE/O/OBJ_LAND.h"
#include "RE/T/TESChildCell.h"
#include "RE/T/TESForm.h"
namespace RE
{
class QueuedFile;
class __declspec(novtable) TESObjectLAND :
public TESForm, // 00
public TESChildCell // 20
{
public:
static constexpr auto RTTI{ RTTI::TESObjectLAND };
static constexpr auto VTABLE{ VTABLE::TESObjectLAND };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kLAND };
enum class COORD_DATA_FLAGS
{
kVertexCoord = 0x1,
kForceToVertex = 02,
kCalcNearest = 0x4,
kBlockOnly = 0x8,
kDefaults = 0x5
};
class LoadedLandData
{
public:
// members
NiNode* mesh[4]; // 0000
float heights[1156]; // 0020
std::uint8_t percentArrays[4][289][12]; // 1230
std::uint8_t colors[4][289][3]; // 4860
CHAR_NORM normals[4][289]; // 55EC
BSTArray<hkRefPtr<hknpShape const>, BSTArrayHeapAllocator> saveLoadHFData; // 6378
NiPointer<BSTriShape> geom[4]; // 6390
NiPointer<BSTriShape> border; // 63B0
NiPoint2 heightExtends; // 63B8
TESLandTexture* defQuadTexture[4]; // 63C0
TESLandTexture* quadTextureArray[4][12]; // 63E0
std::int32_t cellX; // 6560
std::int32_t cellY; // 6564
float baseHeight; // 6568
LoadedLandData* next; // 6570
};
static_assert(sizeof(LoadedLandData) == 0x6578);
// members
OBJ_LAND data; // 28
TESObjectCELL* parentCell; // 30
NiPointer<QueuedFile> queuedTextures; // 38
LoadedLandData* loadedData; // 40
};
static_assert(sizeof(TESObjectLAND) == 0x48);
}
@@ -0,0 +1,48 @@
#pragma once
#include "RE/B/BGSDestructibleObjectForm.h"
#include "RE/B/BGSEquipType.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSMessageIcon.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BGSOpenCloseForm.h"
#include "RE/B/BGSPropertySheet.h"
#include "RE/N/NiColor.h"
#include "RE/O/OBJ_LIGH.h"
#include "RE/T/TESBoundAnimObject.h"
#include "RE/T/TESIcon.h"
#include "RE/T/TESTexture.h"
#include "RE/T/TESValueForm.h"
#include "RE/T/TESWeightForm.h"
namespace RE
{
class __declspec(novtable) TESObjectLIGH :
public TESBoundAnimObject, // 000
public BGSModelMaterialSwap, // 068
public TESIcon, // 0A8
public BGSMessageIcon, // 0B8
public TESWeightForm, // 0D0
public TESValueForm, // 0E0
public BGSDestructibleObjectForm, // 0F0
public BGSEquipType, // 100
public BGSPropertySheet, // 110
public BGSOpenCloseForm, // 120
public BGSKeywordForm // 128
{
public:
static constexpr auto RTTI{ RTTI::TESObjectLIGH };
static constexpr auto VTABLE{ VTABLE::TESObjectLIGH };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kLIGH };
// members
OBJ_LIGH data; // 148
float fade; // 180
BGSSoundDescriptorForm* sound; // 188
TESTexture goboTexture; // 190
NiColor emittanceColor; // 1A0
BGSLensFlare* lensFlare; // 1B0
BGSGodRays* godRays; // 1B8
};
static_assert(sizeof(TESObjectLIGH) == 0x1C0);
}
@@ -0,0 +1,22 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class TESObjectLoadedEvent
{
public:
[[nodiscard]] static BSTEventSource<TESObjectLoadedEvent>* GetEventSource()
{
using func_t = decltype(&TESObjectLoadedEvent::GetEventSource);
static REL::Relocation<func_t> func{ ID::TESObjectLoadedEvent::GetEventSource };
return func();
}
// members
TESFormID formID; // 00
bool loaded; // 04
};
static_assert(sizeof(TESObjectLoadedEvent) == 0x8);
}
@@ -0,0 +1,52 @@
#pragma once
#include "RE/B/BGSDestructibleObjectForm.h"
#include "RE/B/BGSFeaturedItemMessage.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSMessageIcon.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BGSPickupPutdownSounds.h"
#include "RE/B/BGSTypedFormValuePair.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTTuple.h"
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESIcon.h"
#include "RE/T/TESValueForm.h"
#include "RE/T/TESWeightForm.h"
namespace RE
{
class __declspec(novtable) TESObjectMISC :
public TESBoundObject, // 000
public TESFullName, // 068
public BGSModelMaterialSwap, // 078
public TESIcon, // 0B8
public TESValueForm, // 0C8
public TESWeightForm, // 0D8
public BGSDestructibleObjectForm, // 0E8
public BGSMessageIcon, // 0F8
public BGSPickupPutdownSounds, // 110
public BGSKeywordForm, // 128
public BGSFeaturedItemMessage // 148
{
public:
static constexpr auto RTTI{ RTTI::TESObjectMISC };
static constexpr auto VTABLE{ VTABLE::TESObjectMISC };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kMISC };
// add
virtual void SaveImpl() { return; } // 67
virtual void LoadImpl(TESFile*, CHUNK_ID) { return; } // 68
[[nodiscard]] bool IsLooseMod() const noexcept
{
return ((formFlags & 0x80) != 0);
}
// members
BSTArray<BSTTuple<TESForm*, BGSTypedFormValuePair::SharedVal>>* componentData; // 158
std::int8_t* displayIndices; // 160
};
static_assert(sizeof(TESObjectMISC) == 0x168);
}
@@ -0,0 +1,606 @@
#pragma once
#include "RE/A/ActorValueOwner.h"
#include "RE/B/BGSEquipIndex.h"
#include "RE/B/BGSInventoryItem.h"
#include "RE/B/BGSInventoryList.h"
#include "RE/B/BGSObjectInstance.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSHandleRefObject.h"
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSStringT.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTEvent.h"
#include "RE/B/BSTSmartPointer.h"
#include "RE/I/IAnimationGraphManagerHolder.h"
#include "RE/I/IKeywordFormBase.h"
#include "RE/I/ITEM_REMOVE_REASON.h"
#include "RE/M/MapMarkerData.h"
#include "RE/N/NiPoint3.h"
#include "RE/O/OBJ_REFR.h"
#include "RE/T/TESForm.h"
namespace RE
{
enum class BIPED_OBJECT;
enum class IO_TASK_PRIORITY;
enum class RESET_3D_FLAGS;
class ActorCause;
class BGSAnimationSequencer;
class BGSBehaviorRootData;
class BGSDecalGroup;
class BipedAnim;
class BSActiveGraphIfInactiveEvent;
class BSAnimationGraphEvent;
class BSAnimationUpdateData;
class BSFaceGenNiNode;
class DialogueResponse;
class ExtraDataList;
class hknpBodyId;
class hkVector4f;
class INSTANCE_FILTER;
class LOADED_REF_DATA;
class MagicCaster;
class MagicTarget;
class ModelReferenceEffect;
class NiAVObject;
class NiNode;
class NiTransform;
class REFR_LOCK;
class ShaderReferenceEffect;
class TargetEntry;
class TESModel;
class TrapData;
class TrapEntry;
namespace ActorValueEvents
{
class ActorValueChangedEvent;
}
namespace BGSInventoryListEvent
{
class Event;
}
namespace MagicSystem
{
enum class CastingSource;
}
class __declspec(novtable) TESObjectREFR :
public TESForm, // 000
public BSHandleRefObject, // 020
public BSTEventSink<BSActiveGraphIfInactiveEvent>, // 030
public BSTEventSink<BSAnimationGraphEvent>, // 038
public BSTEventSink<BGSInventoryListEvent::Event>, // 040
public IAnimationGraphManagerHolder, // 048
public IKeywordFormBase, // 050
public ActorValueOwner, // 058
public BSTEventSource<ActorValueEvents::ActorValueChangedEvent> // 060
{
public:
static constexpr auto RTTI{ RTTI::TESObjectREFR };
static constexpr auto VTABLE{ VTABLE::TESObjectREFR };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kREFR };
class RemoveItemData
{
public:
RemoveItemData(TESBoundObject* a_object, std::int32_t a_count) :
object(a_object), count(a_count)
{}
RemoveItemData(TESForm* a_form, std::int32_t a_count) :
RemoveItemData(a_form->As<TESBoundObject>(), a_count)
{}
// members
BSTSmallArray<std::uint32_t, 4> stackData; // 00
TESBoundObject* object{ nullptr }; // 20
std::int32_t count{ 0 }; // 28
ITEM_REMOVE_REASON reason{ ITEM_REMOVE_REASON::kNone }; // 2C
TESObjectREFR* otherContainer{ nullptr }; // 30
const NiPoint3* dropLoc{ nullptr }; // 38
const NiPoint3* rotate{ nullptr }; // 40
};
static_assert(sizeof(RemoveItemData) == 0x48);
F4_HEAP_REDEFINE_NEW(TESObjectREFR);
// add
virtual void Predestroy(); // 4A
virtual void PreModelLoaderQueueing() { return; } // 4B
virtual BGSLocation* GetEditorLocation() const; // 4C
virtual bool GetEditorLocation(NiPoint3& a_originalLocation, NiPoint3& a_originalAngle, TESForm*& a_locationFormOut, TESForm* a_locationForm); // 4D
virtual bool IsTalking() const; // 4E
virtual void ForceEditorLocation(BGSLocation* a_location); // 4F
virtual void Update3DPosition(bool a_warp); // 50
virtual void UpdateSoundCallBack(bool a_endSceneAction); // 51
virtual bool SetDialoguewithPlayer(bool a_flag, bool a_forceGreet, TESTopicInfo* a_topicInfo); // 52
virtual void AddDynamicIdleCRC([[maybe_unused]] std::uint32_t a_crc) { return; } // 53
virtual void GetPreviousDynamicIdleCRCS(std::uint32_t* a_crcs, std::uint32_t a_requestSize) const; // 54
virtual bool GetFullLODRef() const; // 55
virtual void SetFullLODRef(bool a_val); // 56
virtual BGSAnimationSequencer* GetSequencer() const; // 57
virtual bool QCanUpdateSync() const { return true; } // 58
virtual bool GetAllowPromoteToPersistent() const { return true; } // 59
virtual bool DoesFloat() const { return false; } // 5A
virtual TESPackage* CheckForCurrentAliasPackage() { return nullptr; } // 5B
virtual BGSScene* GetCurrentScene() const; // 5C
virtual void SetCurrentScene(BGSScene* a_scene); // 5D
virtual bool UpdateInDialogue(DialogueResponse* a_response, bool); // 5E
virtual BGSDialogueBranch* GetExclusiveBranch() const; // 5F
virtual void SetExclusiveBranch(BGSDialogueBranch* a_exclusiveBranch); // 60
virtual void StopCurrentDialogue(bool a_force); // 61
virtual void FadeCurrentDialogue(); // 62
virtual void PauseCurrentDialogue(); // 63
virtual void ResumeCurrentDialogue(); // 64
virtual void SetActorCause(ActorCause* a_actorCause); // 65
virtual ActorCause* GetActorCause() const; // 66
virtual float GetActorWidthOrRefDiameter() const; // 67
virtual float GetActorHeightOrRefBound() const; // 68
virtual NiPoint3 GetStartingAngle(); // 69
virtual NiPoint3 GetStartingLocation(); // 6A
virtual void SetStartingPosition(const NiPoint3& a_position); // 6B
virtual void UpdateRefLight(float a_delta); // 6C
virtual ObjectRefHandle RemoveItem(RemoveItemData& a_data); // 6D
virtual void AddWornOutfitImpl([[maybe_unused]] BGSOutfit* a_outfit, [[maybe_unused]] bool a_queueItem) { return; } // 6E
virtual bool AddWornItem(TESBoundObject* a_object, BSTSmartPointer<ExtraDataList> a_extra, std::int32_t a_number, bool a_forceEquip, BGSEquipIndex a_equipIndex); // 6F
virtual void DoTrap([[maybe_unused]] TrapEntry* a_trap, [[maybe_unused]] TargetEntry* a_target) { return; } // 71
virtual void DoTrap([[maybe_unused]] TrapData& a_trapData) { return; } // 70
virtual void SetEquipStateLocked(TESBoundObject* a_object, bool a_lock); // 72
virtual void SendContainerChangedEvent(const TESObjectREFR* a_oldContainer, const TESObjectREFR* apNewContainer, const TESBoundObject* a_baseObject, std::int32_t a_count, std::uint32_t a_referenceFormID, std::uint16_t a_uniqueID) const; // 73
virtual void UnequipArmorFromSlot([[maybe_unused]] BIPED_OBJECT a_bipedObject, [[maybe_unused]] bool a_markAsReequippable) { return; } // 74
virtual void RemoveAllObjectsWorn(); // 75
virtual void PostRemoveWornObject(const BGSObjectInstance& a_object, const BGSEquipSlot* a_equipSlot); // 76
virtual void Set3DUpdateFlag([[maybe_unused]] RESET_3D_FLAGS a_flag) { return; } // 77
virtual void ClearAll3DUpdateFlags() { return; } // 78
virtual float AdjustItemWeight([[maybe_unused]] TESBoundObject& a_object, [[maybe_unused]] const BGSInventoryItem::Stack& a_stack, float a_weight, [[maybe_unused]] bool* a_shouldModifyWholeStackOut) { return a_weight; } // 79
virtual void AddObjectToContainer(TESBoundObject* a_obj, BSTSmartPointer<ExtraDataList> a_extra, std::int32_t a_count, TESObjectREFR* a_oldContainer, ITEM_REMOVE_REASON a_reason); // 7A
virtual NiPoint3 GetLookingAtLocation() const; // 7B
virtual MagicCaster* GetMagicCaster(MagicSystem::CastingSource a_source); // 7C
virtual MagicTarget* GetMagicTarget(); // 7D
virtual bool IsChild() const { return false; } // 7E
virtual TESActorBase* GetTemplateActorBase() { return nullptr; } // 7F
virtual void SetTemplateActorBase(TESActorBase*) { return; } // 80
virtual BSFaceGenNiNode* GetFaceNodeSkinned() { return nullptr; } // 81
virtual BSFaceGenNiNode* GetFaceNode() { return GetFaceNodeSkinned(); } // 82
virtual bool ClampToGround(); // 83
virtual bool DetachHavok(NiAVObject* a_obj3D); // 84
virtual void InitHavok(); // 85
virtual NiAVObject* Load3D(bool a_backgroundLoading); // 86
virtual void Release3DRelatedData(); // 87
virtual void Set3D(NiAVObject* a_object, bool a_queue3DTasks); // 88
virtual bool ShouldBackgroundClone() const; // 89
virtual bool IsReadyForAttach([[maybe_unused]] const IO_TASK_PRIORITY& a_priority) const { return true; } // 8A
virtual NiAVObject* Get3D() const; // 8C
virtual NiAVObject* Get3D([[maybe_unused]] bool a_firstPerson) const { return Get3D(); } // 8B
virtual NiAVObject* GetFullyLoaded3D() const; // 8D
virtual bool Is3rdPersonVisible() const { return true; } // 8E
virtual bool PopulateGraphProjectsToLoad(const NiAVObject* a_obj3D, BSScrapArray<BSStaticStringT<260>>& a_projectFilenames) const; // 8F
virtual TESModel* GetTESModel() const; // 90
virtual TESRace* GetVisualsRace() const; // 91
virtual void GetPhysicsTransform(NiTransform& a_outTransform) const; // 92
virtual NiPoint3 GetBoundMin() const; // 93
virtual NiPoint3 GetBoundMax() const; // 94
virtual bool GetBehaviorRootNameOverrides([[maybe_unused]] BSScrapArray<BSFixedString>& a_behaviorRoots) const { return false; } // 95
virtual bool GetBehaviorRootNameReplacement([[maybe_unused]] BSFixedString& a_rootNameReplacement) const { return false; } // 96
virtual bool GetBehaviorRootData(bool a_onlyCollectActiveRoots, BSScrapArray<BGSBehaviorRootData>& a_behaviorRoots) const; // 97
virtual void OnHeadInitialized() { return; } // 98
virtual bool InitNonNPCAnimation(NiNode& a_nodeForAnim); // 99
virtual bool CheckAndFixSkinAndBoneOrder(NiNode& a_nodeToTest); // 9A
virtual void ModifyAnimationUpdateData([[maybe_unused]] BSAnimationUpdateData& a_updateData) { return; } // 9B
virtual bool ShouldSaveAnimationOnUnloading() const; // 9C
virtual bool ShouldSaveAnimationOnSaving() const; // 9D
virtual bool ShouldPerformRevert() const { return true; } // 9E
virtual void UpdateAnimation(float a_delta); // 9F
virtual void CollectPickNodes() { return; } // A0
virtual const BSTSmartPointer<BipedAnim>& GetBiped() const; // A2
virtual const BSTSmartPointer<BipedAnim>& GetBiped(bool a_firstPerson) const; // A1
virtual const BSTSmartPointer<BipedAnim>& GetCurrentBiped() const { return GetBiped(); } // A3
virtual void SetBiped([[maybe_unused]] const BSTSmartPointer<BipedAnim>& a_biped) { return; } // A4
virtual void AttachWeapon(const BGSObjectInstanceT<TESObjectWEAP>& a_weapon, BGSEquipIndex a_equipIndex); // A5
virtual void RemoveWeapon([[maybe_unused]] const BGSObjectInstanceT<TESObjectWEAP>& a_weapon, [[maybe_unused]] BGSEquipIndex a_equipIndex, [[maybe_unused]] bool a_queue3DTasks) { return; } // A6
virtual void CreateInventoryList(const TESContainer* a_container); // A7
virtual void DestroyInventoryList(); // A8
virtual void SetRunsInLow(bool) { return; } // A9
virtual void SetObjectReference(TESBoundObject* a_object); // AA
virtual void MoveHavok(bool a_forceRec); // AB
virtual void GetLinearVelocity(NiPoint3& a_velocity) const; // AC
virtual void ApplyMovementDelta(float a_timeDelta, const NiPoint3A& a_delta, const NiPoint3& a_angleDelta); // AD
virtual void SetActionComplete([[maybe_unused]] bool a_value) { return; } // AE
virtual void SetMovementComplete(bool) { return; } // AF
virtual void Disable(); // B0
virtual void ResetInventory(bool a_leveledOnly); // B1
virtual NiAVObject* GetCurrent3D() const { return Get3D(); } // B2
virtual Explosion* IsExplosion() { return nullptr; } // B4
virtual const Explosion* IsExplosion() const { return nullptr; } // B3
virtual Projectile* IsProjectile() { return nullptr; } // B6
virtual const Projectile* IsProjectile() const { return nullptr; } // B5
virtual bool OnAddCellPerformQueueReference([[maybe_unused]] TESObjectCELL& a_cell) const { return true; } // B7
virtual void DoMoveToHigh() { return; } // B8
virtual void TryMoveToMiddleLow() { return; } // B9
virtual bool TryChangeSkyCellActorsProcessLevel() { return false; } // BA
virtual void SetDisplayGeometry(bool) { return; } // BB
virtual void TryUpdateActorLastSeenTime() { return; } // BC
virtual void SaveGameTest(); // BD
virtual TESObjectCELL* GetSaveParentCell() const; // BE
virtual void SetParentCell(TESObjectCELL* a_cell); // BF
virtual bool IsDead(bool a_notEssential) const; // C0
virtual bool ProcessInWater(hknpBodyId a_bodyID, float a_waterHeight, float a_deltaTime); // C1
virtual bool ApplyCurrent([[maybe_unused]] float a_deltaTime, [[maybe_unused]] const hkVector4f& a_linVel, const hkVector4f&) { return false; } // C2
virtual BGSDecalGroup* GetDecalGroup() const; // C3
virtual void InitDefaultWornImpl(bool a_weapon, bool a_allowChanges); // C4
virtual bool HasKeywordHelper(const BGSKeyword* a_keyword, const TBO_InstanceData* a_data) const; // C5
bool ActivateRef(TESObjectREFR* a_actionRef, TESBoundObject* a_objectToGet, std::int32_t a_count, bool a_defaultProcessingOnly, bool a_fromScript, bool a_looping)
{
using func_t = decltype(&TESObjectREFR::ActivateRef);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::ActivateRef };
return func(this, a_actionRef, a_objectToGet, a_count, a_defaultProcessingOnly, a_fromScript, a_looping);
}
void AddInventoryItem(TESBoundObject* a_object, BSTSmartPointer<ExtraDataList> a_extra, std::uint32_t a_count, TESObjectREFR* a_oldContainer, const INSTANCE_FILTER* a_filter, TESObjectREFR* a_overrideRef)
{
using func_t = decltype(&TESObjectREFR::AddInventoryItem);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::AddInventoryItem };
return func(this, a_object, a_extra, a_count, a_oldContainer, a_filter, a_overrideRef);
}
void AddKeyword(BGSKeyword* kwd)
{
using func_t = decltype(&TESObjectREFR::AddKeyword);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::AddKeyword };
return func(this, kwd);
}
void AddLockChange()
{
using func_t = decltype(&TESObjectREFR::AddLockChange);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::AddLockChange };
return func(this);
}
ModelReferenceEffect* ApplyArtObject(
BGSArtObject* a_art,
float a_time = -1.0f,
TESObjectREFR* a_facingRef = nullptr,
bool a_attachToCamera = false,
bool a_inheritRotation = false,
NiAVObject* a_3D = nullptr,
bool a_interfaceEffect = false)
{
using func_t = decltype(&TESObjectREFR::ApplyArtObject);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::ApplyArtObject };
return func(this, a_art, a_time, a_facingRef, a_attachToCamera, a_inheritRotation, a_3D, a_interfaceEffect);
}
ShaderReferenceEffect* ApplyEffectShader(
TESEffectShader* a_art,
float a_time = -1.0f,
TESObjectREFR* a_facingRef = nullptr,
bool a_attachToCamera = false,
bool a_inheritRotation = false,
NiAVObject* a_3D = nullptr,
bool a_interfaceEffect = false)
{
using func_t = decltype(&TESObjectREFR::ApplyEffectShader);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::ApplyEffectShader };
return func(this, a_art, a_time, a_facingRef, a_attachToCamera, a_inheritRotation, a_3D, a_interfaceEffect);
}
void Enable(bool a_resetInventory)
{
using func_t = decltype(&TESObjectREFR::Enable);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::Enable };
return func(this, a_resetInventory);
}
static TESObjectREFR* FindReferenceFor3D(const NiAVObject* a_opbject3D)
{
using func_t = decltype(&TESObjectREFR::FindReferenceFor3D);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::FindReferenceFor3D };
return func(a_opbject3D);
}
void FindAndWriteStackDataForInventoryItem(
TESBoundObject* a_object,
BGSInventoryItem::StackDataCompareFunctor& a_compareFunc,
BGSInventoryItem::StackDataWriteFunctor& a_writeFunc,
bool (*a_objCompFn)(TESBoundObject*, TESBoundObject*) = BGSInventoryList::StandardObjectCompareCallbackFn,
bool a_alwaysContinue = false)
{
if (inventoryList) {
inventoryList->FindAndWriteStackDataForItem(a_object, a_compareFunc, a_writeFunc, a_objCompFn, a_alwaysContinue);
}
}
[[nodiscard]] BGSLocation* GetCurrentLocation() const
{
using func_t = decltype(&TESObjectREFR::GetCurrentLocation);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetCurrentLocation };
return func(this);
}
[[nodiscard]] const char* GetDisplayFullName()
{
using func_t = decltype(&TESObjectREFR::GetDisplayFullName);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetDisplayFullName };
return func(this);
}
[[nodiscard]] float GetDistanceFromPoint(const NiPoint3& a_point) const
{
using func_t = decltype(&TESObjectREFR::GetDistanceFromPoint);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetDistanceFromPoint };
return func(this, a_point);
}
[[nodiscard]] float GetDistanceFromReference(const TESObjectREFR* a_ref, bool a_disabled, bool a_sameSpace) const
{
using func_t = decltype(&TESObjectREFR::GetDistanceFromReference);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetDistanceFromReference };
return func(this, a_ref, a_disabled, a_sameSpace);
}
[[nodiscard]] float GetDistanceSqFromPoint(const NiPoint3& a_point) const
{
using func_t = decltype(&TESObjectREFR::GetDistanceSqFromPoint);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetDistanceSqFromPoint };
return func(this, a_point);
}
[[nodiscard]] float GetDistanceSqFromReference(const TESObjectREFR* a_ref, bool a_disabled, bool a_sameSpace, bool a_diffZHeight) const
{
using func_t = decltype(&TESObjectREFR::GetDistanceSqFromReference);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetDistanceSqFromReference };
return func(this, a_ref, a_disabled, a_sameSpace, a_diffZHeight);
}
[[nodiscard]] bool GetEditorDead() const
{
using func_t = decltype(&TESObjectREFR::GetEditorDead);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetEditorDead };
return func(this);
}
[[nodiscard]] TESBoundObject* GetObjectReference() const noexcept { return data.objectReference; }
[[nodiscard]] TESForm* GetOwner()
{
using func_t = decltype(&TESObjectREFR::GetOwner);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetOwner };
return func(this);
}
[[nodiscard]] TESObjectCELL* GetParentCell() const noexcept { return parentCell; }
[[nodiscard]] NiPoint3 GetPosition() const noexcept { return data.location; }
[[nodiscard]] float GetPositionX() const noexcept { return data.location.x; }
[[nodiscard]] float GetPositionY() const noexcept { return data.location.y; }
[[nodiscard]] float GetPositionZ() const noexcept { return data.location.z; }
[[nodiscard]] std::int64_t GetGoldAmount()
{
using func_t = decltype(&TESObjectREFR::GetGoldAmount);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetGoldAmount };
return func(this);
}
[[nodiscard]] ObjectRefHandle GetHandle()
{
using func_t = decltype(&TESObjectREFR::GetHandle);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetHandle };
return func(this);
}
[[nodiscard]] bool GetHasOwner()
{
using func_t = decltype(&TESObjectREFR::GetHasOwner);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetHasOwner };
return func(this);
}
[[nodiscard]] std::uint32_t GetInventoryObjectCount(const TESBoundObject* a_object)
{
using func_t = decltype(&TESObjectREFR::GetInventoryObjectCount);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetInventoryObjectCount };
return func(this, a_object);
}
[[nodiscard]] TESObjectREFR* GetLinkedRef(BGSKeyword* a_keyword)
{
using func_t = decltype(&TESObjectREFR::GetLinkedRef);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetLinkedRef };
return func(this, a_keyword);
}
[[nodiscard]] REFR_LOCK* GetLock()
{
using func_t = decltype(&TESObjectREFR::GetLock);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetLock };
return func(this);
}
[[nodiscard]] float GetWeightInContainer()
{
using func_t = decltype(&TESObjectREFR::GetWeightInContainer);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetWeightInContainer };
return func(this);
}
BaseFormComponent* HasContainer()
{
using func_t = decltype(&TESObjectREFR::HasContainer);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::HasContainer };
return func(this);
}
[[nodiscard]] bool IsAnOwner(Actor* a_testOwner, bool a_useFaction, bool a_requiresOwner)
{
using func_t = decltype(&TESObjectREFR::IsAnOwner);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::IsAnOwner };
return func(this, a_testOwner, a_useFaction, a_requiresOwner);
}
[[nodiscard]] bool IsCrimeToActivate()
{
using func_t = decltype(&TESObjectREFR::IsCrimeToActivate);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::IsCrimeToActivate };
return func(this);
}
[[nodiscard]] bool IsInWater()
{
return this->GetRelevantWaterHeight() > this->data.location.z;
}
[[nodiscard]] bool IsLeveledCreature()
{
using func_t = decltype(&TESObjectREFR::IsLeveledCreature);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::IsLeveledCreature };
return func(this);
}
void MarkAsDeleted()
{
using func_t = decltype(&TESObjectREFR::MarkAsDeleted);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::MarkAsDeleted };
return func(this);
}
void MoveRefToNewSpace(TESObjectCELL* a_interior, TESWorldSpace* a_world)
{
using func_t = decltype(&TESObjectREFR::MoveRefToNewSpace);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::MoveRefToNewSpace };
return func(this, a_interior, a_world);
}
void RemoveKeyword(BGSKeyword* a_keyworld)
{
using func_t = decltype(&TESObjectREFR::RemoveKeyword);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::RemoveKeyword };
return func(this, a_keyworld);
}
void SetAngleOnReference(const NiPoint3& a_point)
{
using func_t = decltype(&TESObjectREFR::SetAngleOnReference);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::SetAngleOnReference };
return func(this, a_point);
}
void SetLinkedRef(Actor* a_actor, BGSKeyword* a_keyword)
{
using func_t = decltype(&TESObjectREFR::SetLinkedRef);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::SetLinkedRef };
return func(this, a_actor, a_keyword);
}
void SetLocationOnReference(const NiPoint3& a_point)
{
using func_t = decltype(&TESObjectREFR::SetLocationOnReference);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::SetLocationOnReference };
return func(this, a_point);
}
void SetWantsDelete(bool a_delete)
{
using func_t = decltype(&TESObjectREFR::SetWantsDelete);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::SetWantsDelete };
return func(this, a_delete);
}
void RebuildBendableSpline(bool rebuildCollision, NiAVObject* target)
{
using func_t = decltype(&TESObjectREFR::RebuildBendableSpline);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::RebuildBendableSpline };
return func(this, rebuildCollision, target);
}
bool GetItemCount(uint32_t& count, TESForm* item, bool countComponent)
{
using func_t = decltype(&TESObjectREFR::GetItemCount);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetItemCount };
return func(this, count, item, countComponent);
}
void UpdateReference3D()
{
using func_t = decltype(&TESObjectREFR::UpdateReference3D);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::UpdateReference3D };
return func(this);
}
void GetObjectCenter(NiPoint3& center)
{
using func_t = decltype(&TESObjectREFR::GetObjectCenter);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetObjectCenter };
return func(this, center);
}
void SetScale(float scale)
{
using func_t = decltype(&TESObjectREFR::SetScale);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::SetScale };
return func(this, scale);
}
bool IsMarker()
{
using func_t = decltype(&TESObjectREFR::IsMarker);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::IsMarker };
return func(this);
}
bool IsDecalRef()
{
using func_t = decltype(&TESObjectREFR::IsDecalRef);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::IsDecalRef };
return func(this);
}
void UpdateDynamicNavmesh(bool a_active)
{
using func_t = decltype(&TESObjectREFR::UpdateDynamicNavmesh);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::UpdateDynamicNavmesh };
return func(this, a_active);
}
MapMarkerData* GetMapMarkerData()
{
using func_t = decltype(&TESObjectREFR::GetMapMarkerData);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetMapMarkerData };
return func(this);
}
float GetRelevantWaterHeight()
{
using func_t = decltype(&TESObjectREFR::GetRelevantWaterHeight);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::GetRelevantWaterHeight };
return func(this);
}
bool CanBeMoved()
{
using func_t = decltype(&TESObjectREFR::CanBeMoved);
static REL::Relocation<func_t> func{ ID::TESObjectREFR::CanBeMoved };
return func(this);
}
// members
TESObjectCELL* parentCell; // 0x0B8
OBJ_REFR data; // 0x0C0
LOADED_REF_DATA* loadedData; // 0x0F0
BGSInventoryList* inventoryList; // 0x0F8
BSTSmartPointer<ExtraDataList> extraList; // 0x100
std::uint16_t refScale; // 0x018
std::int8_t modelState; // 0x10A
bool predestroyed; // 0x10B
};
static_assert(sizeof(TESObjectREFR) == 0x110);
}
@@ -0,0 +1,28 @@
#pragma once
#include "RE/B/BGSForcedLocRefType.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BGSNavmeshableObject.h"
#include "RE/B/BGSPropertySheet.h"
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESObjectSTATData.h"
namespace RE
{
class __declspec(novtable) TESObjectSTAT :
public TESBoundObject, // 00
public BGSModelMaterialSwap, // 68
public BGSPropertySheet, // A8
public BGSForcedLocRefType, // B8
public BGSNavmeshableObject // C8
{
public:
static constexpr auto RTTI{ RTTI::TESObjectSTAT };
static constexpr auto VTABLE{ VTABLE::TESObjectSTAT };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kSTAT };
// members
TESObjectSTATData data; // D0
};
static_assert(sizeof(TESObjectSTAT) == 0xE8);
}
@@ -0,0 +1,15 @@
#pragma once
namespace RE
{
class TESObjectSTATData
{
public:
// members
BGSMaterialObject* materialObj; // 00
float materialThresholdAngle; // 08
float leafAmplitude; // 0C
float leafFrequency; // 10
};
static_assert(sizeof(TESObjectSTATData) == 0x18);
}
@@ -0,0 +1,39 @@
#pragma once
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/O/OBJ_TREE.h"
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESProduceForm.h"
namespace RE
{
class BaseTreeData;
class __declspec(novtable) TESObjectTREE :
public TESBoundObject, // 000
public BGSModelMaterialSwap, // 068
public TESFullName, // 0A8
public TESProduceForm // 0B8
{
public:
static constexpr auto RTTI{ RTTI::TESObjectTREE };
static constexpr auto VTABLE{ VTABLE::TESObjectTREE };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kTREE };
enum class etTreeType
{
kShortAndThin = 0x0,
kShortAndThick = 0x1,
kTallAndThin = 0x2,
kTallAndThick = 0x3,
kTotal = 0x4
};
// members
OBJ_TREE data; // 0D8
BaseTreeData* baseData; // 108
REX::TEnumSet<etTreeType, std::int32_t> type; // 110
};
static_assert(sizeof(TESObjectTREE) == 0x118);
}
@@ -0,0 +1,227 @@
#pragma once
#include "RE/B/BGSAttachParentArray.h"
#include "RE/B/BGSBlockBashData.h"
#include "RE/B/BGSDestructibleObjectForm.h"
#include "RE/B/BGSEquipType.h"
#include "RE/B/BGSInstanceNamingRulesForm.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSMessageIcon.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BGSPickupPutdownSounds.h"
#include "RE/B/BGSPreloadable.h"
#include "RE/B/BGSTypedFormValuePair.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTTuple.h"
#include "RE/M/MELEE_ATTACK_SPEED.h"
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESDescription.h"
#include "RE/T/TESEnchantableForm.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESIcon.h"
#include "RE/W/WEAPON_FLAGS.h"
#include "RE/W/WEAPON_TYPE.h"
namespace RE
{
enum class SOUND_LEVEL;
enum class STAGGER_MAGNITUDE;
enum class WEAPON_RUMBLE_PATTERN;
enum class WEAPONHITBEHAVIOR;
class __declspec(novtable) TESObjectWEAP :
public TESBoundObject, // 000
public TESFullName, // 068
public BGSModelMaterialSwap, // 078
public TESIcon, // 0B8
public TESEnchantableForm, // 0C8
public BGSDestructibleObjectForm, // 0E0
public BGSEquipType, // 0F0
public BGSPreloadable, // 100
public BGSMessageIcon, // 108
public BGSPickupPutdownSounds, // 120
public BGSBlockBashData, // 138
public BGSKeywordForm, // 150
public TESDescription, // 170
public BGSInstanceNamingRulesForm // 188
{
public:
static constexpr auto RTTI{ RTTI::TESObjectWEAP };
static constexpr auto VTABLE{ VTABLE::TESObjectWEAP };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kWEAP };
class RangedData
{
public:
// members
BGSProjectile* overrideProjectile; // 00
float fireSeconds; // 08
float firingRumbleLeftMotorStrength; // 0C
float firingRumbleRightMotorStrength; // 10
float firingRumbleDuration; // 14
float reloadSeconds; // 18
float boltChargeSeconds; // 1C
float sightedTransitionSeconds; // 20
std::uint32_t rumblePeriod; // 24
REX::TEnumSet<WEAPON_RUMBLE_PATTERN, std::int32_t> rumblePattern; // 28
std::int8_t numProjectiles; // 2C
};
static_assert(sizeof(RangedData) == 0x30);
class __declspec(novtable) InstanceData :
public TBO_InstanceData // 000
{
public:
static constexpr auto RTTI{ RTTI::TESObjectWEAP__InstanceData };
static constexpr auto VTABLE{ VTABLE::TESObjectWEAP__InstanceData };
// members
BGSSoundDescriptorForm* attackSound; // 010
BGSSoundDescriptorForm* attackSound2D; // 018
BGSSoundDescriptorForm* attackLoop; // 020
BGSSoundDescriptorForm* attackFailSound; // 028
BGSSoundDescriptorForm* idleSound; // 030
BGSSoundDescriptorForm* equipSound; // 038
BGSSoundDescriptorForm* unEquipSound; // 040
BGSSoundDescriptorForm* fastEquipSound; // 048
BGSBlockBashData* blockBashData; // 050
BGSImpactDataSet* impactDataSet; // 058
TESLevItem* npcAddAmmoList; // 060
TESAmmo* ammo; // 068
BGSEquipSlot* equipSlot; // 070
SpellItem* effect; // 078
BGSKeywordForm* keywords; // 080
BGSAimModel* aimModel; // 088
BGSZoomData* zoomData; // 090
RangedData* rangedData; // 098
BSTArray<EnchantmentItem*>* enchantments; // 0A0
BSTArray<BGSMaterialSwap*>* materialSwaps; // 0A8
BSTArray<BSTTuple<TESForm*, BGSTypedFormValuePair::SharedVal>>* damageTypes; // 0B0
BSTArray<BSTTuple<TESForm*, BGSTypedFormValuePair::SharedVal>>* actorValues; // 0B8
float attackSeconds; // 0C0
float reloadSpeed; // 0C4
float speed; // 0C8
float reach; // 0CC
float minRange; // 0D0
float maxRange; // 0D4
float attackDelaySec; // 0D8
float damageToWeaponMult; // 0DC
float outOfRangeDamageMult; // 0E0
float secondaryDamage; // 0E4
float criticalChargeBonus; // 0E8
float weight; // 0EC
float soundLevelMult; // 0F0
float attackActionPointCost; // 0F4
float fullPowerSeconds; // 0F8
float minPowerPerShot; // 0FC
float colorRemappingIndex; // 100
float criticalDamageMult; // 104
REX::TEnumSet<STAGGER_MAGNITUDE, std::int32_t> staggerValue; // 108
std::uint32_t value; // 10C
REX::TEnumSet<WEAPON_FLAGS, std::uint32_t> flags; // 110
REX::TEnumSet<SOUND_LEVEL, std::int32_t> soundLevel; // 114
REX::TEnumSet<WEAPONHITBEHAVIOR, std::int32_t> hitBehavior; // 118
ActorValueInfo* skill; // 120
ActorValueInfo* resistance; // 128
std::uint16_t ammoCapacity; // 130
std::uint16_t attackDamage; // 132
std::uint16_t rank; // 134
std::int8_t accuracyBonus; // 136
REX::TEnumSet<WEAPON_TYPE, std::uint8_t> type; // 137
};
static_assert(sizeof(InstanceData) == 0x138);
class __declspec(novtable) Data :
public InstanceData // 000
{
public:
static constexpr auto RTTI{ RTTI::TESObjectWEAP__Data };
static constexpr auto VTABLE{ VTABLE::TESObjectWEAP__Data };
};
static_assert(sizeof(Data) == 0x138);
[[nodiscard]] MELEE_ATTACK_SPEED GetMeleeAttackSpeed()
{
using func_t = decltype(&TESObjectWEAP::GetMeleeAttackSpeed);
static REL::Relocation<func_t> func{ ID::TESObjectWEAP::GetMeleeAttackSpeed };
return func(this);
}
[[nodiscard]] static const char* GetMeleeAttackSpeedLabel(MELEE_ATTACK_SPEED a_speed)
{
using func_t = decltype(&TESObjectWEAP::GetMeleeAttackSpeedLabel);
static REL::Relocation<func_t> func{ ID::TESObjectWEAP::GetMeleeAttackSpeedLabel };
return func(a_speed);
}
bool IsMeleeWeapon() const
{
return weaponData.type.any(
WEAPON_TYPE::kOneHandSword,
WEAPON_TYPE::kOneHandDagger,
WEAPON_TYPE::kOneHandAxe,
WEAPON_TYPE::kOneHandMace,
WEAPON_TYPE::kTwoHandSword,
WEAPON_TYPE::kTwoHandAxe);
}
bool IsGunWeapon() const
{
return weaponData.type.any(
WEAPON_TYPE::kGun);
}
bool IsThrownWeapon() const
{
return weaponData.type.any(
WEAPON_TYPE::kGrenade,
WEAPON_TYPE::kMine);
}
bool IsOneHandedWeapon() const
{
return weaponData.type.any(
WEAPON_TYPE::kOneHandSword,
WEAPON_TYPE::kOneHandDagger,
WEAPON_TYPE::kOneHandAxe,
WEAPON_TYPE::kOneHandMace);
}
bool IsTwoHandedWeapon() const
{
return weaponData.type.any(
WEAPON_TYPE::kTwoHandSword,
WEAPON_TYPE::kTwoHandAxe);
}
bool IsRangedWeapon() const
{
return weaponData.type.any(
WEAPON_TYPE::kBow,
WEAPON_TYPE::kStaff,
WEAPON_TYPE::kGun,
WEAPON_TYPE::kGrenade,
WEAPON_TYPE::kMine);
}
bool IsBoundWeapon() const
{
return weaponData.flags.all(
WEAPON_FLAGS::kBoundWeapon);
}
bool IsEmbeddedWeapon() const
{
return weaponData.flags.all(
WEAPON_FLAGS::kEmbeddedWeapon);
}
// members
TESObjectWEAP::Data weaponData; // 198
BGSModelMaterialSwap* firstPersonModel; // 2D0
TESObjectWEAP* weaponTemplate; // 2D8
BGSMod::Attachment::Mod* embeddedWeaponMod; // 2E0
BGSAttachParentArray attachParents; // 2E8
};
static_assert(sizeof(TESObjectWEAP) == 0x300);
}
@@ -0,0 +1,49 @@
#pragma once
#include "RE/P/PACKAGE_DATA.h"
#include "RE/P/PackageEventAction.h"
#include "RE/P/PackageSchedule.h"
#include "RE/T/TESCondition.h"
#include "RE/T/TESForm.h"
namespace RE
{
enum class PACKAGE_PROCEDURE_TYPE;
class BGSIdleCollection;
class PackageLocation;
class PackageTarget;
class TESPackageData;
class __declspec(novtable) TESPackage :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::TESPackage };
static constexpr auto VTABLE{ VTABLE::TESPackage };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kPACK };
// add
virtual bool IsActorAtLocation(Actor* a_ctor, bool a_ignoredistance, float a_extraRadius, bool a_infurniture); // 4A
virtual bool IsActorAtSecondLocation(Actor* a_mobileObject, Actor* a_packageowner, bool a_ignoredistance, float a_otherRadius, bool bInfurniture); // 4B
virtual bool IsActorAtRefTarget(Actor* a_mobileObject, std::int32_t a_extraRadius); // 4C
virtual bool IsTargetAtLocation(Actor* a_actor, std::int32_t a_extraRadius); // 4D
virtual bool IsPackageOwner(Actor*) { return true; } // 4E
// members
PACKAGE_DATA data; // 20
TESPackageData* packData; // 30
PackageLocation* packLoc; // 38
PackageTarget* packTarg; // 40
BGSIdleCollection* idleCollection; // 48
PackageSchedule packSched; // 50
TESCondition packConditions; // 60
TESCombatStyle* combatStyle; // 68
TESQuest* ownerQuest; // 70
PackageEventAction onBegin; // 78
PackageEventAction onEnd; // 90
PackageEventAction onChange; // A8
REX::TEnumSet<PACKAGE_PROCEDURE_TYPE, std::int32_t> procedureType; // C0
std::uint32_t refCount; // C4
};
static_assert(sizeof(TESPackage) == 0xC8);
}
@@ -0,0 +1,20 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) TESProduceForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESProduceForm };
static constexpr auto VTABLE{ VTABLE::TESProduceForm };
// members
BGSSoundDescriptorForm* harvestSound; // 08
TESBoundObject* produceItem; // 10
std::int8_t produceChance[4]; // 18
};
static_assert(sizeof(TESProduceForm) == 0x20);
}
@@ -0,0 +1,86 @@
#pragma once
#include "RE/B/BGSStoryManagerTreeForm.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSSpinLock.h"
#include "RE/B/BSStringT.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTHashMap.h"
#include "RE/B/BSTSmallIndexScatterTable.h"
#include "RE/B/BSTTuple.h"
#include "RE/N/NiPointer.h"
#include "RE/Q/QUEST_DATA.h"
#include "RE/T/TESCondition.h"
#include "RE/T/TESFullName.h"
namespace RE
{
class BGSBaseAlias;
class BGSQuestInstanceText;
class BGSQuestObjective;
class BGSStoryEvent;
class QueuedPromoteQuestTask;
class TESQuestStage;
class __declspec(novtable) TESQuest :
public BGSStoryManagerTreeForm, // 000
public TESFullName // 028
{
public:
static constexpr auto RTTI{ RTTI::TESQuest };
static constexpr auto VTABLE{ VTABLE::TESQuest };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kQUST };
class AliasesAccess;
class ListObjectivesAccess;
class ListStagesAccess;
bool SetStage(std::uint16_t a_stage)
{
using func_t = decltype(&TESQuest::SetStage);
static REL::Relocation<func_t> func{ ID::TESQuest::SetStage };
return func(this, a_stage);
}
ObjectRefHandle* GetAliasedRef(ObjectRefHandle* a_result, std::uint32_t a_aiAliasID)
{
using func_t = decltype(&TESQuest::GetAliasedRef);
static REL::Relocation<func_t> func{ ID::TESQuest::GetAliasedRef };
return func(this, a_result, a_aiAliasID);
}
// members
BSTArray<BGSQuestInstanceText*> instanceData; // 038
std::uint32_t currentInstanceID; // 050
BSTArray<BSTTuple<TESFile*, std::uint32_t>> fileOffsets; // 058
BSTArray<BGSBaseAlias*> aliases; // 070
BSTHashMap<std::uint32_t, BGSLocation*> aliasedLocMap; // 088
BSTArray<BSTSmallArray<ObjectRefHandle>> aliasedHandles; // 0B8
BSReadWriteLock aliasAccessLock; // 0D0
BGSLocation* nonDormantLocation; // 0D8
TESGlobal* questCompleteXPGlobal; // 0E0
BSFixedString swfFile; // 0E8
QUEST_DATA data; // 0F0
std::uint32_t eventID; // 0F8
BSTArray<TESQuestStage*> stages; // 100
BSTArray<BGSQuestObjective*> objectives; // 118
BSTSmallIndexScatterTable<BSTArray<TESQuestStage*>, ListStagesAccess> stageTable; // 130
BSTSmallIndexScatterTable<BSTArray<BGSQuestObjective*>, ListObjectivesAccess> objectiveTable; // 150
BSTSmallIndexScatterTable<BSTArray<BGSBaseAlias*>, AliasesAccess> aliasesTable; // 170
TESCondition objConditions; // 190
TESCondition storyManagerConditions; // 198
BSTHashMap<BGSDialogueBranch*, BSTArray<TESTopic*>*> branchedDialogues[2]; // 1A0
BSTArray<TESTopic*> topics[6]; // 200
BSTArray<BGSScene*> scenes; // 290
BSTArray<TESGlobal*>* textGlobal; // 2A8
std::uint32_t totalRefsAliased; // 2B0
std::uint16_t currentStage; // 2B4
bool alreadyRun; // 2B6
BSString formEditorID; // 2B8
const BGSStoryEvent* startEventData; // 2C8
NiPointer<QueuedPromoteQuestTask> promoteTask; // 2D0
BSTArray<ObjectRefHandle> promotedRefsArray; // 2D8
};
static_assert(sizeof(TESQuest) == 0x2F0);
}
@@ -0,0 +1,23 @@
#pragma once
namespace RE
{
namespace TESQuestEvent
{
enum Type : std::int32_t
{
kUpdateQuestActiveStatus = 0x0,
kUpdateQuestEnableStatus = 0x1,
kUpdateQuestStageChange = 0x2,
kUpdateMiscQuestVisibility = 0x3
};
class Event
{
public:
TESQuestEvent::Type changeType; // 00
TESQuest* quest; // 08
};
static_assert(sizeof(Event) == 0x10);
}
}
@@ -0,0 +1,125 @@
#pragma once
#include "RE/B/BGSAttachParentArray.h"
#include "RE/B/BGSAttackDataForm.h"
#include "RE/B/BGSBehaviorGraphModel.h"
#include "RE/B/BGSBipedObjectForm.h"
#include "RE/B/BGSCharacterMorph.h"
#include "RE/B/BGSCharacterTint.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSPreloadable.h"
#include "RE/B/BGSPropertySheet.h"
#include "RE/B/BGSSkinForm.h"
#include "RE/B/BGSSoundTagComponent.h"
#include "RE/B/BGSTextureModel.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTHashMap.h"
#include "RE/M/Movement.h"
#include "RE/N/NiPoint3.h"
#include "RE/R/RACE_DATA.h"
#include "RE/T/TESDescription.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESModel.h"
#include "RE/T/TESSpellList.h"
#include "RE/T/TESTexture.h"
namespace RE
{
class EquipSlotData;
class __declspec(novtable) TESRace :
public TESForm, // 000
public TESFullName, // 020
public TESDescription, // 030
public TESSpellList, // 048
public BGSSkinForm, // 058
public BGSBipedObjectForm, // 068
public BGSKeywordForm, // 078
public BGSAttackDataForm, // 098
public BGSPropertySheet, // 0A8
public BGSPreloadable // 0B8
{
public:
static constexpr auto RTTI{ RTTI::TESRace };
static constexpr auto VTABLE{ VTABLE::TESRace };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kRACE };
class MOVEMENT_SPEED_OVERRIDE
{
public:
// members
BGSMovementType* moveType; // 00
Movement::MaxSpeeds overrideData; // 08
};
static_assert(sizeof(MOVEMENT_SPEED_OVERRIDE) == 0x78);
class FaceRelatedData
{
public:
// members
BGSCharacterTint::Template::Groups* tintingTemplate; //
BSTArray<BGSTextureSet*>* faceDetailsTextureSets; //
BGSTextureSet* defaultFaceDetailsTextureSet; //
BSTArray<TESNPC*>* presetNPCs; //
BSTArray<BGSColorForm*>* availableHairColors; //
BGSColorForm* defaultHairColor; //
BSTArray<BGSHeadPart*>* headParts; //
BSTArray<BGSCharacterMorph::Group*>* morphGroups; //
BSTArray<BGSCharacterMorph::FacialBoneRegion*>* facialBoneRegions; //
BGSCharacterMorph::FacialBoneRegion* neckFatFacialBoneRegion; //
NiPoint3 neckFatAdjustmentScales; //
BSFixedString wrinkleMapPath; //
};
static_assert(sizeof(FaceRelatedData) == 0x68);
class BodyMorphData
{
public:
// members
BSTHashMap<BSFixedString, BGSCharacterMorph::BoneBaseScales*> boneBaseScales; // 00
BSTHashMap<BSFixedString, BGSCharacterMorph::BONE_MODIFIER_MIN_MAX*> boneModifiers; // 30
};
static_assert(sizeof(BodyMorphData) == 0x60);
// members
TESModel skeletonModel[2]; // 0C0
TESModel skeletonChargenModel[2]; // 120
RACE_DATA data; // 180
float clampFaceGeoValue; // 280
float clampFaceGeoValue2; // 284
BGSTextureModel bodyTextureModels[2]; // 288
BGSBehaviorGraphModel behaviorGraph[2]; // 2E8
BSFixedString rootBehaviorGraphName[2]; // 348
BSFixedString behaviorGraphProjectName[2]; // 358
BGSVoiceType* defaultVoiceType[2]; // 368
BGSBodyPartData* bodyPartData; // 378
BGSSoundTagComponent soundTagComponent; // 380
BGSAttachParentArray attachParents; // 388
BSFixedString formEditorID; // 3A0
BGSMaterialType* bloodImpactMaterial; // 3A8
BGSArtObject* dismemberBlood; // 3B0
BGSTextureSet* meatCapTextureSet; // 3B8
BGSTextureSet* meatCollarTextureSet; // 3C0
BGSSoundDescriptorForm* corpseOpenSound; // 3C8
BGSSoundDescriptorForm* corpseCloseSound; // 3D0
BSFixedString bipedObjectNames[32]; // 3D8
ActorValueInfo* bipedObjectConditions[32]; // 4D8
BSTArray<EquipSlotData> equipSlotArray; // 5D8
std::uint32_t validEquipTypes; // 5F0
TESObjectWEAP* unarmedWeapon; // 5F8
TESRace* morphRace; // 600
TESRace* armorParentRace; // 608
TESQuest* dialogueQuest; // 610
BSTArray<MOVEMENT_SPEED_OVERRIDE> speedOverrides; // 618
BSTArray<BSFixedString> phonemeTargets; // 630
BSTHashMap<std::uint32_t, BGSCharacterMorph::Slider*> morphSliders; // 648
BGSMovementType* baseMoveTypes[4]; // 678
FaceRelatedData* faceRelatedData[2]; // 698
BodyMorphData* bodyMorphData[2]; // 6A8
TESTexture hairColorLookupTexture; // 6B8
TESTexture hairColorLookupTextureExt; // 6C8
};
static_assert(sizeof(TESRace) == 0x6D8);
}
@@ -0,0 +1,28 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) TESRaceForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESRaceForm };
static constexpr auto VTABLE{ VTABLE::TESRaceForm };
// add
virtual bool SwitchRace(TESRace* a_race) // 07
{
formRace = a_race;
return true;
}
[[nodiscard]] TESRace* GetFormRace() const noexcept { return formRace; }
void SetFormRace(TESRace* a_race) noexcept { formRace = a_race; }
// members
TESRace* formRace; // 08
};
static_assert(sizeof(TESRaceForm) == 0x10);
}
@@ -0,0 +1,22 @@
#pragma once
#include "RE/B/BSSimpleList.h"
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class GROUP_REACTION;
class __declspec(novtable) TESReactionForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::TESReactionForm };
static constexpr auto VTABLE{ VTABLE::TESReactionForm };
// members
BSSimpleList<GROUP_REACTION*> reactionList; // 08
std::int8_t groupFormType; // 18
};
static_assert(sizeof(TESReactionForm) == 0x20);
}
@@ -0,0 +1,33 @@
#pragma once
#include "RE/B/BSSimpleList.h"
#include "RE/N/NiColor.h"
#include "RE/T/TESForm.h"
namespace RE
{
class TESRegionDataList;
class TESRegionPointList;
class __declspec(novtable) TESRegion :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::TESRegion };
static constexpr auto VTABLE{ VTABLE::TESRegion };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kREGN };
// add
virtual bool Validate(); // 49
// members
TESRegionDataList* dataList; // 20
BSSimpleList<TESRegionPointList*>* pointLists; // 28
TESWorldSpace* worldSpace; // 30
TESWeather* currentWeather; // 38
NiColor emittanceColor; // 40
float lodDistanceModifier; // 4C
float occlusionAccuracy; // 50
};
static_assert(sizeof(TESRegion) == 0x58);
}
@@ -0,0 +1,33 @@
#pragma once
#include "RE/R/REGION_DATA_ID.h"
namespace RE
{
class REGION_DATA_BASE;
class TESRegion;
class __declspec(novtable) TESRegionData
{
public:
static constexpr auto RTTI{ RTTI::TESRegionData };
static constexpr auto VTABLE{ VTABLE::TESRegionData };
virtual ~TESRegionData(); // 00
// add
virtual bool LoadRegionData(REGION_DATA_BASE* a_data); // 01
virtual void Initialize(TESRegion* a_formal); // 02
virtual REGION_DATA_ID GetID(); // 03
virtual TESRegionData* Copy(); // 04
virtual TESRegionData* Blend(); // 04
virtual void BlendInto(const TESRegionData* a_regionData, std::uint32_t a_totalBlending); // 05
virtual bool Validate(); // 06
// members
bool override; // 08
bool ignore; // 09
std::uint8_t priority; // 0A
};
static_assert(sizeof(TESRegionData) == 0x10);
}

Some files were not shown because too many files have changed in this diff Show More