docs: add plugin setup guide

This commit is contained in:
2026-05-30 18:33:24 +12:00
parent f3db41c402
commit b61043a3fe
1776 changed files with 122386 additions and 2 deletions
@@ -0,0 +1,23 @@
#pragma once
#include "RE/T/TESBoundObject.h"
namespace RE
{
class __declspec(novtable) BGSAcousticSpace :
public TESBoundObject // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSAcousticSpace };
static constexpr auto VTABLE{ VTABLE::BGSAcousticSpace };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kASPC };
// members
BGSSoundDescriptorForm* loopingSound; // 68
TESRegion* soundRegion; // 70
BGSReverbParameters* reverbType; // 78
std::uint16_t weatherAttenMillibels; // 80
bool isInterior; // 82
};
static_assert(sizeof(BGSAcousticSpace) == 0x88);
}
@@ -0,0 +1,19 @@
#pragma once
#include "RE/B/BGSKeyword.h"
namespace RE
{
class __declspec(novtable) BGSAction :
public BGSKeyword // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSAction };
static constexpr auto VTABLE{ VTABLE::BGSAction };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kAACT };
// members
std::uint32_t index; // 28
};
static_assert(sizeof(BGSAction) == 0x30);
}
@@ -0,0 +1,22 @@
#pragma once
#include "RE/B/BGSActorEvent.h"
namespace RE
{
class BGSActorCellEvent :
public BGSActorEvent
{
public:
enum class CellFlag
{
kEnter = 0x0,
kLeave = 0x1
};
// members
std::uint32_t cellID; // 04
REX::TEnumSet<CellFlag, std::uint32_t> flags; // 08
};
static_assert(sizeof(BGSActorCellEvent) == 0xC);
}
@@ -0,0 +1,16 @@
#pragma once
#include "RE/B/BGSActorEvent.h"
namespace RE
{
class BGSActorDeathEvent :
public BGSActorEvent
{
public:
// members
ActorHandle attacker; // 04
float damage; // 08
};
static_assert(sizeof(BGSActorDeathEvent) == 0xC);
}
@@ -0,0 +1,14 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
namespace RE
{
class BGSActorEvent
{
public:
// member
ActorHandle actor; // 00
};
static_assert(sizeof(BGSActorEvent) == 0x4);
}
@@ -0,0 +1,27 @@
#pragma once
#include "RE/A/ADDON_DATA.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BSSpinLock.h"
#include "RE/T/TESBoundObject.h"
namespace RE
{
class __declspec(novtable) BGSAddonNode :
public TESBoundObject, // 00
public BGSModelMaterialSwap // 68
{
public:
static constexpr auto RTTI{ RTTI::BGSAddonNode };
static constexpr auto VTABLE{ VTABLE::BGSAddonNode };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kADDN };
// members
std::uint32_t index; // A8
BGSSoundDescriptorForm* sound; // B0
TESObjectLIGH* light; // B8
ADDON_DATA data; // C0
BSNonReentrantSpinLock masterParticleLock; // C4
};
static_assert(sizeof(BGSAddonNode) == 0xC8);
}
@@ -0,0 +1,42 @@
#pragma once
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSAimModel :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSAimModel };
static constexpr auto VTABLE{ VTABLE::BGSAimModel };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kAMDL };
class Data
{
public:
// members
float aimModelMinConeDegrees; // 00
float aimModelMaxConeDegrees; // 04
float aimModelConeIncreasePerShot; // 08
float aimModelConeDecreasePerSec; // 0C
std::uint32_t aimModelConeDecreaseDelayMs; // 10
float aimModelConeSneakMultiplier; // 14
float aimModelRecoilDiminishSpringForce; // 18
float aimModelRecoilDiminishSightsMult; // 1C
float aimModelRecoilMaxDegPerShot; // 20
float aimModelRecoilMinDegPerShot; // 24
float aimModelRecoilHipMult; // 28
std::uint32_t aimModelRecoilShotsForRunaway; // 2C
float aimModelRecoilArcDeg; // 30
float aimModelRecoilArcRotateDeg; // 34
float aimModelConeIronSightsMultiplier; // 38
float aimModelBaseStability; // 3C
};
static_assert(sizeof(Data) == 0x40);
// members
Data aimModelData; // 20
};
static_assert(sizeof(BGSAimModel) == 0x60);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTHashMap.h"
namespace RE
{
class BGSActionData;
class BGSAnimationSequencer
{
public:
// members
std::uint32_t numSequences; // 00
BSTHashMap<BSFixedString, BGSActionData*> actions; // 08
};
static_assert(sizeof(BGSAnimationSequencer) == 0x38);
}
@@ -0,0 +1,45 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTObjectArena.h"
#include "RE/B/BSTTuple.h"
namespace RE
{
class IAnimationGraphManagerHolder;
namespace BGSAnimationSystemUtils
{
class ActiveSyncInfo
{
public:
// members
BSTObjectArena<BSTTuple<BSFixedString, float>> otherSyncInfo; // 00
float currentAnimTime; // 40
float animSpeedMult; // 44
float totalAnimTime; // 48
};
static_assert(sizeof(ActiveSyncInfo) == 0x50);
inline bool GetActiveSyncInfo(const IAnimationGraphManagerHolder* a_graphHolder, ActiveSyncInfo& a_infoOut)
{
using func_t = decltype(&GetActiveSyncInfo);
static REL::Relocation<func_t> func{ ID::BGSAnimationSystemUtils::GetActiveSyncInfo };
return func(a_graphHolder, a_infoOut);
}
inline bool InitializeActorInstant(Actor& a_actor, bool a_update3D)
{
using func_t = decltype(&InitializeActorInstant);
static REL::Relocation<func_t> func{ ID::BGSAnimationSystemUtils::InitializeActorInstant };
return func(a_actor, a_update3D);
}
inline bool IsActiveGraphInTransition(const TESObjectREFR* a_refr)
{
using func_t = decltype(&IsActiveGraphInTransition);
static REL::Relocation<func_t> func{ ID::BGSAnimationSystemUtils::IsActiveGraphInTransition };
return func(a_refr);
}
}
}
@@ -0,0 +1,40 @@
#pragma once
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/T/TESBoundObject.h"
namespace RE
{
class __declspec(novtable) BGSArtObject :
public TESBoundObject, // 00
public BGSKeywordForm, // 68
public BGSModelMaterialSwap // 88
{
public:
static constexpr auto RTTI{ RTTI::BGSArtObject };
static constexpr auto VTABLE{ VTABLE::BGSArtObject };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kARTO };
enum class ArtType
{
kMagicCastingArt = 0x0,
kMagicHitEffect = 0x1,
kMagicEnchantEffect = 0x2,
kTotal = 0x3
};
class Data
{
public:
// members
REX::TEnumSet<ArtType, std::int32_t> artType; // 0
};
static_assert(sizeof(Data) == 0x4);
// members
Data data; // C8
};
static_assert(sizeof(BGSArtObject) == 0xD0);
}
@@ -0,0 +1,33 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSAssociationType :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSAssociationType };
static constexpr auto VTABLE{ VTABLE::BGSAssociationType };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kASTP };
enum class Member
{
kParent = 0x0,
kChild = 0x1,
kCount = 0x2
};
enum class Flags
{
kFamily = 0x1
};
// members
BSFixedStringCS associationLabel[2][2]; // 20
REX::TEnumSet<Flags, std::uint32_t> flags; // 40
};
static_assert(sizeof(BGSAssociationType) == 0x48);
}
@@ -0,0 +1,31 @@
#pragma once
#include "RE/B/BGSTypedKeywordValue.h"
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) BGSAttachParentArray :
public BaseFormComponent, // 00
public BGSTypedKeywordValueArray<KeywordType::kAttachPoint> // 08
{
public:
static constexpr auto RTTI{ RTTI::BGSAttachParentArray };
static constexpr auto VTABLE{ VTABLE::BGSAttachParentArray };
// override (BaseFormComponent)
std::uint32_t GetFormComponentType() const override { return 'APPA'; } // 01
void InitializeDataComponent() override { return; } // 02
void ClearDataComponent() override; // 03
void CopyComponent(BaseFormComponent*) override { return; } // 06
void CopyComponent(BaseFormComponent*, TESForm*) override; // 05
void SetParentGroupNumber(BGSKeyword* a_parent, std::uint32_t a_groupID)
{
using func_t = decltype(&BGSAttachParentArray::SetParentGroupNumber);
static REL::Relocation<func_t> func{ ID::BGSAttachParentArray::SetParentGroupNumber };
return func(this, a_parent, a_groupID);
}
};
static_assert(sizeof(BGSAttachParentArray) == 0x18);
}
@@ -0,0 +1,23 @@
#pragma once
#include "RE/A/AttackData.h"
#include "RE/B/BSFixedString.h"
#include "RE/N/NiRefObject.h"
namespace RE
{
class __declspec(novtable) BGSAttackData :
public NiRefObject // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSAttackData };
static constexpr auto VTABLE{ VTABLE::BGSAttackData };
// members
BSFixedString event; // 10
AttackData data; // 18
BGSEquipSlot* weaponEquipSlot; // 50
BGSEquipSlot* requiredEquipSlot; // 58
};
static_assert(sizeof(BGSAttackData) == 0x60);
}
@@ -0,0 +1,21 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class BGSAttackDataMap;
class __declspec(novtable) BGSAttackDataForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSAttackDataForm };
static constexpr auto VTABLE{ VTABLE::BGSAttackDataForm };
// members
NiPointer<BGSAttackDataMap> attackDataMap; // 08
};
static_assert(sizeof(BGSAttackDataForm) == 0x10);
}
@@ -0,0 +1,24 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTHashMap.h"
#include "RE/N/NiPointer.h"
#include "RE/N/NiRefObject.h"
namespace RE
{
class BGSAttackData;
class __declspec(novtable) BGSAttackDataMap :
public NiRefObject // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSAttackDataMap };
static constexpr auto VTABLE{ VTABLE::BGSAttackDataMap };
// members
BSTHashMap<BSFixedString, NiPointer<BGSAttackData>> attackDataMap; // 10
TESRace* defaultDataRace; // 40
};
static_assert(sizeof(BGSAttackDataMap) == 0x48);
}
@@ -0,0 +1,33 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSAttractionRule :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSAttractionRule };
static constexpr auto VTABLE{ VTABLE::BGSAttractionRule };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kAORU };
class ATTRACTION_RULE_DATA
{
public:
// members
float radius; // 00
float minDelay; // 04
float maxDelay; // 08
bool requiresLOS; // 0C
bool combatTarget; // 0D
};
static_assert(sizeof(ATTRACTION_RULE_DATA) == 0x10);
// members
ATTRACTION_RULE_DATA data; // 20
BSFixedString formEditorID; // 30
};
static_assert(sizeof(BGSAttractionRule) == 0x38);
}
@@ -0,0 +1,24 @@
#pragma once
#include "RE/B/BSIAudioEffectChain.h"
#include "RE/B/BSTArray.h"
#include "RE/T/TESForm.h"
namespace RE
{
class BSIAudioEffectParameters;
class __declspec(novtable) BGSAudioEffectChain :
public TESForm, // 00
public BSIAudioEffectChain // 20
{
public:
static constexpr auto RTTI{ RTTI::BGSAudioEffectChain };
static constexpr auto VTABLE{ VTABLE::BGSAudioEffectChain };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kAECH };
// members
BSTArray<BSIAudioEffectParameters*> effects; // 28
};
static_assert(sizeof(BGSAudioEffectChain) == 0x40);
}
@@ -0,0 +1,25 @@
#pragma once
#include "RE/B/BSSoundHandle.h"
namespace RE
{
class BGSAwakeSoundData
{
public:
enum class State : std::uint32_t
{
kPlaying = 0x0,
kPaused = 0x1,
kStopped = 0x2,
kTotal = 0x3
};
BSSoundHandle sound; // 00
std::uint32_t soundFormID; // 08
float volume; // 0C
BGSAwakeSoundData::State state; // 10
};
static_assert(sizeof(BGSAwakeSoundData) == 0x14);
}
@@ -0,0 +1,62 @@
#pragma once
#include "RE/B/BSFixedString.h"
namespace RE
{
class __declspec(novtable) BGSBaseAlias
{
public:
static constexpr auto RTTI{ RTTI::ExtraReferenceHandles };
static constexpr auto VTABLE{ VTABLE::ExtraReferenceHandles };
enum class FLAGS : unsigned
{
kReserves = 1u << 0,
kOptional = 1u << 1,
kQuestObject = 1u << 2,
kAllowReuse = 1u << 3,
kAllowDead = 1u << 4,
kLoadedOnly = 1u << 5,
kEssential = 1u << 6,
kAllowDisabled = 1u << 7,
kStoreName = 1u << 8,
kAllowReserved = 1u << 9,
kProtected = 1u << 10,
kForcedFromAlias = 1u << 11,
kAllowDestroyed = 1u << 12,
kFindPlayerClosest = 1u << 13,
kUsesNames = 1u << 14,
kInitiallyDisabled = 1u << 15,
kAllowCleared = 1u << 16,
kClearNameOnRemove = 1u << 17,
kActorsOnly = 1u << 18,
kTransient = 1u << 19,
kExternalLink = 1u << 20,
kNoPickPocket = 1u << 21,
kDataAlias = 1u << 22,
kSceneOptional = 1u << 24,
};
virtual ~BGSBaseAlias(); // 00
// add
virtual bool Load() = 0; // 01
virtual void InitItem() = 0; // 02
[[nodiscard]] virtual const BSFixedString& QType() const = 0; // 03
[[nodiscard]] virtual TESQuest* QExternalQuest() const = 0; // 04
virtual void ClearExternalQuest() = 0; // 05
virtual void UpdateFromExternalAlias() const = 0; // 06
[[nodiscard]] virtual BGSBaseAlias* GetLinkedAlias() const = 0; // 07
[[nodiscard]] bool IsQuestObject() const noexcept { return flags.all(FLAGS::kQuestObject); }
// mmebers
BSFixedString aliasName; // 08
TESQuest* owningQuest; // 10
std::uint32_t aliasID; // 18
REX::TEnumSet<FLAGS, std::uint32_t> flags; // 1C
std::uint16_t fillType; // 20
};
static_assert(sizeof(BGSBaseAlias) == 0x28);
}
@@ -0,0 +1,15 @@
#pragma once
#include "RE/T/TESModel.h"
namespace RE
{
class __declspec(novtable) BGSBehaviorGraphModel :
public TESModel // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSBehaviorGraphModel };
static constexpr auto VTABLE{ VTABLE::BGSBehaviorGraphModel };
};
static_assert(sizeof(BGSBehaviorGraphModel) == 0x30);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/S/SubgraphIdentifier.h"
namespace RE
{
class BGSBehaviorRootData
{
public:
// members
BSFixedString idleManagerRootToUse; // 00
BSFixedString behaviorRootFilename; // 08
SubgraphIdentifier identifier; // 10
bool firstPerson; // 18
};
static_assert(sizeof(BGSBehaviorRootData) == 0x20);
}
@@ -0,0 +1,42 @@
#pragma once
#include "RE/N/NiColor.h"
#include "RE/T/TESBoundObject.h"
namespace RE
{
class __declspec(novtable) BGSBendableSpline :
public TESBoundObject // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSBendableSpline };
static constexpr auto VTABLE{ VTABLE::BGSBendableSpline };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kBNDS };
class SplineData_Untilv130
{
public:
// members
float numTiles; // 00
std::uint16_t numSlices; // 04
std::uint16_t flags; // 06
NiColor color; // 08
};
static_assert(sizeof(SplineData_Untilv130) == 0x14);
class SplineData :
public SplineData_Untilv130 // 00
{
public:
// members
float windSensibility; // 14
float flexibility; // 18
};
static_assert(sizeof(SplineData) == 0x1C);
// members
SplineData data; // 68
BGSTextureSet* textureSet; // 88
};
static_assert(sizeof(BGSBendableSpline) == 0x90);
}
@@ -0,0 +1,22 @@
#pragma once
#include "RE/B/BIPED_MODEL.h"
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) BGSBipedObjectForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSBipedObjectForm };
static constexpr auto VTABLE{ VTABLE::BGSBipedObjectForm };
// add
virtual bool FillsBipedSlot(std::int32_t a_bipedSlot) const; // 06
// members
BIPED_MODEL bipedModelData; // 08
};
static_assert(sizeof(BGSBipedObjectForm) == 0x10);
}
@@ -0,0 +1,19 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) BGSBlockBashData :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSBlockBashData };
static constexpr auto VTABLE{ VTABLE::BGSBlockBashData };
// members
BGSImpactDataSet* blockBashImpactDataSet; // 08
BGSMaterialType* altBlockMaterialType; // 10
};
static_assert(sizeof(BGSBlockBashData) == 0x18);
}
@@ -0,0 +1,30 @@
#pragma once
#include "RE/B/BGSBodyPartDefs.h"
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BSFixedString.h"
#include "RE/P/PART_DATA.h"
#include "RE/T/TESModel.h"
namespace RE
{
class BGSBodyPart
{
public:
// members
BSFixedString nodeName; // 000
BSFixedString targetName; // 008
BSFixedString hitReactionVariablePrefix; // 010
BGSBodyPartDefs::HitReactionData runtimeHitReactionData; // 018
BGSLocalizedString partName; // 040
BSFixedString goreObjectName; // 048
TESModel explosionSpecialDebris; // 050
PART_DATA data; // 080
BGSArtObject* dismemberBlood; // 128
BGSMaterialType* bloodImpactMaterial; // 130
BGSMaterialType* onCrippleBloodImpactMaterial; // 138
BGSTextureSet* meatCapTextureSet; // 140
BGSTextureSet* meatCollarTextureSet; // 148
};
static_assert(sizeof(BGSBodyPart) == 0x150);
}
@@ -0,0 +1,57 @@
#pragma once
#include "RE/B/BGSBodyPartDefs.h"
#include "RE/B/BGSPreloadable.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESModel.h"
namespace RE
{
class BGSBodyPart;
class __declspec(novtable) BGSBodyPartData :
public TESForm, // 000
public TESModel, // 020
public BGSPreloadable // 050
{
public:
static constexpr auto RTTI{ RTTI::BGSBodyPartData };
static constexpr auto VTABLE{ VTABLE::BGSBodyPartData };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kBPTD };
enum PartType
{
Torso = 0x0,
Head1 = 0x1,
Eye = 0x2,
LookAt = 0x3,
FlyGrab = 0x4,
Head2 = 0x5,
LeftArm1 = 0x6,
LeftArm2 = 0x7,
RightArm1 = 0x8,
RightArm2 = 0x9,
LeftLeg1 = 0xA,
LeftLeg2 = 0xB,
LeftLeg3 = 0xC,
RightLeg1 = 0xD,
RightLeg2 = 0xE,
RightLeg3 = 0xF,
Brain = 0x10,
Weapon = 0x11,
Root = 0x12,
COM = 0x13,
Pelvis = 0x14,
Camera = 0x15,
OffsetRoot = 0x16,
LeftFoot = 0x17,
RightFoot = 0x18,
FaceTargetSource = 0x19
};
// members
BGSBodyPart* partArray[26]; // 058
BGSBodyPartDefs::HitReactionData defaultHitReactionData; // 128
};
static_assert(sizeof(BGSBodyPartData) == 0x150);
}
@@ -0,0 +1,64 @@
#pragma once
#include "RE/B/BSFixedString.h"
namespace RE
{
namespace BGSBodyPartDefs
{
enum class CAUSE_OF_DEATH : std::uint32_t
{
kCauseOfDeathNone = 0xFFFFFFFF,
kCauseOfDeathExplosion = 0x0,
kCauseOfDeathGun = 0x1,
kCauseOfDeathBluntWeapon = 0x2,
kCauseOfDeathHandToHand = 0x3,
kCauseOfDeathObjectImpact = 0x4,
kCauseOfDeathPoison = 0x5,
kCauseOfDeathDecapitation = 0x6
};
enum class LIMB_ENUM : std::uint32_t
{
kNone = 0xFFFFFFFF,
kTorso = 0x0,
kHead1 = 0x1,
kEye1 = 0x2,
kLookAt1 = 0x3,
kFlyGrab = 0x4,
kHead2 = 0x5,
kLeftArm1 = 0x6,
kLeftArm2 = 0x7,
kRightArm1 = 0x8,
kRightArm2 = 0x9,
kLeftLeg1 = 0xA,
kLeftLeg2 = 0xB,
kLeftLeg3 = 0xC,
kRightLeg1 = 0xD,
kRightLeg2 = 0xE,
kRightLeg3 = 0xF,
kBrain = 0x10,
kWeapon = 0x11,
kRoot = 0x12,
kCom = 0x13,
kPelvis = 0x14,
kCamera = 0x15,
kOffsetRoot = 0x16,
kLeftFoot = 0x17,
kRightFoot = 0x18,
kFaceTargetSource = 0x19
};
class HitReactionData
{
public:
// members
BSFixedString chainStart; // 00
BSFixedString chainEnd; // 08
BSFixedString variableX; // 10
BSFixedString variableY; // 18
BSFixedString variableZ; // 20
};
static_assert(sizeof(HitReactionData) == 0x28);
}
}
@@ -0,0 +1,29 @@
#pragma once
#include "RE/B/BSSimpleList.h"
#include "RE/P/PATH_DATA.h"
#include "RE/T/TESCondition.h"
#include "RE/T/TESForm.h"
namespace RE
{
class NiFormArray;
class __declspec(novtable) BGSCameraPath :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSCameraPath };
static constexpr auto VTABLE{ VTABLE::BGSCameraPath };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kCPTH };
// members
TESCondition conditions; // 20
BSSimpleList<BGSCameraShot*> shots; // 28
PATH_DATA data; // 38
NiFormArray* childPaths; // 40
BGSCameraPath* parentPath; // 48
BGSCameraPath* prevPath; // 50
};
static_assert(sizeof(BGSCameraPath) == 0x58);
}
@@ -0,0 +1,82 @@
#pragma once
#include "RE/T/TESCondition.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESImageSpaceModifiableForm.h"
#include "RE/T/TESModel.h"
namespace RE
{
class __declspec(novtable) BGSCameraShot :
public TESForm, // 00
public TESModel, // 20
public TESImageSpaceModifiableForm // 50
{
public:
static constexpr auto RTTI{ RTTI::BGSCameraShot };
static constexpr auto VTABLE{ VTABLE::BGSCameraShot };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kCAMS };
enum class CAM_ACTION
{
kShoot = 0x0,
kFly = 0x1,
kHit = 0x2,
kZoom = 0x3,
kTotal = 0x4
};
enum class CAM_OBJECT
{
kAttacker = 0x0,
kProjectile = 0x1,
kTarget = 0x2,
kLeadActor = 0x3,
kTotal = 0x4
};
enum class CAM_USER
{
kNone = 0x0,
kVATS = 0x1,
kDialogue = 0x2
};
enum class CAM_ZOOM
{
kDefault = 0x0,
kDisable = 0x1,
kShotList = 0x2
};
class CAMERA_SHOT_DATA
{
public:
// members
REX::TEnumSet<CAM_ACTION, std::int32_t> cameraAction; // 00
REX::TEnumSet<CAM_OBJECT, std::int32_t> location; // 04
REX::TEnumSet<CAM_OBJECT, std::int32_t> target; // 08
std::uint32_t flags; // 0C
float playerTimeMult; // 10
float targetTimeMult; // 14
float globalTimeMult; // 18
float maxTime; // 1C
float minTime; // 20
float targetPercentBetweenActors; // 24
float nearTargetDistance; // 28
float locationSpring; // 2C
float targetSpring; // 30
float rotationOffsetX; // 34
float rotationOffsetY; // 38
float rotationOffsetZ; // 3C
};
static_assert(sizeof(CAMERA_SHOT_DATA) == 0x40);
// members
CAMERA_SHOT_DATA data; // 60
TESCondition conditions; // A0
};
static_assert(sizeof(BGSCameraShot) == 0xA8);
}
@@ -0,0 +1,129 @@
#pragma once
#include "RE/B/BGSCharacterTint.h"
#include "RE/B/BGSHeadPart.h"
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTHashMap.h"
#include "RE/N/NiPoint3.h"
namespace RE
{
namespace BGSCharacterMorph
{
class BoneBaseScales
{
public:
// members
NiPoint3 scales[3]; // 00
};
static_assert(sizeof(BoneBaseScales) == 0x24);
class BONE_MODIFIER_MIN_MAX
{
public:
// members
float minY; // 00
float minZ; // 04
float maxY; // 08
float maxZ; // 0C
};
static_assert(sizeof(BONE_MODIFIER_MIN_MAX) == 0x10);
class Slider
{
public:
// members
BSFixedString morphNames[2]; // 00
const std::uint32_t uniqueID; // 10
};
static_assert(sizeof(Slider) == 0x18);
class Transform
{
public:
// members
NiPoint3 position; // 00
NiPoint3 rotation; // 0C
NiPoint3 scale; // 18
};
static_assert(sizeof(Transform) == 0x24);
class TransformMinMax
{
public:
// members
Transform minima; // 00
Transform maxima; // 24
};
static_assert(sizeof(TransformMinMax) == 0x48);
class FacialBoneRegion
{
public:
// members
Transform defaultTransform; // 00
BGSLocalizedString name; // 28
BSFixedString associatedMorphGroupName; // 30
BGSCharacterTint::EntrySlot associatedTintSlot; // 38
BGSHeadPart::HeadPartType associatedHeadPartType; // 3C
BSTHashMap<BSFixedString, TransformMinMax*> boneMinMaxMap; // 40
BSTArray<std::uint32_t> associatedMorphSliders; // 70
const std::uint32_t id; // 88
};
static_assert(sizeof(FacialBoneRegion) == 0x90);
class Preset
{
public:
// members
BGSLocalizedString name; // 00
BSFixedString morph; // 08
BGSTextureSet* textureSet; // 10
std::int8_t flags; // 18
std::uint32_t id; // 1C
};
static_assert(sizeof(Preset) == 0x20);
class Group
{
public:
// members
BSFixedString name; // 00
BSTArray<Preset> presets; // 08
BSTArray<std::uint32_t> sliders; // 20
std::uint16_t presetMaskID; // 38
};
static_assert(sizeof(Group) == 0x40);
enum class WeightComponent : std::uint32_t
{
kThin = 0x0,
kMuscular = 0x1,
kFat = 0x2
};
enum class BODY_MORPH_REGION : std::uint32_t
{
kHead = 0x0,
kUpperTorso = 0x1,
kArms = 0x2,
kLowerTorso = 0x3,
kLegs = 0x4
};
enum class Axis : std::uint32_t
{
kPosX = 0x0,
kPosY = 0x1,
kPosZ = 0x2,
kRotX = 0x3,
kRotY = 0x4,
kRotZ = 0x5,
kScaleX = 0x6,
kScaleY = 0x7,
kScaleZ = 0x8
};
}
}
@@ -0,0 +1,195 @@
#pragma once
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTArray.h"
#include "RE/T/TESCondition.h"
namespace RE
{
namespace BGSCharacterTint
{
enum class BlendOp : std::uint32_t
{
kDefault = 0x0,
kMultiply = 0x1,
kOverlay = 0x2,
kSoftLight = 0x3,
kHardLight = 0x4,
kTotal = 0x5
};
enum class EntryType : std::uint32_t
{
kMask = 0x0,
kPalette = 0x1,
kTexture = 0x2,
kUnknown = 0x3
};
enum class EntrySlot
{
kForeheadMask = 0x0,
kEyesMask = 0x1,
kNoseMask = 0x2,
kEarsMask = 0x3,
kCheeksMask = 0x4,
kMouthMask = 0x5,
kNeckMask = 0x6,
kLipColor = 0x7,
kCheekColor = 0x8,
kEyeliner = 0x9,
kEyeSocketUpper = 0xA,
kEyeSocketLower = 0xB,
kSkinTone = 0xC,
kPaint = 0xD,
kLaughLines = 0xE,
kCheekColorLower = 0xF,
kNose = 0x10,
kChin = 0x11,
kNeck = 0x12,
kForehead = 0x13,
kDirt = 0x14,
kScars = 0x15,
kFaceDetail = 0x16,
kBrow = 0x17,
kWrinkles = 0x18,
kBeard = 0x19
};
namespace Template
{
class __declspec(novtable) Entry
{
public:
static constexpr auto RTTI{ RTTI::BGSCharacterTint__Template__Entry };
static constexpr auto VTABLE{ VTABLE::BGSCharacterTint__Template__Entry };
enum Flags : std::uint32_t
{
kOnOffOnly = 0x1,
kIsChargenDetaul = 0x2,
kTakesSkinTone = 0x4
};
virtual ~Entry(); // 00
// add
virtual float GetDefaultValue() { return 0.0F; } // 01
virtual void InitItem(TESForm* a_owner); // 02
virtual void CopyData(BGSCharacterTint::Template::Entry* a_copy); // 03
virtual void LoadImpl(TESFile* a_file) = 0; // 04
// members
BGSLocalizedString name; // 08
TESCondition chargenConditions; // 10
REX::TEnumSet<BGSCharacterTint::EntrySlot, std::int32_t> slot; // 18
const std::uint16_t uniqueID{ 0 }; // 1C
std::int8_t flags; // 1E
};
static_assert(sizeof(Entry) == 0x20);
class Group
{
public:
// members
BGSLocalizedString name; // 00
std::uint32_t id; // 08
std::uint32_t chargenIndex; // 0C
BSTArray<Entry*> entries; // 10
};
static_assert(sizeof(Group) == 0x28);
class Groups
{
public:
// members
BSTArray<Group*> groups; // 00
};
static_assert(sizeof(Groups) == 0x18);
class __declspec(novtable) Palette :
public Entry
{
public:
static constexpr auto RTTI{ RTTI::BGSCharacterTint__Template__Palette };
static constexpr auto VTABLE{ VTABLE::BGSCharacterTint__Template__Palette };
class ColorValue
{
public:
BGSColorForm* color; // 00
float value; // 08
BlendOp blendOp; // 0C
std::uint16_t swatchID; // 01
};
static_assert(sizeof(ColorValue) == 0x18);
// Members
BSFixedString maskTextureName;
std::uint32_t defaultIndex;
BSTArray<ColorValue> colorValues;
};
static_assert(sizeof(Palette) == 0x48);
}
class __declspec(novtable) Entry
{
public:
static constexpr auto RTTI{ RTTI::BGSCharacterTint__Entry };
static constexpr auto VTABLE{ VTABLE::BGSCharacterTint__Entry };
virtual ~Entry(); // 00
virtual bool GetIsIdentical(const Entry* entry); // 08
virtual bool CopyData(const Entry entry); // 10
virtual bool SetFromTemplateDefault(const Template::Entry* entry); // 18
virtual bool GetMatchesTemplateDefault(const Template::Entry* entry); // 20
virtual EntryType GetType(); // 28
// Members
Entry* templateEntry; // 08
std::uint16_t idLink; // 10
std::uint8_t tingingValue; // 12
};
static_assert(sizeof(Entry) == 0x18);
class Entries
{
public:
BSTArray<Entry*> entriesA;
};
static_assert(sizeof(Entries) == 0x18);
class __declspec(novtable) MaskEntry :
public Entry
{
public:
static constexpr auto RTTI{ RTTI::BGSCharacterTint__MaskEntry };
static constexpr auto VTABLE{ VTABLE::BGSCharacterTint__MaskEntry };
};
static_assert(sizeof(MaskEntry) == 0x18);
class __declspec(novtable) PaletteEntry :
public MaskEntry
{
public:
static constexpr auto RTTI{ RTTI::BGSCharacterTint__PaletteEntry };
static constexpr auto VTABLE{ VTABLE::BGSCharacterTint__PaletteEntry };
// members
std::uint32_t tintingColor; // 18
std::uint16_t swatchID; // 1C
};
static_assert(sizeof(PaletteEntry) == 0x20);
class __declspec(novtable) TextureSetEntry :
public Entry
{
public:
static constexpr auto RTTI{ RTTI::BGSCharacterTint__TextureSetEntry };
static constexpr auto VTABLE{ VTABLE::BGSCharacterTint__TextureSetEntry };
};
static_assert(sizeof(TextureSetEntry) == 0x18);
}
}
@@ -0,0 +1,27 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTArray.h"
#include "RE/T/TESDescription.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSCollisionLayer :
public TESForm, // 00
public TESDescription // 20
{
public:
static constexpr auto RTTI{ RTTI::BGSCollisionLayer };
static constexpr auto VTABLE{ VTABLE::BGSCollisionLayer };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kCOLL };
// members
std::uint32_t collisionIdx; // 38
std::uint32_t debugColor; // 3C
std::uint32_t flags; // 40
BSFixedString name; // 48
BSTArray<BGSCollisionLayer*> collidesWith; // 50
};
static_assert(sizeof(BGSCollisionLayer) == 0x68);
}
@@ -0,0 +1,34 @@
#pragma once
#include "RE/T/TESCondition.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESFullName.h"
namespace RE
{
class __declspec(novtable) BGSColorForm :
public TESForm, // 00
public TESFullName // 20
{
public:
static constexpr auto RTTI{ RTTI::BGSColorForm };
static constexpr auto VTABLE{ VTABLE::BGSColorForm };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kCLFM };
enum class Flags : std::int32_t
{
kPlayable = 0x1,
kRemappingIndex = 0x2
};
// members
union
{
std::uint32_t color;
float remappingIndex;
}; // 30
TESCondition conditions; // 38
std::uint32_t flags; // 40
};
static_assert(sizeof(BGSColorForm) == 0x48);
}
@@ -0,0 +1,26 @@
#pragma once
#include "RE/B/BGSCraftingUseSound.h"
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESValueForm.h"
namespace RE
{
class __declspec(novtable) BGSComponent :
public TESBoundObject, // 00
public TESFullName, // 68
public TESValueForm, // 78
public BGSCraftingUseSound // 88
{
public:
static constexpr auto RTTI{ RTTI::BGSComponent };
static constexpr auto VTABLE{ VTABLE::BGSComponent };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kCMPO };
// members
TESObjectMISC* scrapItem; // 98
TESGlobal* modScrapScalar; // 90
};
static_assert(sizeof(BGSComponent) == 0xA8);
}
@@ -0,0 +1,52 @@
#pragma once
#include "RE/B/BGSPickupPutdownSounds.h"
#include "RE/B/BGSTypedFormValuePair.h"
#include "RE/B/BGSTypedKeywordValue.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTTuple.h"
#include "RE/T/TESCondition.h"
#include "RE/T/TESDescription.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSConstructibleObject :
public TESForm, // 00
public BGSPickupPutdownSounds, // 20
public TESDescription // 38
{
public:
static constexpr auto RTTI{ RTTI::BGSConstructibleObject };
static constexpr auto VTABLE{ VTABLE::BGSConstructibleObject };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kCOBJ };
class ConstructibleObjectData
{
public:
// members
std::uint16_t numConstructed; // 0
std::uint16_t workshopPriority; // 2
};
static_assert(sizeof(ConstructibleObjectData) == 0x4);
[[nodiscard]] TESForm* GetCreatedItem() const noexcept { return createdItem; }
[[nodiscard]] std::uint16_t GetWorkshopPriority() const noexcept { return data.workshopPriority; }
bool PlayerPassesConditions()
{
using func_t = decltype(&BGSConstructibleObject::PlayerPassesConditions);
static REL::Relocation<func_t> func{ ID::BGSConstructibleObject::PlayerPassesConditions };
return func(this);
}
// members
BSTArray<BSTTuple<TESForm*, BGSTypedFormValuePair::SharedVal>>* requiredItems; // 50
TESCondition conditions; // 58
TESForm* createdItem; // 60
BGSKeyword* benchKeyword; // 68
ConstructibleObjectData data; // 70
BGSTypedKeywordValueArray<KeywordType::kRecipeFilter> filterKeywords; // 78
};
static_assert(sizeof(BGSConstructibleObject) == 0x88);
}
@@ -0,0 +1,31 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
#include "RE/T/TESObjectREFR.h"
namespace RE
{
class BGSCraftItemEvent
{
public:
BGSCraftItemEvent(TESObjectREFR* a_workbench, BGSLocation* a_location, TESForm* a_baseObject) :
location(a_location), createdItemBase(a_baseObject)
{
if (a_workbench) {
workbench = a_workbench->GetHandle();
}
}
[[nodiscard]] static std::uint32_t EVENT_INDEX()
{
static REL::Relocation<std::uint32_t*> eventIdx{ ID::BGSCraftItemEvent::EventIndex };
return *eventIdx;
}
// members
ObjectRefHandle workbench; // 00
BGSLocation* location; // 08
TESForm* createdItemBase; // 10
};
static_assert(sizeof(BGSCraftItemEvent) == 0x18);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) BGSCraftingUseSound :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSCraftingUseSound };
static constexpr auto VTABLE{ VTABLE::BGSCraftingUseSound };
// members
BGSSoundDescriptorForm* craftingUseSound; // 08
};
static_assert(sizeof(BGSCraftingUseSound) == 0x10);
}
@@ -0,0 +1,84 @@
#pragma once
#include "RE/B/BSSpinLock.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTHashMap.h"
#include "RE/B/BSTSingleton.h"
#include "RE/B/BSTSmartPointer.h"
namespace RE
{
class BGSCreatedObjectManager :
public BSTSingletonSDM<BGSCreatedObjectManager> // 00
{
public:
template <class T>
class BSTCreatedObjectSmartPointerPolicy
{
public:
static void Acquire(T* a_ptr)
{
const auto manager = BGSCreatedObjectManager::GetSingleton();
if (manager &&
a_ptr->IsCreated() &&
a_ptr->IsAlchemyItem()) {
manager->IncrementRef(static_cast<AlchemyItem*>(a_ptr));
}
}
static void Release(T* a_ptr)
{
const auto manager = BGSCreatedObjectManager::GetSingleton();
if (manager &&
a_ptr->IsCreated() &&
a_ptr->IsAlchemyItem()) {
manager->DecrementRef(static_cast<AlchemyItem*>(a_ptr));
}
}
};
class CreatedMagicItemData
{
public:
// members
MagicItem* createdItem; // 00
std::uint32_t count; // 08
};
static_assert(sizeof(CreatedMagicItemData) == 0x10);
[[nodiscard]] static BGSCreatedObjectManager* GetSingleton()
{
static REL::Relocation<BGSCreatedObjectManager**> singleton{ ID::BGSCreatedObjectManager::Singleton };
return *singleton;
}
void DecrementRef(AlchemyItem* a_alchItem)
{
using func_t = decltype(&BGSCreatedObjectManager::DecrementRef);
static REL::Relocation<func_t> func{ ID::BGSCreatedObjectManager::DecrementRef };
return func(this, a_alchItem);
}
void IncrementRef(AlchemyItem* a_alchItem)
{
using func_t = decltype(&BGSCreatedObjectManager::IncrementRef);
static REL::Relocation<func_t> func{ ID::BGSCreatedObjectManager::IncrementRef };
return func(this, a_alchItem);
}
// members
BSTArray<CreatedMagicItemData> weaponEnchantments; // 08
BSTArray<CreatedMagicItemData> armorEnchantments; // 20
BSTHashMap<std::uint32_t, CreatedMagicItemData> potions; // 38
BSTHashMap<std::uint32_t, CreatedMagicItemData> poisons; // 68
BSTSet<MagicItem*> queuedDeleteMagicItems; // 98
BSSpinLock dataLock; // C8
};
static_assert(sizeof(BGSCreatedObjectManager) == 0xD0);
extern template class BGSCreatedObjectManager::BSTCreatedObjectSmartPointerPolicy<AlchemyItem>;
extern template class BGSCreatedObjectManager::BSTCreatedObjectSmartPointerPolicy<TESForm>;
template <class T>
using CreatedObjPtr = BSTSmartPointer<T, BGSCreatedObjectManager::BSTCreatedObjectSmartPointerPolicy>;
}
@@ -0,0 +1,28 @@
#pragma once
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSDamageType :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSDamageType };
static constexpr auto VTABLE{ VTABLE::BGSDamageType };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kDMGT };
class Data
{
public:
// members
ActorValueInfo* resistance; // 00
MagicItem* spell; // 08
};
static_assert(sizeof(Data) == 0x10);
// members
Data data; // 20
};
static_assert(sizeof(BGSDamageType) == 0x30);
}
@@ -0,0 +1,24 @@
#pragma once
#include "RE/B/BGSPreloadable.h"
#include "RE/B/BSSimpleList.h"
#include "RE/T/TESForm.h"
namespace RE
{
class BGSDebrisData;
class __declspec(novtable) BGSDebris :
public TESForm, // 00
public BGSPreloadable // 20
{
public:
static constexpr auto RTTI{ RTTI::BGSDebris };
static constexpr auto VTABLE{ VTABLE::BGSDebris };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kDEBR };
// members
BSSimpleList<BGSDebrisData*> dataList; // 28
};
static_assert(sizeof(BGSDebris) == 0x38);
}
@@ -0,0 +1,20 @@
#pragma once
#include "RE/N/NiPointer.h"
namespace RE
{
class BGSImpactData;
class BSTempEffectParticle;
class BGSDecalEmitter
{
public:
// members
std::int32_t decalsToEmit; // 00
bool finished; // 04
BGSImpactData* decalImpactData; // 08
NiPointer<BSTempEffectParticle> particleData; // 10
};
static_assert(sizeof(BGSDecalEmitter) == 0x18);
}
@@ -0,0 +1,19 @@
#pragma once
#include "RE/B/BSTArray.h"
namespace RE
{
class DECAL_CREATION_DATA;
class BGSDecalGroup
{
public:
// members
bool permanentGroup; // 00
bool manualSaveLoad; // 01
BSTArray<std::uint32_t> decalGroup; // 08
BSTArray<DECAL_CREATION_DATA*> pendingDecals; // 20
};
static_assert(sizeof(BGSDecalGroup) == 0x38);
}
@@ -0,0 +1,24 @@
#pragma once
#include "RE/B/BSTArray.h"
#include "RE/N/NiNode.h"
namespace RE
{
class BSTempEffect;
class __declspec(novtable) BGSDecalNode :
public NiNode // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSDecalNode };
static constexpr auto VTABLE{ VTABLE::BGSDecalNode };
static constexpr auto Ni_RTTI{ Ni_RTTI::BGSDecalNode };
// members
BSTArray<NiPointer<BSTempEffect>> decals; // 140
BSTArray<std::uint32_t> decalCreationFrames; // 158
bool skinnedNode; // 170
};
static_assert(sizeof(BGSDecalNode) == 0x180);
}
@@ -0,0 +1,48 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTArray.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSDefaultObject :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSDefaultObject };
static constexpr auto VTABLE{ VTABLE::BGSDefaultObject };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kDFOB };
BGSDefaultObject(const char* a_name, ENUM_FORM_ID a_formType, const char* a_description)
{
ctor(a_name, a_formType, a_description);
}
[[nodiscard]] static BSTArray<BGSDefaultObject*>* GetSingleton()
{
static REL::Relocation<BSTArray<BGSDefaultObject*>**> singleton{ ID::BGSDefaultObject::Singleton };
return *singleton;
}
template <class T = TESForm>
[[nodiscard]] T* GetForm()
{
return form ? form->As<T>() : nullptr;
}
// members
TESForm* form; // 20
ENUM_FORM_ID type; // 28
BSFixedString formEditorID; // 30
private:
BGSDefaultObject* ctor(const char* a_name, ENUM_FORM_ID a_formType, const char* a_description)
{
using func_t = decltype(&BGSDefaultObject::ctor);
static REL::Relocation<func_t> func{ ID::BGSDefaultObject::ctor };
return func(this, a_name, a_formType, a_description);
}
};
static_assert(sizeof(BGSDefaultObject) == 0x38);
}
@@ -0,0 +1,48 @@
#pragma once
#include "RE/B/BSTSingleton.h"
#include "RE/D/DEFAULT_OBJECT.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSDefaultObjectManager :
public TESForm, // 00
public BSTSingletonImplicit<BGSDefaultObjectManager> // 20
{
public:
static constexpr auto RTTI{ RTTI::BGSDefaultObjectManager };
static constexpr auto VTABLE{ VTABLE::BGSDefaultObjectManager };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kDOBJ };
[[nodiscard]] static BGSDefaultObjectManager* GetSingleton()
{
using func_t = decltype(&BGSDefaultObjectManager::GetSingleton);
static REL::Relocation<func_t> func{ ID::BGSDefaultObjectManager::Singleton };
return func();
}
[[nodiscard]] TESForm* GetDefaultObject(DEFAULT_OBJECT a_obj) const noexcept
{
assert(a_obj < DEFAULT_OBJECT::kTotal);
return objectInitArray[std::to_underlying(a_obj)] ?
objectArray[std::to_underlying(a_obj)] :
nullptr;
}
template <class T>
[[nodiscard]] T* GetDefaultObject(DEFAULT_OBJECT a_obj) const //
requires(std::derived_from<T, TESForm> &&
!std::is_pointer_v<T> &&
!std::is_reference_v<T>)
{
const auto obj = GetDefaultObject(a_obj);
return obj ? obj->As<T>() : nullptr;
}
// members
TESForm* objectArray[std::to_underlying(DEFAULT_OBJECT::kTotal)]; // 020
bool objectInitArray[std::to_underlying(DEFAULT_OBJECT::kTotal)]; // C70
};
static_assert(sizeof(BGSDefaultObjectManager) == 0xE00);
}
@@ -0,0 +1,20 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class DestructibleObjectData;
class __declspec(novtable) BGSDestructibleObjectForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSDestructibleObjectForm };
static constexpr auto VTABLE{ VTABLE::BGSDestructibleObjectForm };
// members
DestructibleObjectData* data; // 08
};
static_assert(sizeof(BGSDestructibleObjectForm) == 0x10);
}
@@ -0,0 +1,31 @@
#pragma once
#include "RE/T/TESForm.h"
namespace RE
{
enum class DIALOGUE_TYPE;
class __declspec(novtable) BGSDialogueBranch :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSDialogueBranch };
static constexpr auto VTABLE{ VTABLE::BGSDialogueBranch };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kDLBR };
enum class Flag
{
kTopLevel = 0x0,
kBlocking = 0x1,
kExclusive = 0x2
};
// members
std::uint32_t flags; // 20
TESQuest* quest; // 28
TESTopic* startingTopic; // 30
REX::TEnumSet<DIALOGUE_TYPE, std::int32_t> type; // 38
};
static_assert(sizeof(BGSDialogueBranch) == 0x40);
}
@@ -0,0 +1,26 @@
#pragma once
namespace RE
{
class BGSDirectionalAmbientLightingColors
{
public:
enum class ColorIndex : std::uint32_t
{
kXPos = 0x0,
kXNeg = 0x1,
kYPos = 0x2,
kYNeg = 0x3,
kZPos = 0x4,
kZNeg = 0x5,
kAxisCount = 0x6,
kSpecularTint = 0x6,
kColorCount = 0x7
};
// members
std::uint32_t colorValues[7]; // 00
float fresnelPower; // 1C
};
static_assert(sizeof(BGSDirectionalAmbientLightingColors) == 0x20);
}
@@ -0,0 +1,20 @@
#pragma once
#include "RE/B/BGSDualCastDataDEF.h"
#include "RE/T/TESBoundObject.h"
namespace RE
{
class __declspec(novtable) BGSDualCastData :
public TESBoundObject // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSDualCastData };
static constexpr auto VTABLE{ VTABLE::BGSDualCastData };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kDUAL };
// members
BGSDualCastDataDEF data; // 68
};
static_assert(sizeof(BGSDualCastData) == 0x98);
}
@@ -0,0 +1,17 @@
#pragma once
namespace RE
{
class BGSDualCastDataDEF
{
public:
// members
BGSProjectile* projectile; // 00
BGSExplosion* explosion; // 08
TESEffectShader* effectShader; // 10
BGSArtObject* hitEffectArt; // 18
BGSImpactDataSet* impactDataSet; // 20
std::uint32_t flags; // 28
};
static_assert(sizeof(BGSDualCastDataDEF) == 0x30);
}
@@ -0,0 +1,42 @@
#pragma once
#include "RE/B/BSSpinLock.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTSingleton.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class QueuedPromoteReferencesTask;
class BGSDynamicPersistenceManager :
public BSTSingletonExplicit<BGSDynamicPersistenceManager>
{
public:
[[nodiscard]] static BGSDynamicPersistenceManager* GetSingleton()
{
static REL::Relocation<BGSDynamicPersistenceManager**> singleton{ ID::BGSDynamicPersistenceManager::Singleton };
return *singleton;
}
bool PromoteReference(TESObjectREFR* a_refr, TESForm* a_owner)
{
using func_t = decltype(&BGSDynamicPersistenceManager::PromoteReference);
static REL::Relocation<func_t> func{ ID::BGSDynamicPersistenceManager::PromoteReference };
return func(this, a_refr, a_owner);
}
bool DemoteReference(TESObjectREFR* a_refr, TESForm* a_owner, bool a_allowActors = false)
{
using func_t = decltype(&BGSDynamicPersistenceManager::DemoteReference);
static REL::Relocation<func_t> func{ ID::BGSDynamicPersistenceManager::DemoteReference };
return func(this, a_refr, a_owner, a_allowActors);
}
// members
BSTArray<NiPointer<QueuedPromoteReferencesTask>> taskArray; // 00
BSSpinLock taskArrayLock; // 18
volatile std::int32_t pauseCount; // 20
};
static_assert(sizeof(BGSDynamicPersistenceManager) == 0x28);
}
@@ -0,0 +1,32 @@
#pragma once
#include "RE/C/CHANGE_TYPES.h"
#include "RE/E/ENCOUNTER_ZONE_DATA.h"
#include "RE/E/ENCOUNTER_ZONE_GAME_DATA.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSEncounterZone :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSEncounterZone };
static constexpr auto VTABLE{ VTABLE::BGSEncounterZone };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kECZN };
[[nodiscard]] bool NeverResets() const noexcept { return data.flags.all(ENCOUNTER_ZONE_DATA::FLAG::kNeverReset); }
[[nodiscard]] bool IsWorkshop() const noexcept { return data.flags.all(ENCOUNTER_ZONE_DATA::FLAG::kWorkshopZone); }
void SetDetachTime(std::uint32_t a_time)
{
gameData.detachTime = a_time;
AddChange(CHANGE_TYPE::kEncounterZoneGameData);
}
// members
ENCOUNTER_ZONE_DATA data; // 20
ENCOUNTER_ZONE_GAME_DATA gameData; // 38
};
static_assert(sizeof(BGSEncounterZone) == 0x48);
}
@@ -0,0 +1,177 @@
#pragma once
namespace RE
{
namespace BGSEntryPoint
{
enum class ENTRY_POINT : std::uint32_t
{
kModBreathTimer = 0x0,
kCalculateCriticalHitChance = 0x1,
kCalculateCriticalHitDamageMult = 0x2,
kCalculateMineExplodeChance = 0x3,
kModIncomingLimbDamage = 0x4,
kAdjustBookActorValueBonus = 0x5,
kModifyRecoveredHealth = 0x6,
kGetShouldAttack = 0x7,
kModBuyPrices = 0x8,
kAddLeveledListOnDeath = 0x9,
kGetMaxCarryWeight = 0xA,
kModifyAddictionChance = 0xB,
kModifyAddictionDuration = 0xC,
kModifyPositiveChemDuration = 0xD,
kActivate = 0xE,
kIgnoreRunningDuringDetection = 0xF,
kIgnoreBrokenLock = 0x10,
kModifyEnemyCriticalHitChance = 0x11,
kModifySneakAttackMult = 0x12,
kModifyMaxPlaceableMines = 0x13,
kModifyBowZoom = 0x14,
kModifyRecoverArrowChance = 0x15,
kModExperience = 0x16,
kModTelekinesisDistance = 0x17,
kModTelekinesisDamageMult = 0x18,
kModTelekinesisDamage = 0x19,
kModBashingDamage = 0x1A,
kModPowerAttackActionPoints = 0x1B,
kModPowerAttackDamage = 0x1C,
kModSpellMagnitude = 0x1D,
kModSpellDuration = 0x1E,
kModSecondaryValueWeight = 0x1F,
kModArmorWeight = 0x20,
kModIncomingStagger = 0x21,
kModTargetStagger = 0x22,
kModAttackDamage = 0x23,
kModIncomingDamage = 0x24,
kModTargetDamageResistance = 0x25,
kModSpellCost = 0x26,
kModPercentageBlocked = 0x27,
kModShieldDeflectArrowChance = 0x28,
kModIncomingSpellMagnitude = 0x29,
kModIncomingSpellDuration = 0x2A,
kModPlayerIntimidation = 0x2B,
kModRicochetChance = 0x2C,
kModRicochetDamage = 0x2D,
kModBribeAmount = 0x2E,
kModDetectionLight = 0x2F,
kModDetectionMovement = 0x30,
kModScrapRewardMult = 0x31,
kSetSweepAttack = 0x32,
kApplyCombatHitSpell = 0x33,
kApplyBashSpell = 0x34,
kApplyReanimateSpell = 0x35,
kSetBooleanGraphVariable = 0x36,
kModSpellCastingSoundEvent = 0x37,
kModPickpocketChance = 0x38,
kModDetectionSneakSkill = 0x39,
kModFallingDamage = 0x3A,
kModLockpickSweetSpot = 0x3B,
kModSellPrices = 0x3C,
kCanPickpocketEquippedItem = 0x3D,
kGetPlayerGateLockpick = 0x3E,
kSetLockpickStartingArc = 0x3F,
kSetLockpickProgressionPicking = 0x40,
kSetLockpickUnbreakable = 0x41,
kModAlchemyEffectiveness = 0x42,
kApplyWeaponSwingSpell = 0x43,
kModCommandedActorLimit = 0x44,
kApplySneakingSpell = 0x45,
kModPlayerMagicSlowdown = 0x46,
kModWardMagickaAbsorptionPercent = 0x47,
kModInitialIngredientEffectsLearned = 0x48,
kPurifyAlchemyIngredients = 0x49,
kFilterActivation = 0x4A,
kCanDualCastSpell = 0x4B,
kModOutgoingExplosionLimbDamage = 0x4C,
kModEnchantmentPower = 0x4D,
kModSoulPercentCapturedToWeapon = 0x4E,
kModVATSAttackAP = 0x4F,
kModReflectDamageChance = 0x50,
kSetActivateLabel = 0x51,
kModKillExperience = 0x52,
kModPoisonDoseCount = 0x53,
kShouldApplyItem = 0x54,
kModArmorRating = 0x55,
kModLockpickingCrimeChance = 0x56,
kModIngredientsHarvested = 0x57,
kModSpellRange = 0x58,
kModRicochetCriticalChargeMult = 0x59,
kModLockpickRewardKeyChance = 0x5A,
kModAutoLockpickChance = 0x5B,
kModAutoHackingChance = 0x5C,
kModTypedAttackDamage = 0x5D,
kModTypedIncomingDamage = 0x5E,
kModCharismaChallengeChance = 0x5F,
kModSprintAPDrainRate = 0x60,
kModDrawnWeaponWeightSpeedEffect = 0x61,
kGetPlayerGateHacking = 0x62,
kModPlayerExplosionDamage = 0x63,
kModPlayerExplosionScale = 0x64,
kSetRadsToHealthMult = 0x65,
kModActorScopeStability = 0x66,
kModActorGrenadeSpeedMult = 0x67,
kModExplosionForce = 0x68,
kModVATSPenetrationMinVisibility = 0x69,
kModRadsForRadHealthMax = 0x6A,
kModVATSPlayerAPKillAwardChance = 0x6B,
kSetVATSFillCritOnHit = 0x6C,
kModVATSConcentratedFireBonus = 0x6D,
kModVATSCriticalCount = 0x6E,
kModVATSHoldSteadyBonus = 0x6F,
kModTypedSpellMagnitude = 0x70,
kModTypedIncomingSpellMagnitude = 0x71,
kSetVATSGunFuNumTargetsForCrits = 0x72,
kModOutgoingLimbDamage = 0x73,
kModRestoreActionCostValue = 0x74,
kModVATSReloadAP = 0x75,
kModIncomingBatteryDamage = 0x76,
kModVATSCriticalCharge = 0x77,
kModExperienceLocation = 0x78,
kModExperienceSpeech = 0x79,
kModVATSHeadShotChance = 0x7A,
kModVATSHitChance = 0x7B,
kModIncomingExplosionDamage = 0x7C,
kModAmmoHealthMult = 0x7D,
kModHackingGuesses = 0x7E,
kModTerminalLockoutTime = 0x7F,
kSetUndetectable = 0x80,
kInvestInVendor = 0x81,
kModOutgoingLimbBashDamage = 0x82,
kSetRunWhileOverEncumbered = 0x83,
kGetComponentRadarDistance = 0x84,
kShowGrenadeTrajectory = 0x85,
kModConeOfFireMult = 0x86,
kModVATSConcentratedFireDamageMult = 0x87,
kApplyBloodyMessSpell = 0x88,
kModVATSCritFillChanceOnBank = 0x89,
kModVATSCritFillChanceOnUse = 0x8A,
kSetVATSCritFillOnAPReward = 0x8B,
kSetVATSCritFillOnStranger = 0x8C,
kModGunRangeMult = 0x8D,
kModScopeHoldBreathAPDrainMult = 0x8E,
kSetForceDecapitate = 0x8F,
kModVATSShootExplosiveDamageMult = 0x90,
kModScroungerFillAmmoChance = 0x91,
kSetCanExplodePants = 0x92,
kSetVATSPenetrationFullDamage = 0x93,
kModVATSGunFu2ndTargetDmgMult = 0x94,
kModVATSGunFu3rdTargetDmgMult = 0x95,
kModVATSGunFu4thPlusDmgMult = 0x96,
kModVATSBlitzMaxDist = 0x97,
kSetVATSBlitzDmgMultAtMaxDist = 0x98,
kModVATSBlitzDmgBonusDist = 0x99,
kModBashCriticalChance = 0x9A,
kVATSApplyParalyzingPalmSpell = 0x9B,
kModFatigueForFatigueAPMax = 0x9C,
kSetFatigueToAPMult = 0x9D,
};
template <class... Args>
inline void HandleEntryPoint(ENTRY_POINT a_entryPoint, Actor* a_perkOwner, Args... a_args)
{
using func_t = decltype(&BGSEntryPoint::HandleEntryPoint<Args...>);
static REL::Relocation<func_t> func{ ID::BGSEntryPoint::HandleEntryPoint };
return func(a_entryPoint, a_perkOwner, a_args...);
}
}
}
@@ -0,0 +1,14 @@
#pragma once
namespace RE
{
class BGSEquipIndex
{
public:
~BGSEquipIndex() noexcept {} // NOLINT(modernize-use-equals-default)
// members
std::uint32_t index; // 0
};
static_assert(sizeof(BGSEquipIndex) == 0x4);
}
@@ -0,0 +1,22 @@
#pragma once
#include "RE/B/BSTArray.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSEquipSlot :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSEquipSlot };
static constexpr auto VTABLE{ VTABLE::BGSEquipSlot };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kEQUP };
// members
BSTArray<BGSEquipSlot*> parentSlots; // 20
std::uint32_t flags; // 38
ActorValueInfo* conditionActorValue; // 40
};
static_assert(sizeof(BGSEquipSlot) == 0x48);
}
@@ -0,0 +1,22 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) BGSEquipType :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSEquipType };
static constexpr auto VTABLE{ VTABLE::BGSEquipType };
// add
[[nodiscard]] virtual BGSEquipSlot* GetEquipSlot([[maybe_unused]] const TBO_InstanceData* a_data) const { return equipSlot; } // 06
virtual void SetEquipSlot(BGSEquipSlot* a_slot) { equipSlot = a_slot; } // 07
// members
BGSEquipSlot* equipSlot; // 08
};
static_assert(sizeof(BGSEquipType) == 0x10);
}
@@ -0,0 +1,44 @@
#pragma once
#include "RE/B/BGSExplosionData.h"
#include "RE/B/BGSPreloadable.h"
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESEnchantableForm.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESImageSpaceModifiableForm.h"
#include "RE/T/TESModel.h"
namespace RE
{
class __declspec(novtable) BGSExplosion :
public TESBoundObject, // 000
public TESFullName, // 068
public TESModel, // 078
public TESEnchantableForm, // 0A8
public BGSPreloadable, // 0C0
public TESImageSpaceModifiableForm // 0C8
{
public:
static constexpr auto RTTI{ RTTI::BGSExplosion };
static constexpr auto VTABLE{ VTABLE::BGSExplosion };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kEXPL };
enum class EXPLOSION_TYPE
{
kNormal = 0x0,
kChain = 0x1
};
enum class KnockDownMode
{
kNever = 0x0,
kAlways = 0x1,
kFormula = 0x2,
kNPC = 0x3
};
// members
BGSExplosionData data; // 0D8
};
static_assert(sizeof(BGSExplosion) == 0x148);
}
@@ -0,0 +1,35 @@
#pragma once
#include "RE/N/NiPoint3.h"
namespace RE
{
enum class SOUND_LEVEL;
enum class STAGGER_MAGNITUDE;
class BGSExplosionData
{
public:
// members
TESObjectLIGH* light; // 00
BGSSoundDescriptorForm* sound1; // 08
BGSSoundDescriptorForm* sound2; // 10
BGSImpactDataSet* impactDataSet; // 18
TESBoundObject* impactPlacedObject; // 20
BGSProjectile* spawnProjectile; // 28
NiPoint3 projectileVector; // 30
float projectileSpread; // 3C
std::uint32_t projectileCount; // 40
float force; // 44
float damage; // 48
float innerRadius; // 4C
float outerRadius; // 50
float imageSpaceRadius; // 54
float verticalOffsetMult; // 58
std::uint32_t flags; // 5C
REX::TEnumSet<SOUND_LEVEL, std::int32_t> soundLevel; // 60
float placedObjectFadeDelay; // 64
REX::TEnumSet<STAGGER_MAGNITUDE, std::int32_t> staggerMagnitude; // 68
};
static_assert(sizeof(BGSExplosionData) == 0x70);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) BGSFeaturedItemMessage :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSFeaturedItemMessage };
static constexpr auto VTABLE{ VTABLE::BGSFeaturedItemMessage };
// members
BGSMessage* featuredItemMessage; // 08
};
static_assert(sizeof(BGSFeaturedItemMessage) == 0x10);
}
@@ -0,0 +1,21 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSFootstep :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSFootstep };
static constexpr auto VTABLE{ VTABLE::BGSFootstep };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kFSTP };
// members
BSFixedString tagString; // 20
BGSImpactDataSet* impactSet; // 28
};
static_assert(sizeof(BGSFootstep) == 0x30);
}
@@ -0,0 +1,20 @@
#pragma once
#include "RE/B/BSTArray.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSFootstepSet :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSFootstepSet };
static constexpr auto VTABLE{ VTABLE::BGSFootstepSet };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kFSTS };
// members
BSTArray<BGSFootstep*> entries[5]; // 20
};
static_assert(sizeof(BGSFootstepSet) == 0x98);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) BGSForcedLocRefType :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSForcedLocRefType };
static constexpr auto VTABLE{ VTABLE::BGSForcedLocRefType };
// members
BGSLocationRefType* forcedType; // 08
};
static_assert(sizeof(BGSForcedLocRefType) == 0x10);
}
@@ -0,0 +1,36 @@
#pragma once
#include "RE/N/NiColor.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSGodRays :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSGodRays };
static constexpr auto VTABLE{ VTABLE::BGSGodRays };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kGDRY };
class GodRaysData
{
public:
// members
NiColor colorAir; // 00
NiColor colorBack; // 0C
NiColor colorFwd; // 18
float intensity; // 24
float scatterAir; // 28
float scatterBack; // 2C
float scatterFwd; // 30
float phaseBack; // 34
float phaseFwd; // 38
};
static_assert(sizeof(GodRaysData) == 0x3C);
// members
GodRaysData data; // 20
};
static_assert(sizeof(BGSGodRays) == 0x60);
}
@@ -0,0 +1,30 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
#include "RE/T/TESObjectREFR.h"
namespace RE
{
class BGSHackTerminal
{
public:
BGSHackTerminal(TESObjectREFR* a_terminal, std::uint32_t a_success) :
success(a_success)
{
if (a_terminal) {
terminal = a_terminal->GetHandle();
}
}
[[nodiscard]] static std::uint32_t EVENT_INDEX()
{
static REL::Relocation<std::uint32_t*> eventIdx{ ID::BGSHackTerminal::EventIndex };
return *eventIdx;
}
// members
ObjectRefHandle terminal; // 00
std::uint32_t success; // 04
};
static_assert(sizeof(BGSHackTerminal) == 0x08);
}
@@ -0,0 +1,28 @@
#pragma once
#include "RE/B/BGSHazardData.h"
#include "RE/B/BGSPreloadable.h"
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESImageSpaceModifiableForm.h"
#include "RE/T/TESModel.h"
namespace RE
{
class __declspec(novtable) BGSHazard :
public TESBoundObject, // 000
public TESFullName, // 068
public TESModel, // 078
public BGSPreloadable, // 0A8
public TESImageSpaceModifiableForm // 0B0
{
public:
static constexpr auto RTTI{ RTTI::BGSHazard };
static constexpr auto VTABLE{ VTABLE::BGSHazard };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kHAZD };
// members
BGSHazardData data; // 0C0
};
static_assert(sizeof(BGSHazard) == 0x108);
}
@@ -0,0 +1,35 @@
#pragma once
namespace RE
{
class BGSHazardData
{
public:
enum class BGSHazardFlags
{
kNone = 0,
kPlayerOnly = 1 << 0,
kInheritDuration = 1 << 1,
kAlignToNormal = 1 << 2,
kInheritRadius = 1 << 3,
kDropToGround = 1 << 4,
kTaperEffectiveness = 1 << 5,
};
// members
std::uint32_t limit; // 00
float radius; // 04
float lifetime; // 08
float imageSpaceRadius; // 0C
float targetInterval; // 10
REX::TEnumSet<BGSHazardFlags, std::uint32_t> flags; // 14
SpellItem* spell; // 18
TESObjectLIGH* light; // 20
BGSImpactDataSet* impactDataSet; // 28
BGSSoundDescriptorForm* sound; // 30
float fullEffectRadius; // 38
float taperWeight; // 3C
float taperCurve; // 40
};
static_assert(sizeof(BGSHazardData) == 0x48);
}
@@ -0,0 +1,70 @@
#pragma once
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTArray.h"
#include "RE/T/TESCondition.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESFullName.h"
#include "RE/T/TESModel.h"
#include "RE/T/TESModelTri.h"
namespace RE
{
class __declspec(novtable) BGSHeadPart :
public TESForm, // 000
public TESFullName, // 020
public BGSModelMaterialSwap // 030
{
public:
static constexpr auto RTTI{ RTTI::BGSHeadPart };
static constexpr auto VTABLE{ VTABLE::BGSHeadPart };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kHDPT };
enum class Flag
{
kPlayable = 1u << 0,
kCantBeFemale = 1u << 1,
kCantBeMale = 1u << 2,
kExtraPart = 1u << 3,
kUseSolidTint = 1u << 4,
kUseBodyTexture = 1u << 5
};
enum class HeadPartType
{
kMisc = 0x0,
kFace = 0x1,
kEyes = 0x2,
kHair = 0x3,
kFacialHair = 0x4,
kScar = 0x5,
kEyebrows = 0x6,
kMeatcaps = 0x7,
kTeeth = 0x8,
kHeadRear = 0x9
};
enum class MorphIndex
{
kRaceMorph = 0x0,
kDefaultMorph = 0x1,
kChargenMorph = 0x2
};
[[nodiscard]] bool IsExtraPart() const noexcept { return flags.all(Flag::kExtraPart); }
// members
REX::TEnumSet<Flag, std::uint8_t> flags; // 070
REX::TEnumSet<HeadPartType, std::int32_t> type; // 074
BSTArray<BGSHeadPart*> extraParts; // 078
BGSTextureSet* textureSet; // 090
TESModel ChargenModel; // 098
TESModelTri morphs[3]; // 0C8
BGSColorForm* colorForm; // 158
BGSListForm* validRaces; // 160
TESCondition chargenConditions; // 168
BSFixedString formEditorID; // 170
};
static_assert(sizeof(BGSHeadPart) == 0x178);
}
@@ -0,0 +1,21 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) BGSIdleCollection :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSIdleCollection };
static constexpr auto VTABLE{ VTABLE::BGSIdleCollection };
// members
std::int8_t idleFlags; // 08
std::int8_t idleCount; // 09
TESIdleForm** idleArray; // 10
float timerCheckForIdle; // 18
};
static_assert(sizeof(BGSIdleCollection) == 0x20);
}
@@ -0,0 +1,26 @@
#pragma once
#include "RE/B/BGSIdleCollection.h"
#include "RE/B/BGSKeywordForm.h"
#include "RE/T/TESBoundObject.h"
#include "RE/T/TESModel.h"
namespace RE
{
class __declspec(novtable) BGSIdleMarker :
public TESBoundObject, // 00
public BGSKeywordForm, // 68
public TESModel, // 88
public BGSIdleCollection // B8
{
public:
static constexpr auto RTTI{ RTTI::BGSIdleMarker };
static constexpr auto VTABLE{ VTABLE::BGSIdleMarker };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kIDLM };
// members
BGSKeyword* animArchType; // D8
BGSKeyword* flavorAnim; // E0
};
static_assert(sizeof(BGSIdleMarker) == 0xE8);
}
@@ -0,0 +1,53 @@
#pragma once
#include "RE/D/DecalData.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESModel.h"
namespace RE
{
enum class SOUND_LEVEL;
class __declspec(novtable) BGSImpactData :
public TESForm, // 00
public TESModel // 20
{
public:
static constexpr auto RTTI{ RTTI::BGSImpactData };
static constexpr auto VTABLE{ VTABLE::BGSImpactData };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kIPCT };
enum class ORIENTATION
{
kSurfaceNormal = 0x0,
kProjVector = 0x1,
kProjReflect = 0x2
};
class IMPACT_DATA_DATA
{
public:
// members
float effectDuration; // 00
REX::TEnumSet<ORIENTATION, std::int32_t> orient; // 04
float angleThreshold; // 08
float placementRadius; // 0C
REX::TEnumSet<SOUND_LEVEL, std::int32_t> soundLevel; // 10
std::int8_t flags; // 14
std::int8_t resultOverride; // 15
};
static_assert(sizeof(IMPACT_DATA_DATA) == 0x18);
// members
IMPACT_DATA_DATA data; // 50
BGSTextureSet* decalTextureSet; // 68
BGSTextureSet* decalTextureSet2; // 70
BGSSoundDescriptorForm* sound1; // 78
BGSSoundDescriptorForm* sound2; // 80
BGSExplosion* explosion; // 88
BGSHazard* hazard; // 90
DecalData decalData; // 98
float maxFootstepParticleDist; // BC
};
static_assert(sizeof(BGSImpactData) == 0xC0);
}
@@ -0,0 +1,22 @@
#pragma once
#include "RE/B/BGSPreloadable.h"
#include "RE/B/BSTHashMap.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSImpactDataSet :
public TESForm, // 00
public BGSPreloadable // 20
{
public:
static constexpr auto RTTI{ RTTI::BGSImpactDataSet };
static constexpr auto VTABLE{ VTABLE::BGSImpactDataSet };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kIPDS };
// members
BSTHashMap<const BGSMaterialType*, BGSImpactData*> impactMap; // 28
};
static_assert(sizeof(BGSImpactDataSet) == 0x58);
}
@@ -0,0 +1,45 @@
#pragma once
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BSTArray.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSInstanceNamingRules :
public TESForm // 000
{
public:
static constexpr auto RTTI{ RTTI::BGSInstanceNamingRules };
static constexpr auto VTABLE{ VTABLE::BGSInstanceNamingRules };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kINNR };
class RuleData
{
public:
// members
BGSLocalizedString text; // 00
BGSKeywordForm keywords; // 08
float compareVal; // 28
std::int8_t propertyBridgeArrayIndex; // 2C
std::int8_t operatorType; // 2D
std::uint16_t index; // 2E
bool revert; // 30
};
static_assert(sizeof(RuleData) == 0x38);
class RuleSet :
public BSTArray<RuleData> // 00
{
public:
};
static_assert(sizeof(RuleSet) == 0x18);
// members
ENUM_FORM_ID type; // 020
RuleSet ruleSets[10]; // 028
BSTArray<const BGSInstanceNamingRules*> mergeSources; // 118
};
static_assert(sizeof(BGSInstanceNamingRules) == 0x130);
}
@@ -0,0 +1,20 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class BGSInstanceNamingRules;
class __declspec(novtable) BGSInstanceNamingRulesForm :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSInstanceNamingRulesForm };
static constexpr auto VTABLE{ VTABLE::BGSInstanceNamingRulesForm };
// members
BGSInstanceNamingRules* instanceNamingRules; // 08
};
static_assert(sizeof(BGSInstanceNamingRulesForm) == 0x10);
}
@@ -0,0 +1,17 @@
#pragma once
namespace RE
{
enum class QUEST_OBJECTIVE_STATE;
class BGSQuestObjective;
class BGSInstancedQuestObjective
{
public:
// members
BGSQuestObjective* objective; // 00
std::uint32_t instanceID; // 08
REX::TEnumSet<QUEST_OBJECTIVE_STATE, std::int32_t> enstanceState; // 0C
};
static_assert(sizeof(BGSInstancedQuestObjective) == 0x10);
}
@@ -0,0 +1,59 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTEvent.h"
#include "RE/B/BSTSingleton.h"
namespace RE
{
class BGSInventoryItem;
namespace InventoryInterface
{
class CountChangedEvent;
class FavoriteChangedEvent;
}
class BGSInventoryInterface :
BSTSingletonSDM<BGSInventoryInterface>, // 00
BSTEventSource<InventoryInterface::CountChangedEvent>, // 08
BSTEventSource<InventoryInterface::FavoriteChangedEvent> // 60
{
public:
class Agent
{
public:
// members
std::uint32_t handleID; // 0
ObjectRefHandle itemOwner; // 4
std::uint16_t listIndex; // 8
std::uint16_t refCount; // A
};
static_assert(sizeof(Agent) == 0xC);
[[nodiscard]] static BGSInventoryInterface* GetSingleton()
{
static REL::Relocation<BGSInventoryInterface**> singleton{ ID::BGSInventoryInterface::Singleton };
return *singleton;
}
[[nodiscard]] const BGSInventoryItem* RequestInventoryItem(const std::uint32_t& a_handleID) const
{
using func_t = decltype(&BGSInventoryInterface::RequestInventoryItem);
static REL::Relocation<func_t> func{ ID::BGSInventoryInterface::RequestInventoryItem };
return func(this, a_handleID);
}
[[nodiscard]] bool ForceMergeStacks(const std::uint32_t& a_handleID)
{
using func_t = decltype(&BGSInventoryInterface::ForceMergeStacks);
static REL::Relocation<func_t> func{ ID::BGSInventoryInterface::ForceMergeStacks };
return func(this, a_handleID);
}
// members
BSTArray<Agent> agentArray; // B8
};
static_assert(sizeof(BGSInventoryInterface) == 0xD0);
}
@@ -0,0 +1,255 @@
#pragma once
#include "RE/B/BSIntrusiveRefCounted.h"
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSTSmartPointer.h"
#include "RE/E/ExtraDataList.h"
namespace RE
{
class BGSInventoryItem
{
public:
class __declspec(novtable) Stack :
public BSIntrusiveRefCounted // 08
{
public:
static constexpr auto RTTI{ RTTI::BGSInventoryItem__Stack };
static constexpr auto VTABLE{ VTABLE::BGSInventoryItem__Stack };
enum class Flag
{
kSlotIndex1 = 1 << 0,
kSlotIndex2 = 1 << 1,
kSlotIndex3 = 1 << 2,
kEquipStateLocked = 1 << 3,
kInvShouldEquip = 1 << 4,
kTemporary = 1 << 5,
kSlotMask = kSlotIndex1 | kSlotIndex2 | kSlotIndex3
};
virtual ~Stack(); // 00
[[nodiscard]] std::uint32_t GetCount() const noexcept { return count; }
[[nodiscard]] bool IsEquipped() const noexcept { return flags.any(Flag::kSlotMask); }
// members
BSTSmartPointer<Stack> nextStack; // 10
BSTSmartPointer<ExtraDataList> extra; // 18
std::uint32_t count; // 20
REX::TEnumSet<Flag, std::uint16_t> flags; // 24
};
static_assert(sizeof(Stack) == 0x28);
class __declspec(novtable) StackDataCompareFunctor
{
public:
static constexpr auto RTTI{ RTTI::BGSInventoryItem__StackDataCompareFunctor };
static constexpr auto VTABLE{ VTABLE::BGSInventoryItem__StackDataCompareFunctor };
// add
virtual bool CompareData(const BGSInventoryItem::Stack& a_stack) = 0; // 00
virtual bool UseDefaultStackIfNoMatch() const { return false; } // 01
};
static_assert(sizeof(StackDataCompareFunctor) == 0x8);
class alignas(0x08) CheckStackIDFunctor :
public StackDataCompareFunctor // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSInventoryItem__CheckStackIDFunctor };
static constexpr auto VTABLE{ VTABLE::BGSInventoryItem__CheckStackIDFunctor };
CheckStackIDFunctor(std::uint32_t a_targetIndex) noexcept :
targetIndex(a_targetIndex)
{}
// override (StackDataCompareFunctor)
bool CompareData(const BGSInventoryItem::Stack&) override { return targetIndex-- == 0; } // 00
// members
std::uint32_t targetIndex; // 08
};
static_assert(sizeof(CheckStackIDFunctor) == 0x10);
class alignas(0x08) CheckExtraDataFunctor :
public StackDataCompareFunctor // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSInventoryItem__CheckExtraDataFunctor };
static constexpr auto VTABLE{ VTABLE::BGSInventoryItem__CheckExtraDataFunctor };
CheckExtraDataFunctor(const BGSInventoryItem::Stack* a_stack) noexcept :
extra(a_stack->extra.get())
{}
// override (StackDataCompareFunctor)
bool CompareData(const BGSInventoryItem::Stack&) override { return true; } // this->extra == extra; ??
// members
const ExtraDataList* extra; // 08
};
static_assert(sizeof(CheckExtraDataFunctor) == 0x10);
class __declspec(novtable) alignas(0x08) StackDataWriteFunctor
{
public:
static constexpr auto RTTI{ RTTI::BGSInventoryItem__StackDataWriteFunctor };
static constexpr auto VTABLE{ VTABLE::BGSInventoryItem__StackDataWriteFunctor };
// add
virtual void WriteDataImpl(TESBoundObject& a_baseObj, BGSInventoryItem::Stack& a_stack) = 0; // 01
// members
bool shouldSplitStacks{ true }; // 08
bool transferEquippedToSplitStack{ false }; // 09
};
static_assert(sizeof(StackDataWriteFunctor) == 0x10);
class __declspec(novtable) ModifyModDataFunctor :
public StackDataWriteFunctor // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSInventoryItem__ModifyModDataFunctor };
static constexpr auto VTABLE{ VTABLE::BGSInventoryItem__ModifyModDataFunctor };
ModifyModDataFunctor(BGSMod::Attachment::Mod* a_mod, std::int8_t a_slotIndex, bool a_attach, bool* a_success) :
mod(a_mod),
success(a_success),
slotIndex(a_slotIndex),
attach(a_attach)
{
REX::EMPLACE_VTABLE(this);
if (success) {
*success = true;
}
}
// override (StackDataWriteFunctor)
void WriteDataImpl(TESBoundObject&, BGSInventoryItem::Stack&) override; // 01
// members
BGSMod::Attachment::Mod* mod; // 10
TESBoundObject* foundObj{ nullptr }; // 18
bool* success; // 20
const std::int8_t slotIndex; // 28
const bool attach; // 29
bool equipLocked{ false }; // 2A
};
static_assert(sizeof(ModifyModDataFunctor) == 0x30);
class __declspec(novtable) SetHealthFunctor :
public StackDataWriteFunctor // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSInventoryItem__SetHealthFunctor };
static constexpr auto VTABLE{ VTABLE::BGSInventoryItem__SetHealthFunctor };
SetHealthFunctor(float a_health) :
health(a_health)
{
REX::EMPLACE_VTABLE(this);
}
// override (StackDataWriteFunctor)
void WriteDataImpl(TESBoundObject&, BGSInventoryItem::Stack&) override; // 01
// members
float health; // 10
};
static_assert(sizeof(SetHealthFunctor) == 0x18);
bool FindAndWriteStackData(StackDataCompareFunctor& a_compareFunc, StackDataWriteFunctor& a_writeFunc, bool a_manualMerge, ObjectRefHandle a_owner)
{
using func_t = decltype(&BGSInventoryItem::FindAndWriteStackData);
static REL::Relocation<func_t> func{ ID::BGSInventoryItem::FindAndWriteStackData };
return func(this, a_compareFunc, a_writeFunc, a_manualMerge, a_owner);
}
[[nodiscard]] std::uint32_t GetCount() const noexcept;
[[nodiscard]] Stack* GetStackByID(std::uint32_t a_stackID) const
{
auto iter = stackData.get();
while (a_stackID--) {
iter = iter->nextStack.get();
}
return iter;
}
[[nodiscard]] const char* GetDisplayFullName(std::uint32_t a_stackID) const
{
using func_t = const char* (BGSInventoryItem::*)(std::uint32_t) const;
static REL::Relocation<func_t> func{ ID::BGSInventoryItem::GetDisplayFullName1 };
return func(this, a_stackID);
}
[[nodiscard]] const char* GetDisplayFullName(const ExtraDataList* a_extra) const
{
using func_t = const char* (BGSInventoryItem::*)(const ExtraDataList*) const;
static REL::Relocation<func_t> func{ ID::BGSInventoryItem::GetDisplayFullName2 };
return func(this, a_extra);
}
[[nodiscard]] TBO_InstanceData* GetInstanceData(std::uint32_t a_stackID) const
{
using func_t = decltype(&BGSInventoryItem::GetInstanceData);
static REL::Relocation<func_t> func{ ID::BGSInventoryItem::GetInstanceData };
return func(this, a_stackID);
}
[[nodiscard]] std::int32_t GetInventoryValue(std::uint32_t a_stackID, bool a_scale) const
{
using func_t = decltype(&BGSInventoryItem::GetInventoryValue);
static REL::Relocation<func_t> func{ ID::BGSInventoryItem::GetInventoryValue };
return func(this, a_stackID, a_scale);
}
ExtraDataList GetExtraDataAt(std::uint32_t a_index)
{
using func_t = decltype(&BGSInventoryItem::GetExtraDataAt);
static REL::Relocation<func_t> func{ ID::BGSInventoryItem::GetExtraDataAt };
return func(this, a_index);
}
void MergeStacks()
{
using func_t = decltype(&BGSInventoryItem::MergeStacks);
static REL::Relocation<func_t> func{ ID::BGSInventoryItem::MergeStacks };
return func(this);
}
bool IsEquipped(std::uint32_t a_stackID)
{
using func_t = decltype(&BGSInventoryItem::IsEquipped);
static REL::Relocation<func_t> func{ ID::BGSInventoryItem::IsEquipped };
return func(this, a_stackID);
}
int64_t GetStackCount()
{
using func_t = decltype(&BGSInventoryItem::GetStackCount);
static REL::Relocation<func_t> func{ ID::BGSInventoryItem::GetStackCount };
return func(this);
}
bool IsQuestObject(std::uint32_t a_stackID)
{
using func_t = decltype(&BGSInventoryItem::IsQuestObject);
static REL::Relocation<func_t> func{ ID::BGSInventoryItem::IsQuestObject };
return func(this, a_stackID);
}
float GetTotalWeight()
{
using func_t = decltype(&BGSInventoryItem::GetTotalWeight);
static REL::Relocation<func_t> func{ ID::BGSInventoryItem::GetTotalWeight };
return func(this);
}
// members
TESBoundObject* object; // 00
BSTSmartPointer<Stack> stackData; // 08
};
static_assert(sizeof(BGSInventoryItem) == 0x10);
}
@@ -0,0 +1,21 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
namespace RE
{
namespace InventoryInterface
{
class Handle;
}
namespace BGSInventoryItemEvent
{
class Event
{
public:
ObjectRefHandle owner; // 00
InventoryInterface::Handle* item; // 04
};
}
}
@@ -0,0 +1,139 @@
#pragma once
#include "RE/B/BGSInventoryItem.h"
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSSpinLock.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTEvent.h"
#include "RE/M/MemoryManager.h"
namespace RE
{
class TESContainer;
namespace BGSInventoryListEvent
{
class Event;
}
class BGSInventoryList :
public BSTEventSource<BGSInventoryListEvent::Event> // 00
{
public:
BGSInventoryList(const TESContainer* a_container, ObjectRefHandle a_owner)
{
auto native_handle = a_owner.get_handle();
ctor(a_container, &native_handle);
}
F4_HEAP_REDEFINE_NEW(BGSInventoryList)
[[nodiscard]] static bool StandardObjectCompareCallbackFn(TESBoundObject* a_lhs, TESBoundObject* a_rhs)
{
return a_lhs == a_rhs;
}
inline void AddItem2(TESBoundObject* a_object, std::uint32_t a_count, ExtraDataList* a_extra, std::uint16_t a_flags = 0) noexcept
{
using func_t = void (*)(BGSInventoryList*, TESBoundObject*, std::uint32_t, ExtraDataList*, std::uint16_t);
static REL::Relocation<func_t> func{ ID::BGSInventoryList::AddItem2 };
func(this, a_object, a_count, a_extra, a_flags);
}
inline void AddItem2(TESBoundObject* a_object, std::uint32_t a_count, std::uint16_t a_flags = 0) noexcept
{
AddItem2(a_object, a_count, new ExtraDataList(), a_flags);
}
inline void BuildFromContainer(const TESContainer* a_container)
{
using func_t = decltype(&BGSInventoryList::BuildFromContainer);
static REL::Relocation<func_t> func{ ID::BGSInventoryList::BuildFromContainer };
func(this, a_container);
}
inline void Clear() noexcept
{
using func_t = decltype(&BGSInventoryList::Clear);
static REL::Relocation<func_t> func{ ID::BGSInventoryList::Clear };
func(this);
}
inline void FindAndWriteStackDataForItem(
TESBoundObject* a_object,
BGSInventoryItem::StackDataCompareFunctor& a_compareFunc,
BGSInventoryItem::StackDataWriteFunctor& a_writeFunc,
bool (*a_objCompFn)(TESBoundObject*, TESBoundObject*) = StandardObjectCompareCallbackFn,
bool a_alwaysContinue = false)
{
using func_t = decltype(&BGSInventoryList::FindAndWriteStackDataForItem);
static REL::Relocation<func_t> func{ ID::BGSInventoryList::FindAndWriteStackDataForItem };
return func(this, a_object, a_compareFunc, a_writeFunc, a_objCompFn, a_alwaysContinue);
}
[[nodiscard]] inline std::uint32_t FindItemIndex(TESBoundObject* a_object) const noexcept
{
using func_t = decltype(&BGSInventoryList::FindItemIndex);
static REL::Relocation<func_t> func{ ID::BGSInventoryList::FindItemIndex };
return func(this, a_object);
}
// DOES NOT LOCK
inline void ForEachStack(
std::function<bool(BGSInventoryItem&)> a_filter, // return true to iterate stacks
std::function<bool(BGSInventoryItem&, BGSInventoryItem::Stack&)> a_continue // return false to return control from function
)
{
for (auto& elem : data) {
if (a_filter(elem)) {
for (auto stack = elem.stackData.get(); stack; stack = stack->nextStack.get()) {
if (!a_continue(elem, *stack)) {
return;
}
}
}
}
}
[[nodiscard]] inline std::uint32_t GetItemCount(TESBoundObject* a_object) const noexcept
{
using func_t = decltype(&BGSInventoryList::GetItemCount);
static REL::Relocation<func_t> func{ ID::BGSInventoryList::GetItemCount };
return func(this, a_object);
}
[[nodiscard]] inline std::uint32_t GetQuestItemCount(TESBoundObject* a_object) const noexcept
{
using func_t = decltype(&BGSInventoryList::GetQuestItemCount);
static REL::Relocation<func_t> func{ ID::BGSInventoryList::GetQuestItemCount };
return func(this, a_object);
}
inline void RemoveItem1(TESBoundObject* a_object, std::uint32_t a_stackID, std::uint32_t a_count, bool a_manualMerge = false) noexcept
{
using func_t = void (*)(BGSInventoryList*, TESBoundObject*, std::uint32_t, std::uint32_t, bool);
static REL::Relocation<func_t> func{ ID::BGSInventoryList::RemoveItem1 };
func(this, a_object, a_stackID, a_count, a_manualMerge);
}
inline void RemoveItem1(TESBoundObject* a_object, std::uint32_t a_count, bool a_manualMerge = false) noexcept
{
RemoveItem1(a_object, 0, a_count, a_manualMerge);
}
// members
BSTArray<BGSInventoryItem> data; // 58
float cachedWeight; // 70
ObjectRefHandle owner; // 74
BSReadWriteLock rwLock; // 78
private:
void ctor(const TESContainer* a_container, std::uint32_t* a_owner)
{
using func_t = decltype(&BGSInventoryList::ctor);
static REL::Relocation<func_t> func{ ID::BGSInventoryList::ctor };
func(this, a_container, a_owner);
}
};
static_assert(sizeof(BGSInventoryList) == 0x80);
}
@@ -0,0 +1,31 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
namespace RE
{
namespace BGSInventoryListEvent
{
enum class Type
{
kAddStack,
kChangedStack,
kAddNewItem,
kRemoveItem,
kClear,
UpdateWeight
};
class Event
{
public:
// members
REX::TEnumSet<Type, std::uint16_t> changeType; // 00
ObjectRefHandle owner; // 04
TESBoundObject* objAffected; // 08
std::uint32_t count; // 10
std::uint32_t stackID; // 14
};
static_assert(sizeof(Event) == 0x18);
}
}
@@ -0,0 +1,60 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTArray.h"
#include "RE/K/KeywordType.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSKeyword :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSKeyword };
static constexpr auto VTABLE{ VTABLE::BGSKeyword };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kKYWD };
[[nodiscard]] static uint16_t GetIndexForTypedKeyword(const BGSKeyword* a_keyword, KeywordType a_type)
{
assert(a_type < KeywordType::kTotal);
const auto keywords = GetTypedKeywords();
if (keywords) {
const auto& arr = (*keywords)[std::to_underlying(a_type)];
for (uint16_t i = 0; i < arr.size(); ++i) {
if (arr[i] == a_keyword) {
return i;
}
}
}
return 0xFFFF;
}
[[nodiscard]] static BGSKeyword* GetTypedKeywordByIndex(KeywordType a_type, std::uint16_t a_index)
{
assert(a_type < KeywordType::kTotal);
const auto keywords = GetTypedKeywords();
if (keywords) {
const auto& arr = (*keywords)[std::to_underlying(a_type)];
return a_index < arr.size() ? arr[a_index] : nullptr;
} else {
return nullptr;
}
}
[[nodiscard]] static auto GetTypedKeywords()
-> std::optional<std::span<BSTArray<BGSKeyword*>, std::to_underlying(KeywordType::kTotal)>>
{
static REL::Relocation<BSTArray<BGSKeyword*>(*)[std::to_underlying(KeywordType::kTotal)]> keywords{ ID::BGSKeyword::TypedKeywords };
if (*keywords) {
return { *keywords };
} else {
return std::nullopt;
}
}
// members
BSFixedString formEditorID; // 20
};
static_assert(sizeof(BGSKeyword) == 0x28);
}
@@ -0,0 +1,95 @@
#pragma once
#include "RE/B/BGSKeyword.h"
#include "RE/B/BSContainer.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BaseFormComponent.h"
#include "RE/I/IKeywordFormBase.h"
namespace RE
{
class __declspec(novtable) BGSKeywordForm :
public BaseFormComponent, // 00
public IKeywordFormBase // 08
{
public:
static constexpr auto RTTI{ RTTI::BGSKeywordForm };
static constexpr auto VTABLE{ VTABLE::BGSKeywordForm };
// override (BaseFormComponent)
void InitializeDataComponent() override { return; } // 02
void ClearDataComponent() override; // 03
void InitComponent() override { return; } // 04
void CopyComponent(BaseFormComponent*) override; // 06
// override (IKeywordFormBase)
bool HasKeyword(const BGSKeyword* a_keyword, const TBO_InstanceData* a_data = nullptr) const override; // 01
void CollectAllKeywords(BSScrapArray<const BGSKeyword*>&, const TBO_InstanceData*) const override; // 02
// add
virtual BGSKeyword* GetDefaultKeyword() const { return nullptr; } // 07
void CopyKeywords(const std::vector<BGSKeyword*>& a_copiedData);
void AddKeyword(BGSKeyword* a_keyword)
{
using func_t = decltype(&BGSKeywordForm::AddKeyword);
static REL::Relocation<func_t> func{ ID::BGSKeywordForm::AddKeyword };
return func(this, a_keyword);
}
bool AddKeywords(const std::vector<BGSKeyword*>& a_keywords);
[[nodiscard]] bool ContainsKeywordString(std::string_view a_editorID) const;
[[nodiscard]] bool HasKeywordID(TESFormID a_formID) const;
[[nodiscard]] bool HasKeywordString(std::string_view a_editorID) const;
void ForEachKeyword(std::function<BSContainer::ForEachResult(BGSKeyword*)> a_callback) const
{
if (keywords) {
for (std::uint32_t idx = 0; idx < numKeywords; ++idx) {
if (keywords[idx] && a_callback(keywords[idx]) == BSContainer::ForEachResult::kStop) {
return;
}
}
}
}
[[nodiscard]] std::optional<BGSKeyword*> GetKeywordAt(std::uint32_t a_idx) const
{
if (a_idx < numKeywords) {
return std::make_optional(keywords[a_idx]);
} else {
return std::nullopt;
}
}
[[nodiscard]] std::optional<std::uint32_t> GetKeywordIndex(BGSKeyword* a_keyword) const
{
if (keywords) {
for (std::uint32_t i = 0; i < numKeywords; ++i) {
if (keywords[i] == a_keyword) {
return i;
}
}
}
return std::nullopt;
}
[[nodiscard]] std::uint32_t GetNumKeywords() const { return numKeywords; };
void RemoveKeyword(BGSKeyword* a_keyword)
{
using func_t = decltype(&BGSKeywordForm::RemoveKeyword);
static REL::Relocation<func_t> func{ ID::BGSKeywordForm::RemoveKeyword };
return func(this, a_keyword);
}
bool RemoveKeywords(const std::vector<BGSKeyword*>& a_keywords);
// members
BGSKeyword** keywords; // 10
std::uint32_t numKeywords; // 18
};
static_assert(sizeof(BGSKeywordForm) == 0x20);
}
@@ -0,0 +1,21 @@
#pragma once
#include "RE/N/NiRefObject.h"
namespace RE
{
class __declspec(novtable) BGSLOSData :
public NiRefObject // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSLOSData };
static constexpr auto VTABLE{ VTABLE::BGSLOSData };
// members
std::uint8_t* losData; // 10
std::uint16_t* quadGridOffsetArray; // 18
std::uint32_t losDataSize; // 20
std::uint16_t indexCount; // 24
};
static_assert(sizeof(BGSLOSData) == 0x28);
}
@@ -0,0 +1,28 @@
#pragma once
#include "RE/B/BSTArray.h"
#include "RE/B/BSTHashMap.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class QueuedPromoteLargeReferencesTask;
class BGSLargeRefData
{
public:
class REF_CELL_DATA
{
public:
// members
std::uint32_t refID; // 0
std::uint32_t parentCellKey; // 4
};
static_assert(sizeof(REF_CELL_DATA) == 0x8);
// members
BSTHashMap<std::uint32_t, BSTArray<REF_CELL_DATA>*> cellOverlappingRefMap; // 00
BSTHashMap<std::uint32_t, NiPointer<QueuedPromoteLargeReferencesTask>> cellPromoteTaskMap; // 30
};
static_assert(sizeof(BGSLargeRefData) == 0x60);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/B/BSLensFlareRenderData.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSLensFlare :
public TESForm, // 00
public BSLensFlareRenderData // 20
{
public:
static constexpr auto RTTI{ RTTI::BGSLensFlare };
static constexpr auto VTABLE{ VTABLE::BGSLensFlare };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kLENS };
};
static_assert(sizeof(BGSLensFlare) == 0x50);
}
@@ -0,0 +1,23 @@
#pragma once
#include "RE/B/BGSDirectionalAmbientLightingColors.h"
#include "RE/I/INTERIOR_DATA.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSLightingTemplate :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSLightingTemplate };
static constexpr auto VTABLE{ VTABLE::BGSLightingTemplate };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kLGTM };
// members
INTERIOR_DATA data; // 20
BGSGodRays* godRays; // B0
BGSDirectionalAmbientLightingColors directionalAmbientLightingColors; // B8
};
static_assert(sizeof(BGSLightingTemplate) == 0xD8);
}
@@ -0,0 +1,76 @@
#pragma once
#include "RE/B/BSContainer.h"
#include "RE/B/BSTArray.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSListForm :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSListForm };
static constexpr auto VTABLE{ VTABLE::BGSListForm };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kFLST };
void AddScriptAddedForm(TESForm* a_form)
{
using func_t = decltype(&BGSListForm::AddScriptAddedForm);
static REL::Relocation<func_t> func{ ID::BGSListForm::AddScriptAddedForm };
return func(this, a_form);
}
[[nodiscard]] bool ContainsItem(const TESForm* a_form) const noexcept
{
return GetItemIndex(*a_form).has_value();
}
void ForEachForm(std::function<BSContainer::ForEachResult(TESForm*)> a_callback) const
{
for (const auto& form : arrayOfForms) {
if (form && a_callback(form) == BSContainer::ForEachResult::kStop) {
return;
}
}
if (scriptAddedTempForms) {
for (const auto& addedFormID : *scriptAddedTempForms) {
const auto addedForm = TESForm::GetFormByID(addedFormID);
if (addedForm && a_callback(addedForm) == BSContainer::ForEachResult::kStop) {
return;
}
}
}
}
[[nodiscard]] std::optional<std::uint32_t> GetItemIndex(const TESForm& a_item) const noexcept
{
if (scriptAddedTempForms) {
const auto it = std::find(
scriptAddedTempForms->begin(),
scriptAddedTempForms->end(),
a_item.formID);
if (it != scriptAddedTempForms->end()) {
return static_cast<std::uint32_t>(it - scriptAddedTempForms->begin());
}
}
const auto it = std::find(
arrayOfForms.begin(),
arrayOfForms.end(),
&a_item);
if (it != arrayOfForms.end()) {
const auto base = scriptAddedTempForms ? scriptAddedTempForms->size() : 0;
return base + static_cast<std::uint32_t>(it - arrayOfForms.begin());
}
return std::nullopt;
}
// members
BSTArray<TESForm*> arrayOfForms; // 20
BSTArray<std::uint32_t>* scriptAddedTempForms; // 38
std::uint32_t scriptAddedFormCount; // 40
};
static_assert(sizeof(BGSListForm) == 0x48);
}
@@ -0,0 +1,31 @@
#pragma once
#include "RE/B/BGSSaveLoadScrapBuffer.h"
namespace RE
{
class __declspec(novtable) BGSLoadGameBuffer
{
public:
static constexpr auto RTTI{ RTTI::BGSLoadGameBuffer };
static constexpr auto VTABLE{ VTABLE::BGSLoadGameBuffer };
virtual ~BGSLoadGameBuffer(); // 00
// add
virtual std::uint8_t GetVersion(void); // 01
void LoadDataEndian(void* a_data, std::uint32_t a_offset, std::uint32_t a_size)
{
using func_t = decltype(&BGSLoadGameBuffer::LoadDataEndian);
static REL::Relocation<func_t> func{ ID::BGSLoadGameBuffer::LoadDataEndian };
return func(this, a_data, a_offset, a_size);
}
// members
BGSSaveLoadScrapBuffer buffer; // 008
std::uint32_t bufferSize; // 020
std::uint32_t bufferPosition; // 024
};
static_assert(sizeof(BGSLoadGameBuffer) == 0x28);
}
@@ -0,0 +1,31 @@
#pragma once
#include "RE/B/BGSBaseAlias.h"
namespace RE
{
class BGSKeyword;
class BGSLocation;
class TESCondition;
class TESQuest;
class __declspec(novtable) BGSLocAlias :
public BGSBaseAlias // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSLocAlias };
static constexpr auto VTABLE{ VTABLE::BGSLocAlias };
// members
BGSLocation* forcedLoc; // 28
BGSKeyword* forcedFromAliasFilter; // 30
TESQuest* externalQuest; // 38
TESCondition* conditions; // 40
std::uint32_t forcedFromAlias; // 48
std::uint32_t forcedFromEvent; // 4C
std::uint32_t forcedEventData; // 50
std::uint32_t externalAlias; // 54
std::uint32_t closestToAlias; // 58
};
static_assert(sizeof(BGSLocAlias) == 0x60);
}
@@ -0,0 +1,102 @@
#pragma once
#include "RE/B/BSCRC32.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSStringT.h"
#include "RE/M/MemoryManager.h"
namespace RE
{
class TESFile;
class BGSLocalizedStrings
{
public:
class ScrapStringBuffer
{
public:
[[nodiscard]] const char* GetString() const noexcept { return static_cast<const char*>(buffer.GetPtr()) + offset; }
// members
MemoryManager::AutoScrapBuffer buffer; // 00
std::size_t offset; // 08
};
static_assert(sizeof(ScrapStringBuffer) == 0x10);
};
static_assert(std::is_empty_v<BGSLocalizedStrings>);
class BGSLocalizedStringDL
{
public:
[[nodiscard]] BGSLocalizedStrings::ScrapStringBuffer GetText(TESFile& a_file) const
{
using func_t = decltype(&BGSLocalizedStringDL::GetText);
static REL::Relocation<func_t> func{ ID::BGSLocalizedStringDL::GetText };
return func(this, a_file);
}
// members
std::uint32_t id{ 0 }; // 0
};
static_assert(sizeof(BGSLocalizedStringDL) == 0x4);
class BGSLocalizedString
{
public:
using size_type = typename BSFixedStringCS::size_type;
using value_type = typename BSFixedStringCS::value_type;
using pointer = typename BSFixedStringCS::pointer;
using const_pointer = typename BSFixedStringCS::const_pointer;
using reference = typename BSFixedStringCS::reference;
using const_reference = typename BSFixedStringCS::const_reference;
BGSLocalizedString& operator=(std::basic_string_view<value_type> a_rhs)
{
const auto self = static_cast<std::basic_string_view<value_type>>(_data);
if (self.starts_with("<ID=")) {
assert(self.length() >= PREFIX_LENGTH);
std::vector<char> buf(PREFIX_LENGTH + a_rhs.length() + 1, '\0');
strncpy_s(buf.data(), buf.size(), self.data(), PREFIX_LENGTH);
strcpy_s(buf.data() + PREFIX_LENGTH, buf.size() - PREFIX_LENGTH, (a_rhs.empty() ? "" : a_rhs.data()));
_data = std::string_view{ buf.data(), buf.size() };
} else {
_data = a_rhs;
}
return *this;
}
[[nodiscard]] const_pointer data() const noexcept { return _data.data(); }
[[nodiscard]] const_pointer c_str() const noexcept { return _data.c_str(); }
[[nodiscard]] operator std::basic_string_view<value_type>() const { return { _data }; }
[[nodiscard]] bool empty() const noexcept { return _data.empty(); }
[[nodiscard]] size_type size() const noexcept { return _data.size(); }
[[nodiscard]] size_type length() const noexcept { return _data.length(); }
protected:
template <class>
friend struct BSCRC32;
[[nodiscard]] const BSFixedStringCS& hash_accessor() const noexcept { return _data; }
private:
static constexpr std::size_t PREFIX_LENGTH = 13;
// members
BSFixedStringCS _data; // 0
};
static_assert(sizeof(BGSLocalizedString) == 0x8);
template <>
struct BSCRC32<BGSLocalizedString>
{
public:
[[nodiscard]] std::uint32_t operator()(const BGSLocalizedString& a_key) const noexcept
{
return BSCRC32<BSFixedStringCS>()(a_key.hash_accessor());
}
};
}
@@ -0,0 +1,67 @@
#pragma once
#include "RE/B/BGSKeywordForm.h"
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSSpinLock.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTTuple.h"
#include "RE/N/NiPointer.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESFullName.h"
namespace RE
{
class OverrideData;
class QueuedPromoteLocationReferencesTask;
class SpecialRefData;
class UniqueNPCData;
class __declspec(novtable) BGSLocation :
public TESForm, // 000
public TESFullName, // 020
public BGSKeywordForm // 030
{
public:
static constexpr auto RTTI{ RTTI::BGSLocation };
static constexpr auto VTABLE{ VTABLE::BGSLocation };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kLCTN };
class KEYWORD_DATA
{
public:
// members
BGSKeyword* keyword; // 00
float data; // 08
};
static_assert(sizeof(KEYWORD_DATA) == 0x10);
bool IsChild(const BGSLocation* a_possibleChild) const;
bool IsParent(const BGSLocation* a_possibleParent) const;
// members
BGSLocation* parentLoc; // 050
TESFaction* unreportedCrimeFaction; // 058
BGSMusicType* musicType; // 060
BGSEncounterZone* zone; // 068
ObjectRefHandle worldLocMarker; // 070
float worldLocRadius; // 074
float actorFadeMult; // 078
ObjectRefHandle horseLocMarker; // 07C
BSTArray<SpecialRefData> specialRefs; // 080
BSTArray<UniqueNPCData> uniqueNPCs; // 098
OverrideData* overrideData; // 0B0
BSTArray<std::uint32_t> newUnloadedRefs; // 0B8
BSTArray<BSTTuple<BGSLocationRefType*, std::uint32_t>> newSpecialRefs; // 0D0
NiPointer<QueuedPromoteLocationReferencesTask> promoteRefsTask; // 0E8
BSTArray<ObjectRefHandle> promotedRefsArray; // 0F0
volatile std::int32_t loadedCount; // 108
std::uint32_t fileOffset; // 10C
BSTArray<KEYWORD_DATA> keywordData; // 110
BSSpinLock locLoadedLock; // 128
std::uint32_t lastChecked; // 130
bool cleared; // 134
bool everCleared; // 135
BSReadWriteLock locker; // 138
};
static_assert(sizeof(BGSLocation) == 0x140);
}
@@ -0,0 +1,16 @@
#pragma once
#include "RE/B/BGSKeyword.h"
namespace RE
{
class __declspec(novtable) BGSLocationRefType :
public BGSKeyword // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSLocationRefType };
static constexpr auto VTABLE{ VTABLE::BGSLocationRefType };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kLCRT };
};
static_assert(sizeof(BGSLocationRefType) == 0x28);
}
@@ -0,0 +1,33 @@
#pragma once
#include "RE/B/BSMaterialObject.h"
#include "RE/B/BSTArray.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESModel.h"
namespace RE
{
class __declspec(novtable) BGSMaterialObject :
public TESForm, // 00
public TESModel, // 20
public BSMaterialObject // 50
{
public:
static constexpr auto RTTI{ RTTI::BGSMaterialObject };
static constexpr auto VTABLE{ VTABLE::BGSMaterialObject };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kMATO };
class FILE_DATA
{
public:
// members
char* buffer; // 00
std::uint32_t bufferSize; // 08
};
static_assert(sizeof(FILE_DATA) == 0x10);
// members
BSTArray<FILE_DATA> fileData; // A0
};
static_assert(sizeof(BGSMaterialObject) == 0xB8);
}
@@ -0,0 +1,30 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTHashMap.h"
#include "RE/T/TESForm.h"
namespace RE
{
class __declspec(novtable) BGSMaterialSwap :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSMaterialSwap };
static constexpr auto VTABLE{ VTABLE::BGSMaterialSwap };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kMSWP };
class Entry
{
public:
// members
BSFixedString swapMaterial; // 00
float colorRemappingIndex; // 08
};
static_assert(sizeof(Entry) == 0x10);
// members
BSTHashMap<BSFixedString, Entry> swapMap; // 20
};
static_assert(sizeof(BGSMaterialSwap) == 0x50);
}
@@ -0,0 +1,29 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/N/NiColor.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESModel.h"
namespace RE
{
class __declspec(novtable) BGSMaterialType :
public TESForm // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSMaterialType };
static constexpr auto VTABLE{ VTABLE::BGSMaterialType };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kMATT };
// members
TESModel breakableFXModel; // 20
BGSMaterialType* parentType; // 50
BGSImpactDataSet* havokImpactDataSet; // 58
BSFixedString materialName; // 60
std::uint32_t materialID; // 68
NiColor materialColor; // 6C
float buoyancy; // 78
std::uint32_t flags; // 7C
};
static_assert(sizeof(BGSMaterialType) == 0x80);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/B/BaseFormComponent.h"
namespace RE
{
class __declspec(novtable) BGSMenuDisplayObject :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSMenuDisplayObject };
static constexpr auto VTABLE{ VTABLE::BGSMenuDisplayObject };
// members
TESBoundObject* menuDispObject; // 08
};
static_assert(sizeof(BGSMenuDisplayObject) == 0x10);
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/T/TESForm.h"
#include "RE/T/TESIcon.h"
namespace RE
{
class __declspec(novtable) BGSMenuIcon :
public TESForm, // 00
public TESIcon // 20
{
public:
static constexpr auto RTTI{ RTTI::BGSMenuIcon };
static constexpr auto VTABLE{ VTABLE::BGSMenuIcon };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kMICN };
};
static_assert(sizeof(BGSMenuIcon) == 0x30);
}
@@ -0,0 +1,54 @@
#pragma once
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSSimpleList.h"
#include "RE/T/TESDescription.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESFullName.h"
namespace RE
{
class MESSAGEBOX_BUTTON;
class __declspec(novtable) BGSMessage :
public TESForm, // 00
public TESFullName, // 20
public TESDescription // 30
{
public:
static constexpr auto RTTI{ RTTI::BGSMessage };
static constexpr auto VTABLE{ VTABLE::BGSMessage };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kMESG };
enum class MessageFlag
{
kMessageBox = 0x0,
kInitialDelay = 0x1
};
void AddButton(MESSAGEBOX_BUTTON* btn)
{
using func_t = decltype(&BGSMessage::AddButton);
static REL::Relocation<func_t> func{ ID::BGSMessage::AddButton };
return func(this, btn);
}
std::uint32_t GetConvertedDescription(BSFixedString& a_result)
{
using func_t = decltype(&BGSMessage::GetConvertedDescription);
static REL::Relocation<func_t> func{ ID::BGSMessage::GetConvertedDescription };
return func(this, a_result);
}
// members
BGSMenuIcon* icon; // 48
TESQuest* ownerQuest; // 50
BSSimpleList<MESSAGEBOX_BUTTON*> buttonList; // 58
BSFixedStringCS swfFile; // 68
BGSLocalizedString shortName; // 70
std::uint32_t flags; // 78
std::uint32_t displayTime; // 7C
};
static_assert(sizeof(BGSMessage) == 0x80);
}
@@ -0,0 +1,28 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BaseFormComponent.h"
#include "RE/T/TESIcon.h"
namespace RE
{
class __declspec(novtable) BGSMessageIcon :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSMessageIcon };
static constexpr auto VTABLE{ VTABLE::BGSMessageIcon };
// override (BaseFormComponent)
void InitializeDataComponent() override; // 02
void ClearDataComponent() override; // 03
void CopyComponent(BaseFormComponent*) override; // 06
[[nodiscard]] const BSFixedString& GetMessageIconTextureName() const noexcept { return icon.textureName; }
void SetMessageIconTextureName(BSFixedString a_texture) { icon.textureName = std::move(a_texture); }
// members
TESIcon icon; // 08
};
static_assert(sizeof(BGSMessageIcon) == 0x18);
}
@@ -0,0 +1,288 @@
#pragma once
#include "RE/B/BGSAttachParentArray.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BGSTypedKeywordValue.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTDataBuffer.h"
#include "RE/B/BSTHashMap.h"
#include "RE/B/BaseFormComponent.h"
#include "RE/T/TESDescription.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESFullName.h"
namespace RE
{
class ExtraDataList;
class INSTANCE_FILTER;
}
namespace RE::BGSMod
{
namespace Attachment
{
class Instance;
class Mod;
}
namespace Property
{
enum class OP : std::uint32_t
{
kSet = 0,
kMul = 1,
kAnd = 1,
kRem = 1,
kAdd = 2,
kOr = 2
};
enum class TYPE : std::uint32_t
{
kInt,
kFloat,
kBool,
kString,
kForm,
kEnum,
kPair
};
enum class BLOCKIDS : std::uint32_t
{
kOMOD = 0x0,
kPMOD = 0x1
};
class Mod // id == 1
{
public:
union FLOATINT
{
public:
// members
std::int32_t i;
float f;
};
static_assert(sizeof(FLOATINT) == 0x4);
class MinMax
{
public:
// members
FLOATINT min; // 0
FLOATINT max; // 4
};
static_assert(sizeof(MinMax) == 0x8);
class FormValuePair
{
public:
// members
TESFormID formID; // 0
float value; // 4
};
static_assert(sizeof(FormValuePair) == 0x8);
union DATATYPE
{
public:
DATATYPE() noexcept :
form(nullptr)
{}
~DATATYPE() noexcept {}
// members
BSFixedString str;
TESForm* form;
MinMax mm;
FormValuePair fv;
};
static_assert(sizeof(DATATYPE) == 0x8);
// members
DATATYPE data; // 00
std::uint32_t target: 11; // 08:00
OP op: 2; // 08:11
TYPE type: 3; // 08:13
std::int16_t step; // 0C
};
static_assert(sizeof(Mod) == 0x10);
}
class Container :
public BSTDataBuffer<2> // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSMod__Container };
class Data
{
public:
// members
Attachment::Instance* attachments; // 00
Property::Mod* propertyMods; // 08
std::uint32_t attachmentCount; // 10
std::uint32_t propertyModCount; // 14
};
static_assert(sizeof(Data) == 0x18);
Data* GetData(Data* a_data) const
{
using func_t = decltype(&Container::GetData);
static REL::Relocation<func_t> func{ ID::BGSMod::Container::GetData };
return func(this, a_data);
}
};
static_assert(sizeof(Container) == 0x10);
class ObjectIndexData
{
public:
std::uint32_t objectID; // 0
std::uint8_t index; // 4
std::uint8_t rank; // 5
std::uint8_t disabled; // 6
};
static_assert(sizeof(ObjectIndexData) == 0x8);
namespace Attachment
{
[[nodiscard]] inline BSTHashMap<const Mod*, TESObjectMISC*>& GetAllLooseMods()
{
static REL::Relocation<BSTHashMap<const Mod*, TESObjectMISC*>*> mods{ ID::BGSMod::Attachment::GetAllLooseMods, -0x8 };
return *mods;
}
class __declspec(novtable) Mod :
public TESForm, // 00
public TESFullName, // 20
public TESDescription, // 30
public BGSModelMaterialSwap, // 48
public Container // 88
{
public:
static constexpr auto RTTI{ RTTI::BGSMod__Attachment__Mod };
static constexpr auto VTABLE{ VTABLE::BGSMod__Attachment__Mod };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kOMOD };
class Data :
public Container::Data // 00
{
public:
// members
REX::TEnumSet<ENUM_FORM_ID, std::uint8_t> targetFormType; // 18
std::int8_t maxRank; // 19
std::int8_t lvlsPerTierScaledOffset; // 1A
bool optional; // 1B
bool childrenExclusive; // 1C
};
static_assert(sizeof(Data) == 0x20);
static void FindModsForLooseMod(TESObjectMISC* a_looseMod, BSScrapArray<BGSMod::Attachment::Mod*>& a_result)
{
using func_t = decltype(&Mod::FindModsForLooseMod);
static REL::Relocation<func_t> func{ ID::BGSMod::Attachment::Mod::FindModsForLooseMod };
return func(a_looseMod, a_result);
}
void GetData(Data& a_data) const
{
using func_t = decltype(&Mod::GetData);
static REL::Relocation<func_t> func{ ID::BGSMod::Attachment::Mod::GetData };
return func(this, a_data);
}
TESObjectMISC* GetLooseMod()
{
using func_t = decltype(&Mod::GetLooseMod);
static REL::Relocation<func_t> func{ ID::BGSMod::Attachment::Mod::GetLooseMod };
return func(this);
}
void SetLooseMod(TESObjectMISC* misc)
{
using func_t = decltype(&Mod::SetLooseMod);
static REL::Relocation<func_t> func{ ID::BGSMod::Attachment::Mod::SetLooseMod };
return func(this, misc);
}
// members
BGSAttachParentArray attachParents; // 98
BGSTypedKeywordValueArray<KeywordType::kInstantiationFilter> filterKeywords; // B0
BGSTypedKeywordValue<KeywordType::kAttachPoint> attachPoint; // C0
REX::TEnumSet<ENUM_FORM_ID, std::uint8_t> targetFormType; // C2
std::uint8_t maxRank; // C3
std::uint8_t lvlsPerTierScaledOffset; // C4
std::int8_t priority; // C5
bool optional: 1; // C6:0
bool childrenExclusive: 1; // C6:1
};
static_assert(sizeof(Mod) == 0xC8);
class Instance // id == 0
{
public:
// members
Mod* mod; // 00
std::uint8_t index; // 08
bool optional: 1; // 09:0
bool childrenExclusive: 1; // 09:1
};
static_assert(sizeof(Instance) == 0x10);
}
namespace Template
{
class __declspec(novtable) Item :
public TESFullName, // 00
public BGSMod::Container // 10
{
public:
static constexpr auto RTTI{ RTTI::BGSMod__Template__Item };
static constexpr auto VTABLE{ VTABLE::BGSMod__Template__Item };
// members
BGSMod::Template::Items* parentTemplate; // 20
BGSKeyword** nameKeywordA; // 28
std::uint16_t parent; // 30
std::int8_t levelMin; // 32
std::int8_t levelMax; // 33
std::int8_t keywords; // 34
std::int8_t tierStartLevel; // 35
std::int8_t altLevelsPerTier; // 36
bool isDefault: 1; // 37:1
bool fullNameEditorOnly: 1; // 37:2
};
static_assert(sizeof(Item) == 0x38);
class __declspec(novtable) Items :
public BaseFormComponent // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSMod__Template__Items };
static constexpr auto VTABLE{ VTABLE::BGSMod__Template__Items };
static void CreateInstanceDataForObjectAndExtra(TESBoundObject& a_object, ExtraDataList& a_extra, const INSTANCE_FILTER* a_filter, bool a_useDefault)
{
using func_t = decltype(&Items::CreateInstanceDataForObjectAndExtra);
static REL::Relocation<func_t> func{ ID::BGSMod::Template::Items::CreateInstanceDataForObjectAndExtra };
return func(a_object, a_extra, a_filter, a_useDefault);
}
// override (BaseFormComponent)
std::uint32_t GetFormComponentType() const override { return 'TJBO'; } // 01
void InitializeDataComponent() override { return; } // 02
void ClearDataComponent() override; // 03
void InitComponent() override; // 04
void CopyComponent(BaseFormComponent*) override { return; } // 06
void CopyComponent(BaseFormComponent*, TESForm*) override; // 05
// members
BSTArray<Item*> items; // 08
};
static_assert(sizeof(Items) == 0x20);
}
}
@@ -0,0 +1,19 @@
#pragma once
#include "RE/T/TESModel.h"
namespace RE
{
class __declspec(novtable) BGSModelMaterialSwap :
public TESModel // 00
{
public:
static constexpr auto RTTI{ RTTI::BGSModelMaterialSwap };
static constexpr auto VTABLE{ VTABLE::BGSModelMaterialSwap };
// members
BGSMaterialSwap* swapForm; // 30
float colorRemappingIndex; // 38
};
static_assert(sizeof(BGSModelMaterialSwap) == 0x40);
}

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