From 9d7f85bfb06daed9f982ae60aaf8813d057df51c Mon Sep 17 00:00:00 2001 From: powerof3 <32599957+powerof3@users.noreply.github.com> Date: Tue, 21 Nov 2023 18:36:02 +0530 Subject: [PATCH] feat: `BGSProjectile`, `Projectile` classes (#224) --- CommonLibSF/include/RE/A/ArrowProjectile.h | 21 ++ CommonLibSF/include/RE/B/BGSBodyPartDefs.h | 71 ++++++ CommonLibSF/include/RE/B/BGSEquipIndex.h | 14 ++ CommonLibSF/include/RE/B/BGSProjectile.h | 109 +++++++++ CommonLibSF/include/RE/B/BSTSmartPointer.h | 16 ++ CommonLibSF/include/RE/B/BarrierProjectile.h | 30 +++ CommonLibSF/include/RE/B/BeamProjectile.h | 36 +++ CommonLibSF/include/RE/C/ConeProjectile.h | 25 ++ CommonLibSF/include/RE/E/EmitterProjectile.h | 34 +++ CommonLibSF/include/RE/F/FlameProjectile.h | 20 ++ CommonLibSF/include/RE/G/GrenadeProjectile.h | 23 ++ CommonLibSF/include/RE/I/ImpactResults.h | 13 ++ CommonLibSF/include/RE/IDs.h | 6 + CommonLibSF/include/RE/L/Location.h | 19 ++ CommonLibSF/include/RE/M/MissileProjectile.h | 29 +++ CommonLibSF/include/RE/N/NiMatrix3.h | 93 ++++++++ CommonLibSF/include/RE/N/NiTransform.h | 24 ++ CommonLibSF/include/RE/P/PlasmaProjectile.h | 16 ++ CommonLibSF/include/RE/P/Projectile.h | 226 +++++++++++++++++++ CommonLibSF/include/RE/T/TESForm.h | 7 + CommonLibSF/include/RE/T/TESFormRefCount.h | 1 + 21 files changed, 833 insertions(+) create mode 100644 CommonLibSF/include/RE/A/ArrowProjectile.h create mode 100644 CommonLibSF/include/RE/B/BGSBodyPartDefs.h create mode 100644 CommonLibSF/include/RE/B/BGSEquipIndex.h create mode 100644 CommonLibSF/include/RE/B/BGSProjectile.h create mode 100644 CommonLibSF/include/RE/B/BarrierProjectile.h create mode 100644 CommonLibSF/include/RE/B/BeamProjectile.h create mode 100644 CommonLibSF/include/RE/C/ConeProjectile.h create mode 100644 CommonLibSF/include/RE/E/EmitterProjectile.h create mode 100644 CommonLibSF/include/RE/F/FlameProjectile.h create mode 100644 CommonLibSF/include/RE/G/GrenadeProjectile.h create mode 100644 CommonLibSF/include/RE/I/ImpactResults.h create mode 100644 CommonLibSF/include/RE/L/Location.h create mode 100644 CommonLibSF/include/RE/M/MissileProjectile.h create mode 100644 CommonLibSF/include/RE/N/NiMatrix3.h create mode 100644 CommonLibSF/include/RE/N/NiTransform.h create mode 100644 CommonLibSF/include/RE/P/PlasmaProjectile.h create mode 100644 CommonLibSF/include/RE/P/Projectile.h diff --git a/CommonLibSF/include/RE/A/ArrowProjectile.h b/CommonLibSF/include/RE/A/ArrowProjectile.h new file mode 100644 index 00000000..eafff2d8 --- /dev/null +++ b/CommonLibSF/include/RE/A/ArrowProjectile.h @@ -0,0 +1,21 @@ +#pragma once + +#include "RE/M/MissileProjectile.h" + +namespace RE +{ + class AlchemyItem; + + class ArrowProjectile : public MissileProjectile + { + public: + SF_RTTI_VTABLE(ArrowProjectile); + SF_FORMTYPE(PARW); + + ~ArrowProjectile() override; // 00 + + // members + AlchemyItem* poison; // 2D0 + }; + static_assert(sizeof(ArrowProjectile) == 0x2E0); +} diff --git a/CommonLibSF/include/RE/B/BGSBodyPartDefs.h b/CommonLibSF/include/RE/B/BGSBodyPartDefs.h new file mode 100644 index 00000000..440ed6b1 --- /dev/null +++ b/CommonLibSF/include/RE/B/BGSBodyPartDefs.h @@ -0,0 +1,71 @@ +#pragma once + +#include "RE/B/BSFixedString.h" + +namespace RE::BGSBodyPartDefs +{ + struct LIMB_CATEGORIES + { + enum LIMB_CATEGORY + { + kNone = static_cast>(-1), + kTorso = 0, + kBegin, + kHead, + kArm, + kLeg, + + kTotal + }; + }; + using LIMB_CATEGORY = LIMB_CATEGORIES::LIMB_CATEGORY; + + struct LIMB_ENUMS + { + enum LIMB_ENUM + { + kNone = static_cast>(-1), + kTorso = 0, + kHead1, + kEye1, + kLookAt1, + kFlyGrab, + kHead2, + kLeftArm1, + kLeftArm2, + kRightArm1, + kRightArm2, + kLeftLeg1, + kLeftLeg2, + kLeftLeg3, + kRightLeg1, + kRightLeg2, + kRightLeg3, + kBrain, + kWeapon, + kRoot, + kCom, + kPelvis, + kCamera, + kOffsetRoot, + kLeftFoot, + kRightFoot, + kFaceTargetSource, + + kTotal + }; + }; + using LIMB_ENUM = LIMB_ENUMS::LIMB_ENUM; + + struct HitReactionData + { + public: + // members + BSFixedString chainStart; // 00 + BSFixedString chainEnd; // 08 + BSFixedString variableX; // 10 + BSFixedString variableY; // 18 + BSFixedString variableZ; // 20 + }; + static_assert(sizeof(HitReactionData) == 0x28); +} diff --git a/CommonLibSF/include/RE/B/BGSEquipIndex.h b/CommonLibSF/include/RE/B/BGSEquipIndex.h new file mode 100644 index 00000000..f53dc915 --- /dev/null +++ b/CommonLibSF/include/RE/B/BGSEquipIndex.h @@ -0,0 +1,14 @@ +#pragma once + +namespace RE +{ + class BGSEquipIndex + { + public: + ~BGSEquipIndex() noexcept {} + + // members + std::uint32_t index; // 0 + }; + static_assert(sizeof(BGSEquipIndex) == 0x4); +} diff --git a/CommonLibSF/include/RE/B/BGSProjectile.h b/CommonLibSF/include/RE/B/BGSProjectile.h new file mode 100644 index 00000000..5e14e72c --- /dev/null +++ b/CommonLibSF/include/RE/B/BGSProjectile.h @@ -0,0 +1,109 @@ +#pragma once + +#include "RE/B/BGSDestructibleObjectForm.h" +#include "RE/B/BGSPreloadable.h" +#include "RE/T/TESBoundObject.h" +#include "RE/T/TESFullName.h" +#include "RE/T/TESModel.h" +#include "RE/W/WwiseSoundHook.h" + +namespace RE +{ + class BGSCollisionLayer; + class BGSCurveForm; + class BGSExplosion; + class BGSProjectile; + class BGSTextureSet; + class TESObjectLIGH; + class TESObjectWEAP; + + struct BGSProjectileData // DATA + { + public: + enum class BGSProjectileFlags + { + kNone = 0, + kHitScan = 1 << 0, + kExplosion = 1 << 1, + kExplosionAltTrigger = 1 << 2, + kMuzzleFlash = 1 << 3, + kCanTurnOff = 1 << 5, + kCanPickUp = 1 << 6, + kSupersonic = 1 << 7, + kPinsLimbs = 1 << 8, + kPassSMTransparent = 1 << 9, + kDisableCombatAimCorrection = 1 << 10, + kPenetratesGeometry = 1 << 11, + kContinuousUpdate = 1 << 12, + kSeeksTarget = 1 << 13 + }; + + enum class Type + { + kMissile = 1 << 0, + kGrenade = 1 << 1, + kBeam = 1 << 2, + kFlamethrower = 1 << 3, + kCone = 1 << 4, + kBarrier = 1 << 5, + kArrow = 1 << 6 + }; + + // members + BSFixedString unk00; // 00 + BSFixedString unk08; // 08 + TESObjectLIGH* light; // 10 + TESObjectLIGH* muzzleFlashLight; // 18 + BGSExplosion* explosionType; // 20 + TESObjectWEAP* defaultWeaponSource; // 28 + BGSTextureSet* decalData; // 30 + BGSCollisionLayer* collisionLayer; // 38 + BGSProjectile* vatsProjectile; // 40 + stl::enumeration flags; // 48 + float gravity; // 4C + float speed; // 50 + float range; // 54 + float explosionProximity; // 58 + float explosionTimer; // 5C + float muzzleFlashDuration; // 60 + float fadeOutTime; // 64 + float force; // 68 + float coneSpread; // 6C + float collisionRadius; // 70 + float lifetime; // 74 + float relaunchInterval; // 78 + float unk7C; // 7C + std::uint32_t unk80; // 80 + stl::enumeration type; // 84 + std::uint8_t unk85; // 85 + float unk88; // 88 + float unk8C; // 8C + float unk90; // 90 + float unk94; // 94 + }; + static_assert(sizeof(BGSProjectileData) == 0x98); + + class BGSProjectile : + public TESBoundObject, // 000 + public TESFullName, // 118 + public TESModel, // 128 + public BGSPreloadable, // 148 + public BGSDestructibleObjectForm // 150 + { + public: + SF_RTTI_VTABLE(BGSProjectile); + SF_FORMTYPE(PROJ); + + ~BGSProjectile() override; // 00 + + // members + BGSProjectileData data; // 160 + TESModel muzzleFlashModel; // 1F8 + BGSCurveForm* curveTable; // 218 + BGSAudio::WwiseSoundHook activeSoundLoop; // 220 + BGSAudio::WwiseSoundHook countdownSound; // 250 + BGSAudio::WwiseSoundHook deactivateSound; // 280 + std::uint32_t unk2B0; // 2B0 + }; + static_assert(sizeof(BGSProjectile) == 0x2B8); +} diff --git a/CommonLibSF/include/RE/B/BSTSmartPointer.h b/CommonLibSF/include/RE/B/BSTSmartPointer.h index c5413e53..de068f25 100644 --- a/CommonLibSF/include/RE/B/BSTSmartPointer.h +++ b/CommonLibSF/include/RE/B/BSTSmartPointer.h @@ -32,6 +32,22 @@ namespace RE static void Release(stl::not_null a_ptr) { a_ptr->DecRefCount(); } }; + template + struct TESFormPolicy + { + public: + constexpr static void Acquire(stl::not_null a_ptr) { a_ptr->IncRefCount(); } + static void Release(stl::not_null a_ptr) { a_ptr->DecRefCount(); } + }; + + template + struct TESFormExternalPolicy + { + public: + constexpr static void Acquire(stl::not_null a_ptr) { a_ptr->IncExternalRefCount(); } + static void Release(stl::not_null a_ptr) { a_ptr->DecExternalRefCount(); } + }; + template class RefManager = BSTSmartPointerIntrusiveRefCount> class BSTSmartPointer { diff --git a/CommonLibSF/include/RE/B/BarrierProjectile.h b/CommonLibSF/include/RE/B/BarrierProjectile.h new file mode 100644 index 00000000..a1233dc1 --- /dev/null +++ b/CommonLibSF/include/RE/B/BarrierProjectile.h @@ -0,0 +1,30 @@ +#pragma once + +#include "RE/P/Projectile.h" + +namespace RE +{ + class BarrierProjectile : public Projectile + { + public: + SF_RTTI_VTABLE(BarrierProjectile); + SF_FORMTYPE(PBAR); + + struct CollisionData + { + std::uint32_t ref; // 0 - TESPointerHandle + std::uint32_t count; // 4 + }; + static_assert(sizeof(CollisionData) == 0x8); + + ~BarrierProjectile() override; // 00 + + // add + virtual void Unk_15D(); // 15D + + // members + float width; // 280 + BSTArray collisionData; // 288 + }; + static_assert(sizeof(BarrierProjectile) == 0x2A0); +} diff --git a/CommonLibSF/include/RE/B/BeamProjectile.h b/CommonLibSF/include/RE/B/BeamProjectile.h new file mode 100644 index 00000000..2dfc82ab --- /dev/null +++ b/CommonLibSF/include/RE/B/BeamProjectile.h @@ -0,0 +1,36 @@ +#pragma once + +#include "RE/B/BSTEvent.h" +#include "RE/F/FormTypes.h" +#include "RE/P/Projectile.h" + +namespace RE +{ + class BSProceduralGeomEvent; + struct BeamProjectileImpactEvent; + + class BeamProjectile : + public Projectile, // 000 + public BSTEventSource, // 280 + public BSTEventSink // 2A8 + { + public: + SF_RTTI_VTABLE(BeamProjectile); + SF_FORMTYPE(PBEA); + + ~BeamProjectile() override; // 00 + + // members + void* unk2B0; // 2B0 - smart ptr + std::uint64_t unk2B8; // 2B8 + ProjectileLaunchData launchData; // 2C0 + std::uint64_t unk3B0; // 3B0 + std::uint64_t unk3C0; // 3C0 + void* unk3C8; // 3C8 - smart ptr + std::uint32_t unk3D0; // 3D0 + std::uint8_t unk3D4; // 3D4 + std::uint8_t unk3D5; // 3D5 + std::uint8_t unk3D6; // 3D6 + }; + static_assert(sizeof(BeamProjectile) == 0x3E0); +} diff --git a/CommonLibSF/include/RE/C/ConeProjectile.h b/CommonLibSF/include/RE/C/ConeProjectile.h new file mode 100644 index 00000000..317f20a9 --- /dev/null +++ b/CommonLibSF/include/RE/C/ConeProjectile.h @@ -0,0 +1,25 @@ +#pragma once + +#include "RE/P/Projectile.h" + +namespace RE +{ + class ConeProjectile : public Projectile + { + public: + SF_RTTI_VTABLE(ConeProjectile); + SF_FORMTYPE(PCON); + + ~ConeProjectile() override; // 00 + + // members + stl::enumeration impactResult; // 280 + float environmentTimer; // 284 + float coneSpreadTangent; // 288 + float initialCollisionSphereRadius; // 28C + Location origin; // 290 + void* collisionShape; // 2A8 + BSTArray collisions; // 2B0 + }; + static_assert(sizeof(ConeProjectile) == 0x2C0); +} diff --git a/CommonLibSF/include/RE/E/EmitterProjectile.h b/CommonLibSF/include/RE/E/EmitterProjectile.h new file mode 100644 index 00000000..240e92ec --- /dev/null +++ b/CommonLibSF/include/RE/E/EmitterProjectile.h @@ -0,0 +1,34 @@ +#pragma once + +#include "RE/P/Projectile.h" + +namespace RE +{ + namespace Particles + { + class SystemBinding; + } + + class EmitterProjectile : public Projectile + { + public: + SF_RTTI_VTABLE(EmitterProjectile); + SF_FORMTYPE(PEMI); + + ~EmitterProjectile() override; // 00 + + // members + std::int32_t unk280; // 280 + BSTSmartPointer unk288; // 288 + BSTSmartPointer unk290; // 290 + BSTSmartPointer unk298; // 298 + bool unk2A0; // 2A0 + bool unk2A1; // 2A1 + std::uint64_t unk2A8; // 2A8 + std::uint64_t unk2B0; // 2B0 + std::uint64_t unk2B8; // 2B8 + std::uint64_t unk2C0; // 2C0 + std::uint64_t unk2C8; // 2C8 + }; + static_assert(sizeof(EmitterProjectile) == 0x2D0); +} diff --git a/CommonLibSF/include/RE/F/FlameProjectile.h b/CommonLibSF/include/RE/F/FlameProjectile.h new file mode 100644 index 00000000..7af02b4f --- /dev/null +++ b/CommonLibSF/include/RE/F/FlameProjectile.h @@ -0,0 +1,20 @@ +#pragma once + +#include "RE/P/Projectile.h" + +namespace RE +{ + class FlameProjectile : public Projectile + { + public: + SF_RTTI_VTABLE(FlameProjectile); + SF_FORMTYPE(PFLA); + + ~FlameProjectile() override; // 00 + + // members + float expirationTimer; // 280 + float coneAngle; // 284 + }; + static_assert(sizeof(FlameProjectile) == 0x290); +} diff --git a/CommonLibSF/include/RE/G/GrenadeProjectile.h b/CommonLibSF/include/RE/G/GrenadeProjectile.h new file mode 100644 index 00000000..6fd10ed1 --- /dev/null +++ b/CommonLibSF/include/RE/G/GrenadeProjectile.h @@ -0,0 +1,23 @@ +#pragma once + +#include "RE/B/BSTSmartPointer.h" +#include "RE/P/Projectile.h" + +namespace RE +{ + struct BGSDecalGroup; + + class GrenadeProjectile : public Projectile + { + public: + SF_RTTI_VTABLE(GrenadeProjectile); + SF_FORMTYPE(PGRE); + + ~GrenadeProjectile() override; // 00 + + // members + BSTSmartPointer decalGroup; // 280 - NiPointer? + bool collisionGroupReset; // 288 + }; + static_assert(sizeof(GrenadeProjectile) == 0x290); +} diff --git a/CommonLibSF/include/RE/I/ImpactResults.h b/CommonLibSF/include/RE/I/ImpactResults.h new file mode 100644 index 00000000..91a53e73 --- /dev/null +++ b/CommonLibSF/include/RE/I/ImpactResults.h @@ -0,0 +1,13 @@ +#pragma once + +namespace RE +{ + enum class ImpactResult + { + kNone = 0, + kDestroy = 1, + kBounce = 2, + kImpale = 3, + kStick = 4 + }; +} diff --git a/CommonLibSF/include/RE/IDs.h b/CommonLibSF/include/RE/IDs.h index c2cfe30a..7d9aa9e5 100644 --- a/CommonLibSF/include/RE/IDs.h +++ b/CommonLibSF/include/RE/IDs.h @@ -223,6 +223,11 @@ namespace RE::ID inline constexpr REL::ID PlayMenuSound{ 167344 }; } + namespace NiMatrix3 + { + inline constexpr REL::ID ToEulerAnglesXYZ{ 210095 }; + } + namespace ObjectBindPolicy { inline constexpr REL::ID BindObject{ 195981 }; @@ -315,6 +320,7 @@ namespace RE::ID namespace TESForm { + inline constexpr REL::ID DecExternalRefCount{ 34165 }; inline constexpr REL::ID DecRefCount{ 35164 }; inline constexpr REL::ID LookupByID{ 86125 }; inline constexpr REL::ID LookupByEditorID{ 86127 }; diff --git a/CommonLibSF/include/RE/L/Location.h b/CommonLibSF/include/RE/L/Location.h new file mode 100644 index 00000000..4864fb59 --- /dev/null +++ b/CommonLibSF/include/RE/L/Location.h @@ -0,0 +1,19 @@ +#pragma once + +#include "RE/B/BSTSmartPointer.h" +#include "RE/N/NiPoint3.h" + +namespace RE +{ + class TESForm; + + struct Location + { + public: + // members + NiPoint3 position; // 00 + std::int32_t unk0C; // 0C + BSTSmartPointer worldOrCell; // 10 + }; + static_assert(sizeof(Location) == 0x18); +} diff --git a/CommonLibSF/include/RE/M/MissileProjectile.h b/CommonLibSF/include/RE/M/MissileProjectile.h new file mode 100644 index 00000000..0a1347b7 --- /dev/null +++ b/CommonLibSF/include/RE/M/MissileProjectile.h @@ -0,0 +1,29 @@ +#pragma once + +#include "RE/P/Projectile.h" + +namespace RE +{ + class MissileProjectile : public Projectile + { + public: + SF_RTTI_VTABLE(MissileProjectile); + SF_FORMTYPE(PMIS); + + ~MissileProjectile() override; // 00 + + // add + virtual bool ShouldReorient() const; // 15D + + // members + NiMatrix3 unk280; // 280 + NiPoint3 unk2B0; // 2B0 + std::uint32_t unk2BC; // 2BC + NiPointer modelCollision; // 2C0 + stl::enumeration impactResult; // 2C8 + bool waitingToInitialize3D; // 2CC + bool unk2CD; // 2CD + bool unk2CE; // 2CE + }; + static_assert(sizeof(MissileProjectile) == 0x2D0); +} diff --git a/CommonLibSF/include/RE/N/NiMatrix3.h b/CommonLibSF/include/RE/N/NiMatrix3.h new file mode 100644 index 00000000..dc700a3c --- /dev/null +++ b/CommonLibSF/include/RE/N/NiMatrix3.h @@ -0,0 +1,93 @@ +#pragma once + +#include "RE/N/NiPoint4.h" + +namespace RE +{ + class alignas(0x10) NiMatrix3 + { + public: + void MakeIdentity() noexcept + { + entry[0].v = { 1.0F, 0.0F, 0.0F, 0.0F }; + entry[1].v = { 0.0F, 1.0F, 0.0F, 0.0F }; + entry[2].v = { 0.0F, 0.0F, 1.0F, 0.0F }; + } + + NiMatrix3 operator*(const NiMatrix3& rhs) const + { + NiMatrix3 tmp; + tmp.entry[0].pt[0] = + entry[0].pt[0] * rhs.entry[0].pt[0] + + entry[0].pt[1] * rhs.entry[1].pt[0] + + entry[0].pt[2] * rhs.entry[2].pt[0]; + tmp.entry[1].pt[0] = + entry[1].pt[0] * rhs.entry[0].pt[0] + + entry[1].pt[1] * rhs.entry[1].pt[0] + + entry[1].pt[2] * rhs.entry[2].pt[0]; + tmp.entry[2].pt[0] = + entry[2].pt[0] * rhs.entry[0].pt[0] + + entry[2].pt[1] * rhs.entry[1].pt[0] + + entry[2].pt[2] * rhs.entry[2].pt[0]; + tmp.entry[0].pt[1] = + entry[0].pt[0] * rhs.entry[0].pt[1] + + entry[0].pt[1] * rhs.entry[1].pt[1] + + entry[0].pt[2] * rhs.entry[2].pt[1]; + tmp.entry[1].pt[1] = + entry[1].pt[0] * rhs.entry[0].pt[1] + + entry[1].pt[1] * rhs.entry[1].pt[1] + + entry[1].pt[2] * rhs.entry[2].pt[1]; + tmp.entry[2].pt[1] = + entry[2].pt[0] * rhs.entry[0].pt[1] + + entry[2].pt[1] * rhs.entry[1].pt[1] + + entry[2].pt[2] * rhs.entry[2].pt[1]; + tmp.entry[0].pt[2] = + entry[0].pt[0] * rhs.entry[0].pt[2] + + entry[0].pt[1] * rhs.entry[1].pt[2] + + entry[0].pt[2] * rhs.entry[2].pt[2]; + tmp.entry[1].pt[2] = + entry[1].pt[0] * rhs.entry[0].pt[2] + + entry[1].pt[1] * rhs.entry[1].pt[2] + + entry[1].pt[2] * rhs.entry[2].pt[2]; + tmp.entry[2].pt[2] = + entry[2].pt[0] * rhs.entry[0].pt[2] + + entry[2].pt[1] * rhs.entry[1].pt[2] + + entry[2].pt[2] * rhs.entry[2].pt[2]; + return tmp; + } + + NiMatrix3 operator*(float scalar) const + { + NiMatrix3 result; + result.entry[0].pt[0] = entry[0].pt[0] * scalar; + result.entry[0].pt[1] = entry[0].pt[1] * scalar; + result.entry[0].pt[2] = entry[0].pt[2] * scalar; + result.entry[1].pt[0] = entry[1].pt[0] * scalar; + result.entry[1].pt[1] = entry[1].pt[1] * scalar; + result.entry[1].pt[2] = entry[1].pt[2] * scalar; + result.entry[2].pt[0] = entry[2].pt[0] * scalar; + result.entry[2].pt[1] = entry[2].pt[1] * scalar; + result.entry[2].pt[2] = entry[2].pt[2] * scalar; + return result; + } + + NiPoint3 operator*(const NiPoint3& p) const + { + return NiPoint3( + entry[0].pt[0] * p.x + entry[0].pt[1] * p.y + entry[0].pt[2] * p.z, + entry[1].pt[0] * p.x + entry[1].pt[1] * p.y + entry[1].pt[2] * p.z, + entry[2].pt[0] * p.x + entry[2].pt[1] * p.y + entry[2].pt[2] * p.z); + } + + bool ToEulerAnglesXYZ(float& a_x, float& a_y, float& a_z) + { + using func_t = decltype(&NiMatrix3::ToEulerAnglesXYZ); + REL::Relocation func{ ID::NiMatrix3::ToEulerAnglesXYZ }; + return func(this, a_x, a_y, a_z); + } + + // members + NiPoint4 entry[3]; // 00 + }; + static_assert(sizeof(NiMatrix3) == 0x30); +} diff --git a/CommonLibSF/include/RE/N/NiTransform.h b/CommonLibSF/include/RE/N/NiTransform.h new file mode 100644 index 00000000..28ed90ec --- /dev/null +++ b/CommonLibSF/include/RE/N/NiTransform.h @@ -0,0 +1,24 @@ +#pragma once + +#include "RE/N/NiMatrix3.h" +#include "RE/N/NiPoint3.h" + +namespace RE +{ + class NiTransform + { + public: + void MakeIdentity() noexcept + { + rotate.MakeIdentity(); + translate = NiPoint3{}; + scale = 1.0F; + } + + // members + NiMatrix3 rotate; // 00 + NiPoint3 translate; // 30 + float scale{ 1.0F }; // 3C + }; + static_assert(sizeof(NiTransform) == 0x40); +} diff --git a/CommonLibSF/include/RE/P/PlasmaProjectile.h b/CommonLibSF/include/RE/P/PlasmaProjectile.h new file mode 100644 index 00000000..a73889b2 --- /dev/null +++ b/CommonLibSF/include/RE/P/PlasmaProjectile.h @@ -0,0 +1,16 @@ +#pragma once + +#include "RE/C/ConeProjectile.h" + +namespace RE +{ + class PlasmaProjectile : public ConeProjectile + { + public: + SF_RTTI_VTABLE(PlasmaProjectile); + SF_FORMTYPE(PPLA); + + ~PlasmaProjectile() override; // 00 + }; + static_assert(sizeof(PlasmaProjectile) == 0x2C0); +} diff --git a/CommonLibSF/include/RE/P/Projectile.h b/CommonLibSF/include/RE/P/Projectile.h new file mode 100644 index 00000000..9315a9b3 --- /dev/null +++ b/CommonLibSF/include/RE/P/Projectile.h @@ -0,0 +1,226 @@ +#pragma once + +#include "RE/B/BGSBodyPartDefs.h" +#include "RE/B/BGSEquipIndex.h" +#include "RE/B/BGSObjectInstance.h" +#include "RE/B/BSTArray.h" +#include "RE/L/Location.h" +#include "RE/M/MagicSystem.h" +#include "RE/N/NiSmartPointer.h" +#include "RE/N/NiTransform.h" +#include "RE/T/TESObjectREFR.h" + +namespace RE +{ + enum class COL_LAYER; + enum class ImpactResult; + + class bhkNPCollisionObject; + class ActorCause; + class BGSExplosion; + class BGSMaterialType; + class BGSProjectile; + class CombatController; + class EffectSetting; + class MagicItem; + class TESAmmo; + class TESObjectWEAP; + + struct ImpactCreation; + + class ProjectileLaunchData + { + public: + // members + Location origin; // 00 + NiPoint3 contactNormal; // 18 + NiPoint3 destination; // 24 + BGSProjectile* projectileBase; // 30 + TESObjectREFR* shooter; // 38 + CombatController* shooterCombatController; // 40 + TESAmmo* fromAmmo; // 48 + TESObjectREFR* homingTarget; // 50 + TESObjectCELL* parentCell; // 58 + MagicItem* spell; // 60 + AlchemyItem* poison; // 68 + BGSObjectInstanceT fromWeapon; // 70 + stl::enumeration castingSource; // 80 + stl::enumeration targetLimbEnum; // 84 + void* unk88; // 88 - smart ptr + BGSEquipIndex equipIndex; // 90 + std::uint32_t unk94; // 94 + Location unk98; // 98 + float unkB0; // B0 + std::uint32_t unkB4; // B4 + std::uint32_t unkB8; // B8 + std::uint32_t unkBC; // BC + std::uint32_t unkC0; // C0 + float power; // C4 + float unkC8; // C8 + float unkCC; // CC + std::uint32_t unkD0; // D0 + float unkD4; // D4 + float range; // D8 + float unkDC; // DC + std::uint8_t unkE0; // E0 + std::uint8_t unkE1; // E1 + std::uint8_t unkE2; // E2 + std::uint8_t unkE3; // E3 + bool useOrigin; // E4 + std::uint8_t unkE5; // E5 + std::uint8_t unkE6; // E6 + std::uint8_t unkE7; // E7 + std::uint8_t unkE8; // E8 + std::uint8_t unkE9; // E9 + bool penetrates; // EA + std::uint8_t unkEB; // EB + std::uint8_t unkEC; // EC + std::uint8_t unkED; // ED + std::uint8_t unkEE; // EE + std::uint8_t unkEF; // EF + std::uint8_t unkF0; // F0 + std::uint8_t unkF1; // F1 + bool continuousUpdate; // F2 + }; + static_assert(sizeof(ProjectileLaunchData) == 0xF8); + + class Projectile : public TESObjectREFR + { + public: + SF_RTTI_VTABLE(Projectile); + + struct ImpactData + { + public: + // members + Location location; // 00 + NiPoint3 normal; // 18 + std::uint64_t unk28; // 28 + std::uint32_t collidee; // 30 - TESPointerHandle + std::uint32_t unk34; // 34 + NiPointer colObj; // 38 + BGSMaterialType* materialType; // 40 + stl::enumeration damageLimb; // 48 + stl::enumeration collisionLayer; // 4C + std::uint64_t unk50; // 50 + stl::enumeration resultOverride; // 58 + std::uint32_t unk5C; // 5C + float decalSize; // 60 + std::uint32_t collisionShapeKey; // 64 + std::int16_t targetWorldObjectCount; // 68 + std::int16_t targetWorldObjectIndex; // 6A + bool processed; // 6C + bool spellCast; // 6D + bool effectSpawned; // 6E + bool backFace; // 6F + std::uint8_t unk70; // 70 + std::uint64_t unk78; // 78 + }; + static_assert(sizeof(ImpactData) == 0x80); + + ~Projectile() override; // 00 + + // add + virtual bool IsMissileProjectile() const; // 130 + virtual bool IsGrenadeProjectile() const; // 131 + virtual bool IsFlameProjectile() const; // 132 + virtual bool IsBeamProjectile() const; // 133 + virtual bool IsFogProjectile() const; // 134 + virtual bool IsBarrierProjectile() const; // 135 + virtual void Unk_136(); // 136 + virtual void Unk_137(); // 137 + virtual void Unk_138(); // 138 + virtual void UpdateImpl(float a_delta); // 139 + virtual bool ProcessImpacts(); // 13A + virtual void Unk_13B(); // 13B + virtual void Unk_13C(); // 13C + virtual float GetPowerSpeedMult() const; // 13D + virtual float GetWeaponSpeedMult() const; // 13E + virtual void Unk_13F(); // 13F + virtual void Unk_140(); // 140 + virtual void Unk_141(); // 141 + virtual void Unk_142(); // 142 + virtual void Unk_143(); // 143 + virtual void Unk_144(); // 144 + virtual bool TurnOff(Actor* a_actionActor, bool a_silent); // 145 + virtual bool IsPermanent(); // 146 + virtual float GetGravity() const; // 147 + virtual void CleanUpPointersOnDisable(); // 148 + virtual void Unk_149(); // 149 + virtual void Unk_14A(); // 14A + virtual void Unk_14B(); // 14B + virtual void Unk_14C(); // 14C + virtual void Unk_14D(); // 14D + virtual bool GetAllowMovement() const; // 14E + virtual void Unk_14F(); // 14F + virtual void Unk_150(); // 150 + virtual void Unk_151(); // 151 + virtual void Unk_152(); // 152 + virtual void Unk_153(); // 153 + virtual void InitializeImpl(); // 154 + virtual void Relaunch(ProjectileLaunchData& a_data); // 155 + virtual std::uint32_t AddImpact(const ImpactCreation& a_data); // 156 + virtual void Unk_157(); // 157 + virtual void Unk_158(); // 158 + virtual void Unk_159(); // 159 + virtual void Unk_15A(); // 15A + virtual void Unk_15B(); // 15B + virtual bool ShouldUseDesiredTarget(); // 15C + + // members + BSTArray impacts; // 110 + NiPointer collisionObject; // 120 + NiPointer droppedRefr; // 128 + NiTransform followOffset; // 130 + BSSpinLock lock; // 170 + NiPoint3 movementDirection; // 178 + NiPoint3 velocity; // 184 + void* unk190; // 190 - smart ptr + NiPointer actorCause; // 198 + std::uint32_t shooterHandle; // 1A0 - TESPointerHandle + std::uint32_t desiredTargetHandle; // 1A4 - TESPointerHandle + std::uint32_t unk1A8; // 1A8 + std::uint32_t unk1AC; // 1AC + std::uint32_t unk1B0; // 1B0 + std::uint32_t unk1B4; // 1B4 + BGSExplosion* explosion; // 1B8 + MagicItem* spell; // 1C0 + EffectSetting* avEffect; // 1C8 + void* unk1D0; // 1D0 - smart ptr + void* unk1D8; // 1D8 - smart ptr + void* unk1E0; // 1E0 - smart ptr + void* unk1E8; // 1E8 - smart ptr + std::uint64_t unk1F0; // 1F0 + BGSEquipIndex equipIndex; // 1F8 + stl::enumeration targetLimbEnum; // 1FC + NiPointer targetLimbObj; // 200 + std::uint64_t unk208; // 208 + BGSObjectInstanceT weaponSource; // 210 + TESAmmo* ammoSource; // 220 + std::uint64_t flags; // 228 + std::uint32_t unk230; // 230 + float power; // 234 + float speedMult; // 238 + float range; // 23C + float age; // 240 + float damage; // 244 + float alpha; // 248 + float explosionTimer; // 24C + float blinkTimer; // 250 + float distanceMoved; // 254 + std::uint32_t unk258; // 258 + float scale; // 25C + float unk260; // 260 + float unk264; // 264 + std::uint32_t unk268; // 268 + std::uint32_t unk26C; // 26C + std::uint32_t unk270; // 270 + std::uint32_t unk274; // 274 + stl::enumeration castingSource; // 278 + std::uint8_t unk279; // 279 + bool artRequested; // 27A + bool animationsLoaded; // 27B + std::uint8_t unk27C; // 27C + }; + static_assert(sizeof(Projectile) == 0x280); +} diff --git a/CommonLibSF/include/RE/T/TESForm.h b/CommonLibSF/include/RE/T/TESForm.h index 2401debd..7c7d2ba7 100644 --- a/CommonLibSF/include/RE/T/TESForm.h +++ b/CommonLibSF/include/RE/T/TESForm.h @@ -137,6 +137,13 @@ namespace RE virtual void Unk_60(); // 60 virtual void Unk_61(); // 61 + std::uint64_t DecExternalRefCount() const + { + using func_t = decltype(&TESForm::DecRefCount); + REL::Relocation func{ ID::TESForm::DecExternalRefCount }; + return func(this); + } + std::uint64_t DecRefCount() const { using func_t = decltype(&TESForm::DecRefCount); diff --git a/CommonLibSF/include/RE/T/TESFormRefCount.h b/CommonLibSF/include/RE/T/TESFormRefCount.h index 3b5a226a..62d7ec6e 100644 --- a/CommonLibSF/include/RE/T/TESFormRefCount.h +++ b/CommonLibSF/include/RE/T/TESFormRefCount.h @@ -14,6 +14,7 @@ namespace RE kRefCountMask = 0x3FFFFF, }; + std::uint64_t IncExternalRefCount() const; std::uint64_t IncRefCount() const; [[nodiscard]] std::uint64_t QRefCount() const;