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,19 @@
#pragma once
#include "RE/C/ContainerItemExtra.h"
#include "RE/I/INSTANCE_FILTER.h"
namespace RE
{
class CALCED_OBJECT
{
public:
// members
TESBoundObject* object; // 00
const char* overrideName; // 08
std::int32_t count; // 10
ContainerItemExtra itemExtra; // 18
INSTANCE_FILTER instanceFilter; // 30
};
static_assert(sizeof(CALCED_OBJECT) == 0x58);
}
@@ -0,0 +1,34 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class NiAVObject;
class NiUpdateData;
namespace CELLJobs
{
class AnimatedRefJobData
{
public:
// members
NiPointer<NiAVObject> p3d; // 00
ObjectRefHandle ref; // 08
float time; // 0C
std::uint32_t uiFlags; // 10
bool allowTransformUpdates; // 14
};
static_assert(sizeof(AnimatedRefJobData) == 0x18);
class TransUpdateFunctor
{
public:
// members
const AnimatedRefJobData* data; // 00
NiUpdateData* updateData; // 08
};
static_assert(sizeof(TransUpdateFunctor) == 0x10);
};
}
@@ -0,0 +1,71 @@
#pragma once
#include "RE/B/BIPED_PART.h"
#include "RE/C/COL_LAYER.h"
namespace RE
{
class CFilter
{
public:
struct Flags
{
enum Flag
{
kNone = 0,
kNoCollision = 1 << 14,
kLinkedGroup = 1 << 15,
kPartMask = 0x1F, // BIPED_PART
kLayerMask = 0x7F // COL_LAYER
};
};
~CFilter() noexcept {} // intentional
COL_LAYER GetCollisionLayer() const { return static_cast<COL_LAYER>(filter & Flags::kLayerMask); }
BIPED_PART GetBipedPart() const { return static_cast<BIPED_PART>((filter >> 8) & Flags::kPartMask); }
bool QNoCollision() const { return (filter >> 14) & 1; }
bool QLinkedGroup() const { return (filter >> 15) & 1; }
std::uint32_t GetSystemGroup() const { return filter >> 16; }
void SetCollisionLayer(COL_LAYER a_layer)
{
filter &= ~(Flags::kLayerMask);
filter |= (std::to_underlying(a_layer) & Flags::kLayerMask);
}
void SetBipedPart(BIPED_PART a_part)
{
filter &= ~(Flags::kPartMask << 8);
filter |= ((std::to_underlying(a_part) & Flags::kPartMask) << 8);
}
void SetNoCollision(bool a_set)
{
if (a_set) {
filter |= Flags::kNoCollision;
} else {
filter &= ~Flags::kNoCollision;
}
}
void SetLinkedGroup(bool a_set)
{
if (a_set) {
filter |= Flags::kLinkedGroup;
} else {
filter &= ~Flags::kLinkedGroup;
}
}
void SetSystemGroup(std::uint32_t a_group)
{
filter &= 0x0000FFFF;
filter |= a_group << 16;
}
// members
std::uint32_t filter; // 0
};
static_assert(sizeof(CFilter) == 0x4);
}
@@ -0,0 +1,107 @@
#pragma once
namespace RE
{
class CHANGE_TYPES
{
public:
enum CHANGE_TYPE : std::uint32_t
{
kFormCreated = 0,
kFormFlags = 1u << 0,
kRefrMove = 1u << 1,
kRefrHavokMove = 1u << 2,
kRefrCellChange = 1u << 3,
kRefrScale = 1u << 4,
kRefrInventory = 1u << 5,
kRefrExtraOwnership = 1u << 6,
kRefrBaseObject = 1u << 7,
kRefrExtraLinkRef = 1u << 8,
kRefrExtraWorkshop = 1u << 9,
kRefrExtraGameOnly = 1u << 31,
kRefrExtraCreatedOnly = 1u << 30,
kRefrExtraEncounterZone = 1u << 29,
kRefrAnimation = 1u << 28,
kRefrLeveledInventory = 1u << 27,
kRefrExtraActivatingChildren = 1u << 26,
kRefrPromoted = 1u << 25,
kActorLifestate = 1u << 10,
kActorExtraPackageData = 1u << 11,
kActorExtraMerchantContainer = 1u << 12,
kActorPermanentModifiers = 1u << 23,
kActorOverrideModifiers = 1u << 22,
kActorDamageModifiers = 1u << 21,
kActorTempModifiers = 1u << 20,
kActorDispositionModifiers = 1u << 19,
kActorExtraLeveledActor = 1u << 18,
kActorExtraDismemberedLimbs = 1u << 17,
kObjectExtraItemData = 1u << 10,
kObjectExtraAmmo = 1u << 11,
kObjectExtraLock = 1u << 12,
kObjectForceMove = 1u << 13,
kObjectOpenState = 1u << 23,
kObjectOpenDefaultState = 1u << 22,
kObjectEmpty = 1u << 21,
kDoorExtraTeleport = 1u << 17,
kQuestFlags = 1u << 1,
kQuestScriptDelay = 1u << 2,
kQuestStages = 1u << 31,
kQuestScript = 1u << 30,
kQuestObjectives = 1u << 29,
kQuestRunData = 1u << 28,
kQuestInstances = 1u << 27,
kQuestAlreadyRun = 1u << 26,
kTopicSaidPlayer = 1u << 30,
kTopicSaidOnce = 1u << 31,
kRelationshipData = 1u << 1,
kLocationSpecRefs = 1u < 28,
kLocationNewRefs = 1u << 29,
kLocationKeywordData = 1u << 30,
kLocationCleared = 1u << 31,
kNoteRead = 1u << 31,
kCellSeenData = 1u << 31,
kCellDetachTime = 1u << 30,
kCellExteriorChar = 1u << 29,
kCellExteriorShort = 1u << 28,
kCellFlags = 1u << 1,
kCellFullname = 1u << 2,
kCellOwnership = 1u << 3,
kFactionFlags = 1u << 1,
kFactionReactions = 1u << 2,
kFactionVendorData = 1u << 30,
kFactionCrimeCounts = 1u << 31,
kPackageNeverRun = 1u << 31,
kPackageWaiting = 1u << 30,
kBaseObjectValue = 1u << 1,
kBaseObjectFullName = 1u << 2,
kBookTeaches = 1u << 5,
kBookRead = 1u << 6,
kTalkingActivatorSpeaker = 1u << 23,
kActorBaseData = 1u << 1,
kActorBaseAttributes = 1u << 2,
kActorBaseAIData = 1u << 3,
kActorBaseSpellList = 1u << 4,
kActorBaseFullName = 1u << 5,
kActorBaseFactions = 1u << 6,
kNPCSkills = 1u << 9,
kNPCClass = 1u << 10,
kNPCFace = 1u << 11,
kNPCDefaultOutfit = 1u << 12,
kNPCSleepOutfit = 1u << 13,
kNPCBodyScales = 1u << 14,
kNPCRace = 1u << 25,
kNPCGender = 1u << 24,
kCreatureSkills = 1u << 9,
kClassTagSkills = 1u << 1,
kEncounterZoneFlags = 1u << 1,
kEncounterZoneGameData = 1u << 31,
kQuestNodeRunTime = 1u << 31,
kSceneActive = 1u << 31,
kFormListAddedForm = 1u << 31,
kLeveledListAddedObject = 1u << 31,
kIngredientUse = 1u << 31,
kINRMergeTarget = 1u << 31
};
};
using CHANGE_TYPE = CHANGE_TYPES::CHANGE_TYPE;
}
@@ -0,0 +1,39 @@
#pragma once
namespace RE
{
enum class CHARACTER_FLAGS : std::uint32_t
{
kQuadruped = 0x1,
kNoGravityOnGround = 0x2,
kTryStep = 0x4,
kNoFriction = 0x8,
kStuckQuad = 0x20,
kAllowJumpNoContact = 0x10,
kAnimAngleMod = 0x40,
kHitDamage = 0x80,
kSupport = 0x100,
kHasPotentialSupportManifold = 0x200,
kCanJump = 0x400,
kChaseBip = 0x800,
kFollowRagdoll = 0x1000,
kJumping = 0x2000,
kNotPushable = 0x4000,
kCheckSupport = 0x10000,
kNoSim = 0x20000,
kFarAway = 0x40000,
kOnStilts = 0x80000,
kQuickSimulate = 0x100000,
kRecordHits = 0x200000,
kComputeTiltPreIntegrate = 0x400000,
kShouldersUnderWater = 0x800000,
kOnStairs = 0x1000000,
kCanPitch = 0x2000000,
kCanRoll = 0x4000000,
kNoCharacterCollisions = 0x8000000,
kNotPushablePermanent = 0x10000000,
kPossiblePathObstacle = 0x20000000,
kShapeRequiresZRot = 0x40000000,
kSwimAtWaterSurface = 0x80000000
};
}
@@ -0,0 +1,14 @@
#pragma once
namespace RE
{
struct CHAR_NORM
{
public:
// members
char x; // 00
char y; // 01
char z; // 02
};
static_assert(sizeof(CHAR_NORM) == 0x03);
}
@@ -0,0 +1,13 @@
#pragma once
namespace RE
{
class CLASS_DATA
{
public:
// members
std::int32_t serviceFlags; // 0
float bleedoutDefault; // 4
};
static_assert(sizeof(CLASS_DATA) == 0x8);
}
@@ -0,0 +1,74 @@
#pragma once
namespace RE
{
enum class COL_LAYER : std::int32_t
{
kUnidentified = 0,
kStatic = 1,
kAnimStatic = 2,
kTransparent = 3,
kClutter = 4,
kWeapon = 5,
kProjectile = 6,
kSpell = 7,
kBiped = 8,
kTrees = 9,
kProps = 10,
kWater = 11,
kTrigger = 12,
kTerrain = 13,
kTrap = 14,
kNonCollidable = 15,
kCloudTrap = 16,
kGround = 17,
kPortal = 18,
kDebrisSmall = 19,
kDebrisLarge = 20,
kAcousticSpace = 21,
kActorZone = 22,
kProjectileZone = 23,
kGasTrap = 24,
kShellCasing = 25,
kTransparentSmall = 26,
kInvisibleWall = 27,
kTransparentSmallAnim = 28,
kClutterLarge = 29,
kCharController = 30,
kStairHelper = 31,
kDeadBip = 32,
kBipedNoCC = 33,
kAvoidBox = 34,
kCollisionBox = 35,
kCameraSphere = 36,
kDoorDetection = 37,
kConeProjectile = 38,
kCamera = 39,
kItemPicker = 40,
kLOS = 41,
kPathingPick = 42,
kUnused0 = 43,
kUnused1 = 44,
kSpellExplosion = 45,
kDroppingPick = 46,
kNumFilterLayers = 47,
kDataDefinedLayersBegin = kNumFilterLayers,
kDataDefined1 = 48,
kDataDefined2 = 49,
kDataDefined3 = 50,
kDataDefined4 = 51,
kDataDefined5 = 52,
kDataDefined6 = 53,
kDataDefined7 = 54,
kDataDefined8 = 55,
kDataDefined9 = 56,
kDataDefined10 = 57,
kDataDefined11 = 58,
kDataDefined12 = 59,
kDataDefined13 = 60,
kDataDefined14 = 61,
kDataDefined15 = 62,
kDataDefined16 = 63,
kMaxLayerSize = 64
};
}
@@ -0,0 +1,14 @@
#pragma once
namespace RE
{
enum class COMMAND_REFUSAL_TYPE
{
kNone = 0x0,
kAny = 0x1,
kImpossible = 0x2,
kMoral = 0x3,
kTotal = 0x4
};
}
@@ -0,0 +1,21 @@
#pragma once
namespace RE
{
enum class COMMAND_TYPE : std::int32_t
{
kNone = 0x0,
kCall = 0x1,
kFollow = 0x2,
kMove = 0x3,
kAttack = 0x4,
kInspect = 0x5,
kRetrieve = 0x6,
kStay = 0x7,
kRelease = 0x8,
kHeal = 0x9,
kAssign = 0xA,
kRide = 0xB,
kEnter = 0xC,
};
}
@@ -0,0 +1,11 @@
#pragma once
namespace RE
{
enum class COMPILER_NAME : std::int32_t
{
kDefault = 0x0,
kSystemWindow = 0x1,
kDialogue = 0x2
};
}
@@ -0,0 +1,19 @@
#pragma once
namespace RE
{
enum class CONDITIONITEMOBJECT : std::int32_t
{
kSelf = 0x0,
kTarget = 0x1,
kRef = 0x2,
kCombatTarget = 0x3,
kLinkedRef = 0x4,
kQuestAlias = 0x5,
kPackData = 0x6,
kEventData = 0x7,
kCommandTarget = 0x8,
kEventCameraRef = 0x9,
kMyKiller = 0xA
};
}
@@ -0,0 +1,31 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
#include "RE/F/FUNCTION_DATA.h"
namespace RE
{
enum class CONDITIONITEMOBJECT;
class CONDITION_ITEM_DATA
{
public:
// members
union
{
TESGlobal* global;
float value;
}; // 00
ObjectRefHandle runOnRef; // 08
std::uint32_t dataID; // 0C
FUNCTION_DATA functionData; // 10
std::uint8_t compareOr: 1; // 28:0
std::uint8_t aliasParams: 1; // 28:1
std::uint8_t valueIsGlobal: 1; // 28:2
std::uint8_t packDataParams: 1; // 28:3
std::uint8_t swapsSubjectAndTarget: 1; // 28:4
std::uint8_t condition: 3; // 28:5
REX::TEnumSet<CONDITIONITEMOBJECT, std::uint8_t> object; // 29
};
static_assert(sizeof(CONDITION_ITEM_DATA) == 0x30);
}
@@ -0,0 +1,12 @@
#pragma once
namespace RE
{
class CONT_DATA
{
public:
// members
std::int8_t contFlags; // 00
};
static_assert(sizeof(CONT_DATA) == 0x1);
}
@@ -0,0 +1,23 @@
#pragma once
namespace RE
{
enum class COVER_TYPE : std::uint32_t
{
kNone = 0x0,
kLedge = 0x1,
kCrouch = 0x2,
kPartial = 0x2,
kVeryLow = 0x4,
kNarrow = 0x3,
kLow = 0x4,
kFull = 0x4,
kMid = 0x5,
kHigh = 0x6,
kTypeCount = 0x7,
kTypeMask = 0xFFFFFF,
kDirectionLeft = 0x40000000,
kDirectionRight = 0x80000000,
kDirectionMask = 0xC0000000
};
}
@@ -0,0 +1,13 @@
#pragma once
namespace RE
{
class CachedValueData
{
public:
// members
float value; // 0
bool dirty; // 4
};
static_assert(sizeof(CachedValueData) == 0x8);
}
@@ -0,0 +1,28 @@
#pragma once
#include "RE/B/BSTArray.h"
#include "RE/C/CachedValueData.h"
namespace RE
{
class CachedValues
{
public:
// members
float cachedRadius; // 00
float cachedWidth; // 04
float cachedLength; // 08
float cachedForwardLength; // 0C
float cachedDPS; // 10
float cachedEyeLevel; // 14
float cachedWalkSpeed; // 18
float cachedRunSpeed; // 1C
float cachedJogSpeed; // 20
float cachedFastWalkSpeed; // 24
std::uint32_t booleanValues; // 28
std::uint32_t flags; // 2C
BSTArray<CachedValueData> actorValueCache; // 30
BSTArray<CachedValueData> permanentActorValueCache; // 48
};
static_assert(sizeof(CachedValues) == 0x60);
}
@@ -0,0 +1,54 @@
#pragma once
#include "RE/B/BSTSingleton.h"
#include "RE/T/TESGlobal.h"
namespace RE
{
class Calendar :
public BSTSingletonSDM<Calendar>
{
public:
class Months
{
public:
enum Month
{
kJanuary = 0x0,
kFebruary = 0x1,
kMarch = 0x2,
kApril = 0x3,
kMay = 0x4,
kJune = 0x5,
kJuly = 0x6,
kAugust = 0x7,
kSeptember = 0x8,
kOctober = 0x9,
kNovember = 0xA,
kDecember = 0xB,
kTotal = 0xC
};
};
using Month = Months::Month;
[[nodiscard]] static Calendar* GetSingleton()
{
static REL::Relocation<Calendar**> singleton{ ID::Calendar::Singleton };
return *singleton;
}
[[nodiscard]] float GetHoursPassed() const noexcept;
[[nodiscard]] std::uint32_t GetMonth() const noexcept;
// members
TESGlobal* gameYear; // 08
TESGlobal* gameMonth; // 10
TESGlobal* gameDay; // 18
TESGlobal* gameHour; // 20
TESGlobal* gameDaysPassed; // 28
TESGlobal* timeScale; // 30
std::uint32_t midnightsPassed; // 38
float rawDaysPassed; // 3C
};
static_assert(sizeof(Calendar) == 0x40);
}
@@ -0,0 +1,28 @@
#pragma once
namespace RE
{
class CameraStates
{
public:
enum CameraState : std::int32_t
{
kFirstPerson = 0x0,
kAutoVanity = 0x1,
kVATS = 0x2,
kFree = 0x3,
kIronSights = 0x4,
kPCTransition = 0x5,
kTween = 0x6,
kAnimated = 0x7,
k3rdPerson = 0x8,
kFurniture = 0x9,
kMount = 0xA,
kBleedout = 0xB,
kDialogue = 0xC,
kTotal = 0xD
};
};
using CameraState = CameraStates::CameraState;
}
@@ -0,0 +1,29 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class CanDisplayNextHUDMessage :
public BSTValueEvent<bool>
{
private:
using EventSource_t = BSTGlobalEvent::EventSource<CanDisplayNextHUDMessage>;
public:
CanDisplayNextHUDMessage(bool a_value)
{
optionalValue = a_value;
}
[[nodiscard]] static EventSource_t* GetEventSource()
{
static REL::Relocation<EventSource_t**> singleton{ ID::CanDisplayNextHUDMessage::GetEventSource };
if (!*singleton) {
*singleton = new EventSource_t(&BSTGlobalEvent::GetSingleton()->eventSourceSDMKiller);
}
return *singleton;
}
};
static_assert(sizeof(CanDisplayNextHUDMessage) == 0x2);
}
@@ -0,0 +1,21 @@
#pragma once
namespace RE
{
class CellAttachDetachEvent
{
public:
enum class EVENT_TYPE : std::int32_t
{
kPreAttach = 0x0,
kPostAttach = 0x1,
kPreDetach = 0x2,
kPostDetach = 0x3
};
// members
TESObjectCELL* cell; // 00
REX::TEnumSet<EVENT_TYPE, std::int32_t> type; // 08
};
static_assert(sizeof(CellAttachDetachEvent) == 0x10);
}
@@ -0,0 +1,27 @@
#pragma once
#include "RE/B/BSTEvent.h"
#include "RE/B/BSTSingleton.h"
#include "RE/C/CellAttachDetachEvent.h"
namespace RE
{
namespace CellAttachDetachEventSource
{
class CellAttachDetachEventSourceSingleton :
public BSTSingletonImplicit<CellAttachDetachEventSourceSingleton>
{
public:
[[nodiscard]] static CellAttachDetachEventSourceSingleton& GetSingleton()
{
using func_t = decltype(&CellAttachDetachEventSourceSingleton::GetSingleton);
static REL::Relocation<func_t> func{ ID::CellAttachDetachEvent::GetEventSource };
return func();
}
// members
BSTEventSource<CellAttachDetachEvent> source; // 00
};
static_assert(sizeof(CellAttachDetachEventSourceSingleton) == 0x58);
}
}
@@ -0,0 +1,25 @@
#pragma once
#include "RE/I/InputEvent.h"
namespace RE
{
class __declspec(novtable) CharacterEvent :
public InputEvent // 00
{
public:
static constexpr auto RTTI{ RTTI::CharacterEvent };
static constexpr auto VTABLE{ VTABLE::CharacterEvent };
static constexpr auto TYPE{ INPUT_EVENT_TYPE::kChar };
// NOLINTNEXTLINE(modernize-use-override)
virtual ~CharacterEvent() = default; // 00
// members
std::uint32_t charCode{ 0 }; // 28
};
static_assert(sizeof(CharacterEvent) == 0x30);
extern template CharacterEvent* InputEvent::As() noexcept;
extern template const CharacterEvent* InputEvent::As() const noexcept;
}
@@ -0,0 +1,23 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class ColorUpdateEvent
{
private:
using EventSource_t = BSTGlobalEvent::EventSource<ColorUpdateEvent>;
public:
[[nodiscard]] static EventSource_t* GetEventSource()
{
static REL::Relocation<EventSource_t**> singleton{ ID::ColorUpdateEvent::GetEventSource };
if (!*singleton) {
*singleton = new EventSource_t(&BSTGlobalEvent::GetSingleton()->eventSourceSDMKiller);
}
return *singleton;
}
};
static_assert(std::is_empty_v<ColorUpdateEvent>);
}
@@ -0,0 +1,14 @@
#pragma once
namespace RE
{
class CombatBehaviorStack
{
public:
// members
std::uint8_t* buffer; // 00
std::uint32_t bufferSize; // 08
std::uint32_t size; // 0C
};
static_assert(sizeof(CombatBehaviorStack) == 0x10);
}
@@ -0,0 +1,66 @@
#pragma once
#include "RE/B/BGSObjectInstance.h"
#include "RE/T/TESObjectWEAP.h"
namespace RE
{
namespace CombatFormulas
{
[[nodiscard]] inline float GetWeaponDisplayAccuracy(const BGSObjectInstanceT<TESObjectWEAP>& a_weapon, Actor* a_actor)
{
using func_t = decltype(&CombatFormulas::GetWeaponDisplayAccuracy);
static REL::Relocation<func_t> func{ ID::CombatFormulas::GetWeaponDisplayAccuracy };
return func(a_weapon, a_actor);
}
[[nodiscard]] inline float GetWeaponDisplayDamage(const BGSObjectInstanceT<TESObjectWEAP>& a_weapon, const TESAmmo* a_ammo, float a_condition)
{
using func_t = decltype(&CombatFormulas::GetWeaponDisplayDamage);
static REL::Relocation<func_t> func{ ID::CombatFormulas::GetWeaponDisplayDamage };
return func(a_weapon, a_ammo, a_condition);
}
[[nodiscard]] inline float GetWeaponDisplayRange(const BGSObjectInstanceT<TESObjectWEAP>& a_weapon)
{
using func_t = decltype(&CombatFormulas::GetWeaponDisplayRange);
static REL::Relocation<func_t> func{ ID::CombatFormulas::GetWeaponDisplayRange };
return func(a_weapon);
}
[[nodiscard]] inline float GetWeaponDisplayRateOfFire(const TESObjectWEAP& a_weapon, const TESObjectWEAP::InstanceData* a_data)
{
using func_t = decltype(&CombatFormulas::GetWeaponDisplayRateOfFire);
static REL::Relocation<func_t> func{ ID::CombatFormulas::GetWeaponDisplayRateOfFire };
return func(a_weapon, a_data);
}
[[nodiscard]] inline float CalcTargetedLimbDamage(Actor* a_target, const BGSBodyPart* a_bodyPart, float a_physicalDamage, BSTArray<BSTTuple<TESForm*, BGSTypedFormValuePair::SharedVal>, BSTArrayHeapAllocator>* a_damageTypes)
{
using func_t = decltype(&CombatFormulas::CalcTargetedLimbDamage);
static REL::Relocation<func_t> func{ ID::CombatFormulas::CalcWeaponDamage };
return func(a_target, a_bodyPart, a_physicalDamage, a_damageTypes);
}
[[nodiscard]] inline std::int64_t GetNumCrippledAttackConditions(Actor* a_actor)
{
using func_t = decltype(&CombatFormulas::GetNumCrippledAttackConditions);
static REL::Relocation<func_t> func{ ID::CombatFormulas::GetNumCrippledAttackConditions };
return func(a_actor);
}
[[nodiscard]] inline float CalcScopeSteadyActionPointDrain(Actor* a_actor, float a_deltaSec)
{
using func_t = decltype(&CombatFormulas::CalcScopeSteadyActionPointDrain);
static REL::Relocation<func_t> func{ ID::CombatFormulas::CalcScopeSteadyActionPointDrain };
return func(a_actor, a_deltaSec);
}
[[nodiscard]] inline float CalcResistedPercentage(const ActorValueInfo* a_resistance, float a_damage, float a_resistancePoints)
{
using func_t = decltype(&CombatFormulas::CalcResistedPercentage);
static REL::Relocation<func_t> func{ ID::CombatFormulas::CalcResistedPercentage };
return func(a_resistance, a_damage, a_resistancePoints);
}
}
}
@@ -0,0 +1,11 @@
#pragma once
namespace RE
{
class CombatRange
{
float minRange; // 00
float maxRange; // 04
};
static_assert(sizeof(CombatRange) == 0x8);
}
@@ -0,0 +1,22 @@
#pragma once
namespace RE
{
class CombatStyleCloseRangeData
{
public:
// members
float circleMult; // 00
float fallbackMult; // 04
float flankDistanceMult; // 08
float stalkTimeMult; // 0C
float chargeDistanceMult; // 10
float flipThrowProbability; // 14
float sprintChargeProbability; // 18
float sideswipeProbability; // 1C
float disengageProbability; // 20
std::uint32_t throwMaxTargets; // 24
float flankVarianceMult; // 28
};
static_assert(sizeof(CombatStyleCloseRangeData) == 0x2C);
}
@@ -0,0 +1,12 @@
#pragma once
namespace RE
{
class CombatStyleCoverData
{
public:
// members
float coverSearchDistanceMult; // 0
};
static_assert(sizeof(CombatStyleCoverData) == 0x4);
}
@@ -0,0 +1,19 @@
#pragma once
namespace RE
{
class CombatStyleFlightData
{
public:
// members
float hoverChance; // 00
float diveBombChance; // 04
float groundAttackChance; // 08
float hoverTimeMult; // 0C
float groundAttackTimeMult; // 10
float perchAttackChance; // 14
float perchAttackTimeMult; // 18
float flyingAttackChance; // 1C
};
static_assert(sizeof(CombatStyleFlightData) == 0x20);
}
@@ -0,0 +1,23 @@
#pragma once
namespace RE
{
class CombatStyleGeneralData
{
public:
// members
float offensiveMult; // 00
float defensiveMult; // 04
float groupOffensiveMult; // 08
float meleeScoreMult; // 0C
float magicScoreMult; // 10
float rangedScoreMult; // 14
float shoutScoreMult; // 18
float unarmedScoreMult; // 1C
float staffScoreMult; // 20
float avoidThreatChance; // 24
float dodgeThreatChance; // 28
float evadeThreatChance; // 2C
};
static_assert(sizeof(CombatStyleGeneralData) == 0x30);
}
@@ -0,0 +1,16 @@
#pragma once
namespace RE
{
class CombatStyleLongRangeData
{
public:
// members
float strafeMult; // 00
float adjustRangeMult; // 04
float crouchMult; // 08
float waitMult; // 0C
float rangeMult; // 10
};
static_assert(sizeof(CombatStyleLongRangeData) == 0x14);
}
@@ -0,0 +1,21 @@
#pragma once
namespace RE
{
class CombatStyleMeleeData
{
public:
// members
float attackIncapacitatedMult; // 00
float powerAttackIncapacitatedMult; // 04
float powerAttackBlockingMult; // 08
float bashMult; // 0C
float bashRecoiledMult; // 10
float bashAttackMult; // 14
float bashPowerAttackMult; // 18
float specialAttackMult; // 1C
float blockWhenIncapacitatedMult; // 20
float attackWhenIncapacitatedMult; // 24
};
static_assert(sizeof(CombatStyleMeleeData) == 0x28);
}
@@ -0,0 +1,12 @@
#pragma once
namespace RE
{
class CombatStyleRangedData
{
public:
// members
float accuracyMult; // 0
};
static_assert(sizeof(CombatStyleRangedData) == 0x4);
}
@@ -0,0 +1,65 @@
#pragma once
namespace RE
{
class bhkPickData;
class NiPoint3;
namespace CombatUtilities
{
inline bool CalculateProjectileLOS(
Actor* a_actor,
BGSProjectile* a_projectile,
float a_projectileSpeed,
const NiPoint3& a_launchPos,
const NiPoint3& a_targetPos,
NiPoint3* a_hitPos,
TESObjectREFR** a_collidee,
float* a_distanceFraction)
{
using func_t = bool (*)(Actor*, BGSProjectile*, float, const NiPoint3&, const NiPoint3&, NiPoint3*, TESObjectREFR**, float*);
static REL::Relocation<func_t> func{ ID::CombatUtilities::CalculateProjectileLOS1 };
return func(a_actor, a_projectile, a_projectileSpeed, a_launchPos, a_targetPos, a_hitPos, a_collidee, a_distanceFraction);
}
inline bool CalculateProjectileLOS(Actor* a_actor, BGSProjectile* a_projectile, bhkPickData& a_pickData)
{
using func_t = bool (*)(Actor*, BGSProjectile*, bhkPickData&);
static REL::Relocation<func_t> func{ ID::CombatUtilities::CalculateProjectileLOS2 };
return func(a_actor, a_projectile, a_pickData);
}
inline bool CalculateProjectileTrajectory(
const NiPoint3& a_projectilePos,
const NiPoint3& a_projectileVelocity,
float a_projectileGravity,
const NiPoint3& a_targetPos,
float a_heading,
NiPoint3& a_trajectoryPos)
{
using func_t = decltype(&CombatUtilities::CalculateProjectileTrajectory);
static REL::Relocation<func_t> func{ ID::CombatUtilities::CalculateProjectileTrajectory };
return func(a_projectilePos, a_projectileVelocity, a_projectileGravity, a_targetPos, a_heading, a_trajectoryPos);
}
inline float GetWorldGravity()
{
static REL::Relocation<float> value{ ID::CombatUtilities::WorldGravity };
return value.get();
}
inline bool IsActorUsingMelee(Actor* a_actor)
{
using func_t = decltype(CombatUtilities::IsActorUsingMelee);
static REL::Relocation<func_t> func{ ID::CombatUtilities::IsActorUsingMelee };
return func(a_actor);
}
inline bool IsActorUsingUnarmed(Actor* a_actor)
{
using func_t = decltype(CombatUtilities::IsActorUsingUnarmed);
static REL::Relocation<func_t> func{ ID::CombatUtilities::IsActorUsingUnarmed };
return func(a_actor);
}
}
}
@@ -0,0 +1,15 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
namespace RE
{
class CommandedActorData
{
public:
// members
ActorHandle commandedActor; // 00
ActiveEffect* activeEffect; // 08
};
static_assert(sizeof(CommandedActorData) == 0x10);
}
@@ -0,0 +1,23 @@
#pragma once
namespace RE
{
class BSExtraData;
namespace ComparisonQualifiers
{
inline bool ContainerQualifier(const BSExtraData* a_extraData)
{
using func_t = decltype(&ComparisonQualifiers::ContainerQualifier);
static REL::Relocation<func_t> func{ ID::ComparisonQualifiers::ContainerQualifier };
return func(a_extraData);
}
inline bool UIQualifier(const BSExtraData* a_extraData)
{
using func_t = decltype(&ComparisonQualifiers::UIQualifier);
static REL::Relocation<func_t> func{ ID::ComparisonQualifiers::UIQualifier };
return func(a_extraData);
}
};
}
@@ -0,0 +1,23 @@
#pragma once
#include "RE/I/IFormFactory.h"
namespace RE
{
template <class T, ENUM_FORM_ID ID = T::FORM_ID>
class __declspec(novtable) ConcreteFormFactory :
public IFormFactory // 00
{
public:
[[nodiscard]] static ConcreteFormFactory* GetFormFactory()
{
const auto factories = GetFormFactories();
return static_cast<ConcreteFormFactory*>(factories[std::to_underlying(ID)]);
}
[[nodiscard]] T* Create() { return static_cast<T*>(DoCreate()); }
// members
const char* name{ nullptr };
};
}
@@ -0,0 +1,13 @@
#pragma once
#include "RE/C/ConcreteFormFactory.h"
namespace RE
{
template <class T, ENUM_FORM_ID ID, OBJECT_TYPE TYPE, OBJECT_CATEGORY_TYPE CATEGORY>
class __declspec(novtable) ConcreteObjectFormFactory :
public ConcreteFormFactory<T, ID> // 00
{
public:
};
}
@@ -0,0 +1,24 @@
#pragma once
namespace RE
{
class BGSPackageDataList;
class BGSStoryEvent;
class ConditionCheckParams
{
public:
// members
TESObjectREFR* actionRef{ nullptr }; // 00
TESObjectREFR* targetRef{ nullptr }; // 08
const TESQuest* scopeQuest{ nullptr }; // 10
const BGSStoryEvent* scopeEvent{ nullptr }; // 18
Actor* scopeActor{ nullptr }; // 20
const BGSPackageDataList* runningPackageData{ nullptr }; // 28
BGSMod::Template::Item* objectTemplateItem{ nullptr }; // 30
const TESForm* extraForms[5]{ nullptr }; // 38
std::uint32_t extraFormCount{ 0 }; // 60
bool outDispFailure{ false }; // 64
};
static_assert(sizeof(ConditionCheckParams) == 0x68);
}
@@ -0,0 +1,20 @@
#pragma once
#include "RE/P/Projectile.h"
namespace RE
{
class __declspec(novtable) ConeProjectile :
public Projectile // 000
{
public:
static constexpr auto RTTI{ RTTI::ConeProjectile };
static constexpr auto VTABLE{ VTABLE::ConeProjectile };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kPCON };
// members
float expirationTimer; // 270
float coneAngle; // 274
};
static_assert(sizeof(ConeProjectile) == 0x280);
}
@@ -0,0 +1,63 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
#include "RE/G/GameMenuBase.h"
#include "RE/R/Rumble.h"
namespace RE
{
class __declspec(novtable) Console :
public GameMenuBase // 00
{
public:
static constexpr auto RTTI{ RTTI::Console };
static constexpr auto VTABLE{ VTABLE::Console };
static constexpr auto MENU_NAME{ "Console"sv };
static void ExecuteCommand(const char* a_command)
{
using func_t = decltype(&Console::ExecuteCommand);
static REL::Relocation<func_t> func{ ID::Console::ExecuteCommand };
return func(a_command);
}
[[nodiscard]] static decltype(auto) GetCurrentPickIndex()
{
static REL::Relocation<std::int32_t*> currentPickIndex{ ID::Console::GetCurrentPickIndex };
return *currentPickIndex;
}
[[nodiscard]] static decltype(auto) GetPickRef()
{
static REL::Relocation<ObjectRefHandle*> ref{ ID::Console::GetPickRef };
return *ref;
}
[[nodiscard]] static decltype(auto) GetPickRefs()
{
static REL::Relocation<BSTArray<ObjectRefHandle>*> pickRefs{ ID::Console::GetPickRefs };
return *pickRefs;
}
[[nodiscard]] static ObjectRefHandle GetCurrentPickREFR()
{
const auto idx = GetCurrentPickIndex();
const auto& refs = GetPickRefs();
return 0 <= idx && static_cast<std::size_t>(idx) < refs.size() ?
refs[static_cast<std::size_t>(idx)] :
ObjectRefHandle{};
}
void SetCurrentPickREFR(ObjectRefHandle* a_refr)
{
using func_t = decltype(&Console::SetCurrentPickREFR);
static REL::Relocation<func_t> func{ ID::Console::SetCurrentPickREFR };
return func(this, a_refr);
}
// members
Rumble::AutoRumblePause* rumbleLock; // E0
bool minimized; // E8
};
static_assert(sizeof(Console) == 0xF0);
}
@@ -0,0 +1,60 @@
#pragma once
#include "RE/B/BSStringT.h"
#include "RE/B/BSTSingleton.h"
namespace RE
{
class ConsoleLog :
public BSTSingletonSDM<ConsoleLog> // 00
{
public:
[[nodiscard]] static ConsoleLog* GetSingleton()
{
static REL::Relocation<ConsoleLog**> ptr{ ID::ConsoleLog::Singleton };
return *ptr;
}
void AddString(char const* a_str)
{
using func_t = decltype(&ConsoleLog::AddString);
static REL::Relocation<func_t> func{ ID::ConsoleLog::AddString };
return func(this, a_str);
}
// std::format rules, has compile time checking
template <class... Args>
void Log(const std::format_string<Args...> a_fmt, Args&&... a_args)
{
auto str = std::vformat(a_fmt.get(), std::make_format_args(a_args...));
str += '\n';
AddString(str.c_str());
}
// std::printf rules, no compile time checking
void Print(const char* a_fmt, std::va_list a_args)
{
using func_t = decltype(&ConsoleLog::Print);
static REL::Relocation<func_t> func{ ID::ConsoleLog::Print };
func(this, a_fmt, a_args);
}
void PrintLine(const char* a_fmt, ...)
{
std::va_list args;
va_start(args, a_fmt);
Print(a_fmt, args);
va_end(args);
}
void SetUseConsoleOverlay(bool a_value)
{
useConsoleOverlay = a_value;
}
// members
BSString buffer; // 08
bool useConsoleOverlay; // 18
};
static_assert(sizeof(ConsoleLog) == 0x20);
}
@@ -0,0 +1,46 @@
#pragma once
#include "RE/M/MemoryManager.h"
namespace RE
{
class ContainerItemExtra
{
public:
union Conditional
{
Conditional() :
ownerGlobal(nullptr)
{}
~Conditional() = default;
F4_HEAP_REDEFINE_NEW(Conditional);
TESGlobal* ownerGlobal;
std::int32_t ownerRank;
void* u;
};
static_assert(sizeof(Conditional) == 0x8);
ContainerItemExtra() :
ownerForm(nullptr),
conditional(),
healthMult(100.0f)
{}
ContainerItemExtra(TESForm* a_owner) :
ownerForm(a_owner),
conditional(),
healthMult(100.0f)
{}
F4_HEAP_REDEFINE_NEW(ContainerItemExtra);
// members
TESForm* ownerForm; // 00
Conditional conditional; // 08
float healthMult; // 10
};
static_assert(sizeof(ContainerItemExtra) == 0x18);
}
@@ -0,0 +1,41 @@
#pragma once
#include "RE/C/ContainerMenuBase.h"
namespace RE
{
class __declspec(novtable) ContainerMenu :
public ContainerMenuBase // 000
{
public:
static constexpr auto RTTI{ RTTI::ContainerMenu };
static constexpr auto VTABLE{ VTABLE::ContainerMenu };
static constexpr auto MENU_NAME{ "ContainerMenu"sv };
// override
virtual UI_MESSAGE_RESULTS ProcessMessage(UIMessage& a_message) override; // 03
virtual void DoItemTransfer(std::uint32_t a_itemIndex, std::uint32_t a_count, bool a_fromContainer) override; // 15
virtual bool GetCanEquipItem(std::uint32_t a_itemIndex, bool a_inContainer) override; // 17
virtual bool GetIsItemEquipped(std::uint32_t a_itemIndex, bool a_inContainer) override; // 18
virtual void ToggleItemEquipped(std::uint32_t a_itemIndex, bool a_inContainer) override; // 19
virtual void PopulateMenuObj(ObjectRefHandle a_inventoryRef, const InventoryUserUIInterfaceEntry& a_entry, Scaleform::GFx::Value& a_menuObj) override; // 22
virtual void UpdateItemPickpocketInfo(std::int32_t a_index, bool a_inContainer, std::int32_t a_count) override; // 25
virtual void UpdateList(bool a_inContainer) override; // 26
void TakeAllItems()
{
using func_t = decltype(&ContainerMenu::TakeAllItems);
static REL::Relocation<func_t> func{ ID::ContainerMenu::TakeAllItems };
return func(this);
}
// members
std::unique_ptr<BSGFxShaderFXTarget> pickpocketInfo_mc; // 430
std::uint32_t valueStolenFromContainer; // 438
bool containerAccessed; // 43C
bool addedTempItems; // 43D
bool plantedExplosiveWeapon; // 43E
bool containerIsAnimatingOpen; // 43F
};
static_assert(sizeof(ContainerMenu) == 0x440);
}
@@ -0,0 +1,119 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSTEvent.h"
#include "RE/D/DisableHeavyItemsFunc.h"
#include "RE/G/GameMenuBase.h"
#include "RE/I/Inventory3DManager.h"
#include "RE/I/InventoryUserUIInterface.h"
#include "RE/R/Rumble.h"
namespace RE
{
enum class ContainerMenuMode;
class MenuOpenCloseEvent;
class __declspec(novtable) ContainerMenuBase :
public GameMenuBase, // 000
public BSTEventSink<InvInterfaceStateChangeEvent>, // 0E0
public BSTEventSink<MenuOpenCloseEvent> // 0E8
{
public:
static constexpr auto RTTI{ RTTI::ContainerMenuBase };
static constexpr auto VTABLE{ VTABLE::ContainerMenuBase };
class __declspec(novtable) FXQuantityMenu :
public BSGFxShaderFXTarget // 000
{
public:
// members
BSGFxShaderFXTarget label; // 0B0
BSGFxShaderFXTarget value; // 160
BSGFxShaderFXTarget quantityBracketHolder; // 210
};
static_assert(sizeof(FXQuantityMenu) == 0x2C0);
class ItemSorter
{
public:
enum class SORT_ON_FIELD
{
kAlphabetical = 0x0,
kDamage = 0x1,
kRateOfFire = 0x2,
kRange = 0x3,
kAccuracy = 0x4,
kValue = 0x5,
kWeight = 0x6,
};
void IncrementSort()
{
using func_t = decltype(&ItemSorter::IncrementSort);
static REL::Relocation<func_t> func{ ID::ContainerMenuBase::ItemSorter::IncrementSort };
return func(this);
}
void SetTab(std::uint32_t a_tab)
{
currentTab = a_tab;
}
// members
REX::TEnumSet<SORT_ON_FIELD, std::uint32_t> currentSort[14]; // 00
std::uint32_t currentTab; // 38
};
static_assert(sizeof(ItemSorter) == 0x3C);
// override
virtual void Call(const Params&) override; // 01
virtual void MapCodeObjectFunctions() override; // 02
virtual void AdvanceMovie(float a_timeDelta, std::uint64_t a_time) override; // 04
virtual void PreDisplay() override; // 05
// add
virtual void ConfirmInvestment() { return; } // 14
virtual void DoItemTransfer(std::uint32_t a_itemIndex, std::uint32_t a_count, bool a_fromContainer) = 0; // 15
virtual bool GetDisplayBarterValues() { return false; } // 16
virtual bool GetCanEquipItem([[maybe_unused]] std::uint32_t a_itemIndex, [[maybe_unused]] bool a_inContainer) { return false; } // 17
virtual bool GetIsItemEquipped([[maybe_unused]] std::uint32_t a_itemIndex, [[maybe_unused]] bool a_inContainer) { return false; } // 18
virtual void ToggleItemEquipped([[maybe_unused]] std::uint32_t a_itemIndex, [[maybe_unused]] bool a_inContainer) { return; } // 19
virtual std::uint32_t GetItemValue(std::uint32_t a_itemIndex, bool a_inContainer); // 1A
virtual const InventoryUserUIInterfaceEntry* GetInventoryItemByListIndex(bool a_inContainer, std::uint32_t a_index); // 1B
virtual void PopulateMenuObj(ObjectRefHandle a_inventoryRef, const InventoryUserUIInterfaceEntry& a_entry, Scaleform::GFx::Value& a_menuObj) = 0; // 1C
virtual void SetMenuSuppressed(bool a_suppressed); // 1D
virtual void UpdateEncumbranceAndCaps(bool a_inContainer, std::int32_t a_capsDifferential); // 1E
virtual void UpdateItemPickpocketInfo([[maybe_unused]] std::int32_t a_index, [[maybe_unused]] bool a_inContainer, [[maybe_unused]] std::int32_t a_count) { return; } // 1F
virtual void UpdateList(bool a_inContainer) = 0; // 20
void SetMessageBoxMode(bool a_messageBoxMode)
{
if (menuObj.IsObject() && menuObj.HasMember("messageBoxIsActive"sv)) {
menuObj.SetMember("messageBoxIsActive"sv, a_messageBoxMode);
}
}
// members
ItemSorter containerItemSorter; // 0F0
ItemSorter playerItemSorter; // 12C
std::unique_ptr<BSGFxShaderFXTarget> playerBracketBackground_mc; // 168
std::unique_ptr<BSGFxShaderFXTarget> containerBracketBackground_mc; // 170
std::unique_ptr<BSGFxShaderFXTarget> containerList_mc; // 178
std::unique_ptr<BSGFxShaderFXTarget> playerInventory_mc; // 180
std::unique_ptr<BSGFxShaderFXTarget> containerInventory_mc; // 188
std::unique_ptr<BSGFxShaderFXTarget> itemCard_mc; // 190
std::unique_ptr<FXQuantityMenu> quantityMenu_mc; // 198
InventoryUserUIInterface playerInv; // 1A0
InventoryUserUIInterface containerInv; // 220
Inventory3DManager inv3DModelManager; // 2A0
BSTArray<const TESBoundObject*> partialPlayerUpdateList; // 3E0
BSTArray<const TESBoundObject*> partialContainerUpdateList; // 3F8
REX::TEnumSet<ContainerMenuMode, std::uint32_t> menuMode; // 410
Rumble::AutoRumblePause autoRumblePause; // 414
DisableHeavyItemsFunc disableHeavyFunc; // 418
ObjectRefHandle containerRef; // 428
bool suppressed; // 42C
bool menuOpening; // 42D
};
static_assert(sizeof(ContainerMenuBase) == 0x430);
}
@@ -0,0 +1,33 @@
#pragma once
#include "RE/C/ContainerItemExtra.h"
#include "RE/M/MemoryManager.h"
namespace RE
{
class ContainerObject
{
public:
ContainerObject(TESBoundObject* a_obj, std::int32_t a_count) :
count(a_count),
obj(a_obj),
itemExtra()
{}
ContainerObject(TESBoundObject* a_obj, std::int32_t a_count, TESForm* a_ownerForm) :
count(a_count),
obj(a_obj),
itemExtra(new ContainerItemExtra(a_ownerForm))
{}
~ContainerObject() = default;
F4_HEAP_REDEFINE_NEW(ContainerObject);
// members
std::int32_t count; // 00
TESBoundObject* obj; // 08
ContainerItemExtra* itemExtra; // 10
};
static_assert(sizeof(ContainerObject) == 0x18);
}
@@ -0,0 +1,128 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTSingleton.h"
#include "RE/I/INPUT_DEVICE.h"
#include "RE/U/UserEvents.h"
namespace RE
{
enum class PC_GAMEPAD_TYPE;
class ControlMap :
public BSTSingletonSDM<ControlMap> // 000
{
public:
using InputContextID = UserEvents::INPUT_CONTEXT_ID;
enum : std::uint32_t
{
kInvalid = static_cast<std::uint8_t>(-1)
};
class UserEventMapping
{
public:
// members
BSFixedString eventID; // 00
std::int32_t inputKey; // 08
std::int8_t byIndexInContext; // 0C
bool remappable; // 0D
bool linked; // 0E
REX::TEnumSet<UserEvents::USER_EVENT_FLAG, std::int32_t> userEventGroupFlag; // 10
};
static_assert(sizeof(UserEventMapping) == 0x18);
class InputContext
{
public:
// members
BSTArray<UserEventMapping> deviceMappings[std::to_underlying(INPUT_DEVICE::kSupported)]; // 00
};
static_assert(sizeof(InputContext) == 0x48);
class LinkedMapping
{
public:
// members
BSFixedString linkedMappingName; // 00
REX::TEnumSet<UserEvents::INPUT_CONTEXT_ID, std::int32_t> linkedMappingContext; // 08
REX::TEnumSet<INPUT_DEVICE, std::int32_t> device; // 0C
REX::TEnumSet<UserEvents::INPUT_CONTEXT_ID, std::int32_t> linkFromContext; // 10
BSFixedString linkFromName; // 18
};
static_assert(sizeof(LinkedMapping) == 0x20);
[[nodiscard]] static ControlMap* GetSingleton()
{
static REL::Relocation<ControlMap**> singleton{ ID::ControlMap::Singleton };
return *singleton;
}
std::uint32_t GetMappedKey(std::string_view a_eventID, INPUT_DEVICE a_device, InputContextID a_context = InputContextID::kMainGameplay) const
{
assert(a_device < INPUT_DEVICE::kTotal);
assert(a_context < InputContextID::kTotal);
if (controlMaps[std::to_underlying(a_context)]) {
const auto& mappings = controlMaps[std::to_underlying(a_context)]->deviceMappings[std::to_underlying(a_device)];
BSFixedString eventID(a_eventID);
for (auto& mapping : mappings) {
if (mapping.eventID == eventID) {
return mapping.inputKey;
}
}
}
return kInvalid;
}
bool PopInputContext(UserEvents::INPUT_CONTEXT_ID a_context)
{
using func_t = decltype(&ControlMap::PopInputContext);
static REL::Relocation<func_t> func{ ID::ControlMap::PopInputContext };
return func(this, a_context);
}
void PushInputContext(UserEvents::INPUT_CONTEXT_ID a_context)
{
using func_t = decltype(&ControlMap::PushInputContext);
static REL::Relocation<func_t> func{ ID::ControlMap::PushInputContext };
return func(this, a_context);
}
bool RemapButton(BSFixedString const& a_id, INPUT_DEVICE a_device, std::int32_t a_buttonID)
{
using func_t = decltype(&ControlMap::RemapButton);
static REL::Relocation<func_t> func{ ID::ControlMap::RemapButton };
return func(this, a_id, a_device, a_buttonID);
}
void SaveRemappings()
{
using func_t = decltype(&ControlMap::SaveRemappings);
static REL::Relocation<func_t> func{ ID::ControlMap::SaveRemappings };
return func(this);
}
void SetTextEntryMode(bool a_enable)
{
using func_t = decltype(&ControlMap::SetTextEntryMode);
static REL::Relocation<func_t> func{ ID::ControlMap::SetTextEntryMode };
return func(this, a_enable);
}
void SetIgnoreKeyboardMouse(bool a_value) noexcept { ignoreKeyboardMouse = a_value; }
// members
InputContext* controlMaps[std::to_underlying(UserEvents::INPUT_CONTEXT_ID::kTotal)]; // 008
BSTArray<LinkedMapping> linkedMappings; // 110
BSTArray<REX::TEnumSet<UserEvents::INPUT_CONTEXT_ID, std::int32_t>> contextPriorityStack; // 128
std::int8_t byTextEntryCount; // 140
bool ignoreKeyboardMouse; // 141
bool ignoreActivateDisabledEvents; // 142
REX::TEnumSet<PC_GAMEPAD_TYPE, std::int32_t> pcGamePadMapType; // 144
};
static_assert(sizeof(ControlMap) == 0x148);
}
@@ -0,0 +1,14 @@
#pragma once
namespace RE
{
class CountdownTimer
{
public:
// members
std::uint64_t startTime; // 00
std::uint64_t endTime; // 08
bool isActive; // 10
};
static_assert(sizeof(CountdownTimer) == 0x18);
}
@@ -0,0 +1,28 @@
#pragma once
#include "RE/T/TESGrass.h"
namespace RE
{
class GrassParam;
class NiPoint3;
class TESObjectLAND;
struct CreateGrassParams
{
public:
std::int32_t cellX; // 00
std::int32_t cellY; // 04
std::int32_t block; // 08
const TESObjectLAND* land; // 10
const NiPoint3* coord; // 18
const GrassParam* grassParam; // 20
const float* density; // 28
float heightLimit; // 30
TESGrass::GRASS_WATER_STATE waterState; // 34
float cellWaterHeight; // 38
std::uint32_t minSlope; // 3C
std::uint32_t maxSlope; // 40
std::uint32_t randomSeed; // 44
};
static_assert(sizeof(CreateGrassParams) == 0x48);
}
@@ -0,0 +1,17 @@
#pragma once
#include "RE/B/BSTArray.h"
namespace RE
{
class CREATURE_SOUND;
class CreatureSounds
{
public:
// members
BSTArray<CREATURE_SOUND> consciousLoops; // 00
bool stopLoopWhenUnconscious; // 18
};
static_assert(sizeof(CreatureSounds) == 0x20);
}
@@ -0,0 +1,15 @@
#pragma once
namespace RE
{
class CrimeGoldStruct
{
public:
// members
std::uint32_t violent; // 00
std::uint32_t nonViolent; // 04
std::uint32_t totalNonViolentAccumulated; // 08
std::uint32_t totalViolentAccumulated; // 0C
};
static_assert(sizeof(CrimeGoldStruct) == 0x10);
}
@@ -0,0 +1,13 @@
#pragma once
namespace RE
{
class CubeMapSide
{
public:
// members
std::uint32_t side; // 00
float renderTime; // 04
};
static_assert(sizeof(CubeMapSide) == 0x08);
}
@@ -0,0 +1,24 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class CurrentRadiationSourceCount :
public BSTValueEvent<std::uint32_t>
{
private:
using EventSource_t = BSTGlobalEvent::EventSource<CurrentRadiationSourceCount>;
public:
[[nodiscard]] static EventSource_t* GetEventSource()
{
static REL::Relocation<EventSource_t**> singleton{ ID::CurrentRadiationSourceCount::GetEventSource };
if (!*singleton) {
*singleton = new EventSource_t(&BSTGlobalEvent::GetSingleton()->eventSourceSDMKiller);
}
return *singleton;
}
};
static_assert(sizeof(CurrentRadiationSourceCount) == 0x8);
}
@@ -0,0 +1,13 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class CurrentRadsDisplayMagnitude :
public BSTValueEvent<float>
{
public:
};
static_assert(sizeof(CurrentRadsDisplayMagnitude) == 0x8);
}
@@ -0,0 +1,13 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class CurrentRadsPercentOfLethal :
public BSTValueEvent<float>
{
public:
};
static_assert(sizeof(CurrentRadsPercentOfLethal) == 0x8);
}
@@ -0,0 +1,19 @@
#pragma once
#include "RE/G/GameMenuBase.h"
namespace RE
{
class __declspec(novtable) CursorMenu :
public GameMenuBase // 00
{
public:
static constexpr auto RTTI{ RTTI::CursorMenu };
static constexpr auto VTABLE{ VTABLE::CursorMenu };
static constexpr auto MENU_NAME{ "CursorMenu"sv };
// members
std::unique_ptr<BSGFxShaderFXTarget> cursor; // E0
};
static_assert(sizeof(CursorMenu) == 0xE8);
}
@@ -0,0 +1,26 @@
#pragma once
#include "RE/I/IDEvent.h"
namespace RE
{
class __declspec(novtable) CursorMoveEvent :
public IDEvent // 00
{
public:
static constexpr auto RTTI{ RTTI::CursorMoveEvent };
static constexpr auto VTABLE{ VTABLE::CursorMoveEvent };
static constexpr auto TYPE{ INPUT_EVENT_TYPE::kCursorMove };
// NOLINTNEXTLINE(modernize-use-override)
virtual ~CursorMoveEvent() = default; // 00
// members
std::int32_t cursorPosX{ 0 }; // 38
std::int32_t cursorPosY{ 0 }; // 3C
};
static_assert(sizeof(CursorMoveEvent) == 0x40);
extern template CursorMoveEvent* InputEvent::As() noexcept;
extern template const CursorMoveEvent* InputEvent::As() const noexcept;
}
@@ -0,0 +1,13 @@
#pragma once
namespace RE
{
namespace CustomMarkerUpdate
{
class Event
{
public:
};
static_assert(std::is_empty_v<Event>);
}
}