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
+101
View File
@@ -0,0 +1,101 @@
---
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: 'false'
AlignConsecutiveBitFields: 'false'
AlignConsecutiveDeclarations: 'true'
AlignConsecutiveMacros: 'false'
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments: 'true'
AllowAllArgumentsOnNextLine: 'false'
AllowAllConstructorInitializersOnNextLine: 'false'
AllowAllParametersOfDeclarationOnNextLine: 'false'
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: 'false'
AllowShortEnumsOnASingleLine: 'true'
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: 'true'
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: 'true'
AlwaysBreakTemplateDeclarations: 'Yes'
BinPackArguments: 'true'
BinPackParameters: 'true'
BitFieldColonSpacing: After
BraceWrapping:
AfterCaseLabel: 'false'
AfterClass: 'true'
AfterControlStatement: 'false'
AfterEnum: 'true'
AfterFunction: 'true'
AfterNamespace: 'true'
AfterStruct: 'true'
AfterUnion: 'true'
AfterExternBlock: 'true'
BeforeCatch: 'false'
BeforeElse: 'false'
BeforeLambdaBody: 'false'
BeforeWhile: 'false'
IndentBraces: 'false'
SplitEmptyFunction: 'false'
SplitEmptyRecord: 'false'
SplitEmptyNamespace: 'false'
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: 'false'
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
BreakStringLiterals: 'true'
ColumnLimit: 0
CompactNamespaces: 'false'
ConstructorInitializerAllOnOneLineOrOnePerLine: 'false'
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: 'false'
DeriveLineEnding: 'true'
DerivePointerAlignment: 'false'
DisableFormat: 'false'
FixNamespaceComments: 'false'
IncludeBlocks: Preserve
IndentCaseBlocks: 'false'
IndentCaseLabels: 'true'
IndentExternBlock: Indent
IndentGotoLabels: 'false'
IndentPPDirectives: AfterHash
IndentWidth: 4
IndentWrappedFunctionNames: 'true'
KeepEmptyLinesAtTheStartOfBlocks: 'false'
Language: Cpp
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
PointerAlignment: Left
ReflowComments : 'false'
SortIncludes: 'true'
SortUsingDeclarations: 'true'
SpaceAfterCStyleCast: 'false'
SpaceAfterLogicalNot: 'false'
SpaceAfterTemplateKeyword: 'true'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeCpp11BracedList: 'false'
SpaceBeforeCtorInitializerColon: 'true'
SpaceBeforeInheritanceColon: 'true'
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: 'true'
SpaceBeforeSquareBrackets: 'false'
SpaceInEmptyBlock: 'false'
SpaceInEmptyParentheses: 'false'
SpacesBeforeTrailingComments: 2
SpacesInAngles: 'false'
SpacesInCStyleCastParentheses: 'false'
SpacesInConditionalStatement: 'false'
SpacesInContainerLiterals: 'true'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
Standard: Latest
TabWidth: 4
UseCRLF: 'true'
UseTab: AlignWithSpaces
...
+42
View File
@@ -0,0 +1,42 @@
---
Checks: >
-*,
bugprone-*,
-bugprone-branch-clone,
-bugprone-macro-parentheses,
-bugprone-narrowing-conversions,
-bugprone-unhandled-self-assignment,
clang-analyzer-*,
google-*,
-google-build-using-namespace,
-google-default-arguments,
-google-readability-namespace-comments,
-google-readability-todo,
misc-*,
-misc-non-private-member-variables-in-classes,
-misc-unused-alias-decls,
-misc-unused-parameters,
modernize-*,
-modernize-avoid-c-arrays,
-modernize-use-nodiscard,
-modernize-use-trailing-return-type,
performance-*,
-performance-unnecessary-value-param,
portability-*,
readability-*,
-readability-convert-member-functions-to-static,
-readability-else-after-return,
-readability-implicit-bool-conversion,
-readability-magic-numbers,
-readability-named-parameter,
-readability-qualified-auto,
-readability-redundant-control-flow,
---
+15
View File
@@ -0,0 +1,15 @@
[*]
charset = utf-8
insert_final_newline = true
[*.{h,hpp,hxx,c,cpp,cxx}]
indent_style = tab
indent_size = 4
[*.cmake]
indent_style = tab
indent_size = 4
[*.json]
indent_style = space
indent_size = 2
+4
View File
@@ -0,0 +1,4 @@
# Auto detect text files and perform LF normalization
* text=auto
*.h linguist-language=C++
+43
View File
@@ -0,0 +1,43 @@
name: build
on:
push:
branches: [ main ]
paths:
- ".github/workflows/build.yml"
- "include/**"
- "src/**"
- "xmake.lua"
- "xmake-rules.lua"
pull_request:
branches: [ main ]
workflow_dispatch:
jobs:
xmake:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
mode:
- debug
- release
toolchain:
- msvc
- clang-cl
steps:
- name: checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: setup
uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: "latest"
- name: config
run: xmake config -y --mode=${{ matrix.mode }} --toolchain=${{ matrix.toolchain }}
- name: build
run: xmake build -y -vD
@@ -0,0 +1,24 @@
name: maintenance
on: push
jobs:
maintenance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Run clang-format
run: find -type f \( -name *.h -o -name *.cpp \) | xargs clang-format -style=file -i
- name: Glob files
run: python ${{ github.workspace }}/res/scripts/generate_headers.py
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: maintenance
+15
View File
@@ -0,0 +1,15 @@
# dot folders
.idea*/
.vs*/
.vscode/
.xmake/
# folders
build*/
cmake-build*/
out*/
vs*/
# files
*.zip
CMakeUserPresets.json
+3
View File
@@ -0,0 +1,3 @@
[submodule "lib/commonlib-shared"]
path = lib/commonlib-shared
url = https://github.com/libxse/commonlib-shared.git
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 ryan-rsm-mckenzie
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+38
View File
@@ -0,0 +1,38 @@
# CommonLibF4
### Requirements
* [XMake](https://xmake.io) [3.0.0+]
* C++23 Compiler (MSVC or Clang-CL)
## Getting Started
```bat
git clone --recurse-submodules https://github.com/libxse/commonlibf4
cd commonlibf4
```
### Build
To build the project, run the following command:
```bat
xmake build
```
> ***Note:*** *This will generate a `build/windows/` directory in the **project's root directory** with the build output.*
### Project Generation (Optional)
If you use Visual Studio, run the following command:
```bat
xmake project -k vsxmake
```
> ***Note:*** *This will generate a `vsxmakeXXXX/` directory in the **project's root directory** using the latest version of Visual Studio installed on the system.*
**Alternatively**, if you do not use Visual Studio, you can generate a `compile_commands.json` file for use with a laguage server like clangd in any code editor that supports it, like vscode:
```bat
xmake project -k compile_commands
```
> ***Note:*** *You must have a language server extension installed to make use of this file. I recommend `clangd`. Do not have more than one installed at a time as they will conflict with each other. I also recommend installing the `xmake` extension if available to make building the project easier.*
## Notes
CommonLibF4 is intended to replace F4SE as a static dependency. However, the runtime component of F4SE is still required.
+66
View File
@@ -0,0 +1,66 @@
#pragma once
#include "REX/LOG.h"
namespace F4SE
{
using PluginHandle = std::uint32_t;
class PreLoadInterface;
class LoadInterface;
struct PluginInfo;
class MessagingInterface;
class ScaleformInterface;
class PapyrusInterface;
class SerializationInterface;
class TaskInterface;
class ObjectInterface;
class TrampolineInterface;
struct InitInfo
{
bool log{ true };
#ifndef NDEBUG
REX::ELogLevel logLevel{ REX::ELogLevel::Debug };
#else
REX::ELogLevel logLevel{ REX::ELogLevel::Info };
#endif
const char* logName{ nullptr };
const char* logPattern{ nullptr };
std::size_t logRotate{ 0 };
bool trampoline{ false };
std::size_t trampolineSize{ 0 };
bool hook{ true };
};
void Init(const PreLoadInterface* a_intfc, InitInfo a_info = {}) noexcept;
void Init(const LoadInterface* a_intfc, InitInfo a_info = {}) noexcept;
[[nodiscard]] REL::Version GetF4SEVersion() noexcept;
[[nodiscard]] std::string_view GetPluginName() noexcept;
[[nodiscard]] std::string_view GetPluginAuthor() noexcept;
[[nodiscard]] REL::Version GetPluginVersion() noexcept;
[[nodiscard]] PluginHandle GetPluginHandle() noexcept;
[[nodiscard]] const PluginInfo* GetPluginInfo(std::string_view a_plugin) noexcept;
[[nodiscard]] std::uint32_t GetReleaseIndex() noexcept;
[[nodiscard]] std::string_view GetSaveFolderName() noexcept;
[[nodiscard]] const MessagingInterface* GetMessagingInterface() noexcept;
[[nodiscard]] const ScaleformInterface* GetScaleformInterface() noexcept;
[[nodiscard]] const PapyrusInterface* GetPapyrusInterface() noexcept;
[[nodiscard]] const SerializationInterface* GetSerializationInterface() noexcept;
[[nodiscard]] const TaskInterface* GetTaskInterface() noexcept;
[[nodiscard]] const ObjectInterface* GetObjectInterface() noexcept;
[[nodiscard]] const TrampolineInterface* GetTrampolineInterface() noexcept;
}
namespace F4SE
{
// DEPRECATED
[[deprecated("Use F4SE::Init(..., {}) instead")]] void Init(const LoadInterface* a_intfc, bool a_log) noexcept;
// DEPRECATED
[[deprecated("Use F4SE::Init(..., {}) instead")]] void AllocTrampoline(std::size_t a_size) noexcept;
}
@@ -0,0 +1,9 @@
#pragma once
#include "F4SE/Impl/PCH.h"
#include "F4SE/API.h"
#include "F4SE/InputMap.h"
#include "F4SE/Interfaces.h"
#include "F4SE/Trampoline.h"
#include "F4SE/Version.h"
@@ -0,0 +1,26 @@
#pragma once
#include <REL/REL.h>
#include <REX/REX.h>
namespace F4SE
{
using namespace std::literals;
}
namespace RE
{
using namespace std::literals;
}
namespace Scaleform
{
using namespace std::literals;
}
#include "RE/IDs.h"
#include "RE/IDs_NiRTTI.h"
#include "RE/IDs_RTTI.h"
#include "RE/IDs_VTABLE.h"
#include "RE/B/BSCoreTypes.h"
@@ -0,0 +1,51 @@
#pragma once
namespace F4SE
{
namespace InputMap
{
enum
{
// first 256 for keyboard, then 8 mouse buttons, then mouse wheel up, wheel down, then 16 gamepad buttons
kMacro_KeyboardOffset = 0, // not actually used, just for self-documentation
kMacro_NumKeyboardKeys = 256,
kMacro_MouseButtonOffset = kMacro_NumKeyboardKeys, // 256
kMacro_NumMouseButtons = 8,
kMacro_MouseWheelOffset = kMacro_MouseButtonOffset + kMacro_NumMouseButtons, // 264
kMacro_MouseWheelDirections = 2,
kMacro_GamepadOffset = kMacro_MouseWheelOffset + kMacro_MouseWheelDirections, // 266
kMacro_NumGamepadButtons = 16,
kMaxMacros = kMacro_GamepadOffset + kMacro_NumGamepadButtons // 282
};
enum
{
kGamepadButtonOffset_DPAD_UP = kMacro_GamepadOffset, // 266
kGamepadButtonOffset_DPAD_DOWN,
kGamepadButtonOffset_DPAD_LEFT,
kGamepadButtonOffset_DPAD_RIGHT,
kGamepadButtonOffset_START,
kGamepadButtonOffset_BACK,
kGamepadButtonOffset_LEFT_THUMB,
kGamepadButtonOffset_RIGHT_THUMB,
kGamepadButtonOffset_LEFT_SHOULDER,
kGamepadButtonOffset_RIGHT_SHOULDER,
kGamepadButtonOffset_A,
kGamepadButtonOffset_B,
kGamepadButtonOffset_X,
kGamepadButtonOffset_Y,
kGamepadButtonOffset_LT,
kGamepadButtonOffset_RT // 281
};
std::uint32_t XInputToScePadOffset(std::uint32_t keyMask);
std::uint32_t ScePadOffsetToXInput(std::uint32_t keyMask);
std::uint32_t GamepadMaskToKeycode(std::uint32_t keyMask);
std::uint32_t GamepadKeycodeToMask(std::uint32_t keyCode);
}
}
@@ -0,0 +1,568 @@
#pragma once
#include "REL/Relocation.h"
#define F4SEAPI __cdecl
namespace RE
{
namespace BSScript
{
class IVirtualMachine;
}
}
namespace Scaleform
{
namespace GFx
{
class Movie;
class Value;
}
}
namespace F4SE
{
using PluginHandle = std::uint32_t;
class DelayFunctorManager;
class ObjectRegistry;
class PersistentObjectStorage;
namespace Impl
{
struct F4SEInterface
{
std::uint32_t f4seVersion;
std::uint32_t runtimeVersion;
std::uint32_t editorVersion;
std::uint32_t isEditor;
void*(F4SEAPI* QueryInterface)(std::uint32_t);
std::uint32_t(F4SEAPI* GetPluginHandle)(void);
std::uint32_t(F4SEAPI* GetReleaseIndex)(void);
const void*(F4SEAPI* GetPluginInfo)(const char*); // 0.6.22+
const char*(F4SEAPI* GetSaveFolderName)(void); // 0.7.1+
};
struct F4SEMessagingInterface
{
std::uint32_t interfaceVersion;
bool(F4SEAPI* RegisterListener)(std::uint32_t, const char*, void*);
bool(F4SEAPI* Dispatch)(std::uint32_t, std::uint32_t, void*, std::uint32_t, const char*);
void*(F4SEAPI* GetEventDispatcher)(std::uint32_t);
};
struct F4SEScaleformInterface
{
std::uint32_t interfaceVersion;
bool(F4SEAPI* Register)(const char*, void*);
};
struct F4SESerializationInterface
{
std::uint32_t version;
void(F4SEAPI* SetUniqueID)(std::uint32_t, std::uint32_t);
void(F4SEAPI* SetRevertCallback)(std::uint32_t, void*);
void(F4SEAPI* SetSaveCallback)(std::uint32_t, void*);
void(F4SEAPI* SetLoadCallback)(std::uint32_t, void*);
void(F4SEAPI* SetFormDeleteCallback)(std::uint32_t, void*);
bool(F4SEAPI* WriteRecord)(std::uint32_t, std::uint32_t, const void*, std::uint32_t);
bool(F4SEAPI* OpenRecord)(std::uint32_t, std::uint32_t);
bool(F4SEAPI* WriteRecordData)(const void*, std::uint32_t);
bool(F4SEAPI* GetNextRecordInfo)(std::uint32_t*, std::uint32_t*, std::uint32_t*);
std::uint32_t(F4SEAPI* ReadRecordData)(void*, std::uint32_t);
bool(F4SEAPI* ResolveHandle)(std::uint64_t, std::uint64_t*);
bool(F4SEAPI* ResolveFormID)(std::uint32_t, std::uint32_t*);
};
struct F4SEPapyrusInterface
{
std::uint32_t interfaceVersion;
bool(F4SEAPI* Register)(void*);
void(F4SEAPI* GetExternalEventRegistrations)(const char*, void*, void*);
};
struct F4SETaskInterface
{
std::uint32_t interfaceVersion;
void(F4SEAPI* AddTask)(void*);
void(F4SEAPI* AddUITask)(void*);
void(F4SEAPI* AddTaskPermanent)(void*);
};
struct F4SEObjectInterface
{
std::uint32_t interfaceVersion;
DelayFunctorManager&(F4SEAPI* GetDelayFunctorManager)(void);
ObjectRegistry&(F4SEAPI* GetObjectRegistry)(void);
PersistentObjectStorage&(F4SEAPI* GetPersistentObjectStorage)(void);
};
struct F4SETrampolineInterface
{
std::uint32_t interfaceVersion;
void*(F4SEAPI* AllocateFromBranchPool)(std::uint32_t, std::size_t);
void*(F4SEAPI* AllocateFromLocalPool)(std::uint32_t, std::size_t);
};
}
class QueryInterface
{
protected:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SEInterface&>(*this);
}
private:
[[nodiscard]] constexpr static REL::Version MakeVersion(std::uint32_t a_version) noexcept
{
return {
static_cast<std::uint16_t>((a_version >> 8 * 3) & 0x0FF),
static_cast<std::uint16_t>((a_version >> 8 * 2) & 0x0FF),
static_cast<std::uint16_t>((a_version >> 8 / 2) & 0xFFF),
static_cast<std::uint16_t>((a_version >> 8 * 0) & 0x00F)
};
}
public:
[[nodiscard]] REL::Version EditorVersion() const noexcept { return MakeVersion(GetProxy().editorVersion); }
[[nodiscard]] REL::Version F4SEVersion() const noexcept { return MakeVersion(GetProxy().f4seVersion); }
[[nodiscard]] PluginHandle GetPluginHandle() const { return GetProxy().GetPluginHandle(); }
[[nodiscard]] std::uint32_t GetReleaseIndex() const { return GetProxy().GetReleaseIndex(); }
[[nodiscard]] std::string_view GetSaveFolderName() const { return GetProxy().GetSaveFolderName(); }
[[nodiscard]] bool IsEditor() const noexcept { return GetProxy().isEditor != 0; }
[[nodiscard]] REL::Version RuntimeVersion() const noexcept { return MakeVersion(GetProxy().runtimeVersion); }
};
class PreLoadInterface :
public QueryInterface
{
public:
enum : std::uint32_t
{
kInvalid = 0,
kTrampoline = 7
};
[[nodiscard]] void* QueryInterface(std::uint32_t a_id) const { return GetProxy().QueryInterface(a_id); }
template <class T>
T* QueryInterface(std::uint32_t a_id) const noexcept
{
auto result = static_cast<T*>(QueryInterface(a_id));
if (result && result->Version() > T::kVersion)
REX::ERROR("interface definition is out of date");
return result;
}
};
class LoadInterface :
public QueryInterface
{
public:
enum : std::uint32_t
{
kInvalid = 0,
kMessaging = 1,
kScaleform = 2,
kPapyrus = 3,
kSerialization = 4,
kTask = 5,
kObject = 6,
kTrampoline = 7
};
[[nodiscard]] void* QueryInterface(std::uint32_t a_id) const { return GetProxy().QueryInterface(a_id); }
template <class T>
T* QueryInterface(std::uint32_t a_id) const noexcept
{
auto result = static_cast<T*>(QueryInterface(a_id));
if (result && result->Version() > T::kVersion)
REX::ERROR("interface definition is out of date");
return result;
}
};
class MessagingInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SEMessagingInterface&>(*this);
}
public:
enum : std::uint32_t
{
kVersion = 1
};
enum : std::uint32_t
{
kPostLoad,
kPostPostLoad,
kPreLoadGame,
kPostLoadGame,
kPreSaveGame,
kPostSaveGame,
kDeleteGame,
kInputLoaded,
kNewGame,
kGameLoaded,
kGameDataReady
};
struct Message
{
const char* sender;
std::uint32_t type;
std::uint32_t dataLen;
void* data;
};
using EventCallback = void F4SEAPI(Message* a_msg);
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
bool RegisterListener(EventCallback* a_handler) const { return RegisterListener(a_handler, "F4SE"sv); }
bool RegisterListener(EventCallback* a_handler, std::string_view a_sender) const;
bool Dispatch(std::uint32_t a_messageType, void* a_data, std::uint32_t a_dataLen, const char* a_receiver) const;
[[nodiscard]] void* GetEventDispatcher(std::uint32_t a_dispatcherID) const
{
return GetProxy().GetEventDispatcher(a_dispatcherID);
}
};
class ScaleformInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SEScaleformInterface&>(*this);
}
public:
enum : std::uint32_t
{
kVersion = 1
};
using RegisterCallback = bool F4SEAPI(Scaleform::GFx::Movie* a_view, Scaleform::GFx::Value* a_value);
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
bool Register(std::string_view a_name, RegisterCallback* a_callback) const;
};
class SerializationInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SESerializationInterface&>(*this);
}
public:
enum : std::uint32_t
{
kVersion = 1,
};
using EventCallback = void F4SEAPI(const SerializationInterface* a_intfc);
using FormDeleteCallback = void F4SEAPI(std::uint64_t a_handle);
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().version; }
void SetUniqueID(std::uint32_t a_uid) const;
void SetRevertCallback(EventCallback* a_callback) const;
void SetSaveCallback(EventCallback* a_callback) const;
void SetLoadCallback(EventCallback* a_callback) const;
void SetFormDeleteCallback(FormDeleteCallback* a_callback) const;
bool WriteRecord(std::uint32_t a_type, std::uint32_t a_version, const void* a_buf, std::uint32_t a_length) const;
bool OpenRecord(std::uint32_t a_type, std::uint32_t a_version) const;
bool WriteRecordData(const void* a_buf, std::uint32_t a_length) const;
template <class T, std::enable_if_t<std::negation_v<std::is_pointer<T>>, int> = 0>
bool WriteRecordData(const T& a_buf) const
{
return WriteRecordData(std::addressof(a_buf), sizeof(T));
}
template <class T, std::size_t N, std::enable_if_t<std::is_array_v<T>, int> = 0>
bool WriteRecordData(const T (&a_buf)[N]) const
{
return WriteRecordData(std::addressof(a_buf), sizeof(T) * N);
}
bool GetNextRecordInfo(std::uint32_t& a_type, std::uint32_t& a_version, std::uint32_t& a_length) const;
std::uint32_t ReadRecordData(void* a_buf, std::uint32_t a_length) const;
template <class T, std::enable_if_t<std::negation_v<std::is_pointer<T>>, int> = 0>
std::uint32_t ReadRecordData(T& a_buf) const
{
return ReadRecordData(std::addressof(a_buf), sizeof(T));
}
template <class T, std::enable_if_t<std::negation_v<std::is_pointer<T>>, int> = 0>
std::uint32_t ReadRecordDataEx(std::uint32_t& a_length, T& a_buf) const
{
a_length -= sizeof(T);
return ReadRecordData(std::addressof(a_buf), sizeof(T));
}
template <class T, std::size_t N, std::enable_if_t<std::is_array_v<T>, int> = 0>
std::uint32_t ReadRecordData(T (&a_buf)[N]) const
{
return ReadRecordData(std::addressof(a_buf), sizeof(T) * N);
}
template <class T, std::size_t N, std::enable_if_t<std::is_array_v<T>, int> = 0>
std::uint32_t ReadRecordDataEx(std::uint32_t& a_length, T (&a_buf)[N]) const
{
a_length -= sizeof(T);
return ReadRecordData(std::addressof(a_buf), sizeof(T) * N);
}
[[nodiscard]] std::optional<std::uint64_t> ResolveHandle(std::uint64_t a_handle) const
{
std::uint64_t result{ 0 };
if (GetProxy().ResolveHandle(a_handle, std::addressof(result))) {
return result;
} else {
return std::nullopt;
}
}
[[nodiscard]] std::optional<std::uint32_t> ResolveFormID(std::uint32_t a_formID) const
{
std::uint32_t result{ 0 };
if (GetProxy().ResolveFormID(a_formID, std::addressof(result))) {
return result;
} else {
return std::nullopt;
}
}
};
class PapyrusInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SEPapyrusInterface&>(*this);
}
public:
enum : std::uint32_t
{
kVersion = 2
};
using RegisterFunctions = bool F4SEAPI(RE::BSScript::IVirtualMachine* a_vm);
using RegistrantFunctor = void F4SEAPI(std::uint64_t a_handle, const char* a_scriptName, const char* a_callbackName, void* a_data);
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
bool Register(RegisterFunctions* a_callback) const;
void GetExternalEventRegistrations(std::string_view a_eventName, void* a_data, RegistrantFunctor* a_functor) const
{
GetProxy().GetExternalEventRegistrations(a_eventName.data(), a_data, reinterpret_cast<void*>(a_functor));
}
};
class ITaskDelegate
{
public:
virtual ~ITaskDelegate() noexcept = default;
virtual void Run() = 0;
};
class TaskInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SETaskInterface&>(*this);
}
class TaskDelegate :
public ITaskDelegate
{
public:
explicit TaskDelegate(std::function<void()> a_task) noexcept :
_impl(std::move(a_task))
{}
void Run() override { _impl(); }
private:
std::function<void()> _impl;
};
public:
enum
{
kVersion = 2
};
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
void AddTask(ITaskDelegate* a_task) const { GetProxy().AddTask(a_task); }
void AddTask(std::function<void()> a_task) const { AddTask(new TaskDelegate(std::move(a_task))); }
void AddUITask(ITaskDelegate* a_task) const { GetProxy().AddUITask(a_task); }
void AddUITask(std::function<void()> a_task) const { AddUITask(new TaskDelegate(std::move(a_task))); }
void AddTaskPermanent(ITaskDelegate* a_task) const { GetProxy().AddTaskPermanent(a_task); }
void AddTaskPermanent(std::function<void()> a_task) const { AddTaskPermanent(new TaskDelegate(std::move(a_task))); }
};
class ObjectInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SEObjectInterface&>(*this);
}
public:
enum
{
kVersion = 1
};
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
[[nodiscard]] DelayFunctorManager& GetDelayFunctorManager() const { return GetProxy().GetDelayFunctorManager(); }
[[nodiscard]] ObjectRegistry& GetObjectRegistry() const { return GetProxy().GetObjectRegistry(); }
[[nodiscard]] PersistentObjectStorage& GetPersistentObjectStorage() const { return GetProxy().GetPersistentObjectStorage(); }
};
class TrampolineInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SETrampolineInterface&>(*this);
}
public:
enum
{
kVersion = 1
};
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
[[nodiscard]] void* AllocateFromBranchPool(std::size_t a_size) const;
[[nodiscard]] void* AllocateFromLocalPool(std::size_t a_size) const;
};
struct PluginInfo
{
enum : std::uint32_t
{
kVersion = 1
};
std::uint32_t infoVersion;
const char* name;
std::uint32_t version;
};
struct PluginVersionData
{
enum Version : std::uint32_t
{
kVersion = 1
};
constexpr void PluginVersion(const REL::Version a_version) noexcept { pluginVersion = a_version.pack(); }
[[nodiscard]] constexpr REL::Version GetPluginVersion() const noexcept { return REL::Version::unpack(pluginVersion); }
constexpr void PluginName(const std::string_view a_plugin) noexcept { SetCharBuffer(a_plugin, std::span{ pluginName }); }
[[nodiscard]] constexpr std::string_view GetPluginName() const noexcept { return std::string_view{ pluginName }; }
constexpr void AuthorName(const std::string_view a_name) noexcept { SetCharBuffer(a_name, std::span{ author }); }
[[nodiscard]] constexpr std::string_view GetAuthorName() const noexcept { return std::string_view{ author }; }
constexpr void UsesSigScanning(const bool a_value) noexcept { SetOrClearBit(addressIndependence, 1 << 0, a_value); }
// 1 << 2 is for address library for 1.11.137 and later
constexpr void UsesAddressLibrary(const bool a_value) noexcept { SetOrClearBit(addressIndependence, 1 << 2, a_value); }
constexpr void HasNoStructUse(const bool a_value) noexcept { SetOrClearBit(structureIndependence, 1 << 0, a_value); }
// 1 << 2 is for runtime 1.11.137 and later
constexpr void IsLayoutDependent(const bool a_value) noexcept { SetOrClearBit(structureIndependence, 1 << 2, a_value); }
constexpr void CompatibleVersions(std::initializer_list<REL::Version> a_versions) noexcept
{
// must be zero-terminated
assert(a_versions.size() < std::size(compatibleVersions) - 1);
std::ranges::transform(a_versions, std::begin(compatibleVersions), [](const REL::Version& a_version) noexcept {
return a_version.pack();
});
}
constexpr void MinimumRequiredXSEVersion(const REL::Version a_version) noexcept { xseMinimum = a_version.pack(); }
[[nodiscard]] static const PluginVersionData* GetSingleton() noexcept;
const std::uint32_t dataVersion{ kVersion };
std::uint32_t pluginVersion = 0;
char pluginName[256] = {};
char author[256] = {};
std::uint32_t addressIndependence;
std::uint32_t structureIndependence;
std::uint32_t compatibleVersions[16] = {};
std::uint32_t xseMinimum = 0;
const std::uint32_t reservedNonBreaking = 0;
const std::uint32_t reservedBreaking = 0;
const std::uint8_t reserved[512] = {};
private:
static constexpr void SetCharBuffer(std::string_view a_src, std::span<char> a_dst) noexcept
{
assert(a_src.size() < a_dst.size());
std::ranges::fill(a_dst, '\0');
std::ranges::copy(a_src, a_dst.begin());
}
static constexpr void SetOrClearBit(std::uint32_t& a_data, const std::uint32_t a_bit, const bool a_set) noexcept
{
if (a_set)
a_data |= a_bit;
else
a_data &= ~a_bit;
}
};
static_assert(offsetof(PluginVersionData, dataVersion) == 0x000);
static_assert(offsetof(PluginVersionData, pluginVersion) == 0x004);
static_assert(offsetof(PluginVersionData, pluginName) == 0x008);
static_assert(offsetof(PluginVersionData, author) == 0x108);
static_assert(offsetof(PluginVersionData, addressIndependence) == 0x208);
static_assert(offsetof(PluginVersionData, structureIndependence) == 0x20C);
static_assert(offsetof(PluginVersionData, compatibleVersions) == 0x210);
static_assert(offsetof(PluginVersionData, xseMinimum) == 0x250);
static_assert(offsetof(PluginVersionData, reservedNonBreaking) == 0x254);
static_assert(offsetof(PluginVersionData, reservedBreaking) == 0x258);
static_assert(offsetof(PluginVersionData, reserved) == 0x25C);
static_assert(sizeof(PluginVersionData) == 0x45C);
}
#define F4SE_EXPORT extern "C" [[maybe_unused]] __declspec(dllexport)
#define F4SE_PLUGIN_PRELOAD(...) F4SE_EXPORT bool F4SEPlugin_Preload(__VA_ARGS__)
#define F4SE_PLUGIN_LOAD(...) F4SE_EXPORT bool F4SEPlugin_Load(__VA_ARGS__)
#define F4SE_PLUGIN_VERSION F4SE_EXPORT constinit F4SE::PluginVersionData F4SEPlugin_Version
#define F4SEPluginPreload F4SE_PLUGIN_PRELOAD
#define F4SEPluginLoad F4SE_PLUGIN_LOAD
#define F4SEPluginVersion F4SE_PLUGIN_VERSION
@@ -0,0 +1,14 @@
#pragma once
#include "REL/Trampoline.h"
namespace F4SE
{
using Trampoline [[deprecated("Use REL::Trampoline instead")]] = REL::Trampoline;
// DEPRECATED
[[nodiscard, deprecated("Use REL::GetTrampoline instead")]] inline REL::Trampoline& GetTrampoline() noexcept
{
return REL::GetTrampoline();
}
}
@@ -0,0 +1,64 @@
#pragma once
namespace F4SE
{
inline constexpr REL::Version RUNTIME_1_1_29{ 1, 1, 29, 0 };
inline constexpr REL::Version RUNTIME_1_1_30{ 1, 1, 30, 0 };
inline constexpr REL::Version RUNTIME_1_2_0{ 1, 2, 0, 0 };
inline constexpr REL::Version RUNTIME_1_2_37{ 1, 2, 37, 0 };
inline constexpr REL::Version RUNTIME_1_3_45{ 1, 3, 45, 0 };
inline constexpr REL::Version RUNTIME_1_3_47{ 1, 3, 47, 0 };
inline constexpr REL::Version RUNTIME_1_4_124{ 1, 4, 124, 0 };
inline constexpr REL::Version RUNTIME_1_4_125{ 1, 4, 125, 0 };
inline constexpr REL::Version RUNTIME_1_4_131{ 1, 4, 131, 0 };
inline constexpr REL::Version RUNTIME_1_4_132{ 1, 4, 132, 0 };
inline constexpr REL::Version RUNTIME_1_5_141{ 1, 5, 141, 0 };
inline constexpr REL::Version RUNTIME_1_5_147{ 1, 5, 147, 0 };
inline constexpr REL::Version RUNTIME_1_5_151{ 1, 5, 151, 0 };
inline constexpr REL::Version RUNTIME_1_5_154{ 1, 5, 154, 0 };
inline constexpr REL::Version RUNTIME_1_5_157{ 1, 5, 157, 0 };
inline constexpr REL::Version RUNTIME_1_5_205{ 1, 5, 205, 0 };
inline constexpr REL::Version RUNTIME_1_5_210{ 1, 5, 210, 0 };
inline constexpr REL::Version RUNTIME_1_5_307{ 1, 5, 307, 0 };
inline constexpr REL::Version RUNTIME_1_5_412{ 1, 5, 412, 0 };
inline constexpr REL::Version RUNTIME_1_5_414{ 1, 5, 414, 0 };
inline constexpr REL::Version RUNTIME_1_5_416{ 1, 5, 416, 0 };
inline constexpr REL::Version RUNTIME_1_6_0{ 1, 6, 0, 0 };
inline constexpr REL::Version RUNTIME_1_6_3{ 1, 6, 3, 0 };
inline constexpr REL::Version RUNTIME_1_6_9{ 1, 6, 9, 0 };
inline constexpr REL::Version RUNTIME_1_7_7{ 1, 7, 7, 0 };
inline constexpr REL::Version RUNTIME_1_7_9{ 1, 7, 9, 0 };
inline constexpr REL::Version RUNTIME_1_7_10{ 1, 7, 10, 0 };
inline constexpr REL::Version RUNTIME_1_7_12{ 1, 7, 12, 0 };
inline constexpr REL::Version RUNTIME_1_7_15{ 1, 7, 15, 0 };
inline constexpr REL::Version RUNTIME_1_7_19{ 1, 7, 19, 0 };
inline constexpr REL::Version RUNTIME_1_7_22{ 1, 7, 22, 0 };
inline constexpr REL::Version RUNTIME_1_8_7{ 1, 8, 7, 0 };
inline constexpr REL::Version RUNTIME_1_9_4{ 1, 9, 4, 0 };
inline constexpr REL::Version RUNTIME_1_10_20{ 1, 10, 20, 0 };
inline constexpr REL::Version RUNTIME_1_10_26{ 1, 10, 26, 0 };
inline constexpr REL::Version RUNTIME_1_10_40{ 1, 10, 40, 0 };
inline constexpr REL::Version RUNTIME_1_10_50{ 1, 10, 50, 0 };
inline constexpr REL::Version RUNTIME_1_10_64{ 1, 10, 64, 0 };
inline constexpr REL::Version RUNTIME_1_10_75{ 1, 10, 75, 0 };
inline constexpr REL::Version RUNTIME_1_10_82{ 1, 10, 82, 0 };
inline constexpr REL::Version RUNTIME_1_10_89{ 1, 10, 89, 0 };
inline constexpr REL::Version RUNTIME_1_10_98{ 1, 10, 98, 0 };
inline constexpr REL::Version RUNTIME_1_10_106{ 1, 10, 106, 0 };
inline constexpr REL::Version RUNTIME_1_10_111{ 1, 10, 111, 0 };
inline constexpr REL::Version RUNTIME_1_10_114{ 1, 10, 114, 0 };
inline constexpr REL::Version RUNTIME_1_10_120{ 1, 10, 120, 0 };
inline constexpr REL::Version RUNTIME_1_10_130{ 1, 10, 130, 0 };
inline constexpr REL::Version RUNTIME_1_10_138{ 1, 10, 138, 0 };
inline constexpr REL::Version RUNTIME_1_10_162{ 1, 10, 162, 0 };
inline constexpr REL::Version RUNTIME_1_10_163{ 1, 10, 163, 0 };
inline constexpr REL::Version RUNTIME_1_10_980{ 1, 10, 980, 0 };
inline constexpr REL::Version RUNTIME_1_10_984{ 1, 10, 984, 0 };
inline constexpr REL::Version RUNTIME_1_11_137{ 1, 11, 137, 0 };
inline constexpr REL::Version RUNTIME_1_11_159{ 1, 11, 159, 0 };
inline constexpr REL::Version RUNTIME_1_11_169{ 1, 11, 169, 0 };
inline constexpr REL::Version RUNTIME_1_11_191{ 1, 11, 191, 0 };
inline constexpr REL::Version RUNTIME_1_11_221{ 1, 11, 221, 0 };
inline constexpr auto RUNTIME_LATEST = RUNTIME_1_11_221;
}
@@ -0,0 +1,13 @@
#pragma once
namespace RE
{
class ACTION_OBJECT
{
public:
// members
TESForm* form; // 00
std::uint32_t flags; // 08
};
static_assert(sizeof(ACTION_OBJECT) == 0x10);
}
@@ -0,0 +1,14 @@
#pragma once
namespace RE
{
enum class ACTOR_AGGRESSION : std::uint32_t
{
kCalmed = 0xFFFFFFFF,
kUnagressive = 0x0,
kAggressive = 0x1,
kVeryAggressive = 0x2,
kFrenzied = 0x3,
kMax = 0x3
};
}
@@ -0,0 +1,12 @@
#pragma once
namespace RE
{
enum class ACTOR_AGGRO_RADIUS : std::uint32_t
{
kWarn = 0x0,
kWarnAndAttack = 0x1,
kAttack = 0x2,
kCount = 0x3
};
}
@@ -0,0 +1,12 @@
#pragma once
namespace RE
{
enum class ACTOR_ASSISTANCE : std::uint32_t
{
kHelpsNobody = 0x0,
kHelpsAllies = 0x1,
kHelpsFriends = 0x2,
kCount = 0x3
};
}
@@ -0,0 +1,61 @@
#pragma once
namespace RE
{
class ACTOR_BASE_DATA
{
public:
enum class Flag
{
kNone = 0,
kFemale = 1 << 0,
kEssential = 1 << 1,
kIsChargenFacePreset = 1 << 2,
kRespawn = 1 << 3,
kAutoCalcStats = 1 << 4,
kUnique = 1 << 5,
kDoesntAffectStealthMeter = 1 << 6,
kPCLevelMult = 1 << 7,
kUsesTemplate = 1 << 8,
kProtected = 1 << 11,
kSummonable = 1 << 14,
kDoesntBleed = 1 << 16,
kBleedoutOverride = 1 << 18,
kOppositeGenderanims = 1 << 19,
kSimpleActor = 1 << 20,
kLoopedScript = 1 << 21, // ?
kLoopedAudio = 1 << 28, // ?
kIsGhost = 1 << 29,
kInvulnerable = 1 << 31
};
enum class TEMPLATE_USE_FLAG
{
kNone = 0,
kTraits = 1 << 0,
kStats = 1 << 1,
kFactions = 1 << 2,
kSpells = 1 << 3,
kAIData = 1 << 4,
kAIPackages = 1 << 5,
kUnused = 1 << 6,
kBaseData = 1 << 7,
kInventory = 1 << 8,
kScript = 1 << 9,
kAIDefPackList = 1 << 10,
kAttackData = 1 << 11,
kKeywords = 1 << 12
};
// members
REX::TEnumSet<Flag, std::uint32_t> actorBaseFlags; // 00
std::int16_t xpValueOffset; // 04
std::uint16_t level; // 06
std::uint16_t calcLevelMin; // 08
std::uint16_t calcLevelMax; // 0A
std::uint16_t baseDisposition; // 0C
REX::TEnumSet<TEMPLATE_USE_FLAG, std::uint16_t> templateUseFlags; // 0E
std::int16_t bleedoutOverride; // 10
};
static_assert(sizeof(ACTOR_BASE_DATA) == 0x14);
}
@@ -0,0 +1,11 @@
#pragma once
namespace RE
{
enum class ACTOR_COMBAT_STATE : std::int32_t
{
kNone = 0x0,
kCombat = 0x1,
kSearching = 0x2
};
}
@@ -0,0 +1,14 @@
#pragma once
namespace RE
{
enum class ACTOR_CONFIDENCE : std::uint32_t
{
kCowardly = 0x0,
kCautious = 0x1,
kAverage = 0x2,
kBrave = 0x3,
kFoolhardy = 0x4,
kCount = 0x5
};
}
@@ -0,0 +1,15 @@
#pragma once
namespace RE
{
enum class ACTOR_CRITICAL_STAGE : std::int32_t
{
kNone = 0x0,
kGooStart = 0x1,
kGooEnd = 0x2,
kDisintegrateStart = 0x3,
kDisintegrateEnd = 0x4,
kFreezeStart = 0x5,
kFreezeEnd = 0x6,
};
}
@@ -0,0 +1,17 @@
#pragma once
namespace RE
{
enum class ACTOR_LIFE_STATE : std::int32_t
{
kAlive = 0x0,
kDying = 0x1,
kDead = 0x2,
kUnconscious = 0x3,
kReanimate = 0x4,
kRecycle = 0x5,
kRestrained = 0x6,
kEssentialDown = 0x7,
kBleedout = 0x8
};
}
@@ -0,0 +1,14 @@
#pragma once
namespace RE
{
enum class ACTOR_LOS_LOCATION : std::int32_t
{
kNone = 0x0,
kEye = 0x1,
kHead = 0x2,
kTorse = 0x3,
kFeet = 0x4,
kCount = 0x5
};
}
@@ -0,0 +1,13 @@
#pragma once
namespace RE
{
enum class ACTOR_MOVEMENT_TYPE : std::uint32_t
{
kWalk = 0x0,
kRun = 0x1,
kSneak = 0x2,
kBleedout = 0x3,
kSwim = 0x4
};
}
@@ -0,0 +1,15 @@
#pragma once
namespace RE
{
enum class ACTOR_STANCE : std::uint32_t
{
kNormal = 0x0,
kSneaking = 0x1,
kCoverVeryLow = 0x2,
kCoverLow = 0x3,
kCoverMid = 0x4,
kCoverHigh = 0x5,
kCount = 0x6
};
}
@@ -0,0 +1,11 @@
#pragma once
namespace RE
{
enum class ACTOR_VALUE_MODIFIER : std::int32_t
{
kPermanent = 0,
kTemporary = 1,
kDamage = 2
};
}
@@ -0,0 +1,12 @@
#pragma once
namespace RE
{
enum class ACTOR_VISIBILITY_MASK : std::uint32_t
{
kFrustrum = 1 << 0,
kOcclusion = 1 << 1,
kFaded = 1 << 2,
kAll = kFrustrum | kOcclusion | kFaded,
};
}
@@ -0,0 +1,13 @@
#pragma once
namespace RE
{
class ADDON_DATA
{
public:
// members
std::uint16_t masterParticleCap; // 0
std::int8_t flags; // 2
};
static_assert(sizeof(ADDON_DATA) == 0x4);
}
@@ -0,0 +1,20 @@
#pragma once
namespace RE
{
class AIDATA_GAME
{
public:
// members
std::uint32_t aggression: 2; // 00:00
std::uint32_t confidence: 3; // 00:02
std::uint32_t energy: 8; // 00:05
std::uint32_t morality: 2; // 00:13
std::uint32_t unused: 3; // 00:15
std::uint32_t assistance: 2; // 00:18
std::uint32_t useAggroRadius: 1; // 00:20
std::uint16_t aggroRadius[3]; // 04
std::uint32_t noSlowApproach: 1; // 0A:00
};
static_assert(sizeof(AIDATA_GAME) == 0x10);
}
@@ -0,0 +1,21 @@
#pragma once
namespace RE
{
namespace AIFormulas
{
inline float GetBarterValue(float a_baseValue, float a_charisma, bool a_selling, TESObjectREFR* a_refTarget)
{
using func_t = decltype(&AIFormulas::GetBarterValue);
static REL::Relocation<func_t> func{ ID::AIFormulas::GetBarterValue };
return func(a_baseValue, a_charisma, a_selling, a_refTarget);
}
inline std::uint32_t ComputePickpocketSuccess(float a_thiefSkill, float a_targetSkill, std::int32_t a_valueStolen, float a_weightStolen, Actor* a_thief, Actor* a_target, TESForm* a_itemPickpocketing, bool a_placingItem)
{
using func_t = decltype(&AIFormulas::ComputePickpocketSuccess);
static REL::Relocation<func_t> func{ ID::AIFormulas::ComputePickpocketSuccess };
return func(a_thiefSkill, a_targetSkill, a_valueStolen, a_weightStolen, a_thief, a_target, a_itemPickpocketing, a_placingItem);
}
}
}
@@ -0,0 +1,219 @@
#pragma once
#include "RE/A/AITimer.h"
#include "RE/A/ActorPackage.h"
#include "RE/B/BGSEquipIndex.h"
#include "RE/B/BGSObjectInstance.h"
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSSimpleList.h"
#include "RE/D/DEFAULT_OBJECT.h"
#include "RE/N/NiPoint3.h"
namespace RE
{
enum class COMMAND_TYPE;
enum class DIALOGUE_SUBTYPE;
enum class DIALOGUE_TYPE;
enum class WEAPON_CULL_TYPE;
class CachedValues;
class HighProcessData;
class MiddleHighProcessData;
class MiddleLowProcessData;
class ObjectstoAcquire;
class AIProcess
{
public:
enum class FADE_STATE
{
kNormal = 0x0,
kIn = 0x1,
kOut = 0x2,
kTeleportIn = 0x3,
kTeleportOut = 0x4,
kOutDisable = 0x5,
kOutDelete = 0x6
};
enum class HEAD_TRACK_TYPE
{
kDefault = 0x0,
kAction = 0x1,
kCombat = 0x2,
kDialog = 0x3,
kScript = 0x4,
kProcedure = 0x5,
kTotal = 0x6
};
[[nodiscard]] TESAmmo* GetCurrentAmmo(BGSEquipIndex a_equipIndex) const
{
using func_t = decltype(&AIProcess::GetCurrentAmmo);
static REL::Relocation<func_t> func{ ID::AIProcess::GetCurrentAmmo };
return func(this, a_equipIndex);
}
COMMAND_TYPE GetCommandType()
{
using func_t = decltype(&AIProcess::GetCommandType);
static REL::Relocation<func_t> func{ ID::AIProcess::GetCommandType };
return func(this);
}
[[nodiscard]] ObjectRefHandle GetOccupiedFurniture()
{
using func_t = decltype(&AIProcess::GetOccupiedFurniture);
static REL::Relocation<func_t> func{ ID::AIProcess::GetOccupiedFurniture };
return func(this);
}
bool IsWeaponSubgraphFinishedLoading(const Actor& a_actor)
{
using func_t = decltype(&AIProcess::IsWeaponSubgraphFinishedLoading);
static REL::Relocation<func_t> func{ ID::AIProcess::IsWeaponSubgraphFinishedLoading };
return func(this, a_actor);
}
void KnockExplosion(Actor* a_actor, const NiPoint3& a_location, float a_magnitude)
{
using func_t = decltype(&AIProcess::KnockExplosion);
static REL::Relocation<func_t> func{ ID::AIProcess::KnockExplosion };
return func(this, a_actor, a_location, a_magnitude);
}
bool PlayIdle(Actor& a_actor, TESIdleForm* a_idle, TESObjectREFR* a_target)
{
return SetupSpecialIdle(a_actor, DEFAULT_OBJECT::kActionIdle, a_idle, true, a_target);
}
bool ProcessGreet(Actor* a_actor, DIALOGUE_TYPE a_type, DIALOGUE_SUBTYPE a_subType, TESObjectREFR* a_target, BGSDialogueBranch* a_branch, bool a_forceSub, bool a_stop, bool a_que, bool a_sayCallback)
{
using func_t = decltype(&AIProcess::ProcessGreet);
static REL::Relocation<func_t> func{ ID::AIProcess::ProcessGreet };
return func(this, a_actor, a_type, a_subType, a_target, a_branch, a_forceSub, a_stop, a_que, a_sayCallback);
}
bool RequestLoadAnimationsForWeaponChange(Actor& a_actor)
{
using func_t = decltype(&AIProcess::RequestLoadAnimationsForWeaponChange);
static REL::Relocation<func_t> func{ ID::AIProcess::RequestLoadAnimationsForWeaponChange };
return func(this, a_actor);
}
void SetActorsDetectionEvent(Actor* a_actor, const NiPoint3& a_location, std::int32_t a_soundLevel, TESObjectREFR* a_refr)
{
using func_t = decltype(&AIProcess::SetActorsDetectionEvent);
static REL::Relocation<func_t> func{ ID::AIProcess::SetActorsDetectionEvent };
return func(this, a_actor, a_location, a_soundLevel, a_refr);
}
void SetCurrentAmmo(BGSEquipIndex a_equipIndex, TESAmmo* a_ammo)
{
using func_t = decltype(&AIProcess::SetCurrentAmmo);
static REL::Relocation<func_t> func{ ID::AIProcess::SetCurrentAmmo };
return func(this, a_equipIndex, a_ammo);
}
void SetCommandType(COMMAND_TYPE a_type)
{
using func_t = decltype(&AIProcess::SetCommandType);
static REL::Relocation<func_t> func{ ID::AIProcess::SetCommandType };
return func(this, a_type);
}
void SetEquippedItem(Actor* a_actor, const BGSObjectInstance& a_instance, const BGSEquipSlot* a_slot)
{
using func_t = decltype(&AIProcess::SetEquippedItem);
static REL::Relocation<func_t> func{ ID::AIProcess::SetEquippedItem };
return func(this, a_actor, a_instance, a_slot);
}
bool SetupSpecialIdle(Actor& a_actor, DEFAULT_OBJECT a_defaultObject, TESIdleForm* a_idle, bool a_testConditions, TESObjectREFR* a_targetOverride)
{
using func_t = decltype(&AIProcess::SetupSpecialIdle);
static REL::Relocation<func_t> func{ ID::AIProcess::SetupSpecialIdle };
return func(this, a_actor, a_defaultObject, a_idle, a_testConditions, a_targetOverride);
}
bool SetWeaponBonesCulled(const Actor& a_actor, bool a_stateToSet, WEAPON_CULL_TYPE a_weaponCullType)
{
using func_t = decltype(&AIProcess::SetWeaponBonesCulled);
static REL::Relocation<func_t> func{ ID::AIProcess::SetWeaponBonesCulled };
return func(this, a_actor, a_stateToSet, a_weaponCullType);
}
void StopCurrentIdle(Actor* a_actor, bool a_instant, bool a_killFlavor)
{
using func_t = decltype(&AIProcess::StopCurrentIdle);
static REL::Relocation<func_t> func{ ID::AIProcess::StopCurrentIdle };
return func(this, a_actor, a_instant, a_killFlavor);
}
void SetRunOncePackage(TESPackage* a_package, Actor* a_actor)
{
using func_t = decltype(&AIProcess::SetRunOncePackage);
static REL::Relocation<func_t> func{ ID::AIProcess::SetRunOncePackage };
return func(this, a_package, a_actor);
}
void AddToProcedureIndexRunning(Actor* a_actor, std::int32_t a_number)
{
using func_t = decltype(&AIProcess::AddToProcedureIndexRunning);
static REL::Relocation<func_t> func{ ID::AIProcess::AddToProcedureIndexRunning };
return func(this, a_actor, a_number);
}
void ComputeLastTimeProcessed()
{
using func_t = decltype(&AIProcess::ComputeLastTimeProcessed);
static REL::Relocation<func_t> func{ ID::AIProcess::ComputeLastTimeProcessed };
return func(this);
}
float GetActorLightLevel()
{
using func_t = decltype(&AIProcess::GetActorLightLevel);
static REL::Relocation<func_t> func{ ID::AIProcess::GetActorLightLevel };
return func(this);
}
// members
MiddleLowProcessData* middleLow; // 00
MiddleHighProcessData* middleHigh; // 08
HighProcessData* high; // 10
ActorPackage currentPackage; // 18
float hourLastProcessed; // 48
float timeAdjustmentsMade; // 4C
std::uint32_t dateLastProcessed; // 50
CachedValues* cachedValues; // 58
std::int32_t numberItemsActivate; // 60
BSSimpleList<ObjectstoAcquire*> objectList; // 68
BSSimpleList<TESObjectREFR*> genericLocationsList; // 78
ObjectstoAcquire* acquireObject; // 88
ObjectstoAcquire* savedAcquireObject; // 90
float essentialDownTimer; // 98
float deathTime; // 9C
float trackedDamage; // A0
TESBoundObject* itemBeingUsed; // A8
AITimer combatDelayTimer; // B0
ObjectRefHandle followTarget; // B8
ObjectRefHandle target; // BC
ObjectRefHandle genericLocation; // C0
ObjectRefHandle genericSecondLocation; // C4
BGSListForm* targetFormList; // C8
std::uint32_t currentSpeakingTopicID; // D0
ObjectRefHandle patrolLocation; // D4
ObjectRefHandle idleTarget; // D8
std::int16_t formListNumb; // DC
std::uint8_t lowProcessFlags; // DE
std::uint8_t processLevel; // DF
bool skippedTimeStampForPathing; // E0
bool ignoringCombat; // E1
bool endAlarmOnActor; // E2
bool escortingPlayer; // E3
bool updateEditorDeadModel; // E4
bool editorDeadActive; // E5
bool initializingPosition; // E6
};
static_assert(sizeof(AIProcess) == 0xE8);
}
@@ -0,0 +1,12 @@
#pragma once
namespace RE
{
class AITimeStamp
{
public:
// members
float timeStamp; // 0
};
static_assert(sizeof(AITimeStamp) == 0x4);
}
@@ -0,0 +1,19 @@
#pragma once
namespace RE
{
class AITimer
{
public:
static float fTimer()
{
static REL::Relocation<float*> singleton{ ID::AITimer::fTimer };
return *singleton;
}
// members
float startTime; // 00
float targetTime; // 04
};
static_assert(sizeof(AITimer) == 0x8);
}
@@ -0,0 +1,15 @@
#pragma once
namespace RE
{
class AMMO_DATA
{
public:
// members
BGSProjectile* projectile; // 00
std::uint32_t health; // 08
std::int8_t flags; // 0C
float damage; // 10
};
static_assert(sizeof(AMMO_DATA) == 0x18);
}
@@ -0,0 +1,41 @@
#pragma once
#include "RE/N/NiPointer.h"
namespace RE
{
class __declspec(novtable) ActionInput
{
public:
static constexpr auto RTTI{ RTTI::ActionInput };
static constexpr auto VTABLE{ VTABLE::ActionInput };
enum class ACTIONPRIORITY
{
kImperative = 0x0,
kQueue = 0x1,
kTry = 0x2
};
class Data
{
public:
union
{
float f;
std::int32_t i;
std::uint32_t ui;
}; //00
};
virtual ~ActionInput(); // 00
// members
NiPointer<TESObjectREFR> ref; // 08
NiPointer<TESObjectREFR> targetRef; // 10
BGSAction* action; // 18
REX::TEnumSet<ACTIONPRIORITY, std::uint32_t> priority; // 20
Data ActionData; // 24
};
static_assert(sizeof(ActionInput) == 0x28);
}
@@ -0,0 +1,28 @@
#pragma once
#include "RE/B/BSFixedString.h"
namespace RE
{
class TESIdleForm;
class ActionOutput
{
public:
static constexpr auto RTTI{ RTTI::ActionOutput };
enum class ACTION_RESULTS : std::uint32_t
{
kNotAllowed = 0xFFFFFFFF
};
// members
BSFixedString animEvent; // 00
BSFixedString targetAnimEvent; // 08
std::int32_t result; // 10
TESIdleForm* sequence; // 18
const TESIdleForm* animObjIdle; // 20
std::uint32_t sequenceIndex; // 28;
};
static_assert(sizeof(ActionOutput) == 0x30);
}
@@ -0,0 +1,27 @@
#pragma once
namespace RE
{
class ActionPoints
{
public:
enum class Action
{
kUnarmed = 0x0,
kOneHandMelee = 0x1,
kTwoHandMelee = 0x2,
kMagic = 0x3,
kRanged = 0x4,
kReload = 0x5,
kSwitchWeapon = 0x6,
kToggleWeaponDrawn = 0x7,
kHeal = 0x8,
kPlayerVATSDeath = 0x9,
kPlayerDialogue = 0xA,
kSightedEnter = 0xB,
kTotal = 0xC
};
};
static_assert(std::is_empty_v<ActionPoints>);
}
@@ -0,0 +1,84 @@
#pragma once
#include "RE/A/ActiveEffectReferenceEffectController.h"
#include "RE/B/BSIntrusiveRefCounted.h"
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSSimpleList.h"
#include "RE/B/BSSoundHandle.h"
#include "RE/E/ENUM_FORM_ID.h"
#include "RE/N/NiPointer.h"
namespace RE
{
class MagicTarget;
class NiNode;
class ReferenceEffect;
namespace MagicSystem
{
enum class CastingSource : std::int32_t;
}
class __declspec(novtable) ActiveEffect :
public BSIntrusiveRefCounted
{
public:
static constexpr auto RTTI{ RTTI::ActiveEffect };
static constexpr auto VTABLE{ VTABLE::ActiveEffect };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kActiveEffect };
enum class Flags : std::uint32_t
{
kNone = 0,
kNoHitShader = 1U << 1,
kNoHitEffectArt = 1U << 2,
kNoInitialFlare = 1U << 4,
kApplyingHitEffects = 1U << 5,
kApplyingSounds = 1U << 6,
kHasConditions = 1U << 7,
kRecover = 1U << 9,
kDualCasted = 1U << 12,
kInactive = 1U << 15,
kAppliedEffects = 1U << 16,
kRemovedEffects = 1U << 17,
kDispelled = 1U << 18,
kWornOff = 1U << 31
};
enum class ConditionStatus : std::uint32_t
{
kNotAvailable = 0xFFFFFFFF,
kFalse = 0,
kTrue = 1
};
virtual ~ActiveEffect();
bool CheckDisplacementSpellOnTarget()
{
using func_t = decltype(&ActiveEffect::CheckDisplacementSpellOnTarget);
static REL::Relocation<func_t> func{ ID::ActiveEffect::CheckDisplacementSpellOnTarget };
return func(this);
}
// members
ActiveEffectReferenceEffectController hitEffectController; // 0C
BSSoundHandle persistentSound; // 30
ActorHandle caster; // 38
NiPointer<NiNode> sourceNode; // 40
MagicItem* spell; // 48
EffectItem* effect; // 50
MagicTarget* target; // 58
TESBoundObject* source; // 60
BSSimpleList<ReferenceEffect*>* hitEffects; // 68
MagicItem* displacementSpell; // 70
float elapsedSeconds; // 74
float duration; // 78
float magnitude; // 7C
REX::TEnumSet<Flags, std::uint32_t> flags; // 80
ConditionStatus conditionStatus; // 84
std::uint16_t uniqueID; // 8C
MagicSystem::CastingSource castingSource; // 90
};
static_assert(sizeof(ActiveEffect) == 0x98);
}
@@ -0,0 +1,16 @@
#pragma once
#include "RE/B/BSTArray.h"
#include "RE/B/BSTSmartPointer.h"
namespace RE
{
class ActiveEffectList
{
public:
// members
BSTArray<BSTSmartPointer<ActiveEffect>> data; // 00
std::int8_t iterating; // 18
};
static_assert(sizeof(ActiveEffectList) == 0x20);
}
@@ -0,0 +1,46 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/B/BSPointerHandle.h"
#include "RE/N/NiPoint3.h"
#include "RE/R/ReferenceEffectController.h"
namespace RE
{
class __declspec(novtable) ActiveEffectReferenceEffectController :
public ReferenceEffectController // 00
{
public:
static constexpr auto RTTI{ RTTI::ActiveEffectReferenceEffectController };
static constexpr auto VTABLE{ VTABLE::ActiveEffectReferenceEffectController };
// override (ReferenceEffectController)
void HandleEvent(const BSFixedString& a_event) override; // 01 - return { effect->HandleEvent(a_event); }
float GetElapsedTime() override; // 02 - return { effect->elapsedSeconds; }
float GetScale() override; // 03
void SwitchAttachedRoot(NiNode* a_root, NiNode* a_attachRoot) override; // 04 - return { effect->SwitchAttachedRoot(a_root, a_attachRoot); }
const NiPoint3& GetSourcePosition() override; // 05
bool GetUseSourcePosition() override; // 06
bool GetNoInitialFlare() override; // 07
bool GetEffectPersists() override; // 08
bool GetGoryVisuals() override; // 09
void RemoveHitEffect(ReferenceEffect* a_refEffect) override; // 0A
TESObjectREFR* GetTargetReference() override; // 0B
BGSArtObject* GetHitEffectArt() override; // 0C
TESEffectShader* GetHitEffectShader() override; // 0D
bool GetManagerHandlesSaveLoad() override; // 0E - { return false; }
bool EffectShouldFaceTarget() override; // 17
TESObjectREFR* GetFacingTarget() override; // 18
void SetWindPoint(const NiPoint3& a_point) override; // 1E - { windPoint = a_point; }
const NiPoint3& GetWindPoint() override; // 1F - { return windPoint; }
bool GetAllowNo3D() override; // 20
void SaveGame(BGSSaveGameBuffer* a_buf) override; // 21
void LoadGame(BGSLoadGameBuffer* a_buf) override; // 22
// members
ActiveEffect* effect; // 08
NiPoint3 windPoint; // 10
ObjectRefHandle target; // 18
};
static_assert(sizeof(ActiveEffectReferenceEffectController) == 0x20);
}
+674
View File
@@ -0,0 +1,674 @@
#pragma once
#include "RE/A/ACTOR_VISIBILITY_MASK.h"
#include "RE/A/AIProcess.h"
#include "RE/A/AITimeStamp.h"
#include "RE/A/ActorState.h"
#include "RE/A/ActorValueStorage.h"
#include "RE/B/BGSEquipIndex.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTEvent.h"
#include "RE/B/BSTSmartPointer.h"
#include "RE/C/CFilter.h"
#include "RE/I/IPostAnimationChannelUpdateFunctor.h"
#include "RE/M/MagicTarget.h"
#include "RE/M/Modifiers.h"
#include "RE/N/NiPoint3.h"
#include "RE/N/NiTFlags.h"
#include "RE/O/ObjectEquipParams.h"
#include "RE/S/SEX.h"
#include "RE/T/TESObjectREFR.h"
namespace RE
{
enum class ACTOR_CRITICAL_STAGE;
enum class ACTOR_LIFE_STATE;
enum class ACTOR_LOS_LOCATION;
enum class GUN_STATE;
enum class PACKAGE_OBJECT_TYPE;
enum class POWER_ATTACK_TYPE;
template <class>
class BSPointerHandleSmartPointer;
class ActorCPMEvent;
class ActorMagicCaster;
class ActorMotionFeedbackData;
class ActorMotionFeedbackOutput;
class ActorMover;
class bhkCharacterController;
class bhkCharacterMoveFinishEvent;
class bhkCharacterStateChangeEvent;
class bhkNonSupportContactEvent;
class BSMovementDataChangedEvent;
class BSSubGraphActivationUpdate;
class BSTransformDeltaEvent;
class CastPowerItem;
class CombatController;
class CombatGroup;
class DetectionData;
class HitData;
class MovementControllerNPC;
class MovementMessageActorCollision;
class MovementMessageNewPath;
class MovementMessageUpdateRequestImmediate;
class PackageLocation;
class PerkEntryVisitor;
class Perks;
namespace MagicSystem
{
enum class CannotCastReason;
}
namespace PerkValueEvents
{
class PerkEntryUpdatedEvent;
class PerkValueChangedEvent;
}
class __declspec(novtable) Actor :
public TESObjectREFR, // 000
public MagicTarget, // 110
public ActorState, // 128
public BSTEventSink<BSMovementDataChangedEvent>, // 138
public BSTEventSink<BSTransformDeltaEvent>, // 140
public BSTEventSink<BSSubGraphActivationUpdate>, // 148
public BSTEventSink<bhkCharacterMoveFinishEvent>, // 150
public BSTEventSink<bhkNonSupportContactEvent>, // 158
public BSTEventSink<bhkCharacterStateChangeEvent>, // 160
public IPostAnimationChannelUpdateFunctor, // 168
public BSTEventSource<MovementMessageUpdateRequestImmediate>, // 170
public BSTEventSource<PerkValueEvents::PerkValueChangedEvent>, // 1C8
public BSTEventSource<PerkValueEvents::PerkEntryUpdatedEvent>, // 220
public BSTEventSource<ActorCPMEvent> // 278
{
public:
static constexpr auto RTTI{ RTTI::Actor };
static constexpr auto VTABLE{ VTABLE::Actor };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kACHR };
enum class BOOL_FLAGS
{
kNone = 0,
kScenePackage = 1 << 0,
kIsAMount = 1 << 1,
kIsMountPointClear = 1 << 2,
kIsGettingOnOffMount = 1 << 3,
kInRandomScene = 1 << 4,
kNoBleedoutRecovery = 1 << 5,
kInBleedoutAnimation = 1 << 6,
kCanDoFavor = 1 << 7,
kShouldAnimGraphUpdate = 1 << 8,
kCanSpeakToEssentialDown = 1 << 9,
kBribedByPlayer = 1 << 10,
kAngryWithPlayer = 1 << 11,
kIsTresspassing = 1 << 12,
kCanSpeak = 1 << 13,
kIsInKillMove = 1 << 14,
kAttackOnSight = 1 << 15,
kIsCommandedActor = 1 << 16,
kForceOneAnimGraphUpdate = 1 << 17,
kEssential = 1 << 18,
kProtected = 1 << 19,
kAttackingDisabled = 1 << 20,
kCastingDisabled = 1 << 21,
kSceneHeadtrackRotation = 1 << 22,
kForceIncMinBoneUpdate = 1 << 23,
kCrimeSearch = 1 << 24,
kMovingIntoLoadedArea = 1 << 25,
kDoNotShowOnStealthMeter = 1 << 26,
kMovementBlocked = 1 << 27,
kAllowInstantFurniturePopInPlayerCell = 1 << 28,
kForceAnimGraphUpdate = 1 << 29,
kCheckAddEffectDualCast = 1 << 30,
kUnderwater = 1 << 31,
};
// add
virtual void PlayPickUpSound(TESBoundObject* a_boundObj, bool a_pickUp, bool a_use); // 0C6
virtual float GetHeading() const { return data.angle.z; } // 0C7
virtual void SetAvoidanceDisabled([[maybe_unused]] bool a_tf) { return; } // 0C8
virtual void DrawWeaponMagicHands(bool a_draw); // 0C9
virtual void SetPosition(const NiPoint3& a_pos, bool a_updateCharController); // 0CA
virtual void KillDying(); // 0CB
virtual void Resurrect(bool a_resetInventory, bool a_attach3D); // 0CC
virtual bool PutActorInChairBedQuick(TESObjectREFR* a_furniture, std::uint32_t a_index); // 0CD
virtual bool PutActorOnMountQuick(); // 0CE
virtual void Update(float a_delta); // 0CF
virtual void UpdateNoAI(float); // 0D0
virtual void UpdateMotionDrivenState(); // 0D1
virtual void UpdateCharacterControllerSimulationSettings(bhkCharacterController& a_charController); // 0D2
virtual void PotentiallyFixRagdollState(); // 0D3
virtual void UpdateNonRenderSafe(float); // 0D4
virtual bool ShouldHandleEquipNow() const; // 0D5
virtual void SetCrimeGoldValue(TESFaction* a_faction, bool a_violent, std::uint32_t a_value); // 0D6
virtual std::uint32_t ModCrimeGoldValue(TESFaction* a_faction, bool a_violent, std::int32_t a_value); // 0D7
virtual void RemoveCrimeGoldValue(TESFaction* a_faction, bool a_violent, std::int32_t a_value); // 0D8
virtual std::uint32_t GetCrimeGoldValue(const TESFaction* a_faction) const; // 0D9
virtual void GoToPrison([[maybe_unused]] TESFaction* a_faction, [[maybe_unused]] bool a_removeItems, [[maybe_unused]] bool a_realJail) { return; } // 0DA
virtual void ServePrisonTime() { return; } // 0DB
virtual void PayFine([[maybe_unused]] TESFaction* a_faction, [[maybe_unused]] bool a_movetoMarker, [[maybe_unused]] bool a_removeStolenItems) { return; } // 0DC
virtual float GetCurrentEyeLevel() const; // 0DD
virtual void SetInDialoguewithPlayer(bool a_flag); // 0DE
virtual bool GetCannibal() { return false; } // 0DF
virtual void SetCannibal(bool) { return; } // 0E0
virtual bool GetVampireFeed() { return false; } // 0E1
virtual void SetVampireFeed(bool) { return; } // 0E2
virtual void InitiateVampireFeedPackage(Actor* a_target, TESObjectREFR* a_furniture); // 0E3
virtual void InitiateCannibalPackage(Actor* a_target); // 0E4
virtual float GetEyeHeading() const; // 0E5
virtual void GetEyeAngles(float& a_eyeHeading, float& a_eyeLooking) const; // 0E6
virtual void GetEyeVector(NiPoint3& a_origin, NiPoint3& a_direction, bool a_includeCameraOffset) const; // 0E7
virtual void SetRefraction(bool a_enable, float a_refractionPower); // 0E8
virtual float GetAcrobatics() const { return 1.0F; } // 0E9
virtual bool Get3DUpdateFlag(RESET_3D_FLAGS a_flag) const; // 0EA
virtual ObjectRefHandle DropObject(const BGSObjectInstance& a_object, BSTSmallArray<std::uint32_t, 4>* a_stackData, std::int32_t a_number, const NiPoint3* a_point, const NiPoint3* a_rotate); // 0EB
virtual void PickUpObject(TESObjectREFR* a_objREFR, std::int32_t a_count, bool a_playPickUpSounds); // 0EC
virtual void AttachArrow(const BSTSmartPointer<BipedAnim>& a_biped, BGSEquipIndex a_equipIndex); // 0ED
virtual void DetachArrow(const BSTSmartPointer<BipedAnim>& a_biped, BGSEquipIndex a_equipIndex); // 0EE
virtual bool ReloadWeapon(const BGSObjectInstanceT<TESObjectWEAP>& a_weapon, BGSEquipIndex a_equipIndex); // 0EF
virtual std::uint32_t UseAmmo(const BGSObjectInstanceT<TESObjectWEAP>& a_weapon, BGSEquipIndex a_equipIndex, std::uint32_t a_shotCount); // 0F0
virtual bool CalculateCachedOwnerIsInCombatantFaction() const; // 0F1
virtual CombatGroup* GetCombatGroup() const; // 0F2
virtual void SetCombatGroup(CombatGroup* a_group); // 0F3
virtual bool CheckValidTarget(TESObjectREFR& a_ref) const; // 0F4
virtual bool InitiateDialogue(Actor* a_target, PackageLocation* a_packLoc, PackageLocation* a_packSecondLoc); // 0F5
virtual void EndDialogue(); // 0F6
virtual Actor* SetUpTalkingActivatorActor(Actor* a_target, Actor*& a_talkingactivator); // 0F7
virtual void InitiateFlee(TESObjectREFR* a_fleeRef, bool a_runonce, bool a_knows, bool a_combatMode, TESObjectCELL* a_cell, TESObjectREFR* a_ref, float a_fleeFromDist, float a_fleeToDist); // 0F8
virtual void InitiateGetUpPackage(); // 0F9
virtual void PutCreatedPackage(TESPackage* a_pack, bool a_tempPack, bool a_isACreatedPackage, bool a_allowFromFurniture); // 0FA
virtual void UpdateAlpha(); // 0FB
virtual void SetAlpha(float a_newAlpha); // 0FC
virtual float GetAlpha(); // 0FD
virtual bool IsInCombat() const; // 0FE
virtual void UpdateCombat(); // 0FF
virtual void StopCombat(); // 100
virtual bool GetUsesAttackPercents() { return false; } // 101
virtual std::uint8_t GetPowerAttackPercent(POWER_ATTACK_TYPE) { return 0; } // 102
virtual void WeaponSwingCallBack(BGSEquipIndex a_equipIndex); // 103
virtual void SetActorStartingPosition(); // 104
virtual void SetLifeState(ACTOR_LIFE_STATE a_lifeState); // 105
virtual bool HasBeenAttacked(); // 106
virtual void SetBeenAttacked(bool a_flag); // 107
virtual void UseSkill(ActorValueInfo*, float, TESForm*) { return; } // 108
virtual bool IsAtPoint(const NiPoint3& a_point, float a_radius, bool a_expandRadius, bool a_alwaysTestHeight); // 109
virtual bool IsInFaction(const TESFaction* a_faction) const; // 10A
virtual bool HasPerkEntries(std::uint8_t a_entryPoint) const; // 10B
virtual void ForEachPerkEntry(std::uint8_t a_entryPoint, PerkEntryVisitor& a_visitor) const; // 10C
virtual void ApplyPerksFromBase(); // 10D
virtual void StartPowerAttackCoolDown() { return; } // 10E
virtual bool IsPowerAttackCoolingDown() const { return false; } // 10F
virtual void HandleHealthDamage(Actor* a_attacker, float a_damage); // 110
virtual bool QSpeakingDone() const; // 111
virtual void SetSpeakingDone(bool a_done); // 112
virtual NiPoint3 CalculateLOSLocation(ACTOR_LOS_LOCATION a_location) const; // 113
virtual void CreateMovementController(); // 114
virtual bool ShouldPivotToFaceCamera() const { return false; } // 115
virtual BGSKeyword* GetSpeakingAnimArchType() { return speakingAnimArchType; } // 116
virtual void KillImpl(Actor* a_attacker, float a_damage, bool a_sendEvent, bool a_ragdollInstant); // 117
virtual void DoReparentWeapon(const TESObjectWEAP* a_weapon, BGSEquipIndex a_equipIndex, bool a_weaponDrawn); // 118
virtual bool DrinkPotion(AlchemyItem* a_potion, std::uint32_t a_stackID); // 119
virtual bool CheckCast(MagicItem* a_spell, bool a_dualCast, MagicSystem::CannotCastReason* a_reason); // 11A
virtual void CheckTempModifiers() { return; } // 11B
virtual void SetLastRiddenMount([[maybe_unused]] ActorHandle a_mount) { return; } // 11C
virtual ActorHandle QLastRiddenMount() const; // 11D
virtual bool CalculateCachedOwnerIsUndead() const; // 11E
virtual bool CalculateCachedOwnerIsNPC() const; // 11F
virtual bool SetSneaking(bool a_sneaking); // 120
virtual void ResetHavokPhysics(); // 121
virtual bool ShouldDoCharacterUpdate() const { return true; } // 122
virtual bool GetAnimationCanBeInterpolated() const; // 123
virtual const BSFixedString& GetResponseString() const; // 124
virtual void ModifyMovementData(float a_delta, NiPoint3& a_moveDelta, NiPoint3& a_angleDelta); // 125
virtual void UpdateCombatControllerSettings(); // 126
virtual void UpdateFadeSettings(bhkCharacterController* a_charController); // 127
virtual bool ComputeMotionFeedbackSpeedAndDirection(const ActorMotionFeedbackData& a_data, float a_delta, ActorMotionFeedbackOutput& a_retData); // 128
virtual bool UpdateFeedbackGraphSpeedAndDirection(const ActorMotionFeedbackOutput& a_data); // 129
virtual void UpdateActor3DPosition(); // 12A
virtual void PrecacheData(); // 12B
virtual void WornArmorChanged(const BGSObjectInstance& a_object); // 12C
virtual void ProcessTracking(float a_delta, NiAVObject* a_ob3D); // 12D
virtual void CreateActorMover(); // 12E
virtual void DestroyActorMover(); // 12F
virtual bool ShouldRespondToActorCollision(const MovementMessageActorCollision&, const BSPointerHandleSmartPointer<BSPointerHandleManagerInterface<Actor, HandleManager>>& a_otherActor) const; // 130
virtual float CheckClampDamageModifier(ActorValueInfo& a_info, float a_delta); // 131
virtual void ValidateNewPath([[maybe_unused]] const MovementMessageNewPath& a_newPathMessage) { return; } // 132
void AddPerk(BGSPerk* a_perk, std::uint8_t a_rank = 0)
{
using func_t = decltype(&Actor::AddPerk);
static REL::Relocation<func_t> func{ ID::Actor::AddPerk };
return func(this, a_perk, a_rank);
}
bool CanUseIdle(TESIdleForm* a_idle) const
{
using func_t = decltype(&Actor::CanUseIdle);
static REL::Relocation<func_t> func{ ID::Actor::CanUseIdle };
return func(this, a_idle);
}
void ClearAttackStates()
{
using func_t = decltype(&Actor::ClearAttackStates);
static REL::Relocation<func_t> func{ ID::Actor::ClearAttackStates };
return func(this);
}
void EndInterruptPackage(bool a_notRunOnceDialogue)
{
using func_t = decltype(&Actor::EndInterruptPackage);
static REL::Relocation<func_t> func{ ID::Actor::EndInterruptPackage };
return func(this, a_notRunOnceDialogue);
}
void ExitCover()
{
using func_t = decltype(&Actor::ExitCover);
static REL::Relocation<func_t> func{ ID::Actor::ExitCover };
return func(this);
}
void GetAimVector(NiPoint3& a_aimVector)
{
using func_t = decltype(&Actor::GetAimVector);
static REL::Relocation<func_t> func{ ID::Actor::GetAimVector };
return func(this, a_aimVector);
}
NiAVObject* GetClosestBone(NiPoint3 a_impactLocation, NiPoint3 a_movementDirection)
{
using func_t = decltype(&Actor::GetClosestBone);
static REL::Relocation<func_t> func{ ID::Actor::GetClosestBone };
return func(this, a_impactLocation, a_movementDirection);
}
CFilter GetCollisionFilter()
{
using func_t = decltype(&Actor::GetCollisionFilter);
static REL::Relocation<func_t> func{ ID::Actor::GetCollisionFilter };
return func(this);
}
TESCombatStyle* GetCombatStyle()
{
using func_t = decltype(&Actor::GetCombatStyle);
static REL::Relocation<func_t> func{ ID::Actor::GetCombatStyle };
return func(this);
}
[[nodiscard]] TESAmmo* GetCurrentAmmo(BGSEquipIndex a_equipIndex) const
{
return currentProcess ? currentProcess->GetCurrentAmmo(a_equipIndex) : nullptr;
}
std::uint32_t GetCurrentCollisionGroup()
{
using func_t = decltype(&Actor::GetCurrentCollisionGroup);
static REL::Relocation<func_t> func{ ID::Actor::GetCurrentCollisionGroup };
return func(this);
}
bool GetCurrentFireLocation(BGSEquipIndex a_index, NiPoint3& a_fireLocation)
{
using func_t = decltype(&Actor::GetCurrentFireLocation);
static REL::Relocation<func_t> func{ ID::Actor::GetCurrentFireLocation };
return func(this, a_index, a_fireLocation);
}
float GetDesiredSpeed()
{
using func_t = decltype(&Actor::GetDesiredSpeed);
static REL::Relocation<func_t> func{ ID::Actor::GetDesiredSpeed };
return func(this);
}
bool GetGhost()
{
using func_t = decltype(&Actor::GetGhost);
static REL::Relocation<func_t> func{ ID::Actor::GetGhost };
return func(this);
}
[[nodiscard]] bool GetHostileToActor(Actor* a_actor)
{
using func_t = decltype(&Actor::GetHostileToActor);
static REL::Relocation<func_t> func{ ID::Actor::GetHostileToActor };
return func(this, a_actor);
}
[[nodiscard]] ActorHandle GetMountHandle()
{
using func_t = decltype(&Actor::GetMountHandle);
static REL::Relocation<func_t> func{ ID::Actor::GetMountHandle };
return func(this);
}
[[nodiscard]] std::int16_t GetLevel()
{
using func_t = decltype(&Actor::GetLevel);
static REL::Relocation<func_t> func{ ID::Actor::GetLevel };
return func(this);
}
[[nodiscard]] TESNPC* GetNPC() const noexcept;
[[nodiscard]] std::uint8_t GetPerkRank(BGSPerk* a_perk)
{
using func_t = decltype(&Actor::GetPerkRank);
static REL::Relocation<func_t> func{ ID::Actor::GetPerkRank };
return func(this, a_perk);
}
SEX GetSex()
{
using func_t = decltype(&Actor::GetSex);
static REL::Relocation<func_t> func{ ID::Actor::GetSex };
return func(this);
}
void HandleDefaultAnimationSwitch()
{
using func_t = decltype(&Actor::HandleDefaultAnimationSwitch);
static REL::Relocation<func_t> func{ ID::Actor::HandleDefaultAnimationSwitch };
return func(this);
}
void HandleItemEquip(bool bCullBone)
{
using func_t = decltype(&Actor::HandleItemEquip);
static REL::Relocation<func_t> func{ ID::Actor::HandleItemEquip };
return func(this, bCullBone);
}
bool HasObjects(TESBoundObject* a_obj, PACKAGE_OBJECT_TYPE a_formID, std::int32_t a_number, std::uint32_t a_id, PACKAGE_OBJECT_TYPE& a_matchID)
{
using func_t = decltype(&Actor::HasObjects);
static REL::Relocation<func_t> func{ ID::Actor::HasObjects };
return func(this, a_obj, a_formID, a_number, a_id, a_matchID);
}
void InitiateDoNothingPackage()
{
using func_t = decltype(&Actor::InitiateDoNothingPackage);
static REL::Relocation<func_t> func{ ID::Actor::InitiateDoNothingPackage };
return func(this);
}
bool IsCrippled()
{
using func_t = decltype(&Actor::IsCrippled);
static REL::Relocation<func_t> func{ ID::Actor::IsCrippled };
return func(this);
}
bool IsFollowing()
{
using func_t = decltype(&Actor::IsFollowing);
static REL::Relocation<func_t> func{ ID::Actor::IsFollowing };
return func(this);
}
[[nodiscard]] bool IsJumping()
{
using func_t = decltype(&Actor::IsJumping);
static REL::Relocation<func_t> func{ ID::Actor::IsJumping };
return func(this);
}
bool IsPathValid()
{
using func_t = decltype(&Actor::IsPathValid);
static REL::Relocation<func_t> func{ ID::Actor::IsPathValid };
return func(this);
}
bool IsPathing()
{
using func_t = decltype(&Actor::IsPathing);
static REL::Relocation<func_t> func{ ID::Actor::IsPathing };
return func(this);
}
bool IsPathingComplete()
{
using func_t = decltype(&Actor::IsPathingComplete);
static REL::Relocation<func_t> func{ ID::Actor::IsPathingComplete };
return func(this);
}
bool IsQuadruped()
{
using func_t = decltype(&Actor::IsQuadruped);
static REL::Relocation<func_t> func{ ID::Actor::IsQuadruped };
return func(this);
}
bool IsSneaking()
{
using func_t = decltype(&Actor::IsSneaking);
static REL::Relocation<func_t> func{ ID::Actor::IsSneaking };
return func(this);
}
bool IsVisible() const
{
constexpr auto all = std::to_underlying(ACTOR_VISIBILITY_MASK::kAll);
return ((visFlags & all) & 0xF) == all;
}
bhkCharacterController* Move(float a_deltaTime, NiPoint3 a_deltaPos, bool a_defer)
{
using func_t = decltype(&Actor::Move);
static REL::Relocation<func_t> func{ ID::Actor::Move };
return func(this, a_deltaTime, a_deltaPos, a_defer);
}
bool PerformAction(BGSAction* a_action, TESObjectREFR* a_target)
{
using func_t = decltype(&Actor::PerformAction);
static REL::Relocation<func_t> func{ ID::Actor::PerformAction };
return func(this, a_action, a_target);
}
void RemovePerk(BGSPerk* a_perk)
{
using func_t = decltype(&Actor::RemovePerk);
static REL::Relocation<func_t> func{ ID::Actor::RemovePerk };
return func(this, a_perk);
}
void Reset3D(bool a_reloadAll, std::uint32_t a_additionalFlags, bool a_queueReset, std::uint32_t a_excludeFlags)
{
using func_t = decltype(&Actor::Reset3D);
static REL::Relocation<func_t> func{ ID::Actor::Reset3D };
return func(this, a_reloadAll, a_additionalFlags, a_queueReset, a_excludeFlags);
}
void RewardExperience(float a_amount, bool a_direct, TESObjectREFR* a_actionTarget, TESObjectREFR* a_killWeapon)
{
using func_t = decltype(&Actor::RewardExperience);
static REL::Relocation<func_t> func{ ID::Actor::RewardExperience };
return func(this, a_amount, a_direct, a_actionTarget, a_killWeapon);
}
void SetCurrentAmmo(BGSEquipIndex a_equipIndex, TESAmmo* a_ammo)
{
if (currentProcess) {
currentProcess->SetCurrentAmmo(a_equipIndex, a_ammo);
}
}
void SetCurrentAmmoCount(BGSEquipIndex a_equipIndex, std::uint32_t a_count)
{
using func_t = decltype(&Actor::SetCurrentAmmoCount);
static REL::Relocation<func_t> func{ ID::Actor::SetCurrentAmmoCount };
return func(this, a_equipIndex, a_count);
}
void SetGunState(GUN_STATE a_gunState, bool a_val = true)
{
using func_t = decltype(&Actor::SetGunState);
static REL::Relocation<func_t> func{ ID::Actor::SetGunState };
return func(this, a_gunState, a_val);
}
void SetHeading(float a_angle)
{
using func_t = decltype(&Actor::SetHeading);
static REL::Relocation<func_t> func{ ID::Actor::SetHeading };
return func(this, a_angle);
}
void TrespassAlarm(TESObjectREFR* a_refr, TESForm* a_owner, std::int32_t a_crime)
{
using func_t = decltype(&Actor::TrespassAlarm);
static REL::Relocation<func_t> func{ ID::Actor::TrespassAlarm };
return func(this, a_refr, a_owner, a_crime);
}
void UpdateVoiceTimer(bool a_force)
{
using func_t = decltype(&Actor::UpdateVoiceTimer);
static REL::Relocation<func_t> func{ ID::Actor::UpdateVoiceTimer };
return func(this, a_force);
}
BGSBodyPartData* GetBodyPartData()
{
using func_t = decltype(&Actor::GetBodyPartData);
static REL::Relocation<func_t> func{ ID::Actor::GetBodyPartData };
return func(this);
}
BGSObjectInstance* GetEquippedItem(BGSObjectInstance* a_result, BGSEquipIndex a_equipIndex)
{
using func_t = decltype(&Actor::GetEquippedItem);
static REL::Relocation<func_t> func{ ID::Actor::GetEquippedItem };
return func(this, a_result, a_equipIndex);
}
TESFaction* GetCrimeTrackingFaction()
{
using func_t = decltype(&Actor::GetCrimeTrackingFaction);
static REL::Relocation<func_t> func{ ID::Actor::GetCrimeTrackingFaction };
return func(this);
}
void ForceDetect(Actor* a_target, bool a_forceLOS, float a_time)
{
using func_t = decltype(&Actor::ForceDetect);
static REL::Relocation<func_t> func{ ID::Actor::ForceDetect };
return func(this, a_target, a_forceLOS, a_time);
}
void UnequipObject(TESBoundObject* a_object, ObjectEquipParams a_params)
{
using func_t = decltype(&Actor::UnequipObject);
static REL::Relocation<func_t> func{ ID::Actor::UnequipObject };
return func(this, a_object, a_params);
}
void UpdateSprinting()
{
using func_t = decltype(&Actor::UpdateSprinting);
static REL::Relocation<func_t> func{ ID::Actor::UpdateSprinting };
return func(this);
}
std::uint8_t GetMobilityCrippled()
{
using func_t = decltype(&Actor::GetMobilityCrippled);
static REL::Relocation<func_t> func{ ID::Actor::GetMobilityCrippled };
return func(this);
}
void SPECIALModifiedCallback(const ActorValueInfo* a_info, float a_originalValue, float a_delta)
{
using func_t = decltype(&Actor::SPECIALModifiedCallback);
static REL::Relocation<func_t> func{ ID::Actor::SPECIALModifiedCallback };
return func(this, a_info, a_originalValue, a_delta);
}
void StopInteractingQuick(bool a_instance, bool a_moveActor, bool a_update3D)
{
using func_t = decltype(&Actor::StopInteractingQuick);
static REL::Relocation<func_t> func{ ID::Actor::StopInteractingQuick };
return func(this, a_instance, a_moveActor, a_update3D);
}
void CalculateDetectionFormula(Actor* a_target, DetectionData* a_detectionData)
{
using func_t = decltype(&Actor::CalculateDetectionFormula);
static REL::Relocation<func_t> func{ ID::Actor::CalculateDetectionFormula };
return func(this, a_target, a_detectionData);
}
void DoHitMe(const HitData* a_data)
{
using func_t = decltype(&Actor::DoHitMe);
static REL::Relocation<func_t> func{ ID::Actor::DoHitMe };
return func(this, a_data);
}
// members
NiTFlags<std::uint32_t, Actor> niFlags; // 2D0
float updateTargetTimer; // 2D4
NiPoint3 editorLocCoord; // 2D8
NiPoint3 editorLocRot; // 2E4
TESForm* editorLocForm; // 2F0
BGSLocation* editorLocation; // 2F8
AIProcess* currentProcess; // 300
ActorMover* actorMover; // 308
BGSKeyword* speakingAnimArchType; // 310
BSTSmartPointer<MovementControllerNPC> movementController; // 318
TESPackage* initialPackage; // 320
CombatController* combatController; // 328
TESFaction* vendorFaction; // 330
ActorValueStorage avStorage; // 338
BGSDialogueBranch* exclusiveBranch; // 370
REX::TEnumSet<ACTOR_CRITICAL_STAGE, std::int32_t> criticalStage; // 378
ObjectRefHandle dialogueItemTarget; // 37C
ActorHandle currentCombatTarget; // 380
ActorHandle myKiller; // 384
float checkMyDeadBodyTimer; // 388
float voiceTimer; // 38C
float voiceLengthTotal; // 390
float underWaterTimer; // 394
std::int32_t thiefCrimeStamp; // 398
std::int32_t actionValue; // 39C
float timeronAction; // 3A0
AITimeStamp calculateVendorFactionTimer; // 3A4
std::uint32_t intimidateBribeDayStamp; // 3A8
float equippedWeight; // 3AC
BSTSmallArray<SpellItem*> addedSpells; // 3B0
ActorMagicCaster* magicCasters[4]; // 3C8
MagicItem* selectedSpell[4]; // 3E8
CastPowerItem* castPowerItems; // 408
TESForm* selectedPower; // 410
TESRace* race; // 418
Perks* perks; // 420
BSTSmartPointer<BipedAnim> biped; // 428
BSNonReentrantSpinLock addingToOrRemovingFromScene; // 430
BSReadWriteLock perkArrayLock; // 434
REX::TEnumSet<BOOL_FLAGS, std::uint32_t> boolFlags; // 43C
std::uint32_t moreFlags; // 440
Modifiers healthModifiers; // 444
Modifiers actionPointsModifiers; // 450
Modifiers staminaModifiers; // 45C
Modifiers radsModifiers; // 468
float lastUpdate; // 474
std::uint32_t lastSeenTime; // 478
float armorRating; // 47C
float armorBaseFactorSum; // 480
std::uint32_t visFlags: 4; // 484:00
std::int8_t raceSwitchPending: 1; // 488:0
std::int8_t soundCallBackSet; // 489
bool trespassing; // 48A
};
static_assert(sizeof(Actor) == 0x490);
}
@@ -0,0 +1,82 @@
#pragma once
#include "RE/B/BSTEvent.h"
#include "RE/B/BSTSingleton.h"
namespace RE
{
class BGSEquipSlot;
class BGSObjectInstance;
class EquippedItem;
namespace ActorEquipManagerEvent
{
class Event;
}
class ActorEquipManager :
public BSTSingletonSDM<ActorEquipManager>, // 00
public BSTEventSource<ActorEquipManagerEvent::Event> // 08
{
public:
enum class CanEquipResult
{
kSuccess = 0x0,
kInvalidItem = 0x1,
kNoModEquip = 0x2,
kPAWhileNotInPA = 0x3,
kNonPAWhileInPA = 0x4,
kEquipStateLocked = 0x5,
kItemBroken = 0x6,
kNoEquipKeyword = 0x7
};
[[nodiscard]] static ActorEquipManager* GetSingleton()
{
static REL::Relocation<ActorEquipManager**> singleton{ ID::ActorEquipManager::Singleton };
return *singleton;
}
bool EquipObject(
Actor* a_actor,
const BGSObjectInstance& a_object,
std::uint32_t a_stackID,
std::uint32_t a_number,
const BGSEquipSlot* a_slot,
bool a_queueEquip,
bool a_forceEquip,
bool a_playSounds,
bool a_applyNow,
bool a_locked)
{
using func_t = decltype(&ActorEquipManager::EquipObject);
static REL::Relocation<func_t> func{ ID::ActorEquipManager::EquipObject };
return func(this, a_actor, a_object, a_stackID, a_number, a_slot, a_queueEquip, a_forceEquip, a_playSounds, a_applyNow, a_locked);
}
bool UnequipObject(
Actor* a_actor,
const BGSObjectInstance* a_object,
std::uint32_t a_number,
const BGSEquipSlot* a_slot,
std::uint32_t a_stackID,
bool a_queueEquip,
bool a_forceEquip,
bool a_playSounds,
bool a_applyNow,
const BGSEquipSlot* a_slotBeingReplaced)
{
using func_t = decltype(&ActorEquipManager::UnequipObject);
static REL::Relocation<func_t> func{ ID::ActorEquipManager::UnequipObject };
return func(this, a_actor, a_object, a_number, a_slot, a_stackID, a_queueEquip, a_forceEquip, a_playSounds, a_applyNow, a_slotBeingReplaced);
}
void UnequipItem(Actor* a_actor, const EquippedItem* a_equippedItem, bool a_queueEquip)
{
using func_t = decltype(&ActorEquipManager::UnequipItem);
static REL::Relocation<func_t> func{ ID::ActorEquipManager::UnequipItem };
return func(this, a_actor, a_equippedItem, a_queueEquip);
}
};
static_assert(sizeof(ActorEquipManager) == 0x60);
}
@@ -0,0 +1,26 @@
#pragma once
namespace RE
{
class BGSObjectInstance;
namespace ActorEquipManagerEvent
{
enum class Type : std::int32_t
{
kEquip = 0x0,
kUnequip = 0x1
};
class Event
{
public:
// members
REX::TEnumSet<Type, std::uint16_t> changeType; // 00
const BGSObjectInstance* itemAffected; // 08
Actor* actorAffected; // 10
std::uint32_t stackID; // 18
};
static_assert(sizeof(Event) == 0x20);
}
}
@@ -0,0 +1,16 @@
#pragma once
namespace RE
{
namespace ActorItemEquipped
{
class Event
{
public:
// members
const TESBoundObject* item; // 00
const Actor* equipper; // 08
};
static_assert(sizeof(Event) == 0x10);
}
}
@@ -0,0 +1,16 @@
#pragma once
namespace RE
{
namespace ActorKill
{
class Event
{
public:
// members
const Actor* killer;
const Actor* victim;
};
static_assert(sizeof(Event) == 0x10);
}
}
@@ -0,0 +1,18 @@
#pragma once
#include "RE/N/NiPoint3.h"
namespace RE
{
class ActorMotionFeedbackData
{
public:
// members
NiPoint3 desiredWorldDelta; // 00
NiPoint3 actualWorldDelta; // 0C
float previousSpeed; // 18
float previousDirection; // 1C
float currentHeading; // 20
};
static_assert(sizeof(ActorMotionFeedbackData) == 0x24);
}
@@ -0,0 +1,16 @@
#pragma once
#include "RE/M/MovementData.h"
#include "RE/M/MovementTweenerOutputData.h"
namespace RE
{
class ActorMovementData
{
public:
// members
MovementData handlerData; // 00
MovementTweenerOutputData tweenerData; // 30
};
static_assert(sizeof(ActorMovementData) == 0x50);
}
@@ -0,0 +1,26 @@
#pragma once
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSSpinLock.h"
namespace RE
{
class ActorPackageData;
class ActorPackage
{
public:
// members
BSSpinLock packageLock; // 00
TESPackage* package; // 08
ActorPackageData* data; // 10
ObjectRefHandle target; // 18
std::int32_t currentProcedureIndex; // 1C
float packageStartTime; // 20
std::uint32_t modifiedPackageFlag; // 24
std::uint16_t modifiedInterruptFlag; // 28
std::int8_t actorPackageFlags; // 2A
std::int8_t preferredSpeed; // 2B
};
static_assert(sizeof(ActorPackage) == 0x30);
}
@@ -0,0 +1,30 @@
#pragma once
#include "RE/P/PTYPE.h"
namespace RE
{
class ActorPackageLoadFormBuffer;
class BGSSaveFormBuffer;
class IProcedureTreeExecState;
class __declspec(novtable) ActorPackageData
{
public:
static constexpr auto RTTI{ RTTI::ActorPackageData };
static constexpr auto VTABLE{ VTABLE::ActorPackageData };
virtual ~ActorPackageData(); // 00
// add
virtual PTYPE GetPackageType() = 0; // 01
virtual IProcedureTreeExecState* GetProcedureExecState() { return nullptr; } // 02
virtual void SetProcedureExecState([[maybe_unused]] IProcedureTreeExecState& a_procedureExecState) { return; } // 03
virtual void ClearProcedureExecState() { return; } // 04
virtual void SaveGame(BGSSaveFormBuffer* a_saveGameBuffer) = 0; // 05
virtual void LoadGame(ActorPackageLoadFormBuffer* a_loadGameBuffer) = 0; // 06
virtual void InitLoadGame([[maybe_unused]] ActorPackageLoadFormBuffer* a_loadGameBuffer) { return; } // 07
virtual void ResetPackData([[maybe_unused]] TESPackage* a_pack) { return; } // 08
};
static_assert(sizeof(ActorPackageData) == 0x8);
}
@@ -0,0 +1,14 @@
#pragma once
namespace RE
{
class ActorStance
{
public:
// members
std::uint8_t stance; // 00
std::uint8_t stanceModifier; // 01
bool mirrored; // 02
};
static_assert(sizeof(ActorStance) == 0x03);
}
@@ -0,0 +1,58 @@
#pragma once
#include "RE/I/IMovementState.h"
#include "RE/W/WEAPON_STATE.h"
namespace RE
{
enum class GUN_STATE;
enum class INTERACTING_STATE;
enum class SIT_SLEEP_STATE;
class __declspec(novtable) ActorState :
public IMovementState // 00
{
public:
static constexpr auto RTTI{ RTTI::ActorState };
static constexpr auto VTABLE{ VTABLE::ActorState };
// add
virtual bool SetWeaponMagicDrawn(bool a_drawn); // 21
virtual bool SetWeaponState(WEAPON_STATE a_state); // 22
virtual bool DoSetSitSleepState(SIT_SLEEP_STATE a_state) = 0; // 23
virtual SIT_SLEEP_STATE DoGetSitSleepState() const = 0; // 24
virtual bool SetInIronSightsImpl(bool a_sighted) = 0; // 25
virtual void SetReloadingImpl(bool a_reloading); // 26
[[nodiscard]] bool GetWeaponMagicDrawn() const noexcept { return weaponState >= WEAPON_STATE::kDrawn; }
[[nodiscard]] bool IsSwimming() const noexcept { return DoGetMoveModeBits(0x400); }
// members
std::uint32_t moveMode: 14; // 08:00
std::uint32_t flyState: 3; // 08:14
std::uint32_t lifeState: 4; // 08:17
std::uint32_t knockState: 4; // 08:21
std::uint32_t meleeAttackState: 3; // 08:25
std::uint32_t talkingToPlayer: 1; // 08:28
std::uint32_t forceRun: 1; // 08:29
std::uint32_t forceSneak: 1; // 08:30
std::uint32_t headTracking: 1; // 08:31
std::uint32_t reanimating: 1; // 0C:00
WEAPON_STATE weaponState: 3; // 0C:01
std::uint32_t wantBlocking: 1; // 0C:04
std::uint32_t flightBlocked: 1; // 0C:05
std::uint32_t recoil: 2; // 0C:06
std::uint32_t allowFlying: 1; // 0C:08
std::uint32_t staggered: 1; // 0C:09
std::uint32_t inWrongProcessLevel: 1; // 0C:10
std::uint32_t stance: 3; // 0C:11
GUN_STATE gunState: 4; // 0C:14
INTERACTING_STATE interactingState: 2; // 0C:18
std::uint32_t headTrackRotation: 1; // 0C:20
std::uint32_t inSyncAnim: 1; // 0C:21
private:
bool DoGetMoveModeBits(std::uint16_t a_bits) const { return (a_bits & moveMode & 0x3FFF) == a_bits; }
};
static_assert(sizeof(ActorState) == 0x10);
}
@@ -0,0 +1,71 @@
#pragma once
#include "RE/B/BSTArray.h"
namespace RE
{
class BGSInventoryItem;
namespace ActorUtils
{
class __declspec(novtable) ArmorRatingVisitorBase
{
public:
static constexpr auto RTTI{ RTTI::ActorUtils__ArmorRatingVisitorBase };
static constexpr auto VTABLE{ VTABLE::ActorUtils__ArmorRatingVisitorBase };
ArmorRatingVisitorBase()
{
REX::EMPLACE_VTABLE(this);
}
ArmorRatingVisitorBase(const Actor* a_actor, bool a_checkEquipped)
{
ctor(a_actor, a_checkEquipped);
}
// add
virtual bool ShouldProcess(TESBoundObject*) { return 1; }; // 00
virtual void PostProcess(TESBoundObject*) {}; // 01
std::int64_t operator()(const BGSInventoryItem* a_item, std::uint32_t a_stackID)
{
using func_t = decltype(&ArmorRatingVisitorBase::operator());
static REL::Relocation<func_t> func{ ID::ActorUtils::ArmorRatingVisitorBase::_operator };
return func(this, a_item, a_stackID);
}
// members
Actor* actor; // 08
float rating; // 10
float armorPerks; // 14
bool checkEquipped; // 18
private:
void ctor(const Actor* a_actor, bool a_checkEquipped)
{
using func_t = decltype(&ArmorRatingVisitorBase::ctor);
static REL::Relocation<func_t> func{ ID::ActorUtils::ArmorRatingVisitorBase::ctor };
return func(this, a_actor, a_checkEquipped);
}
};
static_assert(sizeof(ArmorRatingVisitorBase) == 0x20);
class __declspec(novtable) ArmorRatingVisitor :
public ArmorRatingVisitorBase // 00
{
static constexpr auto RTTI{ RTTI::ActorUtils__ArmorRatingVisitor };
static constexpr auto VTABLE{ VTABLE::ActorUtils__ArmorRatingVisitor };
BSScrapArray<TESBoundObject*> foundArmor; // 20
};
static_assert(sizeof(ArmorRatingVisitor) == 0x40);
static inline float GetEquippedArmorDamageResistance(Actor* a_actor, const ActorValueInfo* a_info)
{
using func_t = decltype(ActorUtils::GetEquippedArmorDamageResistance);
static REL::Relocation<func_t> func{ ID::ActorUtils::GetEquippedArmorDamageResistance };
return func(a_actor, a_info);
}
}
}
@@ -0,0 +1,197 @@
#pragma once
#include "RE/B/BSTArray.h"
#include "RE/B/BSTSingleton.h"
namespace RE
{
class ActorValue :
public BSTSingletonImplicit<ActorValue> // 000
{
public:
enum class AVType
{
kDerivedAttribute = 0x0,
kAttribute = 0x1,
kSkill = 0x2,
kAIAttribute = 0x3,
kResistance = 0x4,
kCondition = 0x5,
kCharge = 0x6,
kIntValue = 0x7,
kVariable = 0x8,
kResource = 0x9
};
enum class Flags : std::int32_t
{
kDepreciated = 1 << 1,
kEnumeration = 1 << 2,
kNoScriptModAV = 1 << 3,
kCache = 1 << 4,
kCachePermenant = 1 << 5,
kAlwaysClamp = 1 << 6,
kImplicitBase0 = 1 << 10,
kImplicitBase1 = 1 << 11,
kImplicitBase100 = 1 << 12,
kUserDefined = 1 << 13,
kDerived = 1 << 15,
kBaseUseAutoCalc = 1 << 16,
kMin1 = 1 << 20,
kMax10 = 1 << 21,
kMax100 = 1 << 22,
kScaleBy100 = 1 << 23,
kPercentage = 1 << 24,
kDamageMinZero = 1 << 25,
kDamageIsPositive = 1 << 26,
kGodModeNoDamage = 1 << 27,
kDoesNotRecover = 1 << 28,
kHardcoded = 1 << 31,
};
[[nodiscard]] static ActorValue* GetSingleton()
{
using func_t = decltype(&ActorValue::GetSingleton);
static REL::Relocation<func_t> func{ ID::ActorValue::Singleton };
return func();
}
// members
ActorValueInfo* absorbChance; // 000
ActorValueInfo* actionPoints; // 008
ActorValueInfo* aggression; // 010
ActorValueInfo* agility; // 018
ActorValueInfo* aimStability; // 020
ActorValueInfo* alchemy; // 028
ActorValueInfo* animationMult; // 030
ActorValueInfo* armorPerks; // 038
ActorValueInfo* assistance; // 040
ActorValueInfo* attackDamageMult; // 048
ActorValueInfo* blindness; // 050
ActorValueInfo* block; // 058
ActorValueInfo* bloodyMess; // 060
ActorValueInfo* bowSpeedBonus; // 068
ActorValueInfo* bowStaggerBonus; // 070
ActorValueInfo* brainCondition; // 078
ActorValueInfo* carryWeight; // 080
ActorValueInfo* charisma; // 088
ActorValueInfo* combatHealthRegenMult; // 090
ActorValueInfo* confidence; // 098
ActorValueInfo* criticalChance; // 0A0
ActorValueInfo* damageResistance; // 0A8
ActorValueInfo* deafness; // 0B0
ActorValueInfo* enchanting; // 0B8
ActorValueInfo* endurance; // 0C0
ActorValueInfo* enduranceCondition; // 0C8
ActorValueInfo* experience; // 0D0
ActorValueInfo* health; // 0D8
ActorValueInfo* healRateMult; // 0E0
ActorValueInfo* idleChatterTimeMin; // 0E8
ActorValueInfo* idleChatterTimeMAx; // 0F0
ActorValueInfo* ignoreCrippledLimbs; // 0F8
ActorValueInfo* intelligence; // 100
ActorValueInfo* invisibility; // 108
ActorValueInfo* karma; // 110
ActorValueInfo* leftAttackCondition; // 118
ActorValueInfo* leftItemCharge; // 120
ActorValueInfo* leftMobiltyCondition; // 128
ActorValueInfo* leftWeaponSpeedMult; // 130
ActorValueInfo* lockpicking; // 138
ActorValueInfo* luck; // 140
ActorValueInfo* mass; // 148
ActorValueInfo* meleeDamage; // 150
ActorValueInfo* morality; // 158
ActorValueInfo* movementNoiseMult; // 160
ActorValueInfo* nightEyeBonus; // 168
ActorValueInfo* perception; // 170
ActorValueInfo* perceptionCondition; // 178
ActorValueInfo* pickpocket; // 180
ActorValueInfo* poisonResistance; // 188
ActorValueInfo* powerArmorBattery; // 190
ActorValueInfo* powerArmorHeadCondition; // 198
ActorValueInfo* powerArmorTorsoCondition; // 1A0
ActorValueInfo* powerArmorLeftArmCondition; // 1A8
ActorValueInfo* powerArmorRightArmCondition; // 1B0
ActorValueInfo* powerArmorLeftLegCondition; // 1B8
ActorValueInfo* powerArmorRightLegCondition; // 1C0
ActorValueInfo* radHealthMax; // 1C8
ActorValueInfo* rads; // 1D0
ActorValueInfo* fatigueAPMax; // 1D8
ActorValueInfo* fatigue; // 1E0
ActorValueInfo* reflectDamage; // 1E8
ActorValueInfo* restoreConditionRate; // 1F0
ActorValueInfo* rightAttackCondition; // 1F8
ActorValueInfo* rightItemCharge; // 200
ActorValueInfo* rightMobilityCondition; // 208
ActorValueInfo* rotationSpeedCondition; // 210
ActorValueInfo* shieldPerks; // 218
ActorValueInfo* shoutRecoveryMult; // 220
ActorValueInfo* sneak; // 228
ActorValueInfo* speechcraft; // 230
ActorValueInfo* speedMult; // 238
ActorValueInfo* stamina; // 240
ActorValueInfo* strength; // 248
ActorValueInfo* suspicious; // 250
ActorValueInfo* telekinesis; // 258
ActorValueInfo* unarmedDamage; // 260
ActorValueInfo* vansPerk; // 268
ActorValueInfo* wardPower; // 270
ActorValueInfo* waitingForPlayer; // 278
ActorValueInfo* waterBreathing; // 280
ActorValueInfo* waterWalking; // 288
ActorValueInfo* weaponSpeedMult; // 290
ActorValueInfo* weapReloadSpeedMult; // 298
ActorValueInfo* restoreHealthRate; // 2A0
ActorValueInfo* restoreAPRate; // 2A8
ActorValueInfo* apRateMult; // 2B0
ActorValueInfo* restoreRadsRate; // 2B8
ActorValueInfo* radsRateMult; // 2C0
ActorValueInfo* restoreFatigueRate; // 2C8
ActorValueInfo* fatigueRateMult; // 2D0
ActorValueInfo* conditionRateMult; // 2D8
ActorValueInfo* fireResistance; // 2E0
ActorValueInfo* electricalResistance; // 2E8
ActorValueInfo* frostResistance; // 2F0
ActorValueInfo* magicResistance; // 2F8
ActorValueInfo* radIngestionResistance; // 300
ActorValueInfo* radExposureResistance; // 308
ActorValueInfo* energy; // 310
ActorValueInfo* energyResistance; // 318
ActorValueInfo* paralysis; // 320
ActorValueInfo* attackConditionAlt1; // 328
ActorValueInfo* attackConditionAlt2; // 330
ActorValueInfo* attackConditionAlt3; // 338
ActorValueInfo* powerGenerated; // 340
ActorValueInfo* powerRadation; // 348
ActorValueInfo* powerRequired; // 350
ActorValueInfo* resourceFood; // 358
ActorValueInfo* resourceWater; // 360
ActorValueInfo* resourceSafety; // 368
ActorValueInfo* resourceBed; // 370
ActorValueInfo* resourceHappiness; // 378
ActorValueInfo* resourceArtillery; // 380
ActorValueInfo* workshopItemOverlap; // 388
ActorValueInfo* workshopItemClampDirection; // 390
ActorValueInfo* workshopItemZOffset; // 398
ActorValueInfo* workshopPlayerOwned; // 3A0
ActorValueInfo* workshopActorWounded; // 3A8
ActorValueInfo* workshopStackableItem; // 3B0
ActorValueInfo* workshopSnapPointRadius; // 3B8
ActorValueInfo* workshopAnythingIsGround; // 3C0
ActorValueInfo* workshopMaxTriangles; // 3C8
ActorValueInfo* workshopMaxDraws; // 3D0
ActorValueInfo* workshopCurrentTriangles; // 3D8
ActorValueInfo* workshopCurrentDraws; // 3E0
ActorValueInfo* workshopIgnoreSimpleIntersections; // 3E8
ActorValueInfo* workshopAllowUnsupportedStacking; // 3F0
ActorValueInfo* workshopSnapTransmitsPower; // 3F8
ActorValueInfo* workshopPowerConnection; // 400
ActorValueInfo* logicOperation; // 408
ActorValueInfo* logicOutput; // 410
ActorValueInfo* ignorePlayerWhileFrenzied; // 418
BSTArray<ActorValueInfo*> hardcodedActorValues; // 420
BSTArray<ActorValueInfo*> conditionActorValues; // 438
std::uint32_t avTypeCounts[10]; // 450
};
static_assert(sizeof(ActorValue) == 0x478);
}
@@ -0,0 +1,16 @@
#pragma once
namespace RE
{
namespace ActorValueEvents
{
class ActorValueChangedEvent
{
public:
// members
const ActorValueInfo& actorValue; // 00
TESObjectREFR* owner; // 08
};
static_assert(sizeof(ActorValueChangedEvent) == 0x10);
}
}
@@ -0,0 +1,45 @@
#pragma once
#include "RE/A/ActorValue.h"
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BSStringT.h"
#include "RE/T/TESDescription.h"
#include "RE/T/TESForm.h"
#include "RE/T/TESFullName.h"
namespace RE
{
class ActorValueOwner;
class __declspec(novtable) ActorValueInfo :
public TESForm, // 000
public TESFullName, // 020
public TESDescription // 030
{
public:
static constexpr auto RTTI{ RTTI::ActorValueInfo };
static constexpr auto VTABLE{ VTABLE::ActorValueInfo };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kAVIF };
using ModifiedCallback_t = void(Actor* a_actor, const ActorValueInfo& a_info, float a_originalValue, float a_delta, Actor* a_actorSource);
using DerivationFunction_t = float(const ActorValueOwner* a_actor, const ActorValueInfo& a_info);
// members
std::function<ModifiedCallback_t> modifiedCallback; // 048
BSString formEditorID; // 088
ActorValueInfo* dependentActorValues[15]; // 098
std::function<DerivationFunction_t> derivationFunction; // 110
const char* enumNames[10]; // 150
BGSLocalizedString abbreviation; // 1A0
std::int32_t oldActorValue; // 1A8
REX::TEnumSet<ActorValue::Flags, std::int32_t> flags; // 1AC
REX::TEnumSet<ActorValue::AVType, std::int32_t> avType; // 1B0
std::uint32_t numDependentActorValues; // 1B4
std::uint32_t enumCount; // 1B8
std::int32_t fullCacheIndex; // 1BC
std::int32_t permanentCacheIndex; // 1C0
float defaultValue; // 1C4
std::uint32_t sortIndex; // 1C8
};
static_assert(sizeof(ActorValueInfo) == 0x1D0);
}
@@ -0,0 +1,28 @@
#pragma once
namespace RE
{
enum class ACTOR_VALUE_MODIFIER;
class __declspec(novtable) ActorValueOwner
{
public:
static constexpr auto RTTI{ RTTI::ActorValueOwner };
static constexpr auto VTABLE{ VTABLE::ActorValueOwner };
virtual ~ActorValueOwner() = default; // 00
// add
virtual float GetActorValue([[maybe_unused]] const ActorValueInfo& a_info) const { return 0.0F; } // 01
virtual float GetPermanentActorValue([[maybe_unused]] const ActorValueInfo& a_info) const { return 0.0F; } // 02
virtual float GetBaseActorValue([[maybe_unused]] const ActorValueInfo& a_info) const { return 0.0F; } // 03
virtual void SetBaseActorValue([[maybe_unused]] const ActorValueInfo& a_info, [[maybe_unused]] float a_value) { return; } // 04
virtual void ModBaseActorValue([[maybe_unused]] const ActorValueInfo& a_info, [[maybe_unused]] float a_delta) { return; } // 05
virtual void ModActorValue([[maybe_unused]] ACTOR_VALUE_MODIFIER a_modifier, [[maybe_unused]] const ActorValueInfo& a_info, [[maybe_unused]] float a_delta) { return; } // 06
virtual float GetModifier([[maybe_unused]] ACTOR_VALUE_MODIFIER a_modifier, [[maybe_unused]] const ActorValueInfo& a_info) const { return 0.0F; } // 07
virtual void RestoreActorValue([[maybe_unused]] const ActorValueInfo& a_info, [[maybe_unused]] float a_amount) { return; } // 08
virtual void SetActorValue(const ActorValueInfo& a_info, float a_value) { SetBaseActorValue(a_info, a_value); } // 09
virtual bool GetIsPlayerOwner() const { return false; } // 0A
};
static_assert(sizeof(ActorValueOwner) == 0x8);
}
@@ -0,0 +1,19 @@
#pragma once
#include "RE/B/BSSpinLock.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTTuple.h"
#include "RE/M/Modifiers.h"
namespace RE
{
class ActorValueStorage
{
public:
// members
BSTArray<BSTTuple<std::uint32_t, float>> baseValues; // 00
BSTArray<BSTTuple<std::uint32_t, Modifiers>> modifiers; // 18
BSReadWriteLock avLock; // 30
};
static_assert(sizeof(ActorValueStorage) == 0x38);
}
@@ -0,0 +1,25 @@
#pragma once
#include "RE/B/BGSAimModel.h"
#include "RE/B/BSSpring_SpringState.h"
#include "RE/N/NiPoint2.h"
namespace RE
{
class __declspec(novtable) AimModel
{
public:
BGSAimModel::Data aimModelData; // 00
BSSpring::SpringState<NiPoint2> recoilSpring; // 40
BSSpring::SpringState<NiPoint2> recoilDiminishSpring; // 54
NiPoint2 targetRecoilHead; // 68
NiPoint2 currentRecoilHead; // 70
NiPoint2 prevRecoilRad; // 78
NiPoint2 preShotAimRad; // 80
Actor* actor; // 88
float fireConeSize; // 90
float lastShotDeltaMs; // 94
unsigned int continuousShots; // 98
};
static_assert(sizeof(AimModel) == 0xA0);
}
@@ -0,0 +1,23 @@
#pragma once
#include "RE/B/BSSimpleList.h"
#include "RE/T/TESPackage.h"
namespace RE
{
class Crime;
class __declspec(novtable) AlarmPackage :
public TESPackage // 00
{
public:
static constexpr auto RTTI{ RTTI::AlarmPackage };
static constexpr auto VTABLE{ VTABLE::AlarmPackage };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kPACK };
// members
BSSimpleList<Crime*> crimes; // C8
bool forceGreet; // D8
};
static_assert(sizeof(AlarmPackage) == 0xE0);
}
@@ -0,0 +1,51 @@
#pragma once
#include "RE/B/BGSCraftingUseSound.h"
#include "RE/B/BGSDestructibleObjectForm.h"
#include "RE/B/BGSEquipType.h"
#include "RE/B/BGSLocalizedString.h"
#include "RE/B/BGSMessageIcon.h"
#include "RE/B/BGSModelMaterialSwap.h"
#include "RE/B/BGSPickupPutdownSounds.h"
#include "RE/M/MagicItem.h"
#include "RE/T/TESDescription.h"
#include "RE/T/TESIcon.h"
#include "RE/T/TESWeightForm.h"
namespace RE
{
class __declspec(novtable) AlchemyItem :
public MagicItem, // 000
public BGSModelMaterialSwap, // 0D0
public TESIcon, // 110
public BGSMessageIcon, // 120
public TESWeightForm, // 138
public BGSEquipType, // 148
public BGSDestructibleObjectForm, // 158
public BGSPickupPutdownSounds, // 168
public BGSCraftingUseSound, // 180
public TESDescription // 190
{
public:
static constexpr auto RTTI{ RTTI::AlchemyItem };
static constexpr auto VTABLE{ VTABLE::AlchemyItem };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kALCH };
class Data :
public MagicItem::Data // 00
{
public:
// members
SpellItem* addictionItem; // 08
float addictionChance; // 10
BGSSoundDescriptorForm* consumptionSound; // 18
BGSLocalizedString addictionName; // 20
};
static_assert(sizeof(Data) == 0x28);
// members
Data data; // 1A8
TESIcon messageIcon; // 1D0
};
static_assert(sizeof(AlchemyItem) == 0x1E0);
}
@@ -0,0 +1,26 @@
#pragma once
#include "RE/B/BSFixedString.h"
namespace RE
{
namespace AnimationSpeedInformationTypes
{
class AnimationStateAdjustment
{
public:
union Variable
{
float variableFloatValue;
int variableIntValue;
};
// members
BSFixedString adjustmentName; // 00
Variable adjustmentVariable; // 08
bool useFloat; // 0C
bool isVariable; // 0D
};
static_assert(sizeof(AnimationStateAdjustment) == 0x10);
}
}
@@ -0,0 +1,13 @@
#pragma once
namespace RE
{
template <class T>
class AnimationStanceNodeLocationData
{
public:
// members
T nodeLocationArray[3]; // 00
};
static_assert(sizeof(AnimationStanceNodeLocationData<void*>) == 0x18);
}
@@ -0,0 +1,16 @@
#pragma once
#include "RE/B/BSFixedString.h"
namespace RE
{
namespace AnimationSystemUtils
{
inline bool WillEventChangeState(const TESObjectREFR& a_ref, const BSFixedString& a_evn)
{
using func_t = decltype(&WillEventChangeState);
static REL::Relocation<func_t> func{ ID::AnimationSystemUtils::WillEventChangeState };
return func(a_ref, a_evn);
}
}
}
@@ -0,0 +1,32 @@
#pragma once
#include "RE/B/BGSInventoryItem.h"
namespace RE
{
class __declspec(novtable) ApplyChangesFunctor :
public BGSInventoryItem::StackDataWriteFunctor // 00
{
public:
static constexpr auto RTTI{ RTTI::__ApplyChangesFunctor };
static constexpr auto VTABLE{ VTABLE::__ApplyChangesFunctor };
// override
virtual void WriteDataImpl(TESBoundObject& a_baseObj, BGSInventoryItem::Stack& a_stack) override // 01
{
using func_t = decltype(&ApplyChangesFunctor::WriteDataImpl);
static REL::Relocation<func_t> func{ ID::ApplyChangesFunctor::WriteDataImpl };
return func(this, a_baseObj, a_stack);
}
// members
BGSObjectInstanceExtra* extra; // 10
TESBoundObject* object; // 18
const BGSMod::Attachment::Mod* mod; // 20
std::uint8_t rank; // 28
bool remove; // 29
bool excludeTemporary; // 2A
std::int8_t favoriteIndex; // 2B
};
static_assert(sizeof(ApplyChangesFunctor) == 0x30);
}
@@ -0,0 +1,23 @@
#pragma once
#include "RE/B/BSTEvent.h"
namespace RE
{
class ApplyColorUpdateEvent
{
private:
using EventSource_t = BSTGlobalEvent::EventSource<ApplyColorUpdateEvent>;
public:
[[nodiscard]] static EventSource_t* GetEventSource()
{
static REL::Relocation<EventSource_t**> singleton{ ID::ApplyColorUpdateEvent::GetEventSource };
if (!*singleton) {
*singleton = new EventSource_t(&BSTGlobalEvent::GetSingleton()->eventSourceSDMKiller);
}
return *singleton;
}
};
static_assert(std::is_empty_v<ApplyColorUpdateEvent>);
}
@@ -0,0 +1,19 @@
#pragma once
#include "RE/M/MissileProjectile.h"
namespace RE
{
class __declspec(novtable) ArrowProjectile :
public MissileProjectile // 000
{
public:
static constexpr auto RTTI{ RTTI::ArrowProjectile };
static constexpr auto VTABLE{ VTABLE::ArrowProjectile };
static constexpr auto FORM_ID{ ENUM_FORM_ID::kPARW };
// members
AlchemyItem* poison; // 2C0
};
static_assert(sizeof(ArrowProjectile) == 0x2D0);
}
@@ -0,0 +1,30 @@
#pragma once
#include "RE/N/NiPointer.h"
namespace RE
{
class NiAVObject;
class NiNode;
namespace BSAttachTechniques
{
class __declspec(novtable) AttachTechniqueInput
{
public:
static constexpr auto RTTI{ RTTI::BSAttachTechniques__AttachTechniqueInput };
static constexpr auto VTABLE{ VTABLE::BSAttachTechniques__AttachTechniqueInput };
virtual ~AttachTechniqueInput(); // 00
// add
virtual void Clear(); // 01
// members
NiPointer<NiNode> root; // 08
NiPointer<NiAVObject> attaching; // 10
std::uint32_t attachPoint; // 18
};
static_assert(sizeof(AttachTechniqueInput) == 0x20);
}
}
@@ -0,0 +1,48 @@
#pragma once
#include "RE/B/BSFixedString.h"
#include "RE/H/HeldStateHandler.h"
#include "RE/S/Setting.h"
namespace RE
{
class AttackBlockHandler :
public HeldStateHandler
{
public:
static constexpr auto RTTI{ RTTI::AttackBlockHandler };
static constexpr auto VTABLE{ VTABLE::AttackBlockHandler };
enum class POWER_ATTACK_STATE
{
kNone = 0,
kLeft,
kRight,
kDual,
};
// members
std::uint64_t dualAttackStartTime; // 28
BSFixedString debounceEvent; // 30
REX::TEnumSet<POWER_ATTACK_STATE, std::uint32_t> checkForPowerAttack; // 38
std::uint32_t numPowerAttacks; // 3C
SettingT<INISettingCollection>* initialDelay; // 40
SettingT<INISettingCollection>* subsequentDelay; // 48
float attackTimer; // 50
std::uint64_t rightAttackTimestamp; // 58
float rightAttackHeldSeconds; // 60
float rightAttackLastHeldSeconds; // 64
float rightAttackLatchEngage; // 68
float rightAttackLatchRelease; // 6C
bool debounce; // 70
bool castAttemptMade; // 71
bool leftAttackButtonHeld; // 72
bool rightAttackButtonHeld; // 73
bool rightAttackQueued; // 74
bool rightAttackPrevFrame; // 75
bool setAttackTimer; // 76
bool checkPostMeleeActions; // 77
bool checkPostThrowActions; // 78
};
static_assert(sizeof(AttackBlockHandler) == 0x80);
}
@@ -0,0 +1,22 @@
#pragma once
namespace RE
{
class AttackData
{
public:
// members
float damageMult; // 00
float attackChance; // 04
SpellItem* attackSpell; // 08
std::uint32_t flags; // 10
float attackAngle; // 14
float strikeAngle; // 18
std::int32_t staggerOffset; // 1C
BGSKeyword* attackType; // 20
float knockdown; // 28
float recoveryTime; // 2C
float actionPointsMult; // 30
};
static_assert(sizeof(AttackData) == 0x38);
}
@@ -0,0 +1,19 @@
#pragma once
#include "RE/P/PlayerInputHandler.h"
namespace RE
{
class AutoMoveHandler :
public PlayerInputHandler
{
public:
static constexpr auto RTTI{ RTTI::AutoMoveHandler };
static constexpr auto VTABLE{ VTABLE::AutoMoveHandler };
explicit constexpr AutoMoveHandler(PlayerControlsData& a_data) noexcept :
PlayerInputHandler(a_data)
{}
};
static_assert(sizeof(AutoMoveHandler) == 0x20);
}
@@ -0,0 +1,19 @@
#pragma once
#include "RE/B/BSPathingAvoidNode.h"
namespace RE
{
class TESObjectREFR;
class AvoidAreaStruct
{
public:
// members
BSPathingAvoidNode avoideNode; // 00
float timeExpire; // 24
TESObjectREFR* refObj; // 28
AvoidAreaStruct* next; // 30
};
static_assert(sizeof(AvoidAreaStruct) == 0x38);
}
@@ -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);
}

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