docs: add plugin setup guide
This commit is contained in:
@@ -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
|
||||
};
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user