diff --git a/PrivateMenu.sln b/PrivateMenu.sln index b81c1b11a7..a1f090f9a8 100644 --- a/PrivateMenu.sln +++ b/PrivateMenu.sln @@ -16,28 +16,56 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MinHook", "MinHook\MinHook. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cryptlib", "Cryptopp\src\cryptlib.vcxproj", "{C39F4B46-6E89-4074-902E-CA57073044D2}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "classes", "classes\classes.vcxproj", "{64B538A8-E487-477D-A150-38C9A520A5A9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {8F281285-54DA-43C6-BAC9-23D3EB65E636}.Debug|x64.ActiveCfg = Release|x64 {8F281285-54DA-43C6-BAC9-23D3EB65E636}.Debug|x64.Build.0 = Release|x64 + {8F281285-54DA-43C6-BAC9-23D3EB65E636}.Debug|x86.ActiveCfg = Release|x64 + {8F281285-54DA-43C6-BAC9-23D3EB65E636}.Debug|x86.Build.0 = Release|x64 {8F281285-54DA-43C6-BAC9-23D3EB65E636}.Release|x64.ActiveCfg = Release|x64 {8F281285-54DA-43C6-BAC9-23D3EB65E636}.Release|x64.Build.0 = Release|x64 + {8F281285-54DA-43C6-BAC9-23D3EB65E636}.Release|x86.ActiveCfg = Release|x64 + {8F281285-54DA-43C6-BAC9-23D3EB65E636}.Release|x86.Build.0 = Release|x64 {9A8D6D59-23F1-49CB-A556-6E53947FA100}.Debug|x64.ActiveCfg = Debug|x64 {9A8D6D59-23F1-49CB-A556-6E53947FA100}.Debug|x64.Build.0 = Debug|x64 + {9A8D6D59-23F1-49CB-A556-6E53947FA100}.Debug|x86.ActiveCfg = Debug|x64 + {9A8D6D59-23F1-49CB-A556-6E53947FA100}.Debug|x86.Build.0 = Debug|x64 {9A8D6D59-23F1-49CB-A556-6E53947FA100}.Release|x64.ActiveCfg = Release|x64 {9A8D6D59-23F1-49CB-A556-6E53947FA100}.Release|x64.Build.0 = Release|x64 + {9A8D6D59-23F1-49CB-A556-6E53947FA100}.Release|x86.ActiveCfg = Release|x64 + {9A8D6D59-23F1-49CB-A556-6E53947FA100}.Release|x86.Build.0 = Release|x64 {09699103-49E1-4E94-8EEF-E5FC4F7CFF23}.Debug|x64.ActiveCfg = Debug|x64 {09699103-49E1-4E94-8EEF-E5FC4F7CFF23}.Debug|x64.Build.0 = Debug|x64 + {09699103-49E1-4E94-8EEF-E5FC4F7CFF23}.Debug|x86.ActiveCfg = Debug|x64 + {09699103-49E1-4E94-8EEF-E5FC4F7CFF23}.Debug|x86.Build.0 = Debug|x64 {09699103-49E1-4E94-8EEF-E5FC4F7CFF23}.Release|x64.ActiveCfg = Release|x64 {09699103-49E1-4E94-8EEF-E5FC4F7CFF23}.Release|x64.Build.0 = Release|x64 + {09699103-49E1-4E94-8EEF-E5FC4F7CFF23}.Release|x86.ActiveCfg = Release|x64 + {09699103-49E1-4E94-8EEF-E5FC4F7CFF23}.Release|x86.Build.0 = Release|x64 {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|x64.ActiveCfg = Debug|x64 {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|x64.Build.0 = Debug|x64 + {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|x86.ActiveCfg = Debug|Win32 + {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|x86.Build.0 = Debug|Win32 {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|x64.ActiveCfg = Release|x64 {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|x64.Build.0 = Release|x64 + {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|x86.ActiveCfg = Release|Win32 + {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|x86.Build.0 = Release|Win32 + {64B538A8-E487-477D-A150-38C9A520A5A9}.Debug|x64.ActiveCfg = Debug|x64 + {64B538A8-E487-477D-A150-38C9A520A5A9}.Debug|x64.Build.0 = Debug|x64 + {64B538A8-E487-477D-A150-38C9A520A5A9}.Debug|x86.ActiveCfg = Debug|Win32 + {64B538A8-E487-477D-A150-38C9A520A5A9}.Debug|x86.Build.0 = Debug|Win32 + {64B538A8-E487-477D-A150-38C9A520A5A9}.Release|x64.ActiveCfg = Release|x64 + {64B538A8-E487-477D-A150-38C9A520A5A9}.Release|x64.Build.0 = Release|x64 + {64B538A8-E487-477D-A150-38C9A520A5A9}.Release|x86.ActiveCfg = Release|Win32 + {64B538A8-E487-477D-A150-38C9A520A5A9}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PrivateMenu/PrivateMenu.vcxproj b/PrivateMenu/PrivateMenu.vcxproj index baf759775b..e9f4b69c9b 100644 --- a/PrivateMenu/PrivateMenu.vcxproj +++ b/PrivateMenu/PrivateMenu.vcxproj @@ -48,7 +48,7 @@ true true false - $(ProjectDir)src;$(ProjectDir);%(AdditionalIncludeDirectories) + $(ProjectDir)src;$(ProjectDir);$(SolutionDir)classes\src;%(AdditionalIncludeDirectories) Default Neither false diff --git a/classes/classes.vcxproj b/classes/classes.vcxproj new file mode 100644 index 0000000000..48afab0ec4 --- /dev/null +++ b/classes/classes.vcxproj @@ -0,0 +1,157 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + 17.0 + Win32Proj + {64b538a8-e487-477d-a150-38c9a520a5a9} + classes + 10.0 + + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)Build\$(ProjectName)\$(Configuration)\ + $(SolutionDir)Build\Intermediate\$(ProjectName)\$(Configuration)\ + + + $(SolutionDir)Build\$(ProjectName)\$(Configuration)\ + $(SolutionDir)Build\Intermediate\$(ProjectName)\$(Configuration)\ + + + + Level3 + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + Use + pch.h + + + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + Use + pch.h + + + + + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + NotUsing + stdafx.h + stdcpplatest + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + NotUsing + stdafx.h + stdcpplatest + + + + + true + true + true + + + + + + \ No newline at end of file diff --git a/classes/classes.vcxproj.filters b/classes/classes.vcxproj.filters new file mode 100644 index 0000000000..555d1aa9f4 --- /dev/null +++ b/classes/classes.vcxproj.filters @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/classes/src/base/CBaseModelInfo.hpp b/classes/src/base/CBaseModelInfo.hpp new file mode 100644 index 0000000000..f5acebd96c --- /dev/null +++ b/classes/src/base/CBaseModelInfo.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include +#include "fwArchetype.hpp" + +enum class eModelType : std::uint8_t +{ + Invalid, + Object, + MLO, + Time, + Weapon, + Vehicle, + Ped, + Destructable, + WorldObject = 33, + Sprinkler = 35, + Unk65 = 65, + EmissiveLOD = 67, + Plant = 129, + LOD = 131, + Unk132 = 132, + Unk133 = 133, + OnlineOnlyPed = 134, + Building = 161, + Unk193 = 193 +}; + +#pragma pack(push, 8) +class CBaseModelInfo : public rage::fwArchetype +{ +public: + char pad_0070[8]; //0x0070 + uint64_t unk_0078; //0x0078 + uint64_t unk_0080; //0x0080 + char pad_0088[8]; //0x0088 + uint64_t unk_0090; //0x0090 + char pad_0098[5]; //0x0098 + eModelType m_model_type; //0x009D + char pad_009E[6]; //0x009E + uint64_t unk_00A8; //0x00A8 +}; //Size: 0x00B0 +static_assert(sizeof(CBaseModelInfo) == 0xB0); +#pragma pack(pop) diff --git a/classes/src/base/CNavigation.hpp b/classes/src/base/CNavigation.hpp new file mode 100644 index 0000000000..c1c8ae677f --- /dev/null +++ b/classes/src/base/CNavigation.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "../rage/vector.hpp" +#include "phArchetype.hpp" + +#pragma pack(push, 1) +class CNavigation +{ +public: + char pad_0000[16]; //0x0000 + class rage::phArchetypeDamp* m_damp; //0x0010 + char pad_0018[8]; //0x0018 + rage::fmatrix44 m_transformation_matrix; + + rage::fvector3* get_position() + { + return reinterpret_cast(&m_transformation_matrix.rows[3]); + } + + void model_to_world(const rage::fvector3& model_coords, rage::fvector3& world_coords) + { + world_coords.x = model_coords.x * m_transformation_matrix.data[0][0] + model_coords.y * m_transformation_matrix.data[1][0] + model_coords.z * m_transformation_matrix.data[2][0] + m_transformation_matrix.data[3][0]; + world_coords.y = model_coords.x * m_transformation_matrix.data[0][1] + model_coords.y * m_transformation_matrix.data[1][1] + model_coords.z * m_transformation_matrix.data[2][1] + m_transformation_matrix.data[3][1]; + world_coords.z = model_coords.x * m_transformation_matrix.data[0][2] + model_coords.y * m_transformation_matrix.data[1][2] + model_coords.z * m_transformation_matrix.data[2][2] + m_transformation_matrix.data[3][2]; + } +}; //Size: 0x0060 +static_assert(sizeof(CNavigation) == 0x60); +#pragma pack(pop) diff --git a/classes/src/base/CObject.hpp b/classes/src/base/CObject.hpp new file mode 100644 index 0000000000..f825a50a6b --- /dev/null +++ b/classes/src/base/CObject.hpp @@ -0,0 +1,26 @@ +#pragma once +#include "../entities/CPhysical.hpp" + +class CWeapon; + +#pragma pack(push, 2) +class CObject : public rage::CPhysical +{ + char gap30C[60]; + uint64_t qword348; + char gap350[8]; + uint64_t qword358; + uint16_t word360; + uint32_t dword362; + uint16_t word366; + char gap368[120]; + uint64_t qword3E0; + char gap3E8[8]; + uint64_t qword3F0; + uint64_t qword3F8; + uint64_t qword400; + uint64_t qword408; + uint64_t qword410; +}; +static_assert(sizeof(CObject) == 0x3F8); +#pragma pack(pop) diff --git a/classes/src/base/HashTable.hpp b/classes/src/base/HashTable.hpp new file mode 100644 index 0000000000..93d90168ec --- /dev/null +++ b/classes/src/base/HashTable.hpp @@ -0,0 +1,28 @@ +#pragma once +#include + +#pragma pack(push, 1) +class HashNode +{ +public: + int32_t m_hash; //0x0000 + uint16_t m_idx; //0x0004 + char pad_0006[2]; //0x0006 + HashNode* m_next; //0x0008 +}; //Size: 0x0010 +static_assert(sizeof(HashNode) == 0x10); + +template +class HashTable +{ +public: + T* m_data; //0x0000 + uint16_t m_size; //0x0008 + char pad_000A[14]; //0x000A + uint64_t m_item_size; //0x0018 + char pad_0020[64]; //0x0020 + HashNode** m_lookup_table; //0x0060 + uint16_t m_lookup_key; //0x0068 +}; //Size: 0x006A +// static_assert(sizeof(HashTable) == 0x6A); // compiler gives assert error without telling me what the problem is, the class is correct though. +#pragma pack(pop) diff --git a/classes/src/base/atRTTI.hpp b/classes/src/base/atRTTI.hpp new file mode 100644 index 0000000000..f3e86678a7 --- /dev/null +++ b/classes/src/base/atRTTI.hpp @@ -0,0 +1,11 @@ +#pragma once + +#define DEFINE_RAGE_RTTI(className) private:\ + virtual void* _0x00() = 0;\ + virtual void* _0x08() = 0;\ + virtual uint32_t _0x10() = 0;\ + virtual className* _0x18(void*) = 0;\ + virtual bool _0x20(void*) = 0;\ + virtual bool _0x28(void**) = 0;\ + virtual void destructor() = 0;\ + public: \ No newline at end of file diff --git a/classes/src/base/datBase.hpp b/classes/src/base/datBase.hpp new file mode 100644 index 0000000000..ebbe82ec73 --- /dev/null +++ b/classes/src/base/datBase.hpp @@ -0,0 +1,13 @@ +#pragma once + +namespace rage +{ + + class datBase + { + public: + virtual ~datBase() = default; + }; //Size: 0x0008 + static_assert(sizeof(datBase) == 0x8); + +} \ No newline at end of file diff --git a/classes/src/base/fwArchetype.hpp b/classes/src/base/fwArchetype.hpp new file mode 100644 index 0000000000..33b1fc2b15 --- /dev/null +++ b/classes/src/base/fwArchetype.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include "../rage/vector.hpp" +#include "datBase.hpp" +#include "fwArchetypeDef.hpp" + +namespace rage { + #pragma pack(push,8) + class fwArchetype : public datBase + { + public: + virtual void Initialize() = 0; + virtual void InitializeFromArchetypeDef(uint32_t mapTypeStoreIdx, fwArchetypeDef* archetypeDef, bool) = 0; + virtual class fwEntity* CreateEntity() = 0; + + char pad_0008[16]; //0x0008 + int32_t m_hash; //0x0018 + char unk_001C[4]; //0x001C + fvector3 m_bounding_sphere_center; //0x0020 + float m_bounding_sphere_radius; //0x002C + fvector3 m_aabbMin; //0x0030 + float m_lod_dist; //0x003C + fvector3 m_aabbMax; //0x0040 + float m_hd_texture_dist; //0x004C + uint32_t m_flags; //0x0050 + char unk_0054[4]; //0x0054 + uint64_t unk_0058; //0x0058 + char unk_0060[4]; //0x0060 + uint32_t m_asset_index; //0x0064 + uint16_t unk_0068; //0x0068 + uint16_t unk_006A; //0x006A + }; + static_assert(sizeof(fwArchetype) == 0x70); + #pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/base/fwArchetypeDef.hpp b/classes/src/base/fwArchetypeDef.hpp new file mode 100644 index 0000000000..ee5d052a3a --- /dev/null +++ b/classes/src/base/fwArchetypeDef.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include +#include "../rage/vector.hpp" + +namespace rage { +#pragma pack(push,8) + class fwArchetypeDef + { + public: + virtual ~fwArchetypeDef() = 0; + virtual int GetTypeIdentifier() = 0; + + float m_lod_dist; //0x0008 + uint32_t m_flags; //0x000C + uint32_t m_special_attribute; //0x0010 + char pad_0014[12]; //0x0014 + fvector4 m_bounding_box_min; //0x0020 + fvector4 m_bounding_box_max; //0x0030 + fvector4 m_bounding_sphere_center; //0x0040 + float m_bounding_sphere_radius; //0x0050 + float m_hd_texture_dist; //0x0054 + uint32_t m_name_hash; //0x0058 + uint32_t m_texture_dictionary; //0x005C + uint32_t m_clip_dictionary_hash; //0x0060 + uint32_t m_drawable_dictionary_hash; //0x0064 + uint32_t m_physics_dictionary_hash; //0x0068 + enum eAssetType : uint32_t + { + ASSET_TYPE_UNINITIALIZED = 0, + ASSET_TYPE_FRAGMENT = 1, + ASSET_TYPE_DRAWABLE = 2, + ASSET_TYPE_DRAWABLEDICTIONARY = 3, + ASSET_TYPE_ASSETLESS = 4, + } m_asset_type; //0x006C + uint32_t m_asset_name_hash; //0x0070 + uint64_t *m_extensions; //0x0078 + uint16_t unk_0080; //0x0080 + char pad_0082[12]; //0x0082 + }; //Size: 0x0090 + static_assert(sizeof(fwArchetypeDef) == 0x90); +#pragma pack(pop) +} diff --git a/classes/src/base/fwExtensibleBase.hpp b/classes/src/base/fwExtensibleBase.hpp new file mode 100644 index 0000000000..56d5ed24de --- /dev/null +++ b/classes/src/base/fwExtensibleBase.hpp @@ -0,0 +1,22 @@ +#pragma once +#include + +#include "fwRefAwareBase.hpp" +#include "fwExtensionContainer.hpp" + +#include "../rage/joaat.hpp" + +namespace rage +{ + class fwExtensibleBase : public fwRefAwareBase + { + public: + // virtual bool is_of_type(std::uint32_t hash) = 0; + // virtual uint32_t const &get_type() = 0; + + fwExtensionContainer* m_extension_container; // 0x0010 + void *m_extensible_unk; // 0x0018 + }; //Size: 0x0020 + static_assert(sizeof(fwExtensibleBase) == 0x20); + +} diff --git a/classes/src/base/fwExtension.hpp b/classes/src/base/fwExtension.hpp new file mode 100644 index 0000000000..4fe5c79cf6 --- /dev/null +++ b/classes/src/base/fwExtension.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace rage +{ + + class fwExtension + { + public: + virtual ~fwExtension() = default; + virtual void unk_0x08() = 0; + virtual void unk_0x10() = 0; + virtual uint32_t get_id() = 0; + }; //Size: 0x0008 + static_assert(sizeof(fwExtension) == 0x8); + +} \ No newline at end of file diff --git a/classes/src/base/fwExtensionContainer.hpp b/classes/src/base/fwExtensionContainer.hpp new file mode 100644 index 0000000000..7d31bfe6a4 --- /dev/null +++ b/classes/src/base/fwExtensionContainer.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "fwExtension.hpp" + +namespace rage +{ + + class fwExtensionContainer + { + public: + fwExtension *m_entry; //0x0000 + fwExtensionContainer* m_next; //0x0008 + }; //Size: 0x0010 + static_assert(sizeof(fwExtensionContainer) == 0x10); + +} \ No newline at end of file diff --git a/classes/src/base/fwRefAwareBase.hpp b/classes/src/base/fwRefAwareBase.hpp new file mode 100644 index 0000000000..662646e296 --- /dev/null +++ b/classes/src/base/fwRefAwareBase.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "datBase.hpp" +#include "fwRefAwareBaseImpl.hpp" + +namespace rage +{ + + class fwRefAwareBase : public fwRefAwareBaseImpl + { + }; + static_assert(sizeof(fwRefAwareBase) == 0x10); + +} \ No newline at end of file diff --git a/classes/src/base/fwRefAwareBaseImpl.hpp b/classes/src/base/fwRefAwareBaseImpl.hpp new file mode 100644 index 0000000000..89987eb05a --- /dev/null +++ b/classes/src/base/fwRefAwareBaseImpl.hpp @@ -0,0 +1,13 @@ +#pragma once + +namespace rage +{ + + template + class fwRefAwareBaseImpl : public T + { + private: + void *m_ref; // 0x08 + }; + +} \ No newline at end of file diff --git a/classes/src/base/pgBase.hpp b/classes/src/base/pgBase.hpp new file mode 100644 index 0000000000..25dde4ebe9 --- /dev/null +++ b/classes/src/base/pgBase.hpp @@ -0,0 +1,36 @@ +#pragma once + +namespace rage +{ + + class pgBase + { + public: + virtual ~pgBase() = default; + virtual int return_zero() = 0; + virtual void error() = 0; + + void *unk_0000; // 0x0000 + }; //Size: 0x0008 + static_assert(sizeof(pgBase) == 0x10); + + class pgBaseMetaDataType + { + public: + virtual ~pgBaseMetaDataType() = default; + virtual void Lookup(uint32_t hash) = 0; + }; //Size: 0x0008 + + class pgBaseMetaDataDebugNameType : public pgBaseMetaDataType + { + public: + virtual ~pgBaseMetaDataDebugNameType() = default; + char pad_0000[64]; + }; //Size: 0x0072 + + class pgBaseRefCounted : public pgBase + { + public: + virtual ~pgBaseRefCounted() = default; + }; //Size: 0x0008 +} \ No newline at end of file diff --git a/classes/src/base/pgDictionary.hpp b/classes/src/base/pgDictionary.hpp new file mode 100644 index 0000000000..248801240e --- /dev/null +++ b/classes/src/base/pgDictionary.hpp @@ -0,0 +1,87 @@ +#pragma once + +namespace rage +{ + class pgDictionaryBase + { + public: + virtual ~pgDictionaryBase() = default; + }; //Size: 0x0008 + + template + class pgDictionary : public pgDictionaryBase + { + private: + struct Node { + T key; + Node* next; + + Node(const T& k, Node* n = nullptr) + : key(k), next(n) {} + }; + Node* head; + public: + pgDictionary() : head(nullptr) {} + ~pgDictionary() { + clearDict(); + } + + void addDict(const T& key) { + Node* newNode = new Node(key, head); + head = newNode; + } + + bool containsDict(const T& key) const { + Node* current = head; + while (current != nullptr) { + if (current->key == key) { + return true; + } + current = current->next; + } + return false; + } + + void removeDict(const T& key) { + if (head == nullptr) { + return; + } + + if (head->key == key) { + Node* temp = head; + head = head->next; + delete temp; + return; + } + + Node* current = head; + while (current->next != nullptr) { + if (current->next->key == key) { + Node* temp = current->next; + current->next = current->next->next; + delete temp; + return; + } + current = current->next; + } + } + + size_t sizeDict() const { + size_t count = 0; + Node* current = head; + while (current != nullptr) { + count++; + current = current->next; + } + return count; + } + + void clearDict() { + while (head != nullptr) { + Node* temp = head; + head = head->next; + delete temp; + } + } + }; +} \ No newline at end of file diff --git a/classes/src/base/phArchetype.hpp b/classes/src/base/phArchetype.hpp new file mode 100644 index 0000000000..a0186b4a69 --- /dev/null +++ b/classes/src/base/phArchetype.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "phBound.hpp" + +namespace rage +{ + class phArchetype + { + public: + char pad_0000[32]; //0x0000 + class phBound* m_bound; //0x0020 + char pad_0028[16]; //0x0028 + }; //Size: 0x0038 + static_assert(sizeof(phArchetype) == 0x38); + + class phArchetypePhys : public phArchetype + { + public: + char pad_0038[28]; //0x0028 + float m_water_collision; //0x0054 + char pad_0058[40]; //0x0058 + }; //Size: 0x0080 + static_assert(sizeof(phArchetypePhys) == 0x80); + + class phArchetypeDamp : public phArchetypePhys + { + public: + char pad_0080[96]; //0x0080 + }; //Size: 0x00E0 + static_assert(sizeof(phArchetypeDamp) == 0xE0); +} \ No newline at end of file diff --git a/classes/src/base/phBound.hpp b/classes/src/base/phBound.hpp new file mode 100644 index 0000000000..b3a8d01f4c --- /dev/null +++ b/classes/src/base/phBound.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include "pgBase.hpp" +#include "../rage/vector.hpp" + +namespace rage { + class phBoundBase : public pgBase + { + }; + +enum class eBoundType : uint8_t +{ + SPHERE, + CAPSULE, + BOX = 3, + GEOMETRY, + BVH = 8, + COMPOSITE = 10, + DISC = 12, + CYLINDER, + PLANE = 15 +}; + +#pragma pack(push,4) + class phBound : public phBoundBase { + public: + eBoundType m_type; //0x0010 + uint8_t m_flags; //0x0011 + uint16_t m_part_index; //0x0012 + float m_radius_around_centroid; //0x0014 + char pad_0018[8]; //0x0018 + fvector4 m_bounding_box_max_xyz_margin_w; //0x0020 + fvector4 m_bounding_box_min_xyz_ref_count_w; //0x0030 + fvector4 m_centroid_offset_xyz_material_id_0_w; //0x0040 + fvector4 m_cg_offset_xyz_material_id_1_w; //0x0050 + fvector4 m_volume_distribution; //0x0060 + }; //Size: 0x0070 + static_assert(sizeof(phBound) == 0x70); +#pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/base/phBoundCapsule.hpp b/classes/src/base/phBoundCapsule.hpp new file mode 100644 index 0000000000..3346637606 --- /dev/null +++ b/classes/src/base/phBoundCapsule.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "phBound.hpp" + +namespace rage +{ +#pragma pack(push,1) + class phBoundCapsule : public phBound + { + public: + float m_capsule_half_height; + uint64_t unk_0074; + uint32_t unk_007C; + }; //Size: 0x0080 + static_assert(sizeof(phBoundCapsule) == 0x80); +#pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/base/phBoundComposite.hpp b/classes/src/base/phBoundComposite.hpp new file mode 100644 index 0000000000..dc73bc9278 --- /dev/null +++ b/classes/src/base/phBoundComposite.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include +#include "phBound.hpp" +#include "../rage/vector.hpp" + +namespace rage +{ +#pragma pack(push,8) + class phBoundComposite : public phBound + { + public: + class phBound** m_bounds; //0x0070 + fmatrix34* m_current_matrices; //0x0078 + fmatrix34* m_last_matrices; //0x0080 + fvector3* unk_0088; //0x0088 + uint32_t* m_type_and_include_flags; //0x0090 + uint32_t* m_owned_type_and_include_flags; //0x0098 + uint16_t m_max_num_bounds; //0x00A0 + uint16_t m_num_bounds; //0x00A2 + char pad_00A4[4]; //0x00A4 + void* unk_00A8; //0x00A8 + }; //Size: 0x00B0 + static_assert(sizeof(phBoundComposite) == 0xB0); +#pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/camera/CCameraAngles.hpp b/classes/src/camera/CCameraAngles.hpp new file mode 100644 index 0000000000..2a57e6f283 --- /dev/null +++ b/classes/src/camera/CCameraAngles.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "../player/CPlayerAngles.hpp" + +class CCameraAngles +{ +public: + char pad_0000[960]; //0x0000 + CPlayerAngles* angles; //0x03C0 + char pad_03C8[60]; //0x03C8 +}; //Size: 0x0408 +static_assert(sizeof(CCameraAngles) == 0x408); diff --git a/classes/src/camera/CCameraManagerAngles.hpp b/classes/src/camera/CCameraManagerAngles.hpp new file mode 100644 index 0000000000..88c8df1ca8 --- /dev/null +++ b/classes/src/camera/CCameraManagerAngles.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "CCameraAngles.hpp" + +class CCameraManagerAngles +{ +public: + CCameraAngles* m_angles; //0x0000 +}; //Size: 0x0008 +static_assert(sizeof(CCameraManagerAngles) == 0x8); diff --git a/classes/src/camera/CGameCameraAngles.hpp b/classes/src/camera/CGameCameraAngles.hpp new file mode 100644 index 0000000000..141448de03 --- /dev/null +++ b/classes/src/camera/CGameCameraAngles.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "CCameraManagerAngles.hpp" + +class CGameCameraAngles +{ +public: + CCameraManagerAngles* m_angles; //0x0000 + char pad_0008[56]; //0x0008 +}; //Size: 0x0040 +static_assert(sizeof(CGameCameraAngles) == 0x40); diff --git a/classes/src/classes.cpp b/classes/src/classes.cpp new file mode 100644 index 0000000000..f4bfba96b6 --- /dev/null +++ b/classes/src/classes.cpp @@ -0,0 +1,217 @@ +#include "base/atRTTI.hpp" +#include "base/CBaseModelInfo.hpp" +#include "base/CNavigation.hpp" +#include "base/CObject.hpp" +#include "base/datBase.hpp" +#include "base/fwArchetype.hpp" +#include "base/fwArchetypeDef.hpp" +#include "base/fwExtensibleBase.hpp" +#include "base/fwExtension.hpp" +#include "base/fwExtensionContainer.hpp" +#include "base/fwRefAwareBase.hpp" +#include "base/fwRefAwareBaseImpl.hpp" +#include "base/HashTable.hpp" +#include "base/pgBase.hpp" +#include "base/phArchetype.hpp" +#include "base/phBound.hpp" +#include "base/phBoundCapsule.hpp" +#include "base/phBoundComposite.hpp" +#include "base/pgDictionary.hpp" +#include "camera/CCameraAngles.hpp" +#include "camera/CCameraManagerAngles.hpp" +#include "camera/CGameCameraAngles.hpp" +#include "draw_handlers/CEntityDrawHandler.hpp" +#include "draw_handlers/CObjectDrawHandler.hpp" +#include "draw_handlers/CPedDrawHandler.hpp" +#include "draw_handlers/CVehicleDrawHandler.hpp" +#include "draw_handlers/fwDrawData.hpp" +#include "entities/CAttackers.hpp" +#include "entities/CDynamicEntity.hpp" +#include "entities/CEntity.hpp" +#include "entities/CPhysical.hpp" +#include "entities/fwEntity.hpp" +#include "enums/eExplosionTag.hpp" +#include "enums/eHandlingType.hpp" +#include "game_files/CGameConfig.hpp" +#include "misc/CTunables.hpp" +#include "misc/vfx/TimecycleKeyframeData.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" +#include "netsync/CProjectSyncTree.hpp" +#include "netsync/netSyncDataNode.hpp" +#include "netsync/netSyncNodeBase.hpp" +#include "netsync/netSyncParentNode.hpp" +#include "netsync/netSyncTree.hpp" +#include "netsync/NodeCommonDataOperations.hpp" +#include "netsync/nodes/automobile/CAutomobileCreationNode.hpp" +#include "netsync/nodes/CPedComponents.hpp" +#include "netsync/nodes/door/CDoorCreationDataNode.hpp" +#include "netsync/nodes/door/CDoorMovementDataNode.hpp" +#include "netsync/nodes/door/CDoorScriptGameStateDataNode.hpp" +#include "netsync/nodes/door/CDoorScriptInfoDataNode.hpp" +#include "netsync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp" +#include "netsync/nodes/entity/CEntityOrientationDataNode.hpp" +#include "netsync/nodes/entity/CEntityScriptGameStateDataNode.hpp" +#include "netsync/nodes/entity/CEntityScriptInfoDataNode.hpp" +#include "netsync/nodes/heli/CHeliHealthDataNode.hpp" +#include "netsync/nodes/heli/CHeliControlDataNode.hpp" +#include "netsync/nodes/object/CObjectCreationDataNode.hpp" +#include "netsync/nodes/ped/CPedAIDataNode.hpp" +#include "netsync/nodes/ped/CPedAppearanceDataNode.hpp" +#include "netsync/nodes/ped/CPedAttachDataNode.hpp" +#include "netsync/nodes/ped/CPedComponentReservationDataNode.hpp" +#include "netsync/nodes/ped/CPedCreationDataNode.hpp" +#include "netsync/nodes/ped/CPedGameStateDataNode.hpp" +#include "netsync/nodes/ped/CPedHealthDataNode.hpp" +#include "netsync/nodes/ped/CPedInventoryDataNode.hpp" +#include "netsync/nodes/ped/CPedMovementDataNode.hpp" +#include "netsync/nodes/ped/CPedMovementGroupDataNode.hpp" +#include "netsync/nodes/ped/CPedOrientationDataNode.hpp" +#include "netsync/nodes/ped/CPedScriptCreationDataNode.hpp" +#include "netsync/nodes/ped/CPedTaskSequenceDataNode.hpp" +#include "netsync/nodes/ped/CPedTaskSpecificDataNode.hpp" +#include "netsync/nodes/ped/CPedTaskTreeDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalAngVelocityDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalAttachDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalGameStateDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalHealthDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalMigrationDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalScriptGameStateDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalVelocityDataNode.hpp" +#include "netsync/nodes/pickup/CPickupCreationDataNode.hpp" +#include "netsync/nodes/pickup_placement/CPickupPlacementCreationDataNode.hpp" +#include "netsync/nodes/player/CPlayerAmbientModelStreamingNode.hpp" +#include "netsync/nodes/player/CPlayerAppearanceDataNode.hpp" +#include "netsync/nodes/player/CPlayerCameraDataNode.hpp" +#include "netsync/nodes/player/CPlayerCreationDataNode.hpp" +#include "netsync/nodes/player/CPlayerGamerDataNode.hpp" +#include "netsync/nodes/player/CPlayerGameStateDataNode.hpp" +#include "netsync/nodes/player/CPlayerPedGroupDataNode.hpp" +#include "netsync/nodes/player/CPlayerSectorPosNode.hpp" +#include "netsync/nodes/player/CPlayerWantedAndLOSDataNode.hpp" +#include "netsync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp" +#include "netsync/nodes/proximity_migrateable/CMigrationDataNode.hpp" +#include "netsync/nodes/proximity_migrateable/CSectorDataNode.hpp" +#include "netsync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp" +#include "netsync/nodes/task/ClonedTakeOffPedVariationInfo.hpp" +#include "netsync/nodes/train/CTrainGameStateDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleCreationDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleControlDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleTaskDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleGadgetDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleComponentReservationDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleDamageStatusDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleSteeringDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleHealthDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleGameStateDataNode.hpp" +#include "netsync/trees/CDynamicEntitySyncTreeBase.hpp" +#include "netsync/trees/CEntitySyncTreeBase.hpp" +#include "netsync/trees/CPhysicalSyncTreeBase.hpp" +#include "netsync/trees/CProximityMigrateableSyncTreeBase.hpp" +#include "network/CCommunications.hpp" +#include "network/ChatData.hpp" +#include "network/CJoinRequestContext.hpp" +#include "network/ClanData.hpp" +#include "network/CMsgJoinResponse.hpp" +#include "network/CMsgTextMessage.hpp" +#include "network/CNetComplaintMgr.hpp" +#include "network/CNetGamePlayer.hpp" +#include "network/CNetGamePlayerDataMsg.hpp" +#include "network/CNetworkPlayerMgr.hpp" +#include "network/netObject.hpp" +#include "network/netPeerAddress.hpp" +#include "network/netPlayer.hpp" +#include "network/netPlayerMgrBase.hpp" +#include "network/netTime.hpp" +#include "network/Network.hpp" +#include "network/RemoteGamerInfoMsg.hpp" +#include "network/snConnectToPeerTask.hpp" +#include "network/snSession.hpp" +#include "network/netConnection.hpp" +#include "ped/CPed.hpp" +#include "ped/CPedBoneInfo.hpp" +#include "ped/CPedFactory.hpp" +#include "ped/CPedIntelligence.hpp" +#include "ped/CPedInventory.hpp" +#include "ped/CPedModelInfo.hpp" +#include "ped/CPedWeaponManager.hpp" +#include "player/CNonPhysicalPlayerData.hpp" +#include "player/CPlayerAngles.hpp" +#include "player/CPlayerInfo.hpp" +#include "rage/atArray.hpp" +#include "rage/atReferenceCounter.hpp" +#include "rage/atSingleton.hpp" +#include "rage/joaat.hpp" +#include "rage/rlGamerHandle.hpp" +#include "rage/rlGamerInfo.hpp" +#include "rage/rlGamerInfoBase.hpp" +#include "rage/rlMetric.hpp" +#include "rage/rlQueryPresenceAttributesContext.hpp" +#include "rage/rlScHandle.hpp" +#include "rage/rlSessionByGamerTaskResult.hpp" +#include "rage/rlSessionInfo.hpp" +#include "rage/rlTaskStatus.hpp" +#include "rage/sysMemAllocator.hpp" +#include "rage/vector.hpp" +#include "script/dataList.hpp" +#include "script/globals/GlobalPlayerBD.hpp" +#include "script/globals/GPBD_FM.hpp" +#include "script/globals/GPBD_FM_3.hpp" +#include "script/globals/GPBD_Kicking.hpp" +#include "script/globals/GPBD_MissionName.hpp" +#include "script/globals/GSBD.hpp" +#include "script/globals/GSBD_BlockB.hpp" +#include "script/globals/GSBD_FM.hpp" +#include "script/globals/GSBD_Kicking.hpp" +#include "script/globals/GSBD_PropertyInstances.hpp" +#include "script/globals/g_AMC_playerBD.hpp" +#include "script/CGameScriptObjInfo.hpp" +#include "script/GtaThread.hpp" +#include "script/HudColor.hpp" +#include "script/MPScriptData.hpp" +#include "script/scriptHandler.hpp" +#include "script/scriptHandlerMgr.hpp" +#include "script/scriptHandlerNetComponent.hpp" +#include "script/scriptId.hpp" +#include "script/scriptIdBase.hpp" +#include "script/scriptResource.hpp" +#include "script/scrNativeHandler.hpp" +#include "script/scrNativeRegistration.hpp" +#include "script/scrNativeRegistrationTable.hpp" +#include "script/scrProgram.hpp" +#include "script/scrProgramTable.hpp" +#include "script/scrProgramTableEntry.hpp" +#include "script/scrThread.hpp" +#include "script/scrThreadContext.hpp" +#include "script/scrVector.hpp" +#include "script/Timer.hpp" +#include "script/tlsContext.hpp" +#include "script/types.hpp" +#include "security/ObfVar.hpp" +#include "security/RageSecurity.hpp" +#include "socialclub/FriendInfo.hpp" +#include "socialclub/FriendRegistry.hpp" +#include "socialclub/ScInfo.hpp" +#include "stats/CPlayerCardStats.hpp" +#include "stats/CStatsSerializationContext.hpp" +#include "vehicle/CAdvancedData.hpp" +#include "vehicle/CBaseSubHandlingData.hpp" +#include "vehicle/CCarHandlingData.hpp" +#include "vehicle/CHandlingData.hpp" +#include "vehicle/CHandlingObject.hpp" +#include "vehicle/CVehicle.hpp" +#include "vehicle/CVehicleModelInfo.hpp" +#include "vehicle/CVehicleDriveByMetadataMgr.hpp" +#include "vehicle/CVehicleSeatMetadataMgr.hpp" +#include "vehicle/CTrainConfig.hpp" +#include "vehicle/CGetPedSeatReturnClass.hpp" +#include "weapon/CAmmoInfo.hpp" +#include "weapon/CAmmoProjectileInfo.hpp" +#include "weapon/CAmmoRocketInfo.hpp" +#include "weapon/CAmmoThrownInfo.hpp" +#include "weapon/CHomingRocketParams.hpp" +#include "weapon/CItemInfo.hpp" +#include "weapon/CWeaponBoneId.hpp" +#include "weapon/CWeaponInfo.hpp" +#include "ui/CBlipList.hpp" diff --git a/classes/src/draw_handlers/CEntityDrawHandler.hpp b/classes/src/draw_handlers/CEntityDrawHandler.hpp new file mode 100644 index 0000000000..a586b8214e --- /dev/null +++ b/classes/src/draw_handlers/CEntityDrawHandler.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "fwDrawData.hpp" + +namespace rage +{ + class CEntityDrawHandler : public rage::fwDrawData + { + public: + + }; + static_assert(sizeof(CEntityDrawHandler) == 0x2C); +} diff --git a/classes/src/draw_handlers/CObjectDrawHandler.hpp b/classes/src/draw_handlers/CObjectDrawHandler.hpp new file mode 100644 index 0000000000..0edb8f9f58 --- /dev/null +++ b/classes/src/draw_handlers/CObjectDrawHandler.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "CEntityDrawHandler.hpp" + +namespace rage +{ + class CObjectFragmentDrawHandler : public CEntityDrawHandler + { + }; + static_assert(sizeof(CObjectFragmentDrawHandler) == 0x2C); +} diff --git a/classes/src/draw_handlers/CPedDrawHandler.hpp b/classes/src/draw_handlers/CPedDrawHandler.hpp new file mode 100644 index 0000000000..02ebcbf9af --- /dev/null +++ b/classes/src/draw_handlers/CPedDrawHandler.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include + +#include "CEntityDrawHandler.hpp" + +namespace rage +{ +#pragma pack(push, 4) + class CPedDrawHandler : public CEntityDrawHandler + { + public: + uint64_t qword30; + uint64_t qword38; + char gap40[752]; + uint32_t dword330; + }; + static_assert(sizeof(CPedDrawHandler) == 0x330); +#pragma pack(pop) +} diff --git a/classes/src/draw_handlers/CVehicleDrawHandler.hpp b/classes/src/draw_handlers/CVehicleDrawHandler.hpp new file mode 100644 index 0000000000..d4ccc9e07e --- /dev/null +++ b/classes/src/draw_handlers/CVehicleDrawHandler.hpp @@ -0,0 +1,86 @@ +#pragma once + +#include + +#include "CEntityDrawHandler.hpp" + +namespace rage +{ + class CVehicleDrawHandler : public CEntityDrawHandler + { + public: + uint64_t qword30; + char gap38[848]; + uint8_t m_primary_color; //0x0388 + char gap389[3]; //0x0389 + uint8_t m_pearlescent; //0x038C + char gap38D[3]; //0x038D + uint8_t m_secondary_color; //0x0390 + char gap391[15]; //0x0391 + uint8_t m_neon_blue; //0x03A0 + uint8_t m_neon_green; //0x03A1 + uint8_t m_neon_red; //0x03A2 + char gap3A3[15]; //0x03A3 + uint8_t m_spoiler; //0x03B2 + uint8_t m_bumper_front; //0x03B3 + uint8_t m_bumper_rear; //0x03B4 + uint8_t m_sideskirts; //0x03B5 + uint8_t m_exhaust; //0x03B6 + uint8_t m_frame; //0x03B7 + uint8_t m_grille; //0x03B8 + uint8_t m_hood; //0x03B9 + uint8_t m_fenders; //0x03BA + uint8_t m_bullbars; //0x03BB + uint8_t m_roof; //0x03BC + char gap3BD[3]; //0x03BD + uint8_t m_ornaments; //0x03C0 + char gap3C1[1]; //0x03C1 + uint8_t m_dail_design; //0x03C2 + uint8_t m_sunstrips; //0x03C3 + uint8_t m_seats; //0x03C4 + uint8_t m_steering_wheel; //0x03C5 + uint8_t m_column_shifter_levers; //0x03C6 + char gap3C7[2]; //0x03C7 + uint8_t m_truck_beds; //0x03C9 + char gap3CA[4]; //0x03CA + uint8_t m_roll_cages; //0x03CE + uint8_t m_skid_plate; //0x03CF + uint8_t m_secondary_light_surrounds; //0x03D0 + uint8_t m_hood_accessories; //0x03D1 + uint8_t m_doors; //0x03D2 + uint8_t m_snorkel; //0x03D3 + uint8_t m_livery; //0x03D4 + char gap3D5[1]; //0x03D5 + uint8_t m_engine; //0x03D6 + uint8_t m_brakes; //0x03D7 + uint8_t m_transmission; //0x03D8 + uint8_t m_horn; //0x03D9 + uint8_t m_suspension; //0x03DA + uint8_t m_armor; //0x03DB + char gap3DC[1]; //0x03DC + uint8_t m_turbo; //0x03DD + char gap3DE[3]; //0x03DE + uint8_t m_xenon; //0x03E1 + uint8_t m_tire_design; //0x03E2 + char gap3E3[16]; //0x03E3 + uint8_t m_truck_bed; //0x03F3 + uint16_t m_modkit; //0x03F4 + uint8_t byte3F6; + uint8_t byte3F7; + uint8_t byte3F8; + uint8_t m_wheel_color; + uint8_t byte3FA; + uint8_t byte3FB; + char gap3FC[3]; + uint8_t m_window; + char gap400[2]; + uint8_t m_neon_left; + uint8_t m_neon_right; + uint8_t m_neon_front; + uint8_t m_neon_rear; + char gap406[9]; + uint32_t dword410; + uint32_t dword414; + }; + static_assert(sizeof(CVehicleDrawHandler) == 0x418); +} diff --git a/classes/src/draw_handlers/fwDrawData.hpp b/classes/src/draw_handlers/fwDrawData.hpp new file mode 100644 index 0000000000..7315f3f17a --- /dev/null +++ b/classes/src/draw_handlers/fwDrawData.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +namespace rage +{ +#pragma pack(push, 4) + class fwDrawData + { + public: + std::uint64_t qword0; + std::uint64_t qword8; + char gap10[8]; + std::uint32_t dword18; + std::uint32_t dword1C; + std::uint64_t qword20; + std::uint32_t dword28; + }; + static_assert(sizeof(fwDrawData) == 0x2C); +#pragma pack(pop) +} diff --git a/classes/src/entities/CAttackers.hpp b/classes/src/entities/CAttackers.hpp new file mode 100644 index 0000000000..f0876388ec --- /dev/null +++ b/classes/src/entities/CAttackers.hpp @@ -0,0 +1,15 @@ +#pragma once + +class CPed; //fwdec + +#pragma pack(push, 1) +class CAttackers +{ +public: + CPed* m_attacker0; //0x0000 + char pad_0x0008[0x10]; //0x0008 + CPed* m_attacker1; //0x0018 + char pad_0x0020[0x10]; //0x0020 + CPed* m_attacker2; //0x0030 +}; //Size=0x0038 +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/entities/CDynamicEntity.hpp b/classes/src/entities/CDynamicEntity.hpp new file mode 100644 index 0000000000..2d51bc7665 --- /dev/null +++ b/classes/src/entities/CDynamicEntity.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "CEntity.hpp" +#include "../network/netObject.hpp" + +#include + +namespace rage +{ + class CDynamicEntity : public CEntity + { + public: + class rage::netObject *m_net_object; //0x00D0 + char gapD8[16]; + uint64_t qwordE8; + }; + static_assert(sizeof(CDynamicEntity) == 0xF0); +} diff --git a/classes/src/entities/CEntity.hpp b/classes/src/entities/CEntity.hpp new file mode 100644 index 0000000000..14c7bb1c4a --- /dev/null +++ b/classes/src/entities/CEntity.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include "fwEntity.hpp" + +#include + +class CEntityDrawHandler; + +namespace rage +{ + class CEntity : public rage::fwEntity + { + public: + virtual void* _0x120() = 0; // implemented only by CPed + virtual void UpdatePositionImpl() = 0; // 0x128 + virtual void _0x130() = 0; + virtual void _0x138(void*) = 0; + virtual void _0x140() = 0; + virtual void _0x148(int) = 0; + virtual bool _0x150() = 0; + virtual CEntityDrawHandler* CreateDrawHandler() = 0; // 0x158 + virtual int GetTypeFlags() = 0; // 0x160 + virtual int GetTypeFlags2() = 0; // 0x168 + virtual bool _0x170() = 0; // implemented only by CPickup + virtual bool _0x178() = 0; + virtual void _0x180(bool) = 0; + virtual bool _0x188() = 0; + virtual bool _0x190() = 0; + virtual void ClearDecals() = 0; // 0x198 + virtual void GetModelBounds(rage::fvector3* bounds) = 0; // 0x1A0 + virtual void GetModelBounds2(rage::fvector3* bounds) = 0; // 0x1A8 + virtual float GetBoundingBoxSize() = 0; // 0x1B0 + virtual float _0x1B8(void*) = 0; + virtual float _0x1C0(void*) = 0; + virtual rage::fvector3* _0x1C8() = 0; + virtual rage::fvector3* GetCameraOffset() = 0; // 0x1D0 + virtual void GetCameraBasePosition(rage::fvector3* pos) = 0; // 0x1D8 + virtual bool _0x1E0() = 0; + virtual bool Update() = 0; // 0x1E8 always returns true + virtual bool _0x1F0() = 0; + virtual void Warp(rage::fvector3* pos, float heading, bool) = 0; // 0x1F8 + + + uint8_t gapB9; //0x00B9 + char gapBA[6]; //0x00BA + uint32_t m_flags_3; //0x00C0 + uint32_t m_flags_4; //0x00C4 + uint32_t dwordC8; + uint32_t dwordCC; + }; + static_assert(sizeof(CEntity) == 0xD0); +} diff --git a/classes/src/entities/CPhysical.hpp b/classes/src/entities/CPhysical.hpp new file mode 100644 index 0000000000..1bf416b36d --- /dev/null +++ b/classes/src/entities/CPhysical.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "CDynamicEntity.hpp" +#include "CAttackers.hpp" + +#include + +namespace rage +{ +#pragma pack(push, 1) + class CPhysical : public CDynamicEntity + { + public: + char gapF0[144]; + uint64_t qword180; + uint32_t m_damage_bits; //0x0188 + uint8_t m_hostility; //0x018C + char gap18D[3]; + uint8_t byte190; + char gap191[3]; + uint32_t dword194; + char gap198[232]; + float m_health; //0x0280 + float m_maxhealth; //0x0284 + class CAttackers* m_attackers; + char gap2B0[72]; + uint64_t qword2F8; + uint64_t qword300; + uint32_t dword308; + }; + static_assert(sizeof(CPhysical) == 0x2EC); +#pragma pack(pop) +} diff --git a/classes/src/entities/fwEntity.hpp b/classes/src/entities/fwEntity.hpp new file mode 100644 index 0000000000..fa03cfdddb --- /dev/null +++ b/classes/src/entities/fwEntity.hpp @@ -0,0 +1,98 @@ +#pragma once + +#include "../base/CBaseModelInfo.hpp" +#include "../base/CNavigation.hpp" +#include "../base/fwExtensibleBase.hpp" +#include "../base/atRTTI.hpp" + +#include "../draw_handlers/fwDrawData.hpp" + +#include + +class CMoveObjectPooledObject; + +namespace rage +{ + class fwDynamicEntityComponent; + class crmtRequestPose; + class crmtRequestIk; + class crFrameFilter; + class fwAudEntity; + +#pragma pack(push, 1) + class fwEntity : public fwExtensibleBase + { + public: + DEFINE_RAGE_RTTI(rage::fwEntity); + + virtual void* _0x38(void*, void*) = 0; + virtual void AddExtension(void* extension) = 0; // 0x40 + virtual void _0x48() = 0; // not implemented + virtual void _0x50() = 0; // only implemented by CEntityBatch + virtual void _0x58() = 0; + virtual void SetModelInfo(std::uint16_t* model_index) = 0; // 0x60 + virtual void _0x68(int, fvector4*) = 0; + virtual void* _0x70(int) = 0; + virtual CNavigation* GetNavigation() = 0; // 0x78 + virtual CMoveObjectPooledObject* CreateMoveObject() = 0; // 0x80 + virtual std::uint32_t* GetType() = 0; // 0x88 + virtual void _0x90() = 0; + virtual float _0x98() = 0; + virtual bool TryRequestInverseKinematics(rage::crmtRequestPose* pose, rage::crmtRequestIk* ik) = 0; // 0xA0 implemented only by CPed + virtual bool TryRequestFacialAnims(void*) = 0; // 0xA8 implemented only by CPed + virtual void* _0xB0() = 0; + virtual std::uint8_t _0xB8() = 0; // implemented only by CPed + virtual rage::crFrameFilter* GetFrameFilter() = 0; // 0xC0 + virtual rage::fwAudEntity* GetEntityAudio() = 0; // 0xC8 + virtual void _0xD0() = 0; + virtual void SetTransform(fmatrix44* matrix, bool update_pos) = 0; // 0xD8 + virtual void SetTransform2(fmatrix44* matrix, bool update_pos) = 0; // 0xE0 + virtual void SetPosition(fvector4* pos, bool update_pos) = 0; // 0xE8 + virtual void SetHeading(float heading, bool update_pos) = 0; // 0xF0 + virtual void SetEntityTypeFlags() = 0; // 0xF8 + virtual void _0x100() = 0; // not implemented + virtual void UpdatePhysics(CNavigation* navigation) = 0; // 0x108 + virtual void UpdatePhysics2(CNavigation* navigation) = 0; // 0x110 + virtual void UpdatePosition() = 0; // 0x118 + + enum class EntityFlags + { + IS_VISIBLE = (1 << 0) + }; + + class CBaseModelInfo* m_model_info; //0x0020 + uint8_t m_entity_type; //0x0028 + char gap29; //0x0029 + uint16_t gap2A; //0x002A + uint32_t m_flags; //0x002D + class CNavigation *m_navigation; //0x0030 + uint16_t gap38; //0x0038 + uint16_t gap3A; //0x003A + uint32_t gap3C; //0x003C + class rage::fwDynamicEntityComponent* m_dynamic_entity_component; //0x0040 (stores attachments and stuff) + class rage::fwDrawData* m_draw_data; //0x0048 + class rage::fwDynamicEntityComponent* gap50; //0x0050 + uint64_t gap58; //0x0058 + fmatrix44 m_transformation_matrix; //0x0060 + rage::fwEntity* m_render_focus_entity; //0x00A0 + uint32_t m_render_focus_distance; //0x00A8 + uint32_t m_flags_2; //0x00AC + uint32_t m_shadow_flags; //0x00B0 + char gapB4[4]; //0x00B4 + std::uint8_t byteB8; //0x00B8 + + rage::fvector3* get_position() + { + return reinterpret_cast(&m_transformation_matrix.rows[3]); + } + + void model_to_world(const fvector3& model_coords, fvector3& world_coords) + { + world_coords.x = model_coords.x * m_transformation_matrix.data[0][0] + model_coords.y * m_transformation_matrix.data[1][0] + model_coords.z * m_transformation_matrix.data[2][0] + m_transformation_matrix.data[3][0]; + world_coords.y = model_coords.x * m_transformation_matrix.data[0][1] + model_coords.y * m_transformation_matrix.data[1][1] + model_coords.z * m_transformation_matrix.data[2][1] + m_transformation_matrix.data[3][1]; + world_coords.z = model_coords.x * m_transformation_matrix.data[0][2] + model_coords.y * m_transformation_matrix.data[1][2] + model_coords.z * m_transformation_matrix.data[2][2] + m_transformation_matrix.data[3][2]; + } + }; + static_assert(sizeof(fwEntity) == 0xB9); +#pragma pack(pop) +} diff --git a/classes/src/enums/eExplosionTag.hpp b/classes/src/enums/eExplosionTag.hpp new file mode 100644 index 0000000000..4cfca5de4e --- /dev/null +++ b/classes/src/enums/eExplosionTag.hpp @@ -0,0 +1,92 @@ +#pragma once + +#include + +enum eExplosionTag : int32_t +{ + DONTCARE = -1, + GRENADE, + GRENADELAUNCHER, + STICKYBOMB, + MOLOTOV, + ROCKET, + TANKSHELL, + HI_OCTANE, + CAR, + PLANE, + PETROL_PUMP, + BIKE, + DIR_STEAM, + DIR_FLAME, + DIR_WATER_HYDRANT, + DIR_GAS_CANISTER, + BOAT, + SHIP_DESTROY, + TRUCK, + BULLET, + SMOKEGRENADELAUNCHER, + SMOKEGRENADE, + BZGAS, + FLARE, + GAS_CANISTER, + EXTINGUISHER, + _0x988620B8, + EXP_TAG_TRAIN, + EXP_TAG_BARREL, + EXP_TAG_PROPANE, + EXP_TAG_BLIMP, + EXP_TAG_DIR_FLAME_EXPLODE, + EXP_TAG_TANKER, + PLANE_ROCKET, + EXP_TAG_VEHICLE_BULLET, + EXP_TAG_GAS_TANK, + EXP_TAG_BIRD_CRAP, + EXP_TAG_RAILGUN, + EXP_TAG_BLIMP2, + EXP_TAG_FIREWORK, + EXP_TAG_SNOWBALL, + EXP_TAG_PROXMINE, + EXP_TAG_VALKYRIE_CANNON, + EXP_TAG_AIR_DEFENCE, + EXP_TAG_PIPEBOMB, + EXP_TAG_VEHICLEMINE, + EXP_TAG_EXPLOSIVEAMMO, + EXP_TAG_APCSHELL, + EXP_TAG_BOMB_CLUSTER, + EXP_TAG_BOMB_GAS, + EXP_TAG_BOMB_INCENDIARY, + EXP_TAG_BOMB_STANDARD, + EXP_TAG_TORPEDO, + EXP_TAG_TORPEDO_UNDERWATER, + EXP_TAG_BOMBUSHKA_CANNON, + EXP_TAG_BOMB_CLUSTER_SECONDARY, + EXP_TAG_HUNTER_BARRAGE, + EXP_TAG_HUNTER_CANNON, + EXP_TAG_ROGUE_CANNON, + EXP_TAG_MINE_UNDERWATER, + EXP_TAG_ORBITAL_CANNON, + EXP_TAG_BOMB_STANDARD_WIDE, + EXP_TAG_EXPLOSIVEAMMO_SHOTGUN, + EXP_TAG_OPPRESSOR2_CANNON, + EXP_TAG_MORTAR_KINETIC, + EXP_TAG_VEHICLEMINE_KINETIC, + EXP_TAG_VEHICLEMINE_EMP, + EXP_TAG_VEHICLEMINE_SPIKE, + EXP_TAG_VEHICLEMINE_SLICK, + EXP_TAG_VEHICLEMINE_TAR, + EXP_TAG_SCRIPT_DRONE, + EXP_TAG_RAYGUN, + EXP_TAG_BURIEDMINE, + EXP_TAG_SCRIPT_MISSILE, + EXP_TAG_RCTANK_ROCKET, + EXP_TAG_BOMB_WATER, + EXP_TAG_BOMB_WATER_SECONDARY, + _0xF728C4A9, + _0xBAEC056F, + EXP_TAG_FLASHGRENADE, + EXP_TAG_STUNGRENADE, + _0x763D3B3B, + EXP_TAG_SCRIPT_MISSILE_LARGE, + EXP_TAG_SUBMARINE_BIG, + EXP_TAG_EMPLAUNCHER_EMP, +}; \ No newline at end of file diff --git a/classes/src/enums/eHandlingType.hpp b/classes/src/enums/eHandlingType.hpp new file mode 100644 index 0000000000..7257da50ef --- /dev/null +++ b/classes/src/enums/eHandlingType.hpp @@ -0,0 +1,16 @@ +#pragma once + +enum class eHandlingType +{ + HANDLING_TYPE_BIKE, + HANDLING_TYPE_FLYING, + HANDLING_TYPE_VERTICAL_FLYING, + HANDLING_TYPE_BOAT, + HANDLING_TYPE_SEAPLANE, + HANDLING_TYPE_SUBMARINE, + HANDLING_TYPE_TRAIN, + HANDLING_TYPE_TRAILER, + HANDLING_TYPE_CAR, + HANDLING_TYPE_WEAPON, + HANDLING_TYPE_MAX_TYPES +}; \ No newline at end of file diff --git a/classes/src/game_files/CGameConfig.hpp b/classes/src/game_files/CGameConfig.hpp new file mode 100644 index 0000000000..1df087bf13 --- /dev/null +++ b/classes/src/game_files/CGameConfig.hpp @@ -0,0 +1,262 @@ +#pragma once +#include "rage/atArray.hpp" + +class CPoolSizes; +class CPoolSize; +class CGameConfig; + +#pragma pack(push, 1) + +class CPoolSize { +public: + char* m_pool; + uint32_t m_size; +}; +static_assert(sizeof(CPoolSize) == 0xC); + +class CStackSizeData { +public: + rage::joaat_t m_stack_name; + int32_t m_size_of_stack; + int32_t m_number_of_stacks_of_this_size; + + inline CStackSizeData(rage::joaat_t name, int size, int num) : + m_stack_name(name), + m_size_of_stack(size), + m_number_of_stacks_of_this_size(num) + { + } + + inline CStackSizeData(const std::string& name, int size, int num) : + m_stack_name(rage::joaat(name)), + m_size_of_stack(size), + m_number_of_stacks_of_this_size(num) + { + } +}; +static_assert(sizeof(CStackSizeData) == 0xC); + +namespace rage +{ + class parStructure; + + class fwConfig + { + public: + virtual ~fwConfig() = 0; + + virtual void copy_data_from_config(fwConfig* config) = 0; + + virtual fwConfig* clone_config() = 0; + + virtual parStructure* get_structure() = 0; + + rage::atArray m_pool_sizes; + char padding[0x8]; + }; + static_assert(sizeof(fwConfig) == 0x20); + + template + class fwConfigManagerImpl + { + public: + virtual ~fwConfigManagerImpl() = 0; + + virtual T* create_config() = 0; + + char padding[0x10]; + + T* m_config; + }; + static_assert(sizeof(fwConfigManagerImpl) == 0x20); +}; + +class CConfigPopulation +{ +public: + int32_t m_scenario_peds_multiplier_base; //0x0000 + int32_t m_scenario_peds_multiplier; //0x0004 + int32_t m_ambient_peds_multiplier_base; //0x0008 + int32_t m_ambient_peds_multiplier; //0x000C + int32_t m_max_total_peds_base; //0x0010 + int32_t m_max_total_peds; //0x0014 + int32_t m_ped_memory_multiplier; //0x0018 + int32_t m_peds_for_vehicles_base; //0x001C + int32_t m_peds_for_vehicles; //0x0020 + int32_t m_vehicle_timeslice_max_updates_per_frame_base; //0x0024 + int32_t m_vehicle_timeslice_max_updates_per_frame; //0x0028 + int32_t m_vehicle_ambient_density_multiplier_base; //0x002C + int32_t m_vehicle_ambient_density_multiplier; //0x0030 + int32_t m_vehicle_memory_multiplier; //0x0034 + int32_t m_vehicle_parked_density_multiplier_base; //0x0038 + int32_t m_vehicle_parked_density_multiplier; //0x003C + int32_t m_vehicle_low_prio_parked_density_multiplier_base; //0x0040 + int32_t m_vehicle_low_prio_parked_density_multiplier; //0x0044 + int32_t m_vehicle_upper_limit_base; //0x0048 + int32_t m_vehicle_upper_limit; //0x004C + int32_t m_vehicle_upper_limit_mp; //0x0050 + int32_t m_vehicle_parked_upper_limit_base; //0x0054 + int32_t m_vehicle_parked_upper_limit; //0x0058 + int32_t m_vehicle_keyhole_shape_inner_thickness_base; //0x005C + int32_t m_vehicle_keyhole_shape_inner_thickness; //0x0060 + int32_t m_vehicle_keyhole_shape_outer_thickness_base; //0x0064 + int32_t m_vehicle_keyhole_shape_outer_thickness; //0x0068 + int32_t m_vehicle_keyhole_shape_inner_radius_base; //0x006C + int32_t m_vehicle_keyhole_shape_inner_radius; //0x0070 + int32_t m_vehicle_keyhole_shape_outer_radius_base; //0x0074 + int32_t m_vehicle_keyhole_shape_outer_radius; //0x0078 + int32_t m_vehicle_keyhole_side_wall_thickness_base; //0x007C + int32_t m_vehicle_keyhole_side_wall_thickness; //0x0080 + int32_t m_vehicle_max_creation_distance_base; //0x0084 + int32_t m_vehicle_max_creation_distance; //0x0088 + int32_t m_vehicle_max_creation_distance_offscreen_base; //0x008C + int32_t m_vehicle_max_creation_distance_offscreen; //0x0090 + int32_t m_vehicle_cull_range_base; //0x0094 + int32_t m_vehicle_cull_range; //0x0098 + int32_t m_vehicle_cull_range_on_screen_scale_base; //0x009C + int32_t m_vehicle_cull_range_on_screen_scale; //0x00A0 + int32_t m_vehicle_cull_range_off_screen_base; //0x00A4 + int32_t m_vehicle_cull_range_off_screen; //0x00A8 + int32_t m_density_based_removal_rate_scale_base; //0x00AC + int32_t m_density_based_removal_rate_scale; //0x00B0 + int32_t m_density_based_removal_target_headroom_base; //0x00B4 + int32_t m_density_based_removal_target_headroom; //0x00B8 + rage::atArray m_vehicle_spacing_base; // TODO: these are atFixedArrays + char pad_00CC[48]; //0x00CC + rage::atArray m_vehicle_spacing; + char pad_010C[48]; //0x010C + int32_t m_players_road_scan_distance_base; //0x013C + int32_t m_players_road_scan_distance; //0x0140 + rage::atArray m_player_road_density_inc_base; + char pad_0154[48]; //0x0154 + rage::atArray m_player_road_density_inc; + char pad_0194[48]; //0x0194 + rage::atArray m_non_player_road_density_dec_base; + char pad_01D4[56]; //0x01D4 + rage::atArray m_non_player_road_density_dec; + char pad_021C[40]; //0x021C + int32_t m_vehicle_population_frame_rate_base; //0x0244 + int32_t m_vehicle_population_frame_rate; //0x0248 + int32_t m_vehicle_population_cycles_per_frame_base; //0x024C + int32_t m_vehicle_population_cycles_per_frame; //0x0250 + int32_t m_vehicle_population_frame_rate_mp_base; //0x0254 + int32_t m_vehicle_population_frame_rate_mp; //0x0258 + int32_t m_vehicle_population_cycles_per_frame_mp_base; //0x025C + int32_t m_vehicle_population_cycles_per_frame_mp; //0x0260 + int32_t m_ped_population_frame_rate_base; //0x0264 + int32_t m_ped_population_frame_rate; //0x0268 + int32_t m_ped_population_cycles_per_frame_base; //0x026C + int32_t m_ped_population_cycles_per_frame; //0x0270 + int32_t m_ped_population_frame_rate_mp_base; //0x0274 + int32_t m_ped_population_frame_rate_mp; //0x0278 + int32_t m_ped_population_cycles_per_frame_mp_base; //0x027C + int32_t m_ped_population_cycles_per_frame_mp; //0x0280 +}; +static_assert(sizeof(CConfigPopulation) == 0x284); + +class CConfig2DEffects // looks unused +{ +public: + int32_t m_max_attrs_audio; //0x0000 + int32_t m_max_attrs_buoyancy; //0x0004 + int32_t m_max_attrs_decal; //0x0008 + int32_t m_max_attrs_explosion; //0x000C + int32_t m_max_attrs_ladder; //0x0010 + char pad_0014[8]; //0x0014 + int32_t m_max_attrs_light_shaft; //0x001C + int32_t m_max_attrs_particle; //0x0020 + int32_t m_max_attrs_proc_obj; //0x0024 + int32_t m_max_attrs_scroll_bar; //0x0028 + int32_t m_max_attrs_spawn_point; //0x002C + char pad_0030[8]; //0x0030 + int32_t m_max_attrs_wind_disturbance; //0x0038 + int32_t m_max_attrs_world_point; //0x003C + int32_t m_0xFC5DD116; //0x0040 + int32_t m_max_effects_world_2d; //0x0044 + char pad[4]; +}; +static_assert(sizeof(CConfig2DEffects) == 0x4C); + +class CConfigModelInfo +{ +public: + char* m_default_player_name; //0x0000 + char* m_default_prologue_player_name; //0x0008 + int32_t m_max_base_model_infos; //0x0010 + int32_t m_max_comp_entity_model_infos; //0x0014 + int32_t m_max_mlo_instances; //0x0018 + int32_t m_max_mlo_model_infos; //0x001C + int32_t m_max_ped_model_infos; //0x0020 + int32_t m_max_time_model_infos; //0x0024 + int32_t m_max_vehicle_model_infos; //0x0028 + int32_t m_max_weapon_model_infos; //0x002C + int32_t m_max_extra_ped_model_infos; //0x0030 + int32_t m_max_extra_vehicle_model_infos; //0x0034 + int32_t m_max_extra_weapon_model_infos; //0x0038 + int32_t m_unk; +}; +static_assert(sizeof(CConfigModelInfo) == 0x40); + +class CConfigExtensions +{ +public: + int32_t m_max_door_extensions; + int32_t m_max_light_extensions; + int32_t m_max_spawn_point_override_extensions; + int32_t m_max_expression_extensions; + int32_t m_0xBDE77A4F; +}; +static_assert(sizeof(CConfigExtensions) == 0x14); + +class CConfigStreamingEngine +{ +public: + int32_t m_archive_count; + int32_t m_physical_streaming_buffer; + int32_t m_virtual_streaming_buffer; +}; +static_assert(sizeof(CConfigStreamingEngine) == 0xC); + +class CConfigOnlineServices +{ +public: + char* m_ros_title_name; + int32_t m_ros_title_version; + int32_t m_sc_version; + int64_t m_steam_app_id; + char* m_title_directory_name; + char* m_multiplayer_session_template_name; + char* m_sc_auth_title_id; +}; +static_assert(sizeof(CConfigOnlineServices) == 0x30); + +class CConfigUGCDescriptions +{ +public: + int32_t m_max_description_length; + int32_t m_max_num_descriptions; + int32_t m_size_of_description_buffer; +}; +static_assert(sizeof(CConfigUGCDescriptions) == 0xC); + +class CConfigScriptStackSizes +{ +public: + rage::atArray m_stack_size_data; +}; +static_assert(sizeof(CConfigScriptStackSizes) == 0x10); + +class CGameConfig : public rage::fwConfig { +public: + CConfigPopulation m_config_population; + CConfig2DEffects m_config_2d_effects; + CConfigModelInfo m_config_model_info; + CConfigExtensions m_config_extensions; + CConfigStreamingEngine m_config_streaming_engine; + CConfigOnlineServices m_config_online_services; + CConfigUGCDescriptions m_config_ugc_descriptions; + char padding[0x488 - 0x38C]; // CConfigNetScriptBroadcastData + CConfigScriptStackSizes m_config_script_stack_sizes; + // TODO: more stuff down here +}; +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/misc/CTunables.hpp b/classes/src/misc/CTunables.hpp new file mode 100644 index 0000000000..d029c1eeb7 --- /dev/null +++ b/classes/src/misc/CTunables.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include "../base/datBase.hpp" + +enum eTunableType +{ + TunableType_DONTCARE = -1, + TunableType_UNK0, + TunableType_4BYTE, + TunableType_1BYTE, +}; + +class CTunables : public rage::datBase +{ +public: + char pad_0000[104]; //0x0008 + uint64_t m_bPtr; //0x0070 + uint16_t m_bCount; //0x0078 + char pad_007A[0x4E]; //0x007A +}; //Size: 0x00C8 +static_assert(sizeof(CTunables) == 0xC8); diff --git a/classes/src/misc/vfx/TimecycleKeyframeData.hpp b/classes/src/misc/vfx/TimecycleKeyframeData.hpp new file mode 100644 index 0000000000..1a4e3fdd9a --- /dev/null +++ b/classes/src/misc/vfx/TimecycleKeyframeData.hpp @@ -0,0 +1,96 @@ +#pragma once + +class TimecycleKeyframeData +{ +public: + char pad_0000[32]; //0x0000 + rage::fvector4 m_azimuth_east; //0x0020 + float m_azimuth_east_intensity; //0x0030 + char pad_0034[28]; //0x0034 + rage::fvector4 m_azimuth_west; //0x0050 + float m_azimuth_west_intensity; //0x0060 + char pad_0064[28]; //0x0064 + rage::fvector4 m_azimuth_transition; //0x0080 + float m_azimuth_transition_intensity; //0x0090 + char pad_0094[4]; //0x0094 + float m_azimuth_transition_position; //0x0098 + char pad_009C[20]; //0x009C + rage::fvector4 m_zenith; //0x00B0 + float m_zenith_intensity; //0x00C0 + char pad_00C4[28]; //0x00C4 + rage::fvector4 m_zenith_transition; //0x00E0 + float m_zenith_transition_intensity; //0x00F0 + float m_zenith_transition_position; //0x00F4 + float m_zenith_transition_east_blend; //0x00F8 + float m_zenith_transition_west_blend; //0x00FC + float m_zenith_blend_start; //0x0100 + char pad_0104[60]; //0x0104 + rage::fvector3 m_plane; //0x0140 + float m_plane_intensity; //0x014C + char pad_0150[52]; //0x0150 + float m_hdr; //0x0184 + float m_unk_188; //0x0188 + bool m_update_sky_attributes; //0x018C + char pad_018D[3]; //0x018D + uint32_t m_unk_190; //0x0190 + uint32_t m_unk_194; //0x0194 + char pad_0198[8]; //0x0198 + rage::fvector4 m_unk_1A0; //0x01A0 + char pad_01AC[16]; //0x01AC + rage::fvector4 m_sun; //0x01C0 + char pad_01CC[32]; //0x01CC + rage::fvector4 m_sun_disc; //0x01F0 + char pad_01FC[32]; //0x01FC + float m_sun_disc_size; //0x0220 + float m_sun_hdr; //0x0224 + float m_sun_miephase; //0x0228 + float m_sun_miescatter; //0x022C + float m_sun_mie_intensity_mult; //0x0230 + char pad_0234[28]; //0x0234 + rage::fvector4 m_unk_250; //0x0250 + char pad_025C[16]; //0x025C + float m_cloud_shadow_strength; //0x0270 + float m_cloud_density_mult; //0x0274 + float m_cloud_density_bias; //0x0278 + float m_cloud_fadeout; //0x027C + char pad_0280[32]; //0x0280 + float m_unk_2A0; //0x02A0 + float m_cloud_offset; //0x02A4 + float m_cloud_overall_color; //0x02A8 + float m_cloud_hdr; //0x02AC + char pad_02B0[32]; //0x02B0 + float m_cloud_dither_strength; //0x02D0 + char pad_02D4[44]; //0x02D4 + float m_cloud_edge_strength; //0x0300 + char pad_0304[4]; //0x0304 + float m_cloud_overall_strength; //0x0308 + char pad_030C[16]; //0x030C + rage::fvector4 m_unk_320; //0x031C + rage::fvector4 m_cloud_base; //0x032C + rage::fvector4 m_unk_340; //0x033C + char pad_0348[16]; //0x0348 + rage::fvector4 m_cloud_1; //0x035C + char pad_0368[20]; //0x0368 + rage::fvector4 m_cloud_mid; //0x0380 + char pad_038C[32]; //0x038C + float m_unk_380; //0x03B0 + float m_small_cloud_detail_strength; //0x03B4 + float m_small_cloud_density_mult; //0x03B8 + float m_unk_3BC; //0x03BC + char pad_03C0[32]; //0x03C0 + rage::fvector4 m_small_cloud; //0x03E0 + char pad_03EC[32]; //0x03EC + float m_sun_influence_radius; //0x0410 + float m_sun_scatter_inten; //0x0414 + float m_moon_influence_radius; //0x0418 + float m_moon_scatter_inten; //0x041C + char pad_0420[212]; //0x0420 + float m_stars_iten; //0x04F4 + char pad_04F8[60]; //0x04F8 + float m_moon_disc_size; //0x0534 + char pad_0538[24]; //0x0538 + rage::fvector4 m_moon; //0x0550 + float m_moon_intensity; //0x0560 + char pad_0564[140]; //0x0564 +}; //Size: 0x05F0 +static_assert(sizeof(TimecycleKeyframeData) == 0x5F0); \ No newline at end of file diff --git a/classes/src/netsync/CProjectBaseSyncDataNode.hpp b/classes/src/netsync/CProjectBaseSyncDataNode.hpp new file mode 100644 index 0000000000..920c11a3dd --- /dev/null +++ b/classes/src/netsync/CProjectBaseSyncDataNode.hpp @@ -0,0 +1,46 @@ +#pragma once +#include "netSyncDataNode.hpp" +#include "NodeCommonDataOperations.hpp" + +namespace rage +{ + class netSyncData; + class netObject; +} + +class CProjectBaseSyncDataNode : public rage::netSyncDataNode +{ +public: + virtual bool IsSyncNode() { return false; } // 0x50 + virtual bool _0x58() { return false; } // 0x58 + virtual bool IsGlobalFlags() { return false; } // 0x60 + virtual void DoPreCache(rage::netSyncData* data) {} // 0x68 + virtual std::uint8_t GetSyncFrequency(int index) { return 0; } // 0x70 + virtual int GetSyncInterval(int index) { return 0; } // 0x78 + virtual int GetBandwidthForPlayer(int player) { return 200; } // 0x80 (should always return 200) + virtual void _0x88(void*) {} // 0x88 + virtual bool _0x90(void*, void*, int, int, int) { return false; } // 0x90 + virtual int CalculateSize() { return 0; } // 0x98 need to verify later + virtual bool IsPreCacheDisabled() { return false; } // 0xA0 + virtual bool CanApply(rage::netObject* object) { return false; } // 0xA8 + virtual int GetPlayersInScope() { return -1; } // 0xB0 + virtual void DeserializeImpl() {} // 0xB8 need to verify later + virtual void SerializeImpl() {} // 0xC0 need to verify later + virtual int CalculateSize2() { return 0; } // 0xC8 + virtual int _0xD0() { return 0; } // 0xD0 calls NodeCommonDataOperations::Unk() + virtual void Log() {} // 0xD8 + virtual bool CanPreCache(int) { return false; } // 0xE0 arg is always zero afaik + virtual bool CanBeEmpty() { return false; } // 0xE8 + virtual bool IsEmpty() { return false; } // 0xF0 returns true if all data is default + virtual void SetEmpty() {} // 0xF8 sets all data to their default values + virtual void Log2() {} // 0x100 + virtual void ResetScriptData() {} // 0x108 + virtual bool _0x110() { return false; } // 0x110 + +private: + NodeCommonDataOperations m_common_data_operations; // 0xB0 this is generally invalidated by MoveCommonDataOpsVFT() +}; +static_assert(sizeof(CProjectBaseSyncDataNode) == 0xC0); + +class CSyncDataNodeFrequent : public CProjectBaseSyncDataNode {}; +class CSyncDataNodeInfrequent : public CProjectBaseSyncDataNode {}; \ No newline at end of file diff --git a/classes/src/netsync/CProjectSyncTree.hpp b/classes/src/netsync/CProjectSyncTree.hpp new file mode 100644 index 0000000000..4751bbd5b0 --- /dev/null +++ b/classes/src/netsync/CProjectSyncTree.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "netSyncTree.hpp" + +class CProjectSyncTree : public rage::netSyncTree +{ + void* m_unk_data; + int m_unk_data_size; + char pad_04C4[4]; +}; +static_assert(sizeof(CProjectSyncTree) == 0x4C8); \ No newline at end of file diff --git a/classes/src/netsync/NodeCommonDataOperations.hpp b/classes/src/netsync/NodeCommonDataOperations.hpp new file mode 100644 index 0000000000..ee5b642210 --- /dev/null +++ b/classes/src/netsync/NodeCommonDataOperations.hpp @@ -0,0 +1,23 @@ +#pragma once + +namespace rage +{ + class datBitBuffer; + class netSyncDataNode; +} + +class NodeCommonDataOperations +{ +public: + virtual ~NodeCommonDataOperations() = default; + virtual void ReadFromBuffer(rage::netSyncDataNode* node) {}; // 0x08 + virtual void WriteToBuffer(rage::netSyncDataNode* node) {}; // 0x10 + virtual void Unk() {}; // 0x18 + virtual int CalculateSize(rage::netSyncDataNode* node) { return 0; }; // 0x20 + virtual int CalculateSize2(rage::netSyncDataNode* node) { return 0; }; // 0x28 + virtual void LogSyncData(rage::netSyncDataNode* node) {}; // 0x30 + virtual void LogSyncData2(rage::netSyncDataNode* node) {}; // 0x38 + + rage::datBitBuffer* m_buffer; // 0x8 +}; +static_assert(sizeof(NodeCommonDataOperations) == 0x10); \ No newline at end of file diff --git a/classes/src/netsync/netSyncDataNode.hpp b/classes/src/netsync/netSyncDataNode.hpp new file mode 100644 index 0000000000..485dc91c7c --- /dev/null +++ b/classes/src/netsync/netSyncDataNode.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include "netSyncNodeBase.hpp" + +namespace rage +{ +#pragma pack(push, 8) + class netSyncDataNode : public netSyncNodeBase + { + public: + uint32_t flags; //0x40 + uint32_t pad3; //0x44 + uint64_t pad4; //0x48 + + netSyncDataNode* parentData; //0x50 + uint32_t childCount; //0x58 + netSyncDataNode* children[8]; //0x5C + uint8_t syncFrequencies[8]; //0x9C + void* commonDataOpsVFT; //0xA8 wtf + }; + static_assert(sizeof(netSyncDataNode) == 0xB0); +#pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/netsync/netSyncNodeBase.hpp b/classes/src/netsync/netSyncNodeBase.hpp new file mode 100644 index 0000000000..6931aed944 --- /dev/null +++ b/classes/src/netsync/netSyncNodeBase.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +namespace rage +{ + class datBitBuffer; + class netSyncTree; + +#pragma pack(push, 8) + class netSyncNodeBase + { + public: + virtual ~netSyncNodeBase() = default; // 0x00 + virtual bool IsDataNode() { return false; }; // 0x08 + virtual bool IsParentNode() { return false; }; // 0x10 + virtual void MoveCommonDataOpsVFT() {}; // 0x18 + virtual void ClearChildren() {}; // 0x20 + virtual void _0x28(void*, void*, void*, int* out_count) {}; // 0x28 + virtual bool Serialize(int flags, int flags2, void*, rage::datBitBuffer* buffer, int, void*, bool, int*, int* num_serialized) { return false; } // 0x30 + virtual bool Deserialize(int flags, int flags2, rage::datBitBuffer* buffer, void*) { return false; } // 0x38 + virtual int CalculateSize(int flags, int flags2, void*) { return 0; } // 0x40 + virtual int CalculateSize2(int flags, int flags2, bool) { return 0; } // 0x48 + + netSyncNodeBase* m_next_sibling; //0x0008 + netSyncNodeBase* m_prev_sibling; //0x0010 + netSyncTree* m_root; //0x0018 + netSyncNodeBase* m_parent; //0x0020 + + uint32_t m_flags1; //0x0028 + uint32_t m_flags2; //0x002C + uint32_t m_flags3; //0x0030 + + uint32_t m_pad2; //0x0034 + + netSyncNodeBase* m_first_child; //0x0038 + }; //Size: 0x0040 + static_assert(sizeof(netSyncNodeBase) == 0x40); +#pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/netsync/netSyncParentNode.hpp b/classes/src/netsync/netSyncParentNode.hpp new file mode 100644 index 0000000000..ec0935ae01 --- /dev/null +++ b/classes/src/netsync/netSyncParentNode.hpp @@ -0,0 +1,14 @@ +#pragma once +#include "netSyncNodeBase.hpp" + +namespace rage +{ + class netSyncParentNode : public netSyncNodeBase + { + public: + char pad_0040[32]; + }; + static_assert(sizeof(netSyncParentNode) == 0x60); +} + +class CProjectBaseSyncParentNode : public rage::netSyncParentNode {}; \ No newline at end of file diff --git a/classes/src/netsync/netSyncTree.hpp b/classes/src/netsync/netSyncTree.hpp new file mode 100644 index 0000000000..e7dc492eb6 --- /dev/null +++ b/classes/src/netsync/netSyncTree.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include "netSyncNodeBase.hpp" + +namespace rage +{ +#pragma pack(push, 1) + class netSyncTree + { + public: + virtual ~netSyncTree() = default; + + char pad_0008[8]; //0x0008 + netSyncNodeBase* m_next_sync_node; //0x0010 + netSyncNodeBase* m_last_sync_node; //0x0018 + uint32_t m_child_node_count; //0x0020 + uint32_t m_unk_array_count; //0x0024 + char pad_0028[8]; //0x0028 + netSyncNodeBase* m_child_nodes[42]; //0x0030 + uint32_t m_child_node_max_count; //0x0180 + netSyncNodeBase* m_unk_array[32]; //0x0188 + uint32_t m_unk_array_max_count; //0x0288 + char pad_0290[560]; //0x0290 + }; //Size: 0x0030 + static_assert(sizeof(netSyncTree) == 0x4B8); +#pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/netsync/nodes/CPedComponents.hpp b/classes/src/netsync/nodes/CPedComponents.hpp new file mode 100644 index 0000000000..d6d75ec82e --- /dev/null +++ b/classes/src/netsync/nodes/CPedComponents.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include + +#pragma pack(push, 4) +class CPedComponents +{ +public: + uint32_t m_component_bitset; //0x0 + char pad_0x4[4]; //0x4 + uint32_t unk_0x8[12]; //0x8 + uint32_t m_drawables[12]; //0x38 + uint32_t m_textures[12]; //0x68 + uint32_t m_palettes[12]; //0x98 + + inline uint32_t get_drawable(int index) + { + if (m_component_bitset & (1 << index)) + { + return m_drawables[index]; + } + + return 0; + } + + inline uint32_t get_texture(int index) + { + if (m_component_bitset & (1 << index)) + { + return m_textures[index]; + } + + return 0; + } + + inline uint32_t get_palette(int index) + { + if (m_component_bitset & (1 << index)) + { + return m_palettes[index]; + } + + return 0; + } +}; +static_assert(sizeof(CPedComponents) == 0xC8); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/automobile/CAutomobileCreationNode.hpp b/classes/src/netsync/nodes/automobile/CAutomobileCreationNode.hpp new file mode 100644 index 0000000000..e48688258b --- /dev/null +++ b/classes/src/netsync/nodes/automobile/CAutomobileCreationNode.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" + +class CAutomobileCreationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_all_doors_closed; //0x00C0 + bool m_door_closed[10]; //0x00C1 +}; +static_assert(sizeof(CAutomobileCreationDataNode) == 0xD0); \ No newline at end of file diff --git a/classes/src/netsync/nodes/door/CDoorCreationDataNode.hpp b/classes/src/netsync/nodes/door/CDoorCreationDataNode.hpp new file mode 100644 index 0000000000..8600a9a725 --- /dev/null +++ b/classes/src/netsync/nodes/door/CDoorCreationDataNode.hpp @@ -0,0 +1,18 @@ +#pragma once +#include +#include "rage/vector.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CDoorCreationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_model; //0x00C0 + char pad_00C4[12]; //0x00C4 + rage::fvector3 m_pos; //0x00D0 + char pad_00DC[12]; //0x00DC + bool m_is_script_door; //0x00E8 + bool m_player_wants_control; //0x00E9 +}; //Size: 0x00EC +static_assert(sizeof(CDoorCreationDataNode) == 0xEC); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/door/CDoorMovementDataNode.hpp b/classes/src/netsync/nodes/door/CDoorMovementDataNode.hpp new file mode 100644 index 0000000000..739a0eca86 --- /dev/null +++ b/classes/src/netsync/nodes/door/CDoorMovementDataNode.hpp @@ -0,0 +1,17 @@ +#pragma once +#include +#include "rage/vector.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CDoorMovementDataNode : CSyncDataNodeFrequent +{ +public: + bool m_is_manual_door; // 0xC0 + float m_open_ratio; // 0xC4 + bool m_opening; // 0xC8 + bool m_fully_open; // 0xC9 + bool m_closed; // 0xCA +}; +static_assert(sizeof(CDoorMovementDataNode) == 0xCC); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/door/CDoorScriptGameStateDataNode.hpp b/classes/src/netsync/nodes/door/CDoorScriptGameStateDataNode.hpp new file mode 100644 index 0000000000..d1b4a6041e --- /dev/null +++ b/classes/src/netsync/nodes/door/CDoorScriptGameStateDataNode.hpp @@ -0,0 +1,18 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +struct CDoorScriptGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_door_system_state; // 0xC0 + float m_automatic_distance; // 0xC4 + float m_slide_rate; // 0xC8 + bool m_has_broken_flags; // 0xCC + uint32_t m_broken_flags; // 0xD0 + bool m_has_damaged_flags; // 0xD4 + uint32_t m_damaged_flags; // 0xD8 + bool m_hold_open; // 0xDC +}; +static_assert(sizeof(CDoorScriptGameStateDataNode) == 0xE0); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/door/CDoorScriptInfoDataNode.hpp b/classes/src/netsync/nodes/door/CDoorScriptInfoDataNode.hpp new file mode 100644 index 0000000000..44cf2f8dca --- /dev/null +++ b/classes/src/netsync/nodes/door/CDoorScriptInfoDataNode.hpp @@ -0,0 +1,16 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" +#include "script/CGameScriptObjInfo.hpp" + +#pragma pack(push, 4) +struct CDoorScriptInfoDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_has_script_info; + int m_pad; + CGameScriptObjInfo m_script_info; + uint32_t m_door_system_hash; + bool m_existing_door_system_entry; +}; +static_assert(sizeof(CDoorScriptInfoDataNode) == 0x120); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp b/classes/src/netsync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp new file mode 100644 index 0000000000..3eefe6ca26 --- /dev/null +++ b/classes/src/netsync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp @@ -0,0 +1,26 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 1) +struct CDecorator +{ + uint32_t m_type; + uint32_t m_name_hash; + uint32_t m_value; +}; +#pragma pack(pop) + +#pragma pack(push, 4) +class CDynamicEntityGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_interior_index; // 0x00C0 + bool unk_00C4; // 0x00C4 + bool unk_00C5; // 0x00C5 + uint32_t m_decor_count; // 0x00C8 + CDecorator m_decors[10]; // 0x00CC + char pad[8]; // TODO! +}; //Size: 0x15C +static_assert(sizeof(CDynamicEntityGameStateDataNode) == 0x14C); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/entity/CEntityOrientationDataNode.hpp b/classes/src/netsync/nodes/entity/CEntityOrientationDataNode.hpp new file mode 100644 index 0000000000..9f1c4f0de7 --- /dev/null +++ b/classes/src/netsync/nodes/entity/CEntityOrientationDataNode.hpp @@ -0,0 +1,11 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CEntityOrientationDataNode : CSyncDataNodeFrequent +{ +public: + rage::fmatrix44 m_eulers; +}; //Size: 0x00EC +static_assert(sizeof(CEntityOrientationDataNode) == 0x100); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/entity/CEntityScriptGameStateDataNode.hpp b/classes/src/netsync/nodes/entity/CEntityScriptGameStateDataNode.hpp new file mode 100644 index 0000000000..ac12b91124 --- /dev/null +++ b/classes/src/netsync/nodes/entity/CEntityScriptGameStateDataNode.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +struct CEntityScriptGameStateDataNode : CSyncDataNodeInfrequent +{ + bool m_fixed; //0x00C0 + bool m_uses_collision; //0x00C1 + bool m_completely_disabled_collision; //0x00C2 +}; //Size: 0x00C3 +static_assert(sizeof(CEntityScriptGameStateDataNode) == 0xC4); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/entity/CEntityScriptInfoDataNode.hpp b/classes/src/netsync/nodes/entity/CEntityScriptInfoDataNode.hpp new file mode 100644 index 0000000000..0e39858f10 --- /dev/null +++ b/classes/src/netsync/nodes/entity/CEntityScriptInfoDataNode.hpp @@ -0,0 +1,14 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" +#include "script/CGameScriptObjInfo.hpp" + +#pragma pack(push, 4) +struct CEntityScriptInfoDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_has_script_info; + int m_pad; + CGameScriptObjInfo m_script_info; +}; +static_assert(sizeof(CEntityScriptInfoDataNode) == 0x118); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/heli/CHeliControlDataNode.hpp b/classes/src/netsync/nodes/heli/CHeliControlDataNode.hpp new file mode 100644 index 0000000000..aaaaa1ebbd --- /dev/null +++ b/classes/src/netsync/nodes/heli/CHeliControlDataNode.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleControlDataNode.hpp" + +#pragma pack(push, 8) +class CHeliControlDataNode : CVehicleControlDataNode +{ +public: + char m_pad[0x10]; // 0x130 + float m_yaw_control; // 0x140 + float m_pitch_control; // 0x144 + float m_roll_control; // 0x148 + float m_throttle_control; // 0x14C + bool m_engine_off; // 0x150 + int m_landing_gear_state; // 0x154 + bool m_has_landing_gear; // 0x158 + bool m_has_vehicle_task; // 0x159 + bool m_is_thruster_model; // 0x15A + float m_thruster_side_rcs_throttle; // 0x15C + float m_thruster_throttle; // 0x160 + bool m_unk8; // 0x164 +}; +static_assert(sizeof(CHeliControlDataNode) == 0x168); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/heli/CHeliHealthDataNode.hpp b/classes/src/netsync/nodes/heli/CHeliHealthDataNode.hpp new file mode 100644 index 0000000000..4369d84a04 --- /dev/null +++ b/classes/src/netsync/nodes/heli/CHeliHealthDataNode.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalHealthDataNode.hpp" + +#pragma pack(push, 8) +class CHeliHealthDataNode : CPhysicalHealthDataNode // intentionally private since the physical health node fields aren't serialized +{ +public: + char m_pad[0x10]; // 0xF0 + uint32_t m_main_rotor_health; + uint32_t m_rear_rotor_health; + bool m_can_tail_boom_break_off; + bool m_is_tail_boom_broken; + bool m_unk; + bool m_disable_explode_from_body_damage; + uint32_t m_body_health; + uint32_t m_petrol_tank_health; + uint32_t m_engine_health; + float m_unk_deformation_level; + float m_unk2_deformation_level; + float m_unk3_deformation_level; +}; +static_assert(sizeof(CHeliHealthDataNode) == 0x118); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/object/CObjectCreationDataNode.hpp b/classes/src/netsync/nodes/object/CObjectCreationDataNode.hpp new file mode 100644 index 0000000000..0058d9f3be --- /dev/null +++ b/classes/src/netsync/nodes/object/CObjectCreationDataNode.hpp @@ -0,0 +1,45 @@ +#pragma once +#include +#include "rage/vector.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CObjectCreationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t unk_00C0; //0x00C0 + uint32_t unk_00C4; //0x00C4 + uint32_t unk_00C8; //0x00C8 + bool unk_00CC; + bool unk_00CD; + uint16_t unk_00D0; //0x00D0 + char pad_0xC2[14]; //0x00D2 + rage::fvector4 m_object_orientation; //0x00E0 + char pad_00E0[30]; //0x00F0 + rage::fvector3 m_object_position; //0x0110 + char pad_010C[4]; //0x011C + rage::fvector3 m_dummy_position; //0x011E + char pad_011A[20]; //0x012C + rage::fvector3 m_script_grab_position; //0x0140 + char pad_013C[12]; //0x013C + float m_script_grab_radius; //0x0148 + uint32_t m_created_by; //0x014C + uint32_t m_model; //0x0150 + uint32_t m_frag_group_index; //0x0154 + uint32_t m_ownership_token; //0x0158 + uint32_t unk_015C; //0x015C + bool m_no_reassign; //0x0160 + bool unk_0161; //0x0161 + bool m_player_wants_control; //0x0162 + bool m_has_init_physics; //0x0163 + bool m_script_grabbed_from_world; //0x0164 + bool m_has_frag_group; //0x0165 + bool m_is_broken; //0x0166 + bool m_has_exploded; //0x0167 + bool m_keep_registered; //0x0168 + bool unk_0169; //0x0169 + bool unk_016A; //0x016A + bool unk_016B; //0x016B +}; //Size: 0x016C +static_assert(sizeof(CObjectCreationDataNode) == 0x17C); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/ped/CPedAIDataNode.hpp b/classes/src/netsync/nodes/ped/CPedAIDataNode.hpp new file mode 100644 index 0000000000..f00893544a --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedAIDataNode.hpp @@ -0,0 +1,11 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +class CPedAIDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_relationship_group; //0x00C0 + uint32_t m_decision_maker_type; //0x00C4 +}; //Size: 0x00C8 +static_assert(sizeof(CPedAIDataNode) == 0xC8); diff --git a/classes/src/netsync/nodes/ped/CPedAppearanceDataNode.hpp b/classes/src/netsync/nodes/ped/CPedAppearanceDataNode.hpp new file mode 100644 index 0000000000..80338cccc5 --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedAppearanceDataNode.hpp @@ -0,0 +1,33 @@ +#pragma once +#include "../CPedComponents.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPedAppearanceDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t unk_0xC0[6]; //0xC0 + uint32_t unk_0xD8[6]; //0xD8 + class CPedComponents components; //0xF0 + char pad_0x1B8[8]; //0x1B8 + uint32_t unk_0x1C0; //0x1C0 + uint8_t unk_0x1C4; //0x1C4 + uint8_t unk_0x1C5; //0x1C5 + char pad_0x1C6[2]; //0x1C6 + uint32_t unk_0x1C8; //0x1C8 + uint32_t unk_0x1CC; //0x1CC + uint32_t unk_0x1D0; //0x1D0 + bool unk_0x1D4; //0x1D4 + bool unk_0x1D5; //0x1D5 + bool unk_0x1D6; //0x1D6 + uint8_t unk_0x1D7; //0x1D7 + uint16_t unk_0x1D8; //0x1D8 + uint16_t unk_0x1DA; //0x1DA + uint16_t unk_0x1DC; //0x1DC + bool unk_0x1DE; //0x1DE + bool unk_0x1DF; //0x1DF + bool unk_0x1E0; //0x1E0 + uint8_t unk_0x1E1; //0x1E1 +}; +static_assert(sizeof(CPedAppearanceDataNode) == 0x1E4); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/ped/CPedAttachDataNode.hpp b/classes/src/netsync/nodes/ped/CPedAttachDataNode.hpp new file mode 100644 index 0000000000..4c8c087b87 --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedAttachDataNode.hpp @@ -0,0 +1,22 @@ +#pragma once +#include +#include "rage/vector.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPedAttachDataNode : CSyncDataNodeInfrequent +{ +public: + rage::fvector3 m_offset; //0x00C0 + char pad_00CC[4]; //0x00CC + rage::fvector4 m_orientation; //0x00D0 + uint16_t m_attached_to; //0x00E0 + uint16_t m_attachment_bone; //0x00E2 + uint32_t m_attachment_flags; //0x00E4 + float m_heading_1; //0x00E8 + float m_heading_2; //0x00EC + bool m_attached; //0x00F0 + bool unk_00F1; //0x00F1 +}; +static_assert(sizeof(CPedAttachDataNode) == 0xF4); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/ped/CPedComponentReservationDataNode.hpp b/classes/src/netsync/nodes/ped/CPedComponentReservationDataNode.hpp new file mode 100644 index 0000000000..ac12d1c765 --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedComponentReservationDataNode.hpp @@ -0,0 +1,14 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPedComponentReservationDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_num_peds_using_component; //0x00C0 + uint16_t m_peds_using_component[32]; //0x00C4 +}; //Size: 0x00C8 +#pragma pack(pop) + +static_assert(sizeof(CPedComponentReservationDataNode) == 0x104); diff --git a/classes/src/netsync/nodes/ped/CPedCreationDataNode.hpp b/classes/src/netsync/nodes/ped/CPedCreationDataNode.hpp new file mode 100644 index 0000000000..dc8c9f3ea2 --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedCreationDataNode.hpp @@ -0,0 +1,28 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPedCreationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_pop_type; //0x00C0 + uint32_t m_model; //0x00C4 + uint32_t m_random_seed; //0x00C8 + uint32_t m_max_health; //0x00CC + bool m_in_vehicle; //0x00D0 + char pad_0xD1[1]; //0x00D1 + uint16_t m_vehicle_id; //0x00D2 + uint32_t m_vehicle_seat; //0x00D4 + bool m_has_prop; //0x00D8 + char pad_0xD9[3]; //0x00D9 + uint32_t m_prop_model; //0x00DC + bool m_is_standing; //0x00E0 + bool m_is_respawn_object_id; //0x00E1 + bool m_is_respawn_flagged_for_removal; //0x00E2 + bool m_has_attr_damage_to_player; //0x00E3 + uint8_t m_attribute_damage_to_player; //0x00E4 + uint32_t m_voice_hash; //0x00E8 +}; //Size: 0x00EC +static_assert(sizeof(CPedCreationDataNode) == 0xEC); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/ped/CPedGameStateDataNode.hpp b/classes/src/netsync/nodes/ped/CPedGameStateDataNode.hpp new file mode 100644 index 0000000000..bd470dabe0 --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedGameStateDataNode.hpp @@ -0,0 +1,77 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,2) +class CPedGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_weapon_component_something[12]; //0x0C0 + uint32_t m_weapon_component_hash[12]; //0x0CC + uint32_t m_gadget_hash[3]; //0x0F8 + uint32_t unk_0104; // 0x0104 + uint32_t unk_0108; // 0x0108 + uint32_t unk_010C; // 0x010C + float unk_0110; // 0x0110 + float unk_0114; // 0x0114 + float unk_0118; // 0x0118 + bool unk_011C; // 0x011C + char pad_011D[3]; //0x011D + uint32_t m_arrest_state; //0x0120 + uint32_t m_death_state; //0x0124 + uint32_t m_weapon_hash; //0x0128 + uint32_t m_num_weapon_components; //0x012C + uint32_t m_num_equiped_gadgets; //0x0130 + uint32_t m_seat; //0x0134 + uint32_t m_action_mode_override; //0x0138 + uint32_t unk_013C; // 0x013C + uint16_t m_vehicle; //0x0140 + uint16_t m_mount_id; //0x0142 + uint16_t m_custodian_id; //0x0144 + uint16_t unk_0146; // 0x0146 + bool m_tint_index; //0x0148 + char pad_0149; //0x0149 + uint8_t unk_014A; // 0x014A + bool m_is_handcuffed; //0x014B + bool m_can_preform_arrest; //0x014C + bool m_can_preform_uncuff; //0x014D + bool m_can_be_arrested; //0x014E + bool m_is_in_custody; //0x014F + char pad_0150; //0x0150 + bool m_weapon_exists; //0x0151 + bool m_weapon_visible; //0x0152 + bool m_weapon_has_ammo; //0x0153 + bool m_weapon_attach_left; //0x0154 + char pad_0155; //0x0155 + bool m_in_seat; //0x0156 + bool m_in_vehicle; //0x0157 + bool m_on_mount; //0x0158 + bool m_has_custodian_or_arrest_flags; //0x0159 + char pad_015A; //0x015A + bool m_action_mode_enabled; //0x015B + bool m_stealth_mode_enabled; //0x015C + bool unk_015D; // 0x015D + bool unk_015E; // 0x015E + bool unk_015F; // 0x015F + bool unk_0160; // 0x0160 + bool unk_0161; // 0x0161 + bool unk_0162; // 0x0162 + bool unk_0163; // 0x0163 + bool unk_0164; // 0x0164 + bool unk_0165; // 0x0165 + bool unk_0166; // 0x0166 + bool unk_0167; // 0x0167 + bool unk_0168; // 0x0168 + bool unk_0169; // 0x0169 + bool unk_016A; // 0x016A + bool unk_016B; // 0x016B + bool unk_016C; // 0x016C + bool unk_016D; // 0x016D + bool unk_016E; // 0x016E + bool unk_016F; // 0x016F + bool unk_0170; // 0x0170 + bool unk_0171; // 0x0171 + bool unk_0172; // 0x0172 +}; //Size: 0x0174 +static_assert(sizeof(CPedGameStateDataNode) == 0x178); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/ped/CPedHealthDataNode.hpp b/classes/src/netsync/nodes/ped/CPedHealthDataNode.hpp new file mode 100644 index 0000000000..2fe33ed183 --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedHealthDataNode.hpp @@ -0,0 +1,28 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" +#include + +#pragma pack(push,2) +class CPedHealthDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t unk_00C0; //0x00C0 + uint32_t m_health; //0x00C4 + uint32_t m_armor; //0x00C8 + uint32_t unk_00CC; //0x00CC + uint32_t unk_00D0; //0x00D0 + uint32_t m_weapon_damage_hash; //0x00D4 + uint32_t m_hurt_end_time; //0x00D8 + uint32_t m_weapon_damage_component; //0x00DC + uint16_t m_weapon_damage_entity; //0x00E0 + bool m_has_max_health; //0x00E2 + bool m_has_default_armor; //0x00E3 + bool unk_00E4; //0x00E4 + bool m_killed_with_headshot; //0x00E5 + bool m_killed_with_melee; //0x00E6 + char m_hurt_started; //0x00E7 + bool unk_00E8; //0x00E8 + bool unk_00E9; //0x00E9 +}; //Size: 0x0EA +static_assert(sizeof(CPedHealthDataNode) == 0xEA); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/ped/CPedInventoryDataNode.hpp b/classes/src/netsync/nodes/ped/CPedInventoryDataNode.hpp new file mode 100644 index 0000000000..98099fbd0b --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedInventoryDataNode.hpp @@ -0,0 +1,22 @@ +#pragma once +#include + +// todo? +#pragma pack(push, 4) +class CPedInventoryDataNode +{ +public: + char pad_0000[5232]; + uint32_t m_items[105]; + uint32_t m_num_items; + uint32_t m_ammos[65]; + uint32_t m_ammo_quantities[65]; + uint32_t m_num_ammos; + uint8_t unk_1680[105]; + uint8_t unk_16E9[105]; + char pad_1680[1260]; + bool m_infinite_ammos[65]; + bool m_ammo_all_infinite; +}; +static_assert(sizeof(CPedInventoryDataNode) == 0x1E24); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/ped/CPedMovementDataNode.hpp b/classes/src/netsync/nodes/ped/CPedMovementDataNode.hpp new file mode 100644 index 0000000000..ae545dfbbe --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedMovementDataNode.hpp @@ -0,0 +1,17 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPedMovementDataNode : CSyncDataNodeFrequent +{ +public: + bool m_has_desired_move_blend_ratio_x; //0x00C0 + bool m_has_desired_move_blend_ratio_y; //0x00C1 + bool unk_00C2; //0x00C2 + float m_desired_move_blend_ratio_x; //0x00C4 + float m_desired_move_blend_ratio_y; //0x00C8 + float unk_00CC; //0x00CC + float m_desired_pitch; //0x00D0 +}; //Size: 0x00D4 +static_assert(sizeof(CPedMovementDataNode) == 0xD4); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/ped/CPedMovementGroupDataNode.hpp b/classes/src/netsync/nodes/ped/CPedMovementGroupDataNode.hpp new file mode 100644 index 0000000000..bf4c90c8f4 --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedMovementGroupDataNode.hpp @@ -0,0 +1,24 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPedMovementGroupDataNode : CSyncDataNodeFrequent +{ +public: + float m_unk; // 0xC0 (CTaskMotionInAutomobile+0x1EC) + uint32_t m_movement_task_index; // 0xC4 + uint32_t m_movement_task_stage; // 0xC8 + uint32_t m_movement_group; // 0xCC + uint32_t m_overridden_weapon_group; // 0xD0 + uint32_t m_overridden_unk_group; // 0xD4 (SET_PED_ALTERNATE_MOVEMENT_ANIM?) + bool m_is_crouching; // 0xD8 + bool m_is_stealthy; // 0xD9 + bool m_is_strafing; // 0xDA + bool m_is_ragdolling; // 0xDB + bool m_is_ragdoll_constraint_ankle_active;// 0xDC + bool m_is_ragdoll_constraint_wrist_active;// 0xDD + char m_pad1[2]; // 0xDE + char m_tennis_data[0x20]; // 0xE0 TODO +}; +static_assert(sizeof(CPedMovementGroupDataNode) == 0x100); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/ped/CPedOrientationDataNode.hpp b/classes/src/netsync/nodes/ped/CPedOrientationDataNode.hpp new file mode 100644 index 0000000000..c2e5cd08e0 --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedOrientationDataNode.hpp @@ -0,0 +1,14 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPedOrientationDataNode : CSyncDataNodeFrequent +{ +public: + bool m_has_desired_heading_x; //000C1 + bool m_has_desired_heading_y; //000C2 + float m_desired_heading_x; //0x00C4 + float m_desired_heading_y; //0x00C8 +}; +static_assert(sizeof(CPedOrientationDataNode) == 0xCC); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/ped/CPedScriptCreationDataNode.hpp b/classes/src/netsync/nodes/ped/CPedScriptCreationDataNode.hpp new file mode 100644 index 0000000000..8d7e63e9cc --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedScriptCreationDataNode.hpp @@ -0,0 +1,11 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPedScriptCreationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_stay_in_car_when_jacked; //0x00C0 +}; //Size: 0x00C1 +static_assert(sizeof(CPedScriptCreationDataNode) == 0xC4); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/ped/CPedTaskSequenceDataNode.hpp b/classes/src/netsync/nodes/ped/CPedTaskSequenceDataNode.hpp new file mode 100644 index 0000000000..e7353d8dba --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedTaskSequenceDataNode.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPedTaskSequenceData +{ +public: + int m_task_type; // 0x00 + int m_task_data_size; // 0x04 + char m_task_data[602]; // 0x08 +}; +static_assert(sizeof(CPedTaskSequenceData) == 0x264); + +class CPedTaskSequenceDataNode : CSyncDataNodeFrequent +{ +public: + bool m_has_sequence; // 0xC0 + int m_sequence_resource_id; // 0xC4 + int m_num_tasks_in_sequence; // 0xC8 + CPedTaskSequenceData m_task_data[10]; // 0xCC + int m_unk; // 0x18B4 +}; +static_assert(sizeof(CPedTaskSequenceDataNode) == 0x18B8); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/ped/CPedTaskSpecificDataNode.hpp b/classes/src/netsync/nodes/ped/CPedTaskSpecificDataNode.hpp new file mode 100644 index 0000000000..4f4bb7f54d --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedTaskSpecificDataNode.hpp @@ -0,0 +1,15 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPedTaskSpecificDataNode : CSyncDataNodeFrequent +{ +public: + uint32_t m_task_index; //0x00C0 + uint32_t m_task_type; //0x00C4 + uint32_t m_buffer_size; //0x00C8 + uint8_t m_task_data_buffer[603]; //0x00CC +}; //Size: 0x0328 +static_assert(sizeof(CPedTaskSpecificDataNode) == 0x328); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/ped/CPedTaskTreeDataNode.hpp b/classes/src/netsync/nodes/ped/CPedTaskTreeDataNode.hpp new file mode 100644 index 0000000000..f1bf38f4d5 --- /dev/null +++ b/classes/src/netsync/nodes/ped/CPedTaskTreeDataNode.hpp @@ -0,0 +1,26 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPedTaskData +{ +public: + int m_task_type; // 0x00 + int m_priority; // 0x04 + int m_tree_depth; // 0x08 + int m_sequence_id; // 0x0C + bool m_active; // 0x10 +}; +static_assert(sizeof(CPedTaskData) == 0x14); + +class CPedTaskTreeDataNode : CSyncDataNodeFrequent +{ +public: + CPedTaskData m_tasks[8]; // 0xC0 + int m_task_bitset; // 0x160 + int m_script_command; // 0x164 + int m_script_command_stage; // 0x168 +}; +static_assert(sizeof(CPedTaskTreeDataNode) == 0x16C); // tree offset != size for this one +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/physical/CPhysicalAngVelocityDataNode.hpp b/classes/src/netsync/nodes/physical/CPhysicalAngVelocityDataNode.hpp new file mode 100644 index 0000000000..74a115a673 --- /dev/null +++ b/classes/src/netsync/nodes/physical/CPhysicalAngVelocityDataNode.hpp @@ -0,0 +1,14 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPhysicalAngVelocityDataNode : CSyncDataNodeFrequent +{ +public: + int32_t m_ang_velocity_x; //0x00C0 Divide by 16. + int32_t m_ang_velocity_y; //0x00C4 Divide by 16. + int32_t m_ang_velocity_z; //0x00C8 Divide by 16. +}; // 0x00CC +static_assert(sizeof(CPhysicalAngVelocityDataNode) == 0xCC); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/physical/CPhysicalAttachDataNode.hpp b/classes/src/netsync/nodes/physical/CPhysicalAttachDataNode.hpp new file mode 100644 index 0000000000..99a3180356 --- /dev/null +++ b/classes/src/netsync/nodes/physical/CPhysicalAttachDataNode.hpp @@ -0,0 +1,31 @@ +#pragma once +#include +#include "rage/vector.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPhysicalAttachDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_attached; //0x00C0 + bool unk_00C1; //0x00C1 + uint16_t m_attached_to; //0x00C2 + char pad_00C4[12]; //0x00C4 + rage::fvector3 m_offset; //0x00D0 + char pad_00DC[4]; //0x00DC + rage::fvector4 m_orientation; //0x00E0 + rage::fvector3 m_parent_offset; //0x00F0 + char pad_00FC[4]; //0x00FC + uint16_t m_other_attach_bone; //0x0100 + uint16_t m_attach_bone; //0x0102 + uint32_t m_attach_flags; //0x0104 + bool m_allow_initial_separation; //0x0108 + char pad_00109[3]; //0x0109 + float unk_010C; //0x010C + float unk_0110; //0x0110 + bool unk_0114; //0x0114 + bool unk_0115; //0x0115 + bool m_is_cargo_vehicle; //0x0116 +}; //Size: 0x0118 +static_assert(sizeof(CPhysicalAttachDataNode) == 0x118); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/physical/CPhysicalGameStateDataNode.hpp b/classes/src/netsync/nodes/physical/CPhysicalGameStateDataNode.hpp new file mode 100644 index 0000000000..8b44ec3854 --- /dev/null +++ b/classes/src/netsync/nodes/physical/CPhysicalGameStateDataNode.hpp @@ -0,0 +1,19 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPhysicalGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_is_visible; // 0xC0 + bool m_flag2; // 0xC1 + bool m_flag3; // 0xC2 + bool m_flag4; // 0xC3 + char m_pad; // 0xC4 + uint32_t m_val1; // 0xC8 + int16_t m_unk204; // 0xCC + bool m_unk5; // 0xCE +}; // 0x00CC +static_assert(sizeof(CPhysicalGameStateDataNode) == 0xD0); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/physical/CPhysicalHealthDataNode.hpp b/classes/src/netsync/nodes/physical/CPhysicalHealthDataNode.hpp new file mode 100644 index 0000000000..4b4e3b34d9 --- /dev/null +++ b/classes/src/netsync/nodes/physical/CPhysicalHealthDataNode.hpp @@ -0,0 +1,17 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 8) +struct CPhysicalHealthDataNode : CSyncDataNodeInfrequent +{ + bool unk_00C0; //0x00C0 + bool m_has_max_health_changed; //0x00C1 + uint32_t m_max_health; //0x00C4 + uint32_t m_current_health; //0x00C8 + uint16_t m_weapon_damage_entity; //0x00CC + uint32_t m_weapon_damage_hash; //0x00D0 + uint64_t unk_00D8; //0x00D8 +}; +static_assert(sizeof(CPhysicalHealthDataNode) == 0xE0); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/physical/CPhysicalMigrationDataNode.hpp b/classes/src/netsync/nodes/physical/CPhysicalMigrationDataNode.hpp new file mode 100644 index 0000000000..65a9259e06 --- /dev/null +++ b/classes/src/netsync/nodes/physical/CPhysicalMigrationDataNode.hpp @@ -0,0 +1,12 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPhysicalMigrationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_unk; +}; +static_assert(sizeof(CPhysicalMigrationDataNode) == 0xC4); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/physical/CPhysicalScriptGameStateDataNode.hpp b/classes/src/netsync/nodes/physical/CPhysicalScriptGameStateDataNode.hpp new file mode 100644 index 0000000000..43ca261fa7 --- /dev/null +++ b/classes/src/netsync/nodes/physical/CPhysicalScriptGameStateDataNode.hpp @@ -0,0 +1,36 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPhysicalScriptGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_godmode; + bool m_dont_load_collision; + bool m_freeze_on_collision_load; + bool m_only_damaged_by_player; + bool m_bullet_proof; + bool m_fire_proof; + bool m_explosion_proof; + bool m_collision_proof; + bool m_melee_proof; + bool m_cannot_be_damaged_by_relationship_group; + bool m_can_only_be_damaged_by_relationship_group; + bool m_smoke_proof; + bool m_steam_proof; + bool m_can_only_be_damaged_by_participants; + bool m_dont_reset_proofs_on_cleanup_mission; + bool m_no_reassign; + bool m_pass_control_in_tutorial; + bool m_visible_in_cutscene; + bool m_visible_in_cutscene_remain_hack; + bool m_pickup_by_cargobob_disabled; + uint32_t m_relationship_group; + uint32_t m_always_cloned_for_players; + bool m_modified_max_speed; + bool m_trigger_damage_event_for_zero_damage; + float m_max_speed; +}; +static_assert(sizeof(CPhysicalScriptGameStateDataNode) == 0xE4); // don't know the actual size of this one +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp b/classes/src/netsync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp new file mode 100644 index 0000000000..79aaa7f440 --- /dev/null +++ b/classes/src/netsync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp @@ -0,0 +1,14 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPhysicalScriptMigrationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_has_data; // 0xC0 + int m_script_participants; // 0xC4 + uint16_t m_host_token; // 0xC8 +}; +static_assert(sizeof(CPhysicalScriptMigrationDataNode) == 0xCC); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/physical/CPhysicalVelocityDataNode.hpp b/classes/src/netsync/nodes/physical/CPhysicalVelocityDataNode.hpp new file mode 100644 index 0000000000..83ee8cb342 --- /dev/null +++ b/classes/src/netsync/nodes/physical/CPhysicalVelocityDataNode.hpp @@ -0,0 +1,14 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPhysicalVelocityDataNode : CSyncDataNodeFrequent +{ +public: + int32_t m_velocity_x; //0x00C0 Divide by 16. + int32_t m_velocity_y; //0x00C4 Divide by 16. + int32_t m_velocity_z; //0x00C8 Divide by 16. +}; // 0x00CC +static_assert(sizeof(CPhysicalVelocityDataNode) == 0xCC); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/pickup/CPickupCreationDataNode.hpp b/classes/src/netsync/nodes/pickup/CPickupCreationDataNode.hpp new file mode 100644 index 0000000000..f1ded50ca0 --- /dev/null +++ b/classes/src/netsync/nodes/pickup/CPickupCreationDataNode.hpp @@ -0,0 +1,27 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" +#include "script/CGameScriptObjInfo.hpp" + +#pragma pack(push, 8) +class CPickupCreationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_has_placement; //0x00C0 + char pad_00C1[7]; //0x00C1 + CGameScriptObjInfo m_script_object_info; //0x00C8 + uint32_t m_pickup_hash; //0x0118 + uint32_t m_amount; //0x011C + uint32_t m_custom_model; //0x0120 + uint32_t m_life_time; //0x0124 + uint32_t m_weapon_component[12]; //0x0128 + uint32_t m_num_weapon_components; //0x0154 + uint32_t m_tint_index; //0x0158 + bool m_player_gift; //0x015C + bool unk_015D; //0x015D + char pad_015E[6]; //0x015E + uint32_t unk_0164; //0x0164 + bool unk_0168; //0x0168 +}; //Size: 0x0170 +static_assert(sizeof(CPickupCreationDataNode) == 0x170); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/pickup_placement/CPickupPlacementCreationDataNode.hpp b/classes/src/netsync/nodes/pickup_placement/CPickupPlacementCreationDataNode.hpp new file mode 100644 index 0000000000..7dab6ba7e6 --- /dev/null +++ b/classes/src/netsync/nodes/pickup_placement/CPickupPlacementCreationDataNode.hpp @@ -0,0 +1,24 @@ +#pragma once +#include +#include "rage/vector.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 8) +class CPickupPlacementCreationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_has_pickup_data; //0x00C0 + char pad_00C1[15]; //0x00C1 + rage::fvector3 m_pickup_pos; //0x00D0 + char pad_00DC[4]; //0x00DC + rage::fvector4 m_pickup_orientation; //0x00E0 + uint32_t m_pickup_type; //0x00F0 + uint32_t m_pickup_flags; //0x00F4 + uint32_t m_amount; //0x00F8 + uint32_t m_custom_model; //0x00FC + uint32_t m_custom_regeneration_time; //0x0100 + uint32_t m_team_permits; //0x0104 + uint64_t *unk_struct_0108; //0x0108 +}; //Size: 0x0110 +static_assert(sizeof(CPickupPlacementCreationDataNode) == 0x110); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/player/CPlayerAmbientModelStreamingNode.hpp b/classes/src/netsync/nodes/player/CPlayerAmbientModelStreamingNode.hpp new file mode 100644 index 0000000000..51ae06a0d2 --- /dev/null +++ b/classes/src/netsync/nodes/player/CPlayerAmbientModelStreamingNode.hpp @@ -0,0 +1,16 @@ +#pragma once +#include +#include "rage/vector.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPlayerAmbientModelStreamingNode : CSyncDataNodeInfrequent +{ +public: + int m_allowed_ped_model_start_offset; // 0xC0 + int m_allowed_vehicle_model_start_offset; // 0xC4 + int m_vehicle_anim_streaming_target_entrypoint; // 0xC8 + int16_t m_vehicle_anim_streaming_target; // 0xCC +}; +static_assert(sizeof(CPlayerAmbientModelStreamingNode) == 0xD0); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/player/CPlayerAppearanceDataNode.hpp b/classes/src/netsync/nodes/player/CPlayerAppearanceDataNode.hpp new file mode 100644 index 0000000000..6338e46192 --- /dev/null +++ b/classes/src/netsync/nodes/player/CPlayerAppearanceDataNode.hpp @@ -0,0 +1,93 @@ +#pragma once +#include "../CPedComponents.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPlayerAppearanceDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t unk_0xC0[60]; //0xC0 + class CPedComponents components; //0x1A0 + char pad_0x268[8]; //0x268 + uint32_t unk_0x270[6]; //0x270 + uint32_t unk_0x288[6]; //0x288 + char pad_0x2A0[8]; //0x2A0 + float unk_0x2A8; //0x2A8 + uint8_t unk_0x2AC; //0x2AC + uint8_t unk_0x2AD; //0x2AD + char pad_0x2AE[26]; //0x2AE + float m_shape_mix; //0x2C8 + float m_skin_mix; //0x2CC + float m_third_mix; //0x2D0 + float unk_0x2D4; //0x2D4 + float unk_0x2D8[13]; //0x2D8 + float unk_0x30C[13]; //0x30C + float unk_0x340[20]; //0x340 + uint8_t unk_0x390[13]; //0x390 + uint8_t unk_0x39D[13]; //0x39D + uint8_t unk_0x3AA[13]; //0x3AA + uint8_t m_shape_first; //0x3B7 + uint8_t m_shape_second; //0x3B8 + uint8_t m_shape_third; //0x3B9 + uint8_t m_skin_first; //0x3BA + uint8_t m_skin_second; //0x3BB + uint8_t m_skin_third; //0x3BC + uint8_t unk_0x3BD[13]; //0x3BD + uint8_t unk_0x3CA[11]; //0x3CA + int16_t unk_0x3D6; //0x3D6 + uint8_t unk_0x3D8; //0x3D8 + uint8_t unk_0x3D9; //0x3D9 + char pad_0x3DA[1]; //0x3DA + bool unk_0x3DB; //0x3DB + bool unk_0x3DC; //0x3DC + char pad_0x3DD[3]; //0x3DD + uint32_t unk_0x3E0; //0x3E0 + uint32_t unk_0x3E4; //0x3E4 + uint32_t unk_0x3E8; //0x3E8 + uint32_t unk_0x3EC; //0x3EC + uint32_t unk_0x3F0; //0x3F0 + float unk_0x3F4; //0x3F4 + float m_blend_in_duration; //0x3F8 + float m_blend_out_duration; //0x3FC + uint32_t m_anim_name_hash; //0x400 + uint32_t m_anim_dict_index; //0x404 + uint32_t m_anim_flags; //0x408 + uint32_t unk_0x40C; //0x40C + uint32_t unk_0x410; //0x410 + bool m_anim_task_active; //0x414 + bool unk_0x415; //0x415 + bool m_task_move_active; //0x416 + bool m_mobile_phone_task_active; //0x417 + bool m_mobile_phone_gesture_active; //0x418 + bool unk_0x419; //0x419 + uint32_t unk_0x41C; //0x41C + uint32_t m_model_hash; //0x420 + uint32_t m_voice_hash; //0x424 + uint32_t m_phone_mode; //0x428 + uint32_t unk_0x42C; //0x42C + uint8_t m_parachute_tint_index; //0x430 + uint8_t m_parachute_pack_tint_index; //0x431 + uint16_t m_respawn_object; //0x432 + bool m_has_head_blend_data; //0x434 + bool unk_0x435; //0x435 + bool m_has_respawn_object; //0x436 + char pad_0x437; //0x437 + uint32_t unk_0x438_clip_maybe; //0x438 + uint32_t unk_0x43C; //0x43C + uint32_t unk_0x440; //0x440 + bool unk_0x444; //0x444 + bool unk_0x445; //0x445 + bool unk_0x446; //0x446 + uint8_t unk_0x447; //0x447 + uint16_t unk_0x448; //0x448 + uint16_t unk_0x44A; //0x44A + uint16_t unk_0x44C; //0x44C + bool unk_0x44E; //0x44E + bool unk_0x44F; //0x44F + bool unk_0x450; //0x450 + uint8_t unk_0x451; //0x451 + uint32_t unk_0x452; //0x452 + uint32_t unk_0x456; //0x456 +}; +static_assert(sizeof(CPlayerAppearanceDataNode) == 0x46C); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/player/CPlayerCameraDataNode.hpp b/classes/src/netsync/nodes/player/CPlayerCameraDataNode.hpp new file mode 100644 index 0000000000..190b669aa1 --- /dev/null +++ b/classes/src/netsync/nodes/player/CPlayerCameraDataNode.hpp @@ -0,0 +1,27 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CPlayerCameraDataNode : CSyncDataNodeFrequent +{ +public: + float m_free_cam_pos_x; //0x00C0 + float m_free_cam_pos_y; //0x00C4 + float m_free_cam_pos_z; //0x00C8 + char pad_00CC[4]; //0x00CC + float m_lock_on_target_offset_x; //0x00D0 + float m_lock_on_target_offset_y; //0x00D4 + char pad_00D8[40]; //0x00D8 + float m_camera_x; //0x0100 + float m_camera_z; //0x0104 + int16_t m_free_aim_locked_on_target; //0x0108 + bool m_free_cam; //0x010A + char pad_010B[2]; //0x010B + bool m_has_position_offset; //0x010D + char pad_010E[1]; //0x010E + bool m_is_long_range_target; //0x010F + char pad_0110[48]; //0x0110 +}; //Size: 0x0140 +static_assert(sizeof(CPlayerCameraDataNode) == 0x140); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/player/CPlayerCreationDataNode.hpp b/classes/src/netsync/nodes/player/CPlayerCreationDataNode.hpp new file mode 100644 index 0000000000..cc430c2f2f --- /dev/null +++ b/classes/src/netsync/nodes/player/CPlayerCreationDataNode.hpp @@ -0,0 +1,19 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPlayerCreationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_model; //0x00C0 + uint32_t m_num_scars; //0x00C4 + char unk_struct_0xC8[192]; //0x00C8 + uint32_t unk_0188; //0x0188 + char pad_018C[4]; //0x018C + char m_scar_struct[176]; //0x0190 + bool unk_0240; //0x0240 + char pad_0241[19]; //0x0241 +}; //Size: 0x0254 +static_assert(sizeof(CPlayerCreationDataNode) == 0x254); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/player/CPlayerExtendedGameStateNode.hpp b/classes/src/netsync/nodes/player/CPlayerExtendedGameStateNode.hpp new file mode 100644 index 0000000000..7f21e765bc --- /dev/null +++ b/classes/src/netsync/nodes/player/CPlayerExtendedGameStateNode.hpp @@ -0,0 +1,19 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 1) +class CPlayerExtendedGameStateNode : CSyncDataNodeInfrequent +{ +public: + float waypoint_x; //0x00C0 + float waypoint_y; //0x00C4 + bool unk1; //0x00C5 + bool unk2; //0x00C6 + bool unk3; //0x00C7 + bool unk4; //0x00C8 + bool unk5; //0x00C9 + bool has_waypoint_data; //0x00CA + bool is_waypoint_set; //0x00CB +}; +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/player/CPlayerGameStateDataNode.hpp b/classes/src/netsync/nodes/player/CPlayerGameStateDataNode.hpp new file mode 100644 index 0000000000..532a320d28 --- /dev/null +++ b/classes/src/netsync/nodes/player/CPlayerGameStateDataNode.hpp @@ -0,0 +1,148 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPlayerGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_player_state; //0x00C0 + bool m_controls_disabled_by_script; //0x00C4 + bool m_is_max_armor_and_health_default; //0x00C5 + bool unk_000C6; //0x00C6 + bool m_is_spectating; //0x00C7 + bool m_is_antagonistic_to_another_player; //0x00C8 + bool m_never_target; //0x00C9 + bool m_use_kinematic_physics; //0x00CA + bool m_has_tutorial_data; //0x00CB + bool m_pending_tutorial_change; //0x00CC + bool unk_00CD; //0x00CD + bool m_respawning; //0x00CE + bool m_will_jack_any_player; //0x00CF + bool m_will_jack_wanted_players; //0x00D0 + bool m_dont_drag_from_car; //0x00D1 + bool m_random_peds_flee; //0x00D2 + bool m_every_ped_back_away; //0x00D3 + bool m_has_microphone; //0x00D4 + bool m_is_invincible; //0x00D5 + bool unk_00D6; //0x00D6 + bool unk_00D7; //0x00D7 + bool m_seatbelt; //0x00D8 + bool unk_00D9; //0x00D9 + bool m_bullet_proof; //0x00DA + bool m_fire_proof; //0x00DB + bool m_explosion_proof; //0x00DC + bool m_collision_proof; //0x00DD + bool m_melee_proof; //0x00DE + bool m_water_proof; //0x00DF + bool m_steam_proof; //0x00E0 + bool unk_00E1; //0x00E1 + bool unk_00E2; //0x00E2 + bool unk_00E3; //0x00E3 + bool unk_00E4; //0x00E4 + bool unk_00E5; //0x00E5 + bool unk_00E6; //0x00E6 + bool unk_00E7; //0x00E7 + bool unk_00E8; //0x00E8 + bool unk_00E9; //0x00E9 + bool unk_00EA; //0x00EA + bool unk_00EB; //0x00EB + bool unk_00EC; //0x00EC + bool unk_00ED; //0x00ED + bool unk_00EE; //0x00EE + bool unk_00EF; //0x00EF + bool unk_00F0; //0x00F0 + bool unk_00F1; //0x00F1 + bool unk_00F2; //0x00F2 + bool unk_00F3; //0x00F3 + bool unk_00F4; //0x00F4 + bool unk_00F5; //0x00F5 + bool unk_00F6; //0x00F6 + bool unk_00F7; //0x00F7 + bool unk_00F8; //0x00F8 + bool unk_00F9; //0x00F9 + bool unk_00FA; //0x00FA + bool unk_00FB; //0x00FB + uint32_t unk_00FC; //0x00FC + uint32_t m_mobile_ring_state; //0x0100 + int32_t m_player_team; //0x0104 + float m_air_drag_multiplier; //0x0108 + uint32_t m_max_health; //0x010C + uint32_t m_max_armor; //0x0110 + uint32_t m_jack_speed; //0x0114 + uint16_t m_player_is_targetable_by_team; //0x0118 + uint32_t m_override_receive_chat; //0x011C + uint32_t m_override_send_chat; //0x0120 + bool unk_0124; //0x0124 + bool unk_0125; //0x0125 + bool unk_0126; //0x0126 + bool unk_0127; //0x0127 + uint16_t m_spectating_net_id; //0x0128 + uint8_t m_antagonistic_to_player_id; //0x012C + uint8_t m_tutorial_index; //0x012B + uint8_t m_tutorial_instance_id; //0x012C + char pad_012D[2]; //0x012D + float m_microphone_volume; //0x0130 + uint32_t m_voice_channel; //0x0134 + bool m_is_overriding_voice_proximity; //0x0138 + char pad_0139[7]; //0x0139 + float m_voice_proximity_x; //0x0140 + float m_voice_proximity_y; //0x0144 + float m_voice_proximity_z; //0x0148 + float m_voice_proximity_radius_maybe; //0x014C + uint32_t unk_0150; //0x0150 + uint32_t m_vehicle_weapon_index; //0x0154 + bool m_has_vehicle_weapon_index; //0x0158 + uint32_t m_decor_count; //0x015C + uint32_t m_decor_type[3]; // 0x0160 + uint32_t m_decor_value[3]; // 0x016C + uint32_t m_decor_name_hash[3]; // 0x0178 + bool m_friendly_fire_allowed; //0x0184 + bool unk_0185; //0x0185 + uint8_t m_current_garage_instance_index; //0x0186 + uint8_t m_current_property_id; //0x0187 + uint8_t unk_0188; //0x0188 + uint8_t unk_0189; //0x0189 + bool m_battle_aware; //0x018A + bool m_vehicle_jump_down; //0x018B + float m_weapon_defence_modifier; //0x018C + float m_weapon_defence_modifier_2; //0x0190 + bool m_is_overriding_population_control_sphere; //0x0194 + char pad_0195[11]; //0x0195 + float m_population_control_sphere_x; //0x01A0 + float m_population_control_sphere_y; //0x01A4 + float m_population_control_sphere_z; //0x01A8 + uint16_t unk_01AC; //0x01AC + uint16_t unk_01AE; //0x01AE + uint16_t unk_01B0; //0x01B0 + bool new_01B2; + bool new_01B3; + bool pad_01B2; //0x01B2 + bool unk_01B3; //0x01B3 + bool m_no_collision; //0x01B4 + bool unk_01B5; //0x01B5 + bool unk_01B6; //0x01B6 + bool m_super_jump; //0x01B7 + bool unk_01B8; //0x01B8 + bool unk_01B9; //0x01B9 + uint16_t unk_01BA; //0x01BA + uint32_t unk_01BC; //0x01BC + float unk_01C0; //0x01C0 + float m_weapon_damage_modifier; //0x01C4 Divisor: 0x3F800000 + float m_melee_weapon_damage_modifier; //0x01C8 Divisor: 0x3F800000 + float unk_01CC; //0x01CC + bool unk_01D0; //0x01D0 + char pad_01D1[11]; //0x01D1 + float unk_01E0; //0x01E0 + float unk_01E4; //0x01E4 + float unk_01E8; //0x01E8 + uint32_t unk_01EC; //0x01EC + uint8_t unk_01F0; //0x01F0 + uint8_t unk_01F1; //0x01F1 + bool unk_01F2; //0x01F2 + uint8_t unk_01F3; //0x01F3 + bool unk_01F4; //0x01F4 + bool unk_01F5; //0x01F5 +}; //Size: 0x01F8 +static_assert(sizeof(CPlayerGameStateDataNode) == 0x1F8); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/player/CPlayerGamerDataNode.hpp b/classes/src/netsync/nodes/player/CPlayerGamerDataNode.hpp new file mode 100644 index 0000000000..c1f210a6b5 --- /dev/null +++ b/classes/src/netsync/nodes/player/CPlayerGamerDataNode.hpp @@ -0,0 +1,26 @@ +#pragma once +#include +#include "network/ClanData.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 8) +class CPlayerGamerDataNode : CSyncDataNodeInfrequent +{ +public: + ClanData m_clan_data; //0x00C0 + bool m_need_crew_rank_sysflags; //0x0178 + bool m_need_crew_rank_title; //0x0179 + char m_crew_rank_title[25]; //0x017A + bool m_has_started_transition; //0x0193 + bool m_has_transition_info; //0x0194 + char m_transition_info_buffer[169]; //0x0195 + int m_player_privilege_flags; //0x0240 + uint32_t m_matchmaking_group; //0x0244 + bool m_need_mute_data; //0x0248 + int32_t m_mute_count; //0x024C + int32_t m_mute_talkers_count; //0x0250 + uint32_t m_unk; //0x0254 + int32_t m_account_id; //0x0258 +}; +static_assert(sizeof(CPlayerGamerDataNode) == 0x260); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/player/CPlayerPedGroupDataNode.hpp b/classes/src/netsync/nodes/player/CPlayerPedGroupDataNode.hpp new file mode 100644 index 0000000000..2f765ba919 --- /dev/null +++ b/classes/src/netsync/nodes/player/CPlayerPedGroupDataNode.hpp @@ -0,0 +1,35 @@ +#pragma once +#include +#include "rage/vector.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" +#include "ped/CPed.hpp" + +#pragma pack(push, 8) +class CGroup; +class CGroupMember +{ +public: + int16_t m_net_id; + CPed* m_ped; // this isn't serialized +}; +static_assert(sizeof(CGroupMember) == 0x10); + +class CPlayerPedGroupDataNode : CSyncDataNodeInfrequent +{ +public: + char m_unused[0x10]; // 0xC0 + CGroup* m_group; // 0xD0 (not serialized) + CGroupMember m_members[7]; // 0xD8 + CGroupMember m_leader; // 0x148 + char m_unused2[8]; // 0x158 + float m_max_separation; // 0x160 + char m_unused3[0xC]; // 0x164 + int m_pop_type; // 0x170 + bool m_needs_group_event_scan; // 0x175 + char m_unused4[6]; // 0x176 + int m_formation_type; // 0x17C + float m_formation_distance; // 0x180 + char m_unused5[0xC]; // 0x184 +}; +static_assert(sizeof(CPlayerPedGroupDataNode) == 0x190); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/player/CPlayerSectorPosNode.hpp b/classes/src/netsync/nodes/player/CPlayerSectorPosNode.hpp new file mode 100644 index 0000000000..b4608c06d6 --- /dev/null +++ b/classes/src/netsync/nodes/player/CPlayerSectorPosNode.hpp @@ -0,0 +1,22 @@ +#pragma once +#include +#include "rage/vector.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPlayerSectorPosNode : CSyncDataNodeFrequent +{ +public: + rage::fvector3 m_sector_pos; //0x00C0 + bool m_is_standing_on_entity; //0x00CC + bool unk_00CD; //0x00CD + bool unk_00CE; //0x00CE + char pad_00CF[1]; //0x00CF + uint16_t m_entity_standing_on; //0x00D0 + char pad_00D2[12]; //0x00D2 + rage::fvector3 m_standing_on_entity_offset; //0x00E0 + char pad_00EC[8]; //0x00EC + uint32_t m_stealth_noise; //0x00F4 +}; //Size: 0x00F8 +static_assert(sizeof(CPlayerSectorPosNode) == 0xF8); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/player/CPlayerWantedAndLOSDataNode.hpp b/classes/src/netsync/nodes/player/CPlayerWantedAndLOSDataNode.hpp new file mode 100644 index 0000000000..d956e34932 --- /dev/null +++ b/classes/src/netsync/nodes/player/CPlayerWantedAndLOSDataNode.hpp @@ -0,0 +1,27 @@ +#pragma once +#include +#include "rage/vector.hpp" +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CPlayerWantedAndLOSDataNode : CSyncDataNodeInfrequent +{ +public: + rage::fvector3 m_wanted_position; // 0xC0 + int m_time_in_prev_pursuit; // 0xCC + rage::fvector3 m_unk_position; // 0xD0 + int m_time_in_pursuit; // 0xDC + int m_wanted_level; // 0xE0 + int m_unk_wanted_level; // 0xE4 + int m_current_time; // 0xE8 + int m_unk_player_bitset; // 0xEC + int m_pursuit_start_time; // 0xF0 + uint8_t m_fake_wanted_level; // 0xF4 + bool m_cops_cant_see_player; // 0xF5 + bool m_is_evading; // 0xF6 + bool m_pending_wanted_level; // 0xF7 + bool m_unk3; // 0xF8 + uint8_t m_unk_player_index; // 0xF9 +}; +static_assert(sizeof(CPlayerWantedAndLOSDataNode) == 0xFC); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp b/classes/src/netsync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp new file mode 100644 index 0000000000..d72c5dc199 --- /dev/null +++ b/classes/src/netsync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp @@ -0,0 +1,13 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CGlobalFlagsDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_global_flags; //0x00C0 + uint32_t m_ownership_token; //0x00C4 +}; //Size: 0x00C8 +static_assert(sizeof(CGlobalFlagsDataNode) == 0xC8); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/proximity_migrateable/CMigrationDataNode.hpp b/classes/src/netsync/nodes/proximity_migrateable/CMigrationDataNode.hpp new file mode 100644 index 0000000000..2dd2ef73d5 --- /dev/null +++ b/classes/src/netsync/nodes/proximity_migrateable/CMigrationDataNode.hpp @@ -0,0 +1,14 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CMigrationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_cloned_state; //0x00C0 + uint32_t m_cloned_players_that_left; //0x00C4 + uint32_t m_unsynced_nodes; //0x00C8 +}; //Size: 0x00CC +static_assert(sizeof(CMigrationDataNode) == 0xCC); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/proximity_migrateable/CSectorDataNode.hpp b/classes/src/netsync/nodes/proximity_migrateable/CSectorDataNode.hpp new file mode 100644 index 0000000000..fd83204ab6 --- /dev/null +++ b/classes/src/netsync/nodes/proximity_migrateable/CSectorDataNode.hpp @@ -0,0 +1,14 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 2) +class CSectorDataNode : CSyncDataNodeFrequent +{ +public: + uint16_t m_pos_x; //0xC0 + uint16_t m_pos_y; //0xC2 + uint16_t m_pos_z; //0xC4 +}; +static_assert(sizeof(CSectorDataNode) == 0xC6); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp b/classes/src/netsync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp new file mode 100644 index 0000000000..27ba243de9 --- /dev/null +++ b/classes/src/netsync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp @@ -0,0 +1,13 @@ +#pragma once +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CSectorPositionDataNode : CSyncDataNodeFrequent +{ +public: + float m_sector_pos_x; //0x00C0 + float m_sector_pos_y; //0x00C4 + float m_sector_pos_z; //0x00C8 +}; //Size: 0x00CC +static_assert(sizeof(CSectorPositionDataNode) == 0xCC); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/task/CClonedGeneralSweepInfo.hpp b/classes/src/netsync/nodes/task/CClonedGeneralSweepInfo.hpp new file mode 100644 index 0000000000..bfc1c39c40 --- /dev/null +++ b/classes/src/netsync/nodes/task/CClonedGeneralSweepInfo.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +#pragma pack(push, 1) +class CClonedGeneralSweepInfo +{ +public: + char pad_0000[48]; //0x0000 + float m_track_point[4]; //0x0030 + uint16_t m_tracked_entity; //0x0040 + char pad_0042[14]; //0x0042 + float m_delta_per_second; //0x0050 + char pad_0054[4]; //0x0054 + uint32_t m_low_clip; //0x0058 + uint32_t m_med_clip; //0x005C + uint32_t m_high_clip; //0x0060 + uint32_t m_clip_set_id; //0x0064 + uint32_t m_sweep_flags; //0x0068 + float m_turn_rate; //0x006C +}; +static_assert(sizeof(CClonedGeneralSweepInfo) == 0x70); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/task/ClonedTakeOffPedVariationInfo.hpp b/classes/src/netsync/nodes/task/ClonedTakeOffPedVariationInfo.hpp new file mode 100644 index 0000000000..1363566b87 --- /dev/null +++ b/classes/src/netsync/nodes/task/ClonedTakeOffPedVariationInfo.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include "rage/vector.hpp" + +#pragma pack(push, 1) +class ClonedTakeOffPedVariationInfo +{ +public: + char pad_0000[48]; //0x0000 + rage::fvector3 m_attach_offset; //0x0030 + char pad_003C[4]; //0x003C + rage::fvector3 m_velocity; //0x0040 + char pad_004C[4]; //0x004C + rage::fvector3 m_attach_offset_rotation; //0x0050 + char pad_005C[4]; //0x005C + uint32_t m_clip_set_id; //0x0060 + uint32_t m_clip_id_ped; //0x0064 + uint32_t m_clip_id_prop; //0x0068 + int32_t m_variation_component; //0x006C + uint32_t m_prop_hash; //0x0070 + int32_t m_attach_bone_tag; //0x0074 + float m_blend_in_delta_ped; //0x0078 + float m_blend_in_delta_prop; //0x007C + float m_phase_to_blend_out; //0x0080 + float m_blend_out_delta; //0x0084 + float m_force_to_apply; //0x0088 + uint8_t m_variation_drawable_id; //0x008C + uint8_t m_variation_drawable_alt_id; //0x008D + char pad_008E[1]; //0x008E Drawable texture maybe? + uint8_t m_running_flags; //0x008F +}; //Size: 0x0090 +static_assert(sizeof(ClonedTakeOffPedVariationInfo) == 0x90); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/train/CTrainGameStateDataNode.hpp b/classes/src/netsync/nodes/train/CTrainGameStateDataNode.hpp new file mode 100644 index 0000000000..6d1fba256c --- /dev/null +++ b/classes/src/netsync/nodes/train/CTrainGameStateDataNode.hpp @@ -0,0 +1,31 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CTrainGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_is_engine; //0x00C0 + bool m_is_caboose; //0x00C1 + bool m_is_mission_train; //0x00C2 + bool m_direction; //0x00C3 + bool m_has_passenger_carriages; //0x00C4 + bool m_render_derailed; //0x00C5 + bool unk_00C6; //0x00C6 + bool unk_00C7; //0x00C7 + uint16_t m_engine_id; //0x00C8 + int8_t m_train_config_index; //0x00CA + int8_t m_carriage_config_index; //0x00CB + int8_t m_track_id; //0x00CC + char pad_00CD[3]; //0x00CD + float m_distance_from_engine; //0x00D0 + float m_cruise_speed; //0x00D4 + uint16_t m_linked_to_backward_id; //0x00D8 + uint16_t m_linked_to_forward_id; //0x00DA + uint32_t m_train_state; //0x0DC + bool unk_00E0; //0x00E0 + bool m_force_doors_open; //0x0E1 +}; //Size: 0x00E4 +static_assert(sizeof(CTrainGameStateDataNode) == 0xE4); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/vehicle/CVehicleComponentReservationDataNode.hpp b/classes/src/netsync/nodes/vehicle/CVehicleComponentReservationDataNode.hpp new file mode 100644 index 0000000000..70ba08e913 --- /dev/null +++ b/classes/src/netsync/nodes/vehicle/CVehicleComponentReservationDataNode.hpp @@ -0,0 +1,15 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CVehicleComponentReservationDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_has_component_reservations; //0x00C0 + uint32_t m_num_peds_using_component; //0x00C4 + uint16_t m_peds_using_component[32]; //0x00C8 +}; //Size: 0x00C8 +#pragma pack(pop) + +static_assert(sizeof(CVehicleComponentReservationDataNode) == 0x108); diff --git a/classes/src/netsync/nodes/vehicle/CVehicleControlDataNode.hpp b/classes/src/netsync/nodes/vehicle/CVehicleControlDataNode.hpp new file mode 100644 index 0000000000..ea297eaef0 --- /dev/null +++ b/classes/src/netsync/nodes/vehicle/CVehicleControlDataNode.hpp @@ -0,0 +1,41 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CVehicleControlDataNode : CSyncDataNodeFrequent +{ +public: + uint32_t m_num_wheels; + uint32_t dwordC4; + uint32_t m_brake_control; + uint32_t dwordCC; + uint32_t m_road_node_address; + bool m_kers_active; + bool m_bringing_vehicle_to_halt; + float m_halt_distance; + bool m_control_vertical_velocity; + bool m_has_suspension_data; + bool byteDE; + float m_suspension_heights[10]; + bool byte108; + bool byte109; + bool byte10A; + bool byte10B; + bool byte10C; + bool byte10D; + bool byte10E; + float float110; + uint32_t dword114; + char byte118; + bool m_is_submarine_car; + char gap11A[2]; + float m_rudder_rotation_x; + float m_rudder_rotation_y; + float m_rudder_rotation_z; + char byte128; + char byte129; + char pad[5]; +}; +static_assert(sizeof(CVehicleControlDataNode) == 0x130); +#pragma pack(pop) diff --git a/classes/src/netsync/nodes/vehicle/CVehicleCreationDataNode.hpp b/classes/src/netsync/nodes/vehicle/CVehicleCreationDataNode.hpp new file mode 100644 index 0000000000..c6542710ed --- /dev/null +++ b/classes/src/netsync/nodes/vehicle/CVehicleCreationDataNode.hpp @@ -0,0 +1,21 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CVehicleCreationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_pop_type; //0x00C0 + uint32_t m_random_seed; //0x00C4 + uint32_t m_model; //0x00C8 + uint32_t m_vehicle_status; //0x00CC + uint32_t m_max_health; //0x00D0 + uint32_t m_creation_token; //0x00D4 + bool m_car_budget; //0x00D8 + bool m_needs_to_be_hotwired; //0x00D9 + bool m_tires_dont_burst; //0x00DA + char pad_00DB[165]; //0x00DB +}; //Size: 0x0180 +static_assert(sizeof(CVehicleCreationDataNode) == 0x180); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/vehicle/CVehicleDamageStatusDataNode.hpp b/classes/src/netsync/nodes/vehicle/CVehicleDamageStatusDataNode.hpp new file mode 100644 index 0000000000..20740b9efa --- /dev/null +++ b/classes/src/netsync/nodes/vehicle/CVehicleDamageStatusDataNode.hpp @@ -0,0 +1,32 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CVehicleDamageStatusDataNode : CSyncDataNodeInfrequent +{ +public: + uint8_t m_bullet_counts[6]; // 0xC0 + uint8_t m_front_damage_level; // 0xC6 + uint8_t m_rear_damage_level; // 0xC7 + uint8_t m_left_damage_level; // 0xC8 + uint8_t m_right_damage_level; // 0xC9 + uint8_t m_rear_left_damage_level; // 0xCA + uint8_t m_rear_right_damage_level; // 0xCB + uint8_t m_windows_state[8]; // 0xCC + float m_unk2[8]; // 0xD4 + bool m_sirens_broken[20]; // 0xF4 + bool m_lights_broken[20]; // 0x108 + uint8_t m_front_bumper_state; // 0x11E + uint8_t m_rear_bumper_state; // 0x11F + uint8_t m_unk3[8]; // 0x120 + bool m_has_damage_levels; // 0x128 + bool m_has_broken_lights; // 0x129 + bool m_has_broken_sirens; // 0x12A + bool m_has_broken_windows; // 0x12B + bool m_has_broken_bumpers; // 0x12C + bool m_has_bullets; // 0x12D + bool m_has_unk; // 0x12E +}; //Size: 0x00C8 +#pragma pack(pop) +static_assert(sizeof(CVehicleDamageStatusDataNode) == 0x130); diff --git a/classes/src/netsync/nodes/vehicle/CVehicleGadgetDataNode.hpp b/classes/src/netsync/nodes/vehicle/CVehicleGadgetDataNode.hpp new file mode 100644 index 0000000000..73b4cd3c39 --- /dev/null +++ b/classes/src/netsync/nodes/vehicle/CVehicleGadgetDataNode.hpp @@ -0,0 +1,38 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +enum eVehicleGadgetType : uint32_t +{ + FORKS, + SEARCH_LIGHT, + PICK_UP_ROPE_WITH_HOOK, + PICK_UP_ROPE_WITH_MAGNET, + DIGGER_ARM, + HANDLER_FRAME, + BOMB_BAY, +}; + +#pragma pack(push,4) +class CVehicleGadgetData +{ +public: + eVehicleGadgetType m_gadget_type; //0x0000 + uint8_t m_data[94]; //0x0004 +}; //Size: 0x64 +static_assert(sizeof(CVehicleGadgetData) == 0x64); + +class CVehicleGadgetDataNode : CSyncDataNodeFrequent +{ +public: + bool m_has_parent_offset; //0x00C0 + char pad_00C1[15]; //0x00C1 + uint32_t m_parent_offset_x; //0x00D0 + uint32_t m_parent_offset_y; //0x00D4 + uint32_t m_parent_offset_z; //0x00D8 + uint32_t m_parent_offset_w; //0x00DC + uint32_t m_gadget_count; //0x00E0 + CVehicleGadgetData m_gadget_data[2]; //0x00E4 +}; //Size: 0x01AC +static_assert(sizeof(CVehicleGadgetDataNode) == 0x1AC); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/vehicle/CVehicleGameStateDataNode.hpp b/classes/src/netsync/nodes/vehicle/CVehicleGameStateDataNode.hpp new file mode 100644 index 0000000000..a24d51b7c1 --- /dev/null +++ b/classes/src/netsync/nodes/vehicle/CVehicleGameStateDataNode.hpp @@ -0,0 +1,80 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 2) +class CVehicleGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + float m_unk66; + float m_unk32; + float m_unk200; + float m_unk204; + int m_radio_station; + uint32_t m_lock_status; + uint32_t m_unk17; + uint32_t m_unbreakable_doors; + uint32_t m_open_windows; + uint32_t m_unk34; + uint8_t m_unk49[4]; + unsigned int m_unk62_1; + uint32_t m_unk240; + uint16_t m_unk35; + uint16_t m_unk37[2]; + uint16_t m_unk39; + uint8_t m_unk252; + char m_light_state; + uint8_t m_unk21; + char m_unk27[8]; + uint8_t m_doors_open; + char m_door_positions[8]; + uint32_t m_locked_players; + uint8_t m_is_engine_on; + bool m_is_engine_starting; + bool unk4; + bool m_handbrake; + bool m_unk6; + uint8_t m_siren_on; + bool m_unk1; + uint8_t m_unk13; + uint8_t m_unk12; + uint8_t m_unk14; + uint8_t m_unk25; + uint8_t m_unk26; + bool m_no_longer_needed; + uint8_t m_unk28; + uint8_t m_unk33; + uint8_t m_unk30; + bool m_lights_on; + bool m_highbeams_on; + char m_unk43; + char m_unk44; + bool m_unk7; + char m_unk29; + char m_unk45; + char m_unk46; + char m_unk47; + char m_unk48; + uint8_t m_unk38; + char m_unk51; + bool m_has_been_owned_by_player; + char m_unk53; + char m_unk54; + char m_unk55; + char m_unk56; + char m_unk57; + char m_unk58; + char m_unk61; + uint8_t m_unk62; + char m_unk63; + char m_unk64; + char m_unk67; + char m_unk68; + char m_unk138; + char m_unk139; + char m_unk59; + char m_unk60; + char pad[6]; +}; +#pragma pack(pop) +static_assert(sizeof(CVehicleGameStateDataNode) == 0x148); \ No newline at end of file diff --git a/classes/src/netsync/nodes/vehicle/CVehicleHealthDataNode.hpp b/classes/src/netsync/nodes/vehicle/CVehicleHealthDataNode.hpp new file mode 100644 index 0000000000..228de387a0 --- /dev/null +++ b/classes/src/netsync/nodes/vehicle/CVehicleHealthDataNode.hpp @@ -0,0 +1,35 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CVehicleHealthDataNode : CSyncDataNodeInfrequent +{ +public: + float m_tires_unk14[10]; //0x00C0 + float m_tires_open_wheel_heat[10]; //0x00E8 + bool m_tires_bursted[10]; //0x0110 + bool m_tires_bursted_on_rim[10]; //0x011A + bool m_tires_unk11[10]; //0x0124 + bool m_tires_unk12[10]; //0x012E + uint64_t m_unk24; //0x0138 + int32_t m_engine_health; //0x0140 + uint32_t m_petrol_tank_health; //0x0144 + uint32_t m_num_tires; //0x0148 + bool m_tires_fine; //0x014C + bool m_unk7; //0x014D + char pad_014E[1]; //0x014E + bool m_health_changed; //0x014F + uint32_t m_health; //0x0150 + uint32_t m_body_health; //0x0154 + uint32_t m_damage_weapon; //0x0158 + int16_t m_damager_net_id; //0x015C + uint8_t m_total_repairs; //0x015E + uint8_t m_unk21; //0x015F + bool m_unk1; //0x0160 + bool m_unk2; //0x0161 + bool m_body_health_changed; //0x0162 + uint32_t m_pad2; // 0x0164 +}; //Size: 0x0380 +#pragma pack(pop) +static_assert(sizeof(CVehicleHealthDataNode) == 0x168); \ No newline at end of file diff --git a/classes/src/netsync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp b/classes/src/netsync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp new file mode 100644 index 0000000000..0346401552 --- /dev/null +++ b/classes/src/netsync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp @@ -0,0 +1,20 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CVehicleProximityMigrationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_max_occupants; + bool m_has_occupants[16]; + int16_t m_occupants[16]; + char pad[16]; + bool m_override_position; + char pad2[8]; + rage::fvector3 m_position; + rage::vector3 m_velocity; + char pad3[352]; +}; //Size: 0x0180 +static_assert(sizeof(CVehicleProximityMigrationDataNode) == 0x288); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/nodes/vehicle/CVehicleSteeringDataNode.hpp b/classes/src/netsync/nodes/vehicle/CVehicleSteeringDataNode.hpp new file mode 100644 index 0000000000..525ae885ff --- /dev/null +++ b/classes/src/netsync/nodes/vehicle/CVehicleSteeringDataNode.hpp @@ -0,0 +1,13 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 4) +class CVehicleSteeringNodeData : CSyncDataNodeFrequent +{ +public: + float m_steering_handle; // 0xC0 + char pad[4]; // 0xC4 +}; //Size: 0x00C8 +#pragma pack(pop) +static_assert(sizeof(CVehicleSteeringNodeData) == 0xC8); diff --git a/classes/src/netsync/nodes/vehicle/CVehicleTaskDataNode.hpp b/classes/src/netsync/nodes/vehicle/CVehicleTaskDataNode.hpp new file mode 100644 index 0000000000..90d52d9035 --- /dev/null +++ b/classes/src/netsync/nodes/vehicle/CVehicleTaskDataNode.hpp @@ -0,0 +1,14 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push,4) +class CVehicleTaskDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_task_type; // 0xC0 + uint32_t m_task_data_size; // 0xC4 + char m_task_data[255]; // 0xC8 +}; //Size: 0x0180 +static_assert(sizeof(CVehicleTaskDataNode) == 0x1C8); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/netsync/trees/CDynamicEntitySyncTreeBase.hpp b/classes/src/netsync/trees/CDynamicEntitySyncTreeBase.hpp new file mode 100644 index 0000000000..f1d696d27b --- /dev/null +++ b/classes/src/netsync/trees/CDynamicEntitySyncTreeBase.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "CEntitySyncTreeBase.hpp" +#include "netsync/netSyncParentNode.hpp" + +#include "netsync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp" + +class CDynamicEntitySyncTreeBase : public CEntitySyncTreeBase +{ +public: + char m_dynamic_entity_game_state_data_node[0xE28 - 0xCD8]; +}; +static_assert(sizeof(CDynamicEntitySyncTreeBase) == 0xE28); \ No newline at end of file diff --git a/classes/src/netsync/trees/CEntitySyncTreeBase.hpp b/classes/src/netsync/trees/CEntitySyncTreeBase.hpp new file mode 100644 index 0000000000..45ced73026 --- /dev/null +++ b/classes/src/netsync/trees/CEntitySyncTreeBase.hpp @@ -0,0 +1,15 @@ +#pragma once +#include "CProximityMigrateableSyncTreeBase.hpp" +#include "netsync/netSyncParentNode.hpp" + +#include "netsync/nodes/entity/CEntityScriptInfoDataNode.hpp" +#include "netsync/nodes/entity/CEntityScriptGameStateDataNode.hpp" + +class CEntitySyncTreeBase : public CProximityMigrateableSyncTreeBase +{ +public: + CProjectBaseSyncParentNode m_parent_node_4[5]; + CEntityScriptInfoDataNode m_entity_script_info_data_node; + CEntityScriptGameStateDataNode m_entity_script_game_state_data_node; +}; +static_assert(sizeof(CEntitySyncTreeBase) == 0xCD8); \ No newline at end of file diff --git a/classes/src/netsync/trees/CPhysicalSyncTreeBase.hpp b/classes/src/netsync/trees/CPhysicalSyncTreeBase.hpp new file mode 100644 index 0000000000..69854f3fc9 --- /dev/null +++ b/classes/src/netsync/trees/CPhysicalSyncTreeBase.hpp @@ -0,0 +1,29 @@ +#pragma once +#include "CEntitySyncTreeBase.hpp" +#include "netsync/netSyncParentNode.hpp" + +#include "netsync/nodes/physical/CPhysicalMigrationDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp" +#include "netsync/nodes/entity/CEntityOrientationDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalVelocityDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalAngVelocityDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalHealthDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalAttachDataNode.hpp" + +class CPhysicalSyncTreeBase : public CDynamicEntitySyncTreeBase +{ +public: + CPhysicalMigrationDataNode m_physical_migration_data_node; + CPhysicalScriptMigrationDataNode m_physical_script_migration_data_node; + char pad_0FB8[8]; + CEntityOrientationDataNode m_entity_orientation_data_node; + CPhysicalVelocityDataNode m_physical_velocity_data_node; + CPhysicalAngVelocityDataNode m_physical_angular_velocity_data_node; + char pad_1258[8]; + CPhysicalHealthDataNode m_physical_health_data_node; + CPhysicalAttachDataNode m_physical_attach_data_node; + char pad_1458[8]; + char m_physical_game_state_data_node[0x1530 - 0x1460]; // TODO + char m_physical_script_game_state_data_node[0x1620 - 0x1530]; // TODO +}; +static_assert(sizeof(CPhysicalSyncTreeBase) == 0x1620); \ No newline at end of file diff --git a/classes/src/netsync/trees/CProximityMigrateableSyncTreeBase.hpp b/classes/src/netsync/trees/CProximityMigrateableSyncTreeBase.hpp new file mode 100644 index 0000000000..38b525d814 --- /dev/null +++ b/classes/src/netsync/trees/CProximityMigrateableSyncTreeBase.hpp @@ -0,0 +1,22 @@ +#pragma once +#include "netsync/CProjectSyncTree.hpp" +#include "netsync/netSyncParentNode.hpp" + +#include "netsync/nodes/proximity_migrateable/CMigrationDataNode.hpp" +#include "netsync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp" +#include "netsync/nodes/proximity_migrateable/CSectorDataNode.hpp" +#include "netsync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp" + +class CProximityMigrateableSyncTreeBase : public CProjectSyncTree +{ +public: + CProjectBaseSyncParentNode m_parent_node_1; + CProjectBaseSyncParentNode m_parent_node_2; + CProjectBaseSyncParentNode m_parent_node_3; + CMigrationDataNode m_migration_data_node; + CGlobalFlagsDataNode m_global_flags_data_node; + CSectorDataNode m_sector_data_node; + CSectorPositionDataNode m_sector_position_data_node; + char pad_0910[8]; +}; +static_assert(sizeof(CProximityMigrateableSyncTreeBase) == 0x918); \ No newline at end of file diff --git a/classes/src/network/CCommunications.hpp b/classes/src/network/CCommunications.hpp new file mode 100644 index 0000000000..3dbb2ba994 --- /dev/null +++ b/classes/src/network/CCommunications.hpp @@ -0,0 +1,33 @@ +#pragma once +#include +#include "../rage/rlGamerInfo.hpp" + +#pragma pack(push, 1) +class CVoiceConnection +{ +public: + class rage::rlGamerInfo m_gamer_info; //0x0000 + char pad_0098[40]; //0x00F8 +}; //Size: 0x00C0 +static_assert(sizeof(CVoiceConnection) == 0x118); + +class CVoice +{ +public: + class CVoiceConnection m_connection_storage[32]; //0x0000 + char pad_2300[8]; //0x2300 + class CVoiceConnection* m_connections[32]; //0x2308 + uint32_t m_connection_count; //0x2408 + char pad_240C[3508]; //0x240C +}; //Size: 0x31C0 +static_assert(sizeof(CVoice) == 0x31C0); + +class CCommunications +{ +public: + char pad_0000[48]; //0x0000 + class CVoice m_voice; //0x0030 + char pad_31F0[280300]; //0x31F0 +}; //Size: 0x478DC +static_assert(sizeof(CCommunications) == 0x478DC); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/network/CJoinRequestContext.hpp b/classes/src/network/CJoinRequestContext.hpp new file mode 100644 index 0000000000..dae65263b8 --- /dev/null +++ b/classes/src/network/CJoinRequestContext.hpp @@ -0,0 +1,16 @@ +#pragma once +#include + +#pragma pack(push, 1) +class CJoinRequestContext +{ +public: + char pad_0000[40]; //0x0000 + void* m_join_request_data; //0x0028 + uint32_t m_join_request_size; //0x0030 + uint8_t m_join_response_data[512]; //0x0034 + uint32_t m_join_response_size; //0x0234 + char pad_0238[12]; //0x0238 +}; //Size: 0x0244 +static_assert(sizeof(CJoinRequestContext) == 0x244); +#pragma pack(pop) diff --git a/classes/src/network/CMsgJoinResponse.hpp b/classes/src/network/CMsgJoinResponse.hpp new file mode 100644 index 0000000000..c1fd254c55 --- /dev/null +++ b/classes/src/network/CMsgJoinResponse.hpp @@ -0,0 +1,18 @@ +#pragma once +#include + +#pragma pack(push, 1) +class CMsgJoinResponse +{ +public: + uint32_t m_status_code; //0x0000 + uint32_t m_visibility_flags; //0x0004 + bool m_can_wait_for_slot; //0x0008 + char pad_0009[3]; //0x0009 + bool m_is_activity_session; //0x000C + char pad_000D[7]; //0x000D + uint32_t m_network_time; //0x0014 + char pad_0018[72]; //0x0018 +}; //Size: 0x0060 +static_assert(sizeof(CMsgJoinResponse) == 0x60); +#pragma pack(pop) diff --git a/classes/src/network/CMsgTextMessage.hpp b/classes/src/network/CMsgTextMessage.hpp new file mode 100644 index 0000000000..bd2050d64a --- /dev/null +++ b/classes/src/network/CMsgTextMessage.hpp @@ -0,0 +1,13 @@ +#pragma once +#include + +#pragma pack(push, 1) +class CMsgTextMessage +{ +public: + char m_message[256]; //0x0000 + uint64_t m_peer_id; //0x0100 + bool m_is_team; //0x0108 +}; //Size: 0x0109 +static_assert(sizeof(CMsgTextMessage) == 0x109); +#pragma pack(pop) diff --git a/classes/src/network/CNetComplaintMgr.hpp b/classes/src/network/CNetComplaintMgr.hpp new file mode 100644 index 0000000000..f520185ed6 --- /dev/null +++ b/classes/src/network/CNetComplaintMgr.hpp @@ -0,0 +1,70 @@ +#pragma once +#include + +class CNetRemoteComplaint +{ +public: + uint64_t m_complainer_token; //0x0000 + uint64_t m_complainee_token; //0x0008 + uint32_t m_flags; //0x0010 + uint32_t m_time; //0x0014 +}; //Size: 0x0018 +static_assert(sizeof(CNetRemoteComplaint) == 0x18); + +class CNetComplaintMgr +{ +public: + uint64_t m_host_token; //0x0000 + uint32_t m_host_peer_id; //0x0008 + char pad_000C[4]; //0x000C + void* m_net_connection_mgr; //0x0010 + char pad_0018[64]; //0x0018 + class rage::rlGamerHandle m_handles_in_scope[64]; //0x0058 + uint32_t m_num_handles_in_scope; //0x0458 + char pad_045C[4]; //0x045C + class CNetRemoteComplaint m_remote_complaints[64]; //0x0460 + uint32_t m_num_remote_complaints; //0x0A60 + char pad_0A64[4]; //0x0A64 + uint64_t m_host_tokens_complained[64]; //0x0A68 + uint32_t m_num_tokens_complained; //0x0C68 + char pad_0C6C[520]; //0x0C6C + uint32_t m_connection_identifier; //0x0E74 + uint32_t m_last_resend_time; //0x0E78 + char pad_0E7C[4]; //0x0E7C + uint32_t m_time_to_resend; //0x0E80 + uint32_t m_flags; //0x0E84 + char pad_0E88[16]; //0x0E88 + + inline bool has_local_complaint(uint64_t host_token) + { + for (std::uint32_t i = 0; i < m_num_tokens_complained; i++) + if (m_host_tokens_complained[i] == host_token) + return true; + + return false; + } + + inline void raise_complaint(uint64_t host_token) + { + if (has_local_complaint(host_token)) + return; + + m_host_tokens_complained[m_num_tokens_complained++] = host_token; + + // big::g_pointers->m_raise_network_complaint(this, host_token); + } + + inline void remove_complaint(uint64_t host_token) + { + if (!has_local_complaint(host_token)) + return; + + for (std::uint32_t i = 0; i < m_num_tokens_complained; i++) + if (m_host_tokens_complained[i] == host_token) + m_host_tokens_complained[i] = m_host_tokens_complained[m_num_tokens_complained - 1]; + + m_num_tokens_complained--; + } + +}; //Size: 0x0C98 +static_assert(sizeof(CNetComplaintMgr) == 0xE98); \ No newline at end of file diff --git a/classes/src/network/CNetGamePlayer.hpp b/classes/src/network/CNetGamePlayer.hpp new file mode 100644 index 0000000000..323fe67cc4 --- /dev/null +++ b/classes/src/network/CNetGamePlayer.hpp @@ -0,0 +1,66 @@ +#pragma once + +#include "../player/CPlayerInfo.hpp" +#include "../player/CNonPhysicalPlayerData.hpp" + +#include "../rage/rlSessionInfo.hpp" + +#include "ClanData.hpp" +#include "netPlayer.hpp" + +#include + +#pragma pack(push, 8) +// WARNING: most fields are out of date +class CNetGamePlayer : public rage::netPlayer +{ +public: + void* m_unk; + CPlayerInfo* m_player_info; //0x00A0 + uint32_t m_matchmaking_group; //0x0008 + bool m_is_spectating; //0x000C + char pad_00AD[3]; //0x000AD + uint64_t unk_00B0; //0x00B0 + char unk_00B8; //0x00B8 + char pad_00B9[3]; //0x00B9 + uint32_t unk_00BC; //0x00BC + uint32_t unk_00C0; //0x00C0 + char pad_00C4[4]; //0x00C4 + ClanData m_clan_data; //0x00C8 + char m_crew_rank_title[25]; //0x0180 + bool m_is_rockstar_dev; //0x0199 + bool m_is_rockstar_qa; //0x019A + bool m_is_cheater; //0x019B + uint32_t unk_019C; //0x019C + uint16_t unk_01A0; //0x01A0 + char unk_01A2; //0x01A2 + char pad_01A3; //0x01A3 + uint32_t m_phone_explosion_vehicle_net_id; //0x01A4 + uint16_t unk_01A8; //0x01A8 + bool m_has_started_transition; //0x01AA + char pad_01AB[5]; //0x01AB + rage::rlSessionInfo m_transition_session_info; //0x01A3 + char pad_022D[16]; //0x022D + void* m_unk2; + uint64_t unk_0230; //0x0230 + uint64_t unk_0238; //0x0238 + uint32_t m_mute_count; //0x0240 + uint32_t m_mute_talkers_count; //0x0244 + char pad_0248[5]; //0x0248 + bool m_have_communication_privileges; //0x024D + uint16_t unk_024E; //0x024E + uint16_t unk_0250; //0x0250 + char pad_0252[2]; //0x0252 + uint32_t m_cheat_report_ids[20]; //0x0254 + uint32_t m_num_cheat_reports; //0x02A4 + uint8_t unk_02A8; //0x02A8 + char pad_02A9[3]; //0x02A9 + uint32_t unk_02AC; //0x02AC + char unk_02B0; //0x02B0 + char pad_02B1[3]; //0x02B1 + uint32_t unk_02B4; //0x02B4 + uint32_t m_account_id; //0x02B4 + uint32_t m_unk_02BC; //0x02BC +}; //Size: 0x02C0 +static_assert(sizeof(CNetGamePlayer) == 0x330); +#pragma pack(pop) diff --git a/classes/src/network/CNetGamePlayerDataMsg.hpp b/classes/src/network/CNetGamePlayerDataMsg.hpp new file mode 100644 index 0000000000..18179ed053 --- /dev/null +++ b/classes/src/network/CNetGamePlayerDataMsg.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include + +class datBitBuffer; + +#pragma pack(push,8) +namespace rage { + class playerDataMsg + { + public: + virtual ~playerDataMsg() = 0; + virtual int GetBufferSize() = 0; + virtual void Log() = 0; + virtual bool Serialize(datBitBuffer* buffer) = 0; + virtual bool Deserialize(datBitBuffer* buffer) = 0; + + uint32_t m_game_version; //0x0008 + uint32_t m_nat_type; //0x000C + }; //Size: 0x0010 + static_assert(sizeof(playerDataMsg) == 0x10); +} + +class CNetGamePlayerDataMsg : public rage::playerDataMsg +{ +public: + uint32_t m_player_type; //0x0010 + uint32_t m_matchmaking_group; //0x0014 + uint32_t m_flags; //0x0018 + uint32_t m_team; //0x001C + uint64_t m_crew_id; //0x0020 + uint32_t m_aim_preference; //0x0028 + uint16_t m_rank; //0x002C + uint16_t unk_002E; //0x002E + uint16_t unk_0030; //0x0030 +}; //Size: 0x0038 +static_assert(sizeof(CNetGamePlayerDataMsg) == 0x38); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/network/CNetworkPlayerMgr.hpp b/classes/src/network/CNetworkPlayerMgr.hpp new file mode 100644 index 0000000000..3ccb2deb07 --- /dev/null +++ b/classes/src/network/CNetworkPlayerMgr.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include "netPlayerMgrBase.hpp" +#include "CNetGamePlayer.hpp" +#include "../player/CNonPhysicalPlayerData.hpp" + +#include + +#pragma pack(push, 2) +class CNetworkPlayerMgr : public rage::netPlayerMgrBase +{ +public: + CNetGamePlayer m_net_players[32]; //0x08E0 + uint64_t unk_60E0; //0x60E0 + uint64_t unk_60E8; //0x60E8 + uint64_t unk_60F0; //0x60F0 + uint64_t unk_60F8; //0x60F8 + CNetGamePlayer m_net_players_2[32]; //0x6100 + uint64_t unk_B900; //0xB900 + uint64_t unk_B908; //0xB908 + uint64_t unk_B910; //0xB910 + uint64_t unk_B918; //0xB918 + uint64_t unk_B920; //0xB920 + uint64_t unk_B928; //0xB928 + uint64_t unk_B930; //0xB930 + uint32_t unk_B938; //0xB938 + char pad_B93C[3]; //0xB93C + bool unk_B93F; //0xB93F + uint32_t unk_B940; //0xB940 + uint32_t unk_B944; //0xB944 + uint16_t unk_B948; //0xB948 +}; //Size: 0xB94A +static_assert(sizeof(CNetworkPlayerMgr) == 0xD552); +#pragma pack(pop) diff --git a/classes/src/network/ChatData.hpp b/classes/src/network/ChatData.hpp new file mode 100644 index 0000000000..dc65b0e17d --- /dev/null +++ b/classes/src/network/ChatData.hpp @@ -0,0 +1,25 @@ +#pragma once +#include + +class ChatData +{ +public: + uint32_t m_timer_one; //0x0000 + uint32_t m_timer_two; //0x0004 + uint32_t m_char_count; //0x0008 + uint32_t m_key_held_time; //0x000C + uint32_t m_team_label; //0x0010 + uint8_t m_chat_open; //0x0014 + uint8_t m_is_job; //0x0015 + uint8_t m_disabled; //0x0016 + uint8_t m_not_typing; //0x0017 + uint32_t m_focus_mode; //0x0018 + uint32_t m_chat_mode; //0x001C + uint32_t m_scaleform; //0x0020 + char pad_0024[8]; //0x0024 + char16_t m_current_text[142]; //0x002C + uint32_t m_hud_color; //0x0148 + uint8_t m_hud_color_override; // 0x014C + char pad_014D[43]; // 0x014D +}; //Size: 0x0178 +static_assert(sizeof(ChatData) == 0x178); \ No newline at end of file diff --git a/classes/src/network/ClanData.hpp b/classes/src/network/ClanData.hpp new file mode 100644 index 0000000000..1136ba4370 --- /dev/null +++ b/classes/src/network/ClanData.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include + +#pragma pack(push, 1) +class ClanData +{ +public: + int64_t m_clan_member_id; //0x0000 + int64_t m_clan_id; //0x0008 + int32_t m_clan_color; //0x0010 + int32_t m_clan_member_count; //0x0014 + int32_t m_clan_created_time; //0x0018 + bool m_is_system_clan; //0x001C + bool m_is_clan_open; //0x001D + char m_clan_name[25]; //0x001E + char m_clan_tag[5]; //0x0037 + char m_clan_motto[65]; //0x003C + char pad_007D[3]; //0x007D + int64_t m_clan_id_2; //0x0080 + char m_clan_rank_name[25]; //0x0088 + char pad_00A1[3]; //0x00A1 + int32_t m_clan_rank_order; //0x00A4 + int64_t m_clan_rank_flags; //0x00A8 + char unk_00B0[8]; //0x00B0 +}; +#pragma pack(pop) diff --git a/classes/src/network/Network.hpp b/classes/src/network/Network.hpp new file mode 100644 index 0000000000..46c77aa125 --- /dev/null +++ b/classes/src/network/Network.hpp @@ -0,0 +1,288 @@ +#pragma once +#include "../rage/rlMetric.hpp" +#include "../security/ObfVar.hpp" +#include "CNetComplaintMgr.hpp" +#include "snSession.hpp" +#include + +#pragma pack(push, 1) + +class MetricSessionMigrated : public rage::rlMetric +{ +public: + char pad_0008[828]; //0x0008 + uint32_t m_num_players; //0x0344 +}; //Size: 0x0348 +static_assert(sizeof(MetricSessionMigrated) == 0x348); + +class NetworkGameConfig +{ +public: + char pad_0000[48]; //0x0000 + uint32_t m_public_slots; //0x0030 + uint32_t m_private_slots; //0x0034 + char pad_0038[272]; //0x0038 +}; //Size: 0x0148 +static_assert(sizeof(NetworkGameConfig) == 0x148); + +class NetworkGameFilterMatchmakingComponent +{ +public: + // do not use for actual network filters, this will break things + inline void SetParameter(const char* name, int index, int value) + { + std::strcpy(m_param_names[index], name); + m_param_mappings[index] = index; + m_param_values[index] = value; + m_enabled_params_bitset |= (1 << index); + + if (m_num_parameters <= (uint32_t)index) + m_num_parameters++; + } + + uint32_t m_filter_type; //0x0000 + char m_filter_name[24]; //0x0004 + uint32_t m_num_parameters; //0x001C + uint16_t m_game_mode; //0x0020 + uint16_t m_session_type; //0x0022 + uint32_t m_param_unk[8]; //0x0024 + char m_param_names[8][24]; //0x0044 + char pad_0104[4]; //0x0104 + uint32_t m_param_mappings[8]; //0x0108 + char pad_0128[352]; //0x0128 + uint32_t m_param_values[8]; //0x0288 + char pad_02A8[96]; //0x02A8 + uint32_t m_enabled_params_bitset; //0x0308 + char pad_030C[8]; //0x030C +}; //Size: 0x0314 +static_assert(sizeof(NetworkGameFilterMatchmakingComponent) == 0x314); + +class MatchmakingAttributes +{ +public: + uint32_t m_game_mode; //0x0000 + uint32_t m_num_params; //0x0004 + uint32_t m_param_unk[8]; //0x0008 + char m_param_names[8][24]; //0x0028 + uint32_t m_param_values[8]; //0x00E8 + uint32_t m_params_bitset; //0x0108 +}; //Size: 0x010C +static_assert(sizeof(MatchmakingAttributes) == 0x10C); + +class NetworkGameFilter +{ +public: + virtual ~NetworkGameFilter() = default; + virtual void Reset() {}; + + uint32_t m_build_type; //0x0008 + uint32_t m_discriminator; //0x000C + uint32_t m_discriminator_mapping; //0x0010 + uint32_t m_region_mapping; //0x0014 + uint32_t m_language_mapping; //0x0018 + uint32_t m_mm_group_1_mapping; //0x001C + uint32_t m_mm_group_2_mapping; //0x0020 + uint32_t m_activity_type_mapping; //0x0024 + uint32_t m_activity_id_mapping; //0x0028 + uint32_t m_activity_players_mapping; //0x002C + class NetworkGameFilterMatchmakingComponent m_matchmaking_component; //0x0030 +}; //Size: 0x0344 +static_assert(sizeof(NetworkGameFilter) == 0x344); + +class SessionInfoBackup +{ +public: + class rage::rlSessionInfo m_session_info; + uint32_t m_unk; //0x0070 + char pad_0074[4]; //0x0074 + uint32_t m_flags; //0x0078 +}; //Size: 0x007C +static_assert(sizeof(SessionInfoBackup) == 0xDC); + +class MatchmakingSessionResult +{ +public: + class rage::rlSessionDetail m_detail; + char pad_03B8[24]; //0x03B8 +}; //Size: 0x03D0 +static_assert(sizeof(MatchmakingSessionResult) == 0x490); + +class PlayerNameMapNode +{ +public: + char m_name[16]; //0x0000 + class rage::rlGamerHandle m_handle; //0x0010 + class PlayerNameMapNode* m_next; //0x0020 + class PlayerNameMapNode* m_prev; //0x0028 +}; //Size: 0x0030 +static_assert(sizeof(PlayerNameMapNode) == 0x30); + +class JoiningPlayerNameMap +{ +public: + class PlayerNameMapNode m_names[100]; //0x0000 + char pad_12C0[40]; //0x12C0 + uint32_t m_num_name_nodes; //0x12E8 + char pad_12EC[796]; //0x12EC +}; //Size: 0x1608 +static_assert(sizeof(JoiningPlayerNameMap) == 0x1608); + +class CNetBlacklistNode +{ +public: + class rage::rlGamerHandle m_handle; //0x0000 + bool m_block_rejoin; //0x0010 + char pad_0011[3]; //0x0011 + uint32_t m_added_time; //0x0014 + class CNetBlacklistNode* m_next; //0x0018 + class CNetBlacklistNode* m_prev; //0x0020 +}; //Size: 0x0028 +static_assert(sizeof(CNetBlacklistNode) == 0x28); + +class CNetBlacklist +{ +public: + class CNetBlacklistNode m_nodes[16]; //0x0000 + class CNetBlacklistNode* m_head; //0x0280 + class CNetBlacklistNode* m_tail; //0x0288 + uint32_t m_free_nodes; //0x0290 + char pad_0294[4]; //0x0294 + class CNetBlacklistNode* m_start; //0x0298 + char pad_02A0[24]; //0x02A0 +}; //Size: 0x02B8 +static_assert(sizeof(CNetBlacklist) == 0x2B8); + +class RemotePlayerData +{ +public: + class rage::netGamePlayerData m_data[32]; //0x0000 + uint32_t m_count; //0x0600 + char pad_0604[4]; //0x0604 +}; //Size: 0x0608 +static_assert(sizeof(RemotePlayerData) == 0x608); + +class InvitedGamer +{ +public: + class rage::rlGamerHandle m_handle; + char pad_0010[12]; //0x0010 + uint32_t m_flags; //0x001C +}; //Size: 0x0020 +static_assert(sizeof(InvitedGamer) == 0x20); + +class InvitedGamers +{ +public: + class InvitedGamer m_invited_gamers[100]; //0x0000 + uint32_t m_num_invited_gamers; //0x0C80 + char pad_0C84[4]; //0x0C84 +}; //Size: 0x0C88 +static_assert(sizeof(InvitedGamers) == 0xC88); + +class Network +{ +public: + rage::rlSessionInfo m_steam_unk_session; //0x0000 + rage::Obf32 m_num_dinput8_instances; //0x0070 + rage::Obf32 m_last_time_dinput8_checked; //0x0080 + class rage::snSession m_game_session; //0x00F0 + class rage::snSession m_transition_session; //0x5578 + char pad_AA00[16]; //0xAA00 + class rage::snSession* m_game_session_ptr_2; //0xAA10 + class rage::snSession* m_transition_session_ptr_2; //0xAA18 + char pad_AA20[16]; //0xAA20 + class rage::snSession* m_game_session_ptr; //0xAA30 + class rage::snSession* m_transition_session_ptr; //0xAA38 + char pad_AA40[24]; //0xAA40 + class NetworkGameConfig m_network_game_config; //0xAA58 + class NetworkGameConfig m_network_transition_config; //0xABA0 + bool m_session_attributes_dirty; //0xACE8 + char pad_ACE9[19]; //0xACE9 + uint32_t m_session_visibility_flags; //0xACFC + uint32_t m_transition_visibility_flags; //0xAD00 + char pad_AD04[68]; //0xAD04 + class MetricSessionMigrated m_metric_session_migrated; //0xAD48 + bool m_migrated_metric_enabled; //0xB090 + char pad_B091[3]; //0xB091 + uint32_t m_game_session_state; //0xB094 + class NetworkGameFilter m_network_game_filter; //0xB098 + char pad_B3DC[33]; //0xB3DC + bool m_was_invited; //0xB3FD + char pad_B3FE[26]; //0xB3FE TODO: the reclass file is broken + class rage::rlSessionInfo m_unk_session_info; //0xB408 + char pad_B4D8[635]; //0xB4D8 + bool m_need_host_change; //0xB753 + char pad_B754[74316]; //0xB754 + class rage::rlSessionDetail m_joining_session_detail; //0x1D9A0 + class SessionInfoBackup m_last_joined_session; //0x1DE18 + char pad_1DEF4[40]; //0x1DEF4 + uint32_t m_current_matchmaking_group; //0x1DF1C + uint32_t m_matchmaking_group_max_players[5]; //0x1DF20 + uint32_t m_num_active_matchmaking_groups; //0x1DF34 + char pad_1DF38[8]; //0x1DF38 + uint8_t m_matchmaking_property_id; //0x1DF40 + uint8_t m_matchmaking_mental_state; //0x1DF41 + char pad_1DF42[366]; //0x1DF42 + class rage::rlMatchmakingFindResult m_game_session_matchmaking[3]; //0x1E0B0 + char pad_2ABC0[40]; //0x2ABC0 + class MatchmakingSessionResult m_game_matchmaking_session_results[10]; //0x2ABE8 + char pad_2D988[308]; //0x2D988 + uint32_t m_num_bosses; //0x2DABC + bool m_num_bosses_set; //0x2DAC0 + char pad_2DAC1[7]; //0x2DAC1 + class rage::rlGamerHandle m_transition_creator_handle; //0x2DAC8 + char pad_2DAD8[12]; //0x2DAD8 + bool m_is_waiting_async; //0x2DAE4 + bool m_is_preferred_activity; //0x2DAE5 + char pad_2DAE6[2]; //0x2DAE6 + uint32_t m_in_progress_finish_time; //0x2DAE8 + char pad_2DAEC[4]; //0x2DAEC + bool m_local_player_info_dirty; //0x2DAF0 + char pad_2DAF1[495]; //0x2DAF1 + class rage::rlGamerHandle m_inviter_handle; //0x2DCE0 + class CNetComplaintMgr m_game_complaint_mgr; //0x2DCF0 + class CNetComplaintMgr m_transition_complaint_mgr; //0x2EB88 + char pad_2FA20[32]; //0x2FA20 + class JoiningPlayerNameMap m_unused_joining_player_name_map; //0x2FA40 + char pad_31048[8]; //0x31048 + class CNetBlacklist m_blacklist; //0x31050 + char pad_31308[8]; //0x31308 + class InvitedGamers m_game_invited_gamers; //0x31310 + char pad_31F98[5888]; //0x31F98 + class SessionInfoBackup m_last_joined_transition; //0x33698 + uint32_t m_activity_max_players; //0x33774 + uint32_t m_activity_max_spectators; //0x33778 + char pad_3377C[48]; //0x3377C + bool m_do_not_launch_from_join_as_migrated_host; //0x337AC + char pad_337AD[7]; //0x337AD + bool m_is_activity_session; //0x337B4 + char pad_337B5[35]; //0x337B5 + class RemotePlayerData m_remote_player_data; //0x337D8 + char pad_33DE0[8]; //0x33DE0 + class rage::netGamePlayerData m_local_net_game_player_data; //0x33DE8 + char pad_33E18[608]; //0x33E18 + class rage::rlMatchmakingFindResult m_transition_matchmaking[4]; //0x34078 + class NetworkGameFilter m_transition_filters[4]; //0x44F38 + char pad_45C48[20]; //0x45C48 + uint32_t m_transition_quickmatch_group_handle_count; //0x45C5C + class rage::rlGamerHandle m_transition_quickmatch_group_handles[32]; //0x45C60 + bool m_retain_activity_group; //0x45E60 + char pad_45E61[7]; //0x45E61 + class rage::rlSessionInfo m_transition_to_activity_session_info; //0x45E68 + char pad_45F38[48]; //0x45F38 + class MatchmakingSessionResult m_transition_matchmaking_session_results[10]; //0x45F68 + char pad_48D08[8]; //0x48D08 + class InvitedGamers m_transition_invited_gamers; //0x48D10 + char pad_49998[16]; //0x49998 + class rage::rlGamerHandle m_transition_to_game_handle; //0x499A8 + class rage::rlSessionInfo m_transition_to_game_session_info; //0x499B8 + char pad_49A88[4]; //0x49A88 + uint32_t m_transition_to_game_session_participant_count; //0x49A8C + class rage::rlGamerHandle m_transition_to_game_session_participants[32]; //0x49A90 + char pad_49C90[80]; //0x49C90 + class rage::rlGamerHandle m_follower_handles[32]; //0x49CE0 + uint32_t m_follower_count; //0x49EE0 + char pad_49EE4[628]; //0x49EE4 +}; //Size: 0x38650 +static_assert(sizeof(Network) == 0x4A168); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/network/RemoteGamerInfoMsg.hpp b/classes/src/network/RemoteGamerInfoMsg.hpp new file mode 100644 index 0000000000..7061dfccd2 --- /dev/null +++ b/classes/src/network/RemoteGamerInfoMsg.hpp @@ -0,0 +1,20 @@ +#pragma once +#include +#include "../rage/rlGamerInfo.hpp" +#include "netConnection.hpp" + +#pragma pack(push, 8) +class RemoteGamerInfoMsg +{ +public: + uint64_t m_session_id; //0x0000 + class rage::rlGamerInfo m_gamer_info; //0x0008 + class rage::netPeerAddress m_peer_address; //0x00A0 + uint32_t unk_0xC0; //0x00C0 + uint32_t m_unk_struct_size; //0x00C4 + char m_unk_struct[512]; //0x00C8 Might be bitbuffer data + uint32_t m_num_handles; //0x02C8 + class rage::rlGamerHandle m_handles[32]; //0x02D0 +}; //Size: 0x04D0 +static_assert(sizeof(RemoteGamerInfoMsg) == 0x528); +#pragma pack(pop) diff --git a/classes/src/network/netConnection.hpp b/classes/src/network/netConnection.hpp new file mode 100644 index 0000000000..8e12e979d7 --- /dev/null +++ b/classes/src/network/netConnection.hpp @@ -0,0 +1,187 @@ +#pragma once +#include +#include "rage/rlGamerInfoBase.hpp" +#include "netPeerAddress.hpp" + +#pragma pack(push, 1) +namespace rage +{ + class netConnectionManager; + class netConnectionPeer; + + class netQueuedMessage + { + public: + void* m_data_buffer; + void* qword8; + void* qword10; + void* qword18; + rage::netQueuedMessage* m_next; + void* qword28; + char gap30[8]; + int m_creation_time; + int m_last_send_time; + int m_resend_count; + char gap44[4]; + int dword48; + uint16_t word4C; + char byte4E; + }; + static_assert(sizeof(netQueuedMessage) == 0x4F); + + class netMessageQueue + { + public: + rage::netQueuedMessage* m_first; + rage::netQueuedMessage* m_last; + uint64_t m_count; + }; + + class netPackedMessage + { + public: + void* m_data_buffer; + void* m_allocator; + void* qword10; + void* qword18; + }; + + class netPackedMessageQueue + { + public: + rage::netPackedMessage* m_first; + rage::netPackedMessage* m_last; + uint64_t m_count; + }; + + class netConnection + { + public: + class InFrame + { + public: + enum class EventType + { + ConnectionClosed = 3, + FrameReceived = 4, + BandwidthExceeded = 6, + OutOfMemory = 7 + }; + + virtual ~InFrame() = default; + + virtual void destroy() = 0; + virtual EventType get_event_type() = 0; + virtual uint32_t _0x18() = 0; + + uint32_t m_timestamp; //0x0008 + char pad_0008[52]; //0x000C + uint32_t m_msg_id; //0x0040 + uint32_t m_connection_identifier; //0x0044 + InFrame* m_this; //0x0048 + uint32_t m_peer_id; //0x0050 + char pad_0050[44]; //0x0058 + uint32_t m_length; //0x0080 + char pad_007C[4]; //0x0084 + void* m_data; //0x0088 + }; + static_assert(sizeof(rage::netConnection::InFrame) == 0x90); + + char gap0[8]; + rage::netConnectionPeer* m_connection_peer; + int m_msg_id; + uint32_t m_connection_id; + void* m_allocator; + uint32_t m_connection_state; + uint32_t m_last_send_time; + uint32_t m_last_receive_time; + uint32_t m_num_failed_messages; + char gap30[8]; + uint32_t m_timeout_reason; + uint32_t dword3C; + uint32_t m_timeout; + uint32_t dword44; + uint32_t m_resend_threshold; + char gap4C[4]; + rage::netMessageQueue m_reliables_resend_queue; + rage::netMessageQueue m_normal_message_queue; + rage::netQueuedMessage* m_unacked_reliable_message_list; + int m_unacked_reliable_message_count; + char gap8C[36]; + netConnectionManager* m_net_connection_mgr; + char gapB8[8]; + uint32_t dwordC0; + int16_t m_msg_counter; + int16_t wordC6; + char gapC8[2]; + int16_t m_last_reliable_msg_counter; + char m_flags; + char gapCD[3]; + int m_failed_allocation_size; + int32_t m_failed_allocations; + rage::netConnection* m_next; + char gapE0[208]; + int m_flags2; + char gap1B4[69]; + }; + static_assert(sizeof(netConnection) == 0x1F9); + + class netConnectionQueue + { + public: + rage::netConnection* m_first; + rage::netConnection* m_last; + uint64_t m_count; + }; + + class netConnectionPeer + { + public: + rage::netConnection* m_connections_by_id[16]; + rage::netConnectionQueue m_net_connection_queue; + rage::netPackedMessageQueue m_packed_message_queue; + void* qwordB0; + char byteB8; + char gapB9[3]; + int intBC; + uint32_t dwordC0; + char gapC4[4]; + void* qwordC8; + rage::netPeerAddress m_relay_address; + rage::rlGamerInfoBase m_gamer_info; + char gap1B0[24]; + uint32_t dword1C8; + char gap1CC[28]; + uint32_t m_security_id; + char gap1EC[28]; + void* qword208; + char gap210[24]; + rage::netPeerAddress m_peer_address; + rage::netConnectionPeer* m_next; + char gap250[8]; + int m_time_until_next_batch; + int m_empty_batch_interval; + uint32_t m_time_until_timeout; + int m_last_msg_process_time; + int gap268; + void* qword26C; + char gap274[4]; + void* qword278; + char gap280[24]; + void* qword298; + char gap2A0[64]; + uint32_t m_peer_id; + char byte2E4; + char more[51]; + int gap318; + char gap31C[24]; + int m_num_encryption_attempts; + char gap338[60]; + int m_num_messages_batched; + int m_num_reliable_messages_batched; + int m_num_resent_reliable_messages_batched; + char gap380[145]; + }; + static_assert(sizeof(netConnectionPeer) == 0x411); +} +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/network/netObject.hpp b/classes/src/network/netObject.hpp new file mode 100644 index 0000000000..08f44677cd --- /dev/null +++ b/classes/src/network/netObject.hpp @@ -0,0 +1,133 @@ +#pragma once + +#include +#include "../netsync/netSyncTree.hpp" +#include "../base/atRTTI.hpp" + +class CObject; +namespace rage +{ + class netObject + { + public: + int16_t m_object_type; //0x0008 + int16_t m_object_id; //0x000A + char pad_000C[61]; //0x000C + int8_t m_owner_id; //0x0049 + int8_t m_control_id; //0x004A + int8_t m_next_owner_id; //0x004B + bool m_is_remote; //0x004C + bool m_wants_to_delete; //0x004D + char pad_004E[1]; //0x004E + bool m_should_not_be_delete; //0x004F + + DEFINE_RAGE_RTTI(rage::netObject) + + virtual void mov1() = 0; // 0x38 + virtual void mov2() = 0; // 0x40 + + virtual void m_8() = 0; // 0x48 + virtual void m_10() = 0; // 0x50 + virtual void m_18() = 0; // 0x58 + virtual void* m_20() = 0; // 0x60 + virtual void m_28() = 0; // 0x68 + virtual netSyncTree* GetSyncTree() = 0; // 0x70 + virtual void m_38() = 0; // 0x78 + virtual void m_40() = 0; // 0x80 + virtual void m_48() = 0; + virtual void m_50() = 0; + virtual void m_58() = 0; + virtual void m_60() = 0; + virtual void m_68() = 0; + virtual void m_70() = 0; + virtual void m_78() = 0; + virtual CObject* GetGameObject() = 0; + virtual void m_88() = 0; + virtual void m_90() = 0; + virtual void m_98() = 0; + virtual int GetObjectFlags() = 0; + virtual void m_A8() = 0; + virtual void m_B0() = 0; + virtual void m_B8() = 0; + virtual void m_C0() = 0; + virtual void m_C8() = 0; + virtual int GetSyncFrequency() = 0; + virtual void m_D8() = 0; + virtual void m_E0() = 0; + virtual void m_E8() = 0; + virtual void m_F0() = 0; + virtual void m_F8() = 0; + virtual void Update() = 0; + virtual bool m_108_1604() = 0; // added in 1604 + virtual void m_108() = 0; + virtual void m_110() = 0; + virtual void m_118() = 0; + virtual void m_120() = 0; + virtual void m_128() = 0; + virtual void m_130() = 0; + virtual void m_138() = 0; + virtual void m_140() = 0; + virtual void m_148() = 0; + virtual void m_150() = 0; + virtual bool m_158(void* player, int type, int* outReason) = 0; + virtual void m_160() = 0; + virtual bool m_168(int* outReason) = 0; + virtual void m_170() = 0; + virtual void m_178() = 0; + virtual void m_180() = 0; + virtual void m_188() = 0; + virtual void m_190() = 0; + virtual void m_198() = 0; + virtual void m_1A0() = 0; + virtual void m_1A8() = 0; + virtual void m_1B0() = 0; + virtual void m_1B8() = 0; + virtual void m_1C0() = 0; + virtual void m_1C8() = 0; + virtual void m_1D0() = 0; + virtual void m_1D8() = 0; + virtual void m_1E0() = 0; + virtual void m_1E8() = 0; + virtual void m_1F0() = 0; + virtual void m_1F8() = 0; + virtual void m_200() = 0; + virtual void m_208() = 0; + virtual void m_210() = 0; + virtual void m_218() = 0; + virtual void m_220() = 0; + virtual void m_228() = 0; + virtual void m_230() = 0; + virtual void m_238() = 0; + virtual void m_240() = 0; + virtual void m_248() = 0; + virtual void m_250() = 0; + virtual void m_258() = 0; + virtual void m_260() = 0; + virtual void m_268() = 0; + virtual void m_270() = 0; + virtual void m_278() = 0; + virtual void m_280() = 0; + virtual void m_288() = 0; + virtual void m_290() = 0; + virtual void m_298() = 0; + virtual void m_2A0() = 0; + virtual void m_2A8() = 0; + virtual void m_2B0() = 0; + virtual void m_2B8() = 0; + virtual void m_2C0() = 0; + virtual void m_2C8() = 0; + virtual void m_2D0() = 0; + virtual void m_2D8() = 0; + virtual void m_2E0() = 0; + virtual void m_2E8() = 0; + virtual void m_2F0() = 0; + virtual void m_2F8() = 0; + virtual void m_300() = 0; + virtual void m_308() = 0; + virtual void m_310() = 0; + virtual void m_318() = 0; + virtual void m_320() = 0; + virtual void UpdatePendingVisibilityChanges() = 0; + }; //Size: 0x0050 + static_assert(sizeof(netObject) == 0x50); +} diff --git a/classes/src/network/netPeerAddress.hpp b/classes/src/network/netPeerAddress.hpp new file mode 100644 index 0000000000..0127e58ac4 --- /dev/null +++ b/classes/src/network/netPeerAddress.hpp @@ -0,0 +1,32 @@ +#pragma once +#include + +union netAddress { + uint32_t m_packed; //0x0000 + struct { + uint8_t m_field4; //0x0000 + uint8_t m_field3; //0x0001 + uint8_t m_field2; //0x0002 + uint8_t m_field1; //0x0003 + }; +}; //Size: 0x0004 +static_assert(sizeof(netAddress) == 0x04); + +namespace rage +{ +#pragma pack(push, 4) + class netPeerAddress + { + public: + netAddress m_internal_ip; //0x0000 + uint16_t m_internal_port; //0x0004 + netAddress m_external_ip; //0x0008 + uint16_t m_external_port; //0x000C + uint64_t m_peer_id; //0x0010 + netAddress m_relay_address; //0x0018 + uint16_t m_relay_port; //0x001C + uint8_t m_connection_type; //0x001E + }; + static_assert(sizeof(netPeerAddress) == 0x20); +#pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/network/netPlayer.hpp b/classes/src/network/netPlayer.hpp new file mode 100644 index 0000000000..30b29373a8 --- /dev/null +++ b/classes/src/network/netPlayer.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include "../rage/rlGamerInfo.hpp" +#include "../player/CNonPhysicalPlayerData.hpp" + +namespace rage +{ +#pragma pack(push, 8) + class netPlayer + { + public: + virtual void* _0x00(); + virtual void* _0x08(); + virtual uint32_t _0x10(); + virtual netPlayer* _0x18(void*); + virtual bool _0x20(void*); + virtual bool _0x28(void**); + virtual void destructor(); + virtual void reset(); + virtual bool is_valid(); + virtual const char* get_name(); + virtual void _0x50(); + virtual bool is_host(); + virtual rage::rlGamerInfo* get_net_data(); + virtual void _0x68(); + + char pad_0008[8]; //0x0008 + CNonPhysicalPlayerData* m_non_physical_player; //0x0010 + uint32_t m_msg_id; //0x0018 + char pad_001C[4]; //0x001C + uint8_t m_active_id; //0x0020 + uint8_t m_player_id; //0x0021 + char pad_0022[3]; //0x0022 + uint16_t m_complaints; //0x0026 + char pad_0027[17]; //0x0028 + class CNetGamePlayer* m_unk_net_player_list[10]; //0x0040 + char pad_0090[4]; //0x0090 + uint64_t pad_0098; //0x0098 + }; //Size: 0x00A0 + static_assert(sizeof(netPlayer) == 0xA0); +#pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/network/netPlayerMgrBase.hpp b/classes/src/network/netPlayerMgrBase.hpp new file mode 100644 index 0000000000..12226709ce --- /dev/null +++ b/classes/src/network/netPlayerMgrBase.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include "CNetGamePlayer.hpp" +#include "CNetGamePlayerDataMsg.hpp" +#include "../player/CNonPhysicalPlayerData.hpp" + +#include + +namespace rage +{ +#pragma pack(push, 8) + class netPlayerMgrBase + { + public: + virtual ~netPlayerMgrBase() = default; + virtual void Initialize() = 0; + virtual void Shutdown() = 0; + virtual void unk_0x18() = 0; + virtual CNetGamePlayer* AddPlayer_raw(rage::rlGamerInfo* gamer_info, uint32_t a2, CNetGamePlayerDataMsg* player_data, CNonPhysicalPlayerData* non_physical_player_data) = 0; + virtual void RemovePlayer(CNetGamePlayer* net_game_player) = 0; + virtual void UpdatePlayerListsForPlayer(CNetGamePlayer* net_game_player) = 0; + virtual CNetGamePlayer* AddPlayer(rage::rlGamerInfo* gamer_info, uint32_t a3, CNetGamePlayerDataMsg* player_data, CNonPhysicalPlayerData* non_physical_player_data) = 0; + + char pad_0008[8]; //0x0008 + uint64_t* m_network_bandwidth_manager; //0x0010 + char pad_0018[216]; //0x0018 + CNetGamePlayer* m_local_net_player; //0x00E8 + char pad_00F0[144]; //0x00F0 + CNetGamePlayer* m_player_list[32]; //0x0180 + uint16_t m_player_limit; //0x0280 + char pad_0282[10]; //0x0282 + uint16_t m_player_count; //0x028C + char pad_0290[1618]; //0x0290 + }; //Size: 0x08E0 + static_assert(sizeof(netPlayerMgrBase) == 0x8E8); +#pragma pack(pop) +} diff --git a/classes/src/network/netTime.hpp b/classes/src/network/netTime.hpp new file mode 100644 index 0000000000..c18e0e96a7 --- /dev/null +++ b/classes/src/network/netTime.hpp @@ -0,0 +1,40 @@ +#pragma once +#include + +namespace rage +{ + class netConnectionManager; +} + +namespace rage +{ + class netTime + { + public: + virtual ~netTime() = default; + + netConnectionManager* m_net_connection_mgr; //0x0008 + uint32_t m_host_peer_id; //0x0010 + uint32_t m_time_token; //0x0014 + uint32_t m_time_offset; //0x0018 + char pad_001C[72]; //0x001C + uint32_t m_failed_sync_counter; //0x0064 + uint32_t m_last_sync_id_sent; //0x0068 + uint32_t m_last_sync_id_received; //0x006C + uint32_t m_role_flags; //0x0070 + uint32_t m_connection_identifier; //0x0074 + uint32_t m_time; //0x0078 + uint32_t m_calculation_flags; //0x007C + }; //Size: 0x0080 + static_assert(sizeof(netTime) == 0x80); + + struct netTimeSyncMsg + { + int action; + int counter; + int token; + int timestamp; + int increment; + }; + static_assert(sizeof(netTimeSyncMsg) == 0x14); +} \ No newline at end of file diff --git a/classes/src/network/snConnectToPeerTask.hpp b/classes/src/network/snConnectToPeerTask.hpp new file mode 100644 index 0000000000..8edc25bf88 --- /dev/null +++ b/classes/src/network/snConnectToPeerTask.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace rage +{ + class snConnectToPeerTaskData + { + public: + int m_unk; + int m_reason; + uint64_t m_session_token; + }; + + class snConnectToPeerTaskResult + { + public: + char pad[0x10]{}; + int m_peer_id; + char pad2[0x400]{}; + }; +} \ No newline at end of file diff --git a/classes/src/network/snSession.hpp b/classes/src/network/snSession.hpp new file mode 100644 index 0000000000..27621513c7 --- /dev/null +++ b/classes/src/network/snSession.hpp @@ -0,0 +1,195 @@ +#pragma once + +#include "../rage/rlGamerInfo.hpp" +#include "../rage/rlSessionInfo.hpp" + +#pragma pack(push, 1) +namespace rage +{ + class netConnectionManager; + class sysMemAllocator; + + class snPlayer + { + public: + uint64_t m_msg_id; //0x0000 + class rage::rlGamerInfo m_player_data; //0x0008 + char pad_00F8[8]; //0x00F8 + }; //Size: 0x0100 + static_assert(sizeof(rage::snPlayer) == 0x100); + + class snPeer + { + public: + class rage::rlGamerInfo m_peer_data; //0x0000 + char pad_0098[40]; //0x0098 + }; //Size: 0x00C0 + static_assert(sizeof(rage::snPeer) == 0x118); + + class rlRemoteGamer + { + public: + rage::rlGamerHandle m_handle; + char pad_0010[4]; //0x0010 + uint32_t m_timeout_time; //0x0014 + uint32_t m_time_unk; //0x0018 + char pad_001C[4]; //0x001C + }; //Size: 0x0020 + static_assert(sizeof(rage::rlRemoteGamer) == 0x20); + + + class rlSession + { + public: + char pad_0008[248]; //0x0008 + class rage::rlSessionInfo m_session_info; //0x0100 + char pad_01D0[296]; //0x01D0 + uint64_t m_session_id; //0x02F8 + char pad_0300[1136]; //0x0300 + + virtual ~rlSession() = default; + }; //Size: 0x0770 + static_assert(sizeof(rage::rlSession) == 0x770); + + class rlSessionDetail + { + public: + class rage::rlGamerInfoBase m_base_gamer_info; + char pad_0060[8]; //0x0060 + class rage::rlSessionInfo m_session_info; //0x0068 + char pad_00D8[14]; //0x00D8 + uint16_t m_session_type; //0x00E6 + char pad_00E8[324]; //0x00E8 + uint32_t m_player_count; //0x022C + uint32_t m_unk_player_count; //0x0230 + char pad_0234[2]; //0x0234 + int16_t m_unk_pos_x; //0x0236 + int16_t m_unk_pos_y; //0x0238 + int16_t m_unk_pos_z; //0x023A + uint8_t m_matchmaking_property_ids[32]; //0x023C + char pad_025C[2]; //0x025C + uint16_t m_rank; //0x025E + char pad_0260[1]; //0x0260 + uint8_t m_mental_state; //0x0261 + char pad_0262[21]; //0x0262 + uint8_t m_population_density; //0x0277 + char pad_0278[320]; //0x0278 + }; //Size: 0x03CA + static_assert(sizeof(rlSessionDetail) == 0x478); + + + class rlMatchmakingFindResult + { + public: + class rage::rlSessionDetail m_result_session_details[15]; //0x0000 + char pad_37C8[168]; //0x37C8 + }; //Size: 0x3870 + static_assert(sizeof(rage::rlMatchmakingFindResult) == 0x43B0); + + class netGamePlayerData + { + public: + class rlGamerHandle m_handle; + bool m_is_activity_spectator; //0x0010 + char pad_0011[7]; //0x0011 + uint64_t m_crew_id; //0x0018 + uint16_t m_rank; //0x0020 + uint16_t m_debug_unk; //0x0022 + char pad_0024[4]; //0x0024 + uint32_t m_nat_type; //0x0028 + bool m_is_rockstar_dev; //0x002C + char pad_002D[3]; //0x002D + }; //Size: 0x0030 + static_assert(sizeof(rage::netGamePlayerData) == 0x30); + + + class snSession + { + public: + uint64_t m_memory_allocator; //0x0000 + char pad_0008[64]; //0x0008 + rage::netConnectionManager* m_net_connection_mgr; //0x0048 + char pad_0050[48]; //0x0050 + class rage::rlSession m_rline_session; //0x0080 + class rage::snPlayer m_local_player; //0x07F0 + uint64_t m_host_token; //0x08F0 + char pad_08F8[144]; //0x08F8 + class rage::snPeer m_peer_storage[32]; //0x0988 + char pad_2C88[24]; //0x2C88 + class rage::snPeer* m_peers[32]; //0x2CA0 + uint32_t m_peer_count; //0x2DA0 + char pad_2DA4[4]; //0x2DA4 + class rage::snPlayer m_player_storage[32]; //0x2DA8 + char pad_4DA8[24]; //0x4DA8 + class rage::snPlayer* m_players[32]; //0x4DC0 + int32_t m_player_count; //0x4EC0 + char pad_4EC4[4]; //0x4EC4 + class rage::rlRemoteGamer m_remote_gamers[32]; //0x4EC8 + uint32_t m_num_remote_gamers; //0x52C8 + bool m_player_joining; //0x52CC + char pad_52CD[107]; //0x52CD + uint32_t m_connection_identifier; //0x5338 + char pad_533C[4]; //0x533C + uint32_t m_profile_index; //0x5340 + char m_token_key[64]; //0x5344 + char m_id_key[64]; //0x5384 + char m_info_key[64]; //0x53C4 + char m_host_key[64]; //0x5404 + char m_join_key[64]; //0x5444 + char pad_5484[4]; //0x5484 + + inline bool is_host() + { + return m_local_player.m_player_data.m_host_token == m_host_token; + } + + inline snPlayer* get_player_by_token(uint64_t token) + { + for (std::uint32_t i = 0; i < m_player_count; i++) + { + if (m_players[i]->m_player_data.m_host_token == token) + { + return m_players[i]; + } + } + + return nullptr; + } + + inline snPeer* get_peer_by_rockstar_id(uint64_t rid) + { + for (uint32_t i = 0; i < m_peer_count; i++) + { + if (m_peers[i]->m_peer_data.m_gamer_handle_2.m_rockstar_id == rid) + { + return m_peers[i]; + } + } + + return nullptr; + } + + }; //Size: 0x3E70 + static_assert(sizeof(rage::snSession) == 0x5488); + + class snMsgRemoveGamersFromSessionCmd + { + public: + uint64_t m_session_id; //0x0000 + rage::rlGamerHandle m_handles[32]; //0x0008 + int32_t m_unk = -1; //0x208 + uint32_t m_num_peers; //0x20C + }; //Size: 0x0110 + static_assert(sizeof(rage::snMsgRemoveGamersFromSessionCmd) == 0x210); +} + +class SessionSortEntry +{ +public: + class rage::rlSessionDetail* m_session_detail; //0x0000 + char pad_0008[4]; //0x0008 + float m_score; //0x000C + char pad_0010[8]; //0x0010 +}; //Size: 0x0018 +static_assert(sizeof(SessionSortEntry) == 0x18); +#pragma pack(pop) diff --git a/classes/src/ped/CPed.hpp b/classes/src/ped/CPed.hpp new file mode 100644 index 0000000000..a24b2d11e2 --- /dev/null +++ b/classes/src/ped/CPed.hpp @@ -0,0 +1,75 @@ +#pragma once + +#include "../vehicle/CVehicle.hpp" +#include "../player/CPlayerInfo.hpp" +#include "CPedModelInfo.hpp" +#include "CPedWeaponManager.hpp" +#include "CPedInventory.hpp" +#include "../entities/fwEntity.hpp" +#include "../rage/vector.hpp" +#include "CPedIntelligence.hpp" +#include "CPedBoneInfo.hpp" + +#include +#include + +#pragma pack(push, 1) +class CPed : public rage::CPhysical +{ +public: + char gap2EC[20]; + rage::fvector3 m_velocity; //0x0300 + char pad_030C[260]; //0x030C + class CPedBoneInfo m_bone_info[9]; //0x0410 + char pad_04A0[2160]; //0x04A0 + class CVehicle *m_vehicle; //0x0D10 + char pad_0D18[896]; //0x0D18 + uint32_t m_ped_type; //0x1098 + char pad_109C[4]; //0x109C + class CPedIntelligence* m_ped_intelligence; //0x10A0 + class CPlayerInfo *m_player_info; //0x10A8 + class CPedInventory* m_inventory; //0x10B0 + class CPedWeaponManager *m_weapon_manager; //0x10B8 + char pad_10C0[892]; //0x10C0 + uint8_t m_seatbelt; //0x143C + char pad_143D[13]; //0x143D + uint8_t m_can_switch_weapon; //0x144A + uint8_t m_ped_task_flag; //0x144B + char pad_144C[4]; //0x144C + uint8_t m_forced_aim; //0x1450 m_forced_aim ^= (m_forced_aim ^ -(char)toggle) & 0x20; + char pad_1451[187]; //0x1451 + float m_armor; //0x150C + float unk_health_threshold; //0x1510 + float m_fatigued_health_threshold; //0x1514 + float m_injured_health_threshold; //0x1518 + float m_dying_health_threshold; //0x151C + float m_hurt_health_threshold; //0x1520 + char pad_1524[12]; //0x1524 + void* m_seat_info; //0x1530 + char pad_1538[220]; //0x1538 + uint16_t m_cash; //0x1614 + char pad_1616[842]; //0x1616 + uint8_t fired_sticky_bombs; //0x1960 reverse from 1.66 2824 function E8 ? ? ? 48 8B F8 EB 5F add(1).rip(), function string: WM_MAX_STICKY + uint8_t fired_unk_0; //0x1961 + uint8_t fired_flares; //0x1962 + uint8_t fired_unk_1; //0x1963 + + float get_speed() { return sqrt(m_velocity.x * m_velocity.x + m_velocity.y * m_velocity.y + m_velocity.z * m_velocity.z); } + + rage::fvector3 get_bone_coords(ePedBoneType type) + { + rage::fvector3 world_coords; + model_to_world(m_bone_info[(uint32_t)type].model_coords, world_coords); + return world_coords; + } + + bool can_be_ragdolled() { return m_ped_type & 0x20; } + + uint32_t get_ped_type() { return m_ped_type << 11 >> 25; } + + bool has_seatbelt() { return m_seatbelt & 0x3; } + + void forced_aim(bool toggle) { m_forced_aim ^= (m_forced_aim ^ -(char)toggle) & 0x20; } +}; //Size: 0x1964 +static_assert(sizeof(CPed) == 0x1964); +#pragma pack(pop) diff --git a/classes/src/ped/CPedBoneInfo.hpp b/classes/src/ped/CPedBoneInfo.hpp new file mode 100644 index 0000000000..ba54b77b69 --- /dev/null +++ b/classes/src/ped/CPedBoneInfo.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "../rage/vector.hpp" + +enum class ePedBoneType +{ + HEAD, + L_FOOT, + R_FOOT, + L_ANKLE, + R_ANKLE, + L_HAND, + R_HAND, + NECK, + ABDOMEN +}; + +class CPedBoneInfo +{ +public: + rage::fvector3 model_coords; + char pad_000C[4]; +}; +static_assert(sizeof(CPedBoneInfo) == 0x10); \ No newline at end of file diff --git a/classes/src/ped/CPedFactory.hpp b/classes/src/ped/CPedFactory.hpp new file mode 100644 index 0000000000..bb54363847 --- /dev/null +++ b/classes/src/ped/CPedFactory.hpp @@ -0,0 +1,23 @@ +#pragma once +#include "CPed.hpp" + +class CPedFactory +{ +public: + enum class PedCreateFlags + { + IS_NETWORKED = (1 << 0), + IS_PLAYER = (1 << 1) + }; + + virtual ~CPedFactory() = default; + virtual CPed* CreatePed(std::uint8_t* flags, std::uint16_t* model_index, rage::fmatrix44* matrix, bool default_component_variation, bool register_network_object, bool give_default_loadout, bool, bool) = 0; // 0x08 + virtual CPed* CreateClone(std::uint8_t* flags, std::uint16_t* model_index, rage::fmatrix44* matrix, bool default_component_variation, bool, bool register_network_object, bool) = 0; // 0x10 + virtual CPed* ClonePed(CPed* ped, bool register_network_object, bool link_blends, bool clone_compressed_damage) = 0; // 0x18 + virtual CPed* ClonePedToTarget(CPed* source, CPed* target, bool clone_compressed_damage) = 0; // 0x20 + virtual CPed* CreatePlayer(std::uint8_t* flags, std::uint16_t model_index, rage::fmatrix44* matrix, CPlayerInfo* player_info) = 0; // 0x28 + virtual void DestroyPed(CPed* ped) = 0; // 0x30 + + class CPed* m_local_ped; //0x0008 +}; //Size: 0x0010 +static_assert(sizeof(CPedFactory) == 0x10); diff --git a/classes/src/ped/CPedIntelligence.hpp b/classes/src/ped/CPedIntelligence.hpp new file mode 100644 index 0000000000..3dd798eac2 --- /dev/null +++ b/classes/src/ped/CPedIntelligence.hpp @@ -0,0 +1,9 @@ +#pragma once + +class CPedIntelligence +{ +public: + char pad_0000[632]; //0x0000 + float m_oxygen_time; //0x0278 +}; //Size: 0x027C +static_assert(sizeof(CPedIntelligence) == 0x27C); \ No newline at end of file diff --git a/classes/src/ped/CPedInventory.hpp b/classes/src/ped/CPedInventory.hpp new file mode 100644 index 0000000000..0f546f3277 --- /dev/null +++ b/classes/src/ped/CPedInventory.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include +#include "../base/atRTTI.hpp" + +class CPed; + +#pragma pack(push, 8) +class CPedInventory +{ +public: + DEFINE_RAGE_RTTI(CPedInventory); + + uint64_t unk_0008; + CPed* m_ped; //0x0010 + uint64_t unk_0018; + uint32_t unk_0020; + uint64_t unk_0028; + uint64_t unk_0030; + uint32_t unk_0038; + char pad_003C[4]; + char unk_0040; + char pad_0041[7]; + uint64_t unk_0048; + uint32_t unk_0050; + uint64_t unk_0058; + uint64_t unk_0060; + uint32_t unk_0068; + char pad_006C[4]; + char unk_0070; + char pad_0071[7]; + bool m_infinite_ammo : 1; + bool m_infinite_clip : 1; + char pad_0079[7]; + uint64_t unk_0080; +}; +static_assert(sizeof(CPedInventory) == 0x88); +#pragma pack(pop) diff --git a/classes/src/ped/CPedModelInfo.hpp b/classes/src/ped/CPedModelInfo.hpp new file mode 100644 index 0000000000..b1c7108742 --- /dev/null +++ b/classes/src/ped/CPedModelInfo.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "../base/CBaseModelInfo.hpp" + +#include + +class CPedModelInfo : public CBaseModelInfo +{ +public: + char gapB0[48]; + uint64_t qwordE0; + uint32_t dwordE8; + char gapEC[4]; + uint32_t dwordF0; + char gapF4[4]; + uint64_t qwordF8; + uint32_t dword100; + uint64_t qword108; + uint64_t qword110; + uint64_t qword118; + uint64_t qword120; + uint64_t qword128; + uint32_t dword130; + char gap134[4]; + uint32_t ped_type; + char gap13C[140]; + uint64_t qword1C8; + uint32_t dword1D0; + uint64_t qword1D8; + uint32_t dword1E0; + char gap1E4[52]; + uint64_t qword218; + char gap220[8]; + uint64_t qword228; + uint32_t dword230; + char gap234[4]; + uint32_t dword238; + char gap23C[12]; + uint64_t qword248; + uint64_t qword250; + uint64_t qword258; + uint64_t qword260; + uint64_t qword268; + uint64_t qword270; + uint64_t qword278; + char gap280[16]; +}; +static_assert(sizeof(CPedModelInfo) == 0x290); diff --git a/classes/src/ped/CPedWeaponManager.hpp b/classes/src/ped/CPedWeaponManager.hpp new file mode 100644 index 0000000000..3e484a1c13 --- /dev/null +++ b/classes/src/ped/CPedWeaponManager.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "../weapon/CWeaponInfo.hpp" + +#include + +class CPedWeaponManager +{ +public: + char pad_0000[16]; //0x0000 + class CPed* m_owner; //0x0010 + uint32_t m_selected_weapon_hash; //0x0018 + char pad_001C[4]; //0x001C + class CWeaponInfo* m_weapon_info; //0x0020 + char pad_0028[72]; //0x0028 + class CWeaponInfo* m_vehicle_weapon_info; //0x0070 + class CObject* m_weapon_object; //0x0078 +}; //Size: 0x0080 +static_assert(sizeof(CPedWeaponManager) == 0x80); diff --git a/classes/src/player/CNonPhysicalPlayerData.hpp b/classes/src/player/CNonPhysicalPlayerData.hpp new file mode 100644 index 0000000000..13cc735598 --- /dev/null +++ b/classes/src/player/CNonPhysicalPlayerData.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "../rage/vector.hpp" + +#include + +namespace rage +{ + class nonPhysicalPlayerDataBase + { + public: + virtual ~nonPhysicalPlayerDataBase(); + virtual void read(); + virtual void write(); + virtual void calculate_size(); + virtual void log(); + }; //Size: 0x0008 + static_assert(sizeof(nonPhysicalPlayerDataBase) == 0x8); +} + +#pragma pack(push, 4) +class CNonPhysicalPlayerData : public rage::nonPhysicalPlayerDataBase +{ +public: + int32_t m_bubble_id; //0x0008 + int32_t m_player_id; //0x000C + rage::fvector3 m_position; //0x0010 +}; //Size: 0x001C +static_assert(sizeof(CNonPhysicalPlayerData) == 0x1C); +#pragma pack(pop) diff --git a/classes/src/player/CPlayerAngles.hpp b/classes/src/player/CPlayerAngles.hpp new file mode 100644 index 0000000000..bdbdb8b40c --- /dev/null +++ b/classes/src/player/CPlayerAngles.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "../rage/vector.hpp" +#include "CPlayerCameraData.hpp" + +class CPlayerAngles +{ +public: + char pad_0000[16]; //0x0000 + CPlayerCameraData* m_cam_data; //0x0010 + char pad_0018[24]; //0x0018 + rage::fvector3 m_right; //0x0030 + char pad_003C[4]; //0x003C + rage::fvector3 m_forward; //0x0040 + char pad_004C[4]; //0x004C + rage::fvector3 m_up; //0x0050 + char pad_005C[4]; //0x005C + rage::fvector3 m_position; //0x0060 + char pad_006C[36]; //0x006C +}; //Size: 0x0090 +static_assert(sizeof(CPlayerAngles) == 0x90); diff --git a/classes/src/player/CPlayerCameraData.hpp b/classes/src/player/CPlayerCameraData.hpp new file mode 100644 index 0000000000..4570ada7c5 --- /dev/null +++ b/classes/src/player/CPlayerCameraData.hpp @@ -0,0 +1,11 @@ +#pragma once + +class CPlayerCameraData +{ +public: + char m_unk_0x0[0x30]; + float m_fov; + char m_unk_0x34[0x24]; + uint32_t m_zoom_state; +}; +static_assert(sizeof(CPlayerCameraData) == 0x5C); diff --git a/classes/src/player/CPlayerInfo.hpp b/classes/src/player/CPlayerInfo.hpp new file mode 100644 index 0000000000..5b5a0bd393 --- /dev/null +++ b/classes/src/player/CPlayerInfo.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include "../rage/rlGamerInfo.hpp" + +#include + +enum class eGameState : int32_t +{ + Invalid = -1, + Playing, + Died, + Arrested, + FailedMission, + LeftGame, + Respawn, + InMPCutscene +}; + +#pragma pack(push, 4) +class CPlayerInfo +{ +public: + char pad_0000[32]; //0x0000 + class rage::rlGamerInfo m_net_player_data; //0x0020 + char pad_0110[184]; //0x0110 + float m_swim_speed; //0x01C8 + char pad_01CC[20]; //0x01CC + uint32_t m_water_proof; //0x01E0 + char pad_01E4[76]; //0x01E4 + eGameState m_game_state; //0x0230 + char pad_0234[12]; //0x0234 + class CPed* m_ped; //0x0240 + char pad_0248[40]; //0x0248 + uint32_t m_frame_flags; //0x0270 + char pad_0274[52]; //0x0274 + uint32_t m_player_controls; //0x02A8 + char pad_02AC[1248]; //0x02AC + float m_wanted_can_change; //0x078C + char pad_0790[304]; //0x0790 + uint32_t m_npc_ignore; //0x08C0 + char pad_08C4[12]; //0x08C4 + bool m_is_wanted; //0x08D0 + char pad_08D1[7]; //0x08D1 + uint32_t m_wanted_level; //0x08D8 + uint32_t m_wanted_level_display; //0x08DC + char pad_08E0[1120]; //0x08E0 + float m_run_speed; //0x0D40 + float m_stamina; //0x0D44 + float m_stamina_regen; //0x0D48 + char pad_0D4C[16]; //0x0D4C + float m_weapon_damage_mult; //0x0D5C + float m_weapon_defence_mult; //0x0D60 + char pad_0D64[4]; //0x0D64 + float m_melee_weapon_damage_mult; //0x0D68 + float m_melee_damage_mult; //0x0D6C + float m_melee_defence_mult; //0x0D70 + char pad_0D74[8]; //0x0D74 + float m_melee_weapon_defence_mult; //0x0D7C +}; //Size: 0x0D80 +static_assert(sizeof(CPlayerInfo) == 0xD80); +#pragma pack(pop) diff --git a/classes/src/rage/atArray.hpp b/classes/src/rage/atArray.hpp new file mode 100644 index 0000000000..b0b9ca1e35 --- /dev/null +++ b/classes/src/rage/atArray.hpp @@ -0,0 +1,234 @@ +#pragma once +#include +#include +#include +#include + +#include "script/tlsContext.hpp" + +namespace rage +{ +#pragma pack(push, 8) + template + class atArray + { + public: + atArray() : + m_data(nullptr), + m_size(0), + m_count(0) + { + + } + +#if _WIN32 + atArray(const atArray& right) + { + m_count = right.m_count; + m_size = right.m_size; + + if (right.m_data == nullptr) + { + m_data = nullptr; + return; + } + + m_data = (T*)tlsContext::get()->m_allocator->Allocate(m_size * sizeof(T), 16, 0); + std::uninitialized_copy(right.m_data, right.m_data + right.m_count, m_data); + } + + atArray(void* data_ptr, std::uint16_t size, std::uint16_t count) : + m_data(data_ptr), + m_size(size), + m_count(count) + { + + } + + void clear() + { + m_count = 0; + m_size = 0; + + if (m_data) + { + tlsContext::get()->m_allocator->Free(m_data); + + m_data = nullptr; + } + } + + bool append(atArray value_array) + { + auto value_array_size = value_array.size(); + auto old_capacity = m_count; + + if ((value_array_size + m_count) > (std::numeric_limits::max)()) + return false; + + auto size = (uint16_t)value_array_size; + expand(m_count + size); + m_size += size; + + auto i = old_capacity; + for (auto iter_value : value_array) + { + m_data[i] = iter_value; + i++; + } + return true; + } + + bool append(std::vector value_array) + { + auto value_array_size = value_array.size(); + auto old_capacity = m_count; + + if ((value_array_size + m_count) > (std::numeric_limits::max)()) + return false; + + auto size = (uint16_t)value_array_size; + expand(m_count + size); + m_size += size; + + auto i = old_capacity; + for (auto iter_value : value_array) + { + m_data[i] = iter_value; + i++; + } + return true; + } + + bool append(const std::initializer_list value_array) + { + auto value_array_size = value_array.size(); + auto old_capacity = m_count; + + if ((value_array_size + m_count) > (std::numeric_limits::max)()) + return false; + + auto size = (uint16_t)value_array_size; + expand(m_count + size); + m_size += size; + + auto i = old_capacity; + for (const T* it = value_array.begin(); it != value_array.end(); ++it) + { + m_data[i] = *it; + i++; + } + return true; + } + + void set(uint16_t offset, const T& value) + { + if (offset >= m_count) + { + expand(offset + 1); + } + + if (offset >= m_size) + { + m_size = offset + 1; + } + + m_data[offset] = value; + } + + void expand(uint16_t newSize) + { + if (m_count >= newSize) + { + return; + } + + T* newOffset = (T*)tlsContext::get()->m_allocator->Allocate(newSize * sizeof(T), 16, 0); + + + // initialize the new entries + std::uninitialized_fill(newOffset, newOffset + newSize, T()); + + // copy the existing entries + if (m_data) + { + std::copy(m_data, m_data + m_size, newOffset); + tlsContext::get()->m_allocator->Free(m_data); + } + + m_data = newOffset; + m_count = newSize; + } + + void append(T value) + { + set(m_count, value); + } +#endif + + T* begin() const + { + return &m_data[0]; + } + + T* end() const + { + return &m_data[m_size]; + } + + T* data() const + { + return m_data; + } + + std::uint16_t size() const + { + return m_size; + } + + std::uint16_t count() const + { + return m_count; + } + + T& operator[](std::uint16_t index) const + { + return m_data[index]; + } + + bool contains(T comparator) + { + for (auto iter_value : *this) + { + if (iter_value == comparator) + { + return true; + } + } + return false; + } + + friend std::ostream& operator<<(std::ostream& o, const atArray& j) + { + o << "Array Size: " << j.size() << std::endl; + for (int i = 0; i < j.size(); i++) + { + T item = j[i]; + if (std::is_pointer()) + o << "\tArray Pointer: " << std::hex << std::uppercase << item << std::nouppercase << std::dec << " Item: [" << std::hex << std::uppercase << (*(T*)item) << std::nouppercase << std::dec << "]"; + else + o << "\tArray Item: " << item; + if (i != j.size() - 1) + o << std::endl; + } + return o; + } + + private: + T* m_data; + std::uint16_t m_size; + std::uint16_t m_count; + }; + static_assert(sizeof(rage::atArray) == 0x10, "rage::atArray is not properly sized"); +#pragma pack(pop) +} diff --git a/classes/src/rage/atReferenceCounter.hpp b/classes/src/rage/atReferenceCounter.hpp new file mode 100644 index 0000000000..e9bb2facc2 --- /dev/null +++ b/classes/src/rage/atReferenceCounter.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "../base/datBase.hpp" + +namespace rage +{ + class atReferenceCounter : public datBase + { + public: + atReferenceCounter() : m_ref_count(0) {} + + void AddReference() { + m_ref_count++; + } + + void ReleaseReference() { + m_ref_count--; + if(m_ref_count == 0) { + delete this; + } + } + + int GetReferenceCount() const { + return m_ref_count; + } + + private: + int m_ref_count; // 0x0000 + }; +} \ No newline at end of file diff --git a/classes/src/rage/atSingleton.hpp b/classes/src/rage/atSingleton.hpp new file mode 100644 index 0000000000..bd3f8d02b0 --- /dev/null +++ b/classes/src/rage/atSingleton.hpp @@ -0,0 +1,22 @@ +#pragma once + +namespace rage +{ + template + struct atSingleton + { + private: + T* m_basePtr{}; + + public: + bool isValid() const + { + return m_basePtr != nullptr; + } + + T* getInstance() + { + return m_basePtr; + } + }; +} diff --git a/classes/src/rage/gameSkeleton.hpp b/classes/src/rage/gameSkeleton.hpp new file mode 100644 index 0000000000..7e72884776 --- /dev/null +++ b/classes/src/rage/gameSkeleton.hpp @@ -0,0 +1,85 @@ +#pragma once + +#include +#include "atArray.hpp" + +namespace rage +{ + +#pragma pack(push, 8) + +struct skeleton_data +{ + uint64_t m_init_func; //0x0 + uint64_t m_shutdown_func; //0x8 + uint32_t m_unk1; // 0x10 + uint32_t m_unk2; // 0x14 + uint32_t m_unk3; // 0x18 + uint32_t m_unk4; // 0x1C + uint32_t m_hash; // 0x20 +}; +static_assert(sizeof(skeleton_data) == 0x28); + +struct game_skeleton_update_base +{ + virtual ~game_skeleton_update_base() = default; + virtual void run() = 0; + uint64_t m_pad; // 0x08 + uint32_t m_hash; // 0x10 + game_skeleton_update_base* m_next; // 0x18 +}; +static_assert(sizeof(game_skeleton_update_base) == 0x20); + +struct game_skeleton_update_group : game_skeleton_update_base +{ + game_skeleton_update_base* m_head; // 0x20 +}; +static_assert(sizeof(game_skeleton_update_group) == 0x28); + +struct game_skeleton_update_element : game_skeleton_update_base +{ + void(*m_function)(); // 0x20 +}; +static_assert(sizeof(game_skeleton_update_element) == 0x28); + +struct game_skeleton_update_mode +{ + int m_type; // 0x00 + game_skeleton_update_base* m_head; // 0x08 + game_skeleton_update_mode* m_next; // 0x10 +}; +static_assert(sizeof(game_skeleton_update_mode) == 0x18); + +struct game_skeleton_init_dependency +{ + int m_level; // 0x00 + atArray m_data; // 0x08 + game_skeleton_init_dependency* m_next; // 0x10 +}; + +struct game_skeleton_mode +{ + int m_type; // 0x00 + game_skeleton_init_dependency* m_head; // 0x08 + game_skeleton_mode* m_next; // 0x10 +}; +static_assert(sizeof(game_skeleton_mode) == 0x18); + +struct game_skeleton +{ + virtual ~game_skeleton() = 0; + uint32_t m_unk1; //0x08 + uint32_t m_unk2; //0x0C + uint32_t m_unk3; // 0x10 + uint32_t m_unk4; // 0x14 + atArray m_sys_data; // 0x18 + uint32_t m_unk5; // 0x28 + void* m_unk6[32]; // 0x30 + game_skeleton_mode* m_init_modes; // 0x130 + game_skeleton_mode* m_shutdown_modes; // 0x138 + game_skeleton_update_mode* m_update_modes; // 0x140 +}; +static_assert(sizeof(game_skeleton) == 0x148); + +#pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/rage/joaat.hpp b/classes/src/rage/joaat.hpp new file mode 100644 index 0000000000..482311473b --- /dev/null +++ b/classes/src/rage/joaat.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +namespace rage +{ + using joaat_t = std::uint32_t; + inline constexpr char joaat_to_lower(char c) + { + return c >= 'A' && c <= 'Z' ? c | 1 << 5 : c; + } + + inline constexpr joaat_t joaat(const std::string_view str) + { + joaat_t hash = 0; + for (auto c : str) + { + hash += joaat_to_lower(c); + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return hash; + } +}; diff --git a/classes/src/rage/rlGamerHandle.hpp b/classes/src/rage/rlGamerHandle.hpp new file mode 100644 index 0000000000..3feebdd9ae --- /dev/null +++ b/classes/src/rage/rlGamerHandle.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace rage +{ +#pragma pack(push,8) + class rlGamerHandle + { + public: + uint64_t m_rockstar_id; //0x0000 + uint8_t m_platform; //0x0008 + uint8_t unk_0009; //0x0009 + + inline rlGamerHandle() = default; + + inline rlGamerHandle(uint64_t rockstar_id) : + m_rockstar_id(rockstar_id), + m_platform(3), + unk_0009(0) + { + } + }; //Size: 0x0010 + static_assert(sizeof(rlGamerHandle) == 0x10); +#pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/rage/rlGamerInfo.hpp b/classes/src/rage/rlGamerInfo.hpp new file mode 100644 index 0000000000..a061a496db --- /dev/null +++ b/classes/src/rage/rlGamerInfo.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include "rlGamerInfoBase.hpp" + +namespace rage +{ +#pragma pack(push,8) + class rlGamerInfo : public rlGamerInfoBase + { + public: + uint64_t m_host_token; + + union + { + rlGamerHandle m_gamer_handle_2; + uint32_t m_peer_id_2; // not found in all instances + }; + + uint32_t m_ros_privilege; + char m_name[17]; + }; //Size: 0x0098 + static_assert(sizeof(rlGamerInfo) == 0xF0); +#pragma pack(pop) +} diff --git a/classes/src/rage/rlGamerInfoBase.hpp b/classes/src/rage/rlGamerInfoBase.hpp new file mode 100644 index 0000000000..d63a356629 --- /dev/null +++ b/classes/src/rage/rlGamerInfoBase.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include "rlGamerHandle.hpp" +#include "network/netPeerAddress.hpp" + +namespace rage +{ +#pragma pack(push,8) + class rlGamerInfoBase + { + public: + int m_security_enabled; //0x0000 + uint64_t m_peer_id; //0x0008 + rlGamerHandle m_gamer_handle; //0x0010 + char m_aes_key[0x28]; //0x0020 + netPeerAddress m_relay_address; //0x0048 + char m_relay_signature[0x40]; //0x0068 + netAddress m_external_ip; //0x00A8 + uint16_t m_external_port; //0x00AC + netAddress m_internal_ip; //0x00B0 + uint16_t m_internal_port; //0x00B4 + uint32_t m_nat_type; //0x00B8 + bool m_force_relays; //0x00BC + }; + static_assert(sizeof(rlGamerInfoBase) == 0xC0); +#pragma pack(pop) +} diff --git a/classes/src/rage/rlMetric.hpp b/classes/src/rage/rlMetric.hpp new file mode 100644 index 0000000000..79dea88f18 --- /dev/null +++ b/classes/src/rage/rlMetric.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "joaat.hpp" + +namespace rage +{ + class rlMetric + { + public: + virtual ~rlMetric() = default; + + virtual int _0x08() { return 0; }; // returns a constant integer + + virtual int _0x10() { return 0; }; // returns a constant integer + + virtual int _0x18() { return 0; }; + + virtual const char* get_name() { return ""; }; + + virtual bool serialize(void* serializer) { return false; }; + + virtual int get_size() { return 0; }; + + virtual joaat_t get_name_hash() { return 0; }; + }; +}; \ No newline at end of file diff --git a/classes/src/rage/rlQueryPresenceAttributesContext.hpp b/classes/src/rage/rlQueryPresenceAttributesContext.hpp new file mode 100644 index 0000000000..5f94abebb1 --- /dev/null +++ b/classes/src/rage/rlQueryPresenceAttributesContext.hpp @@ -0,0 +1,19 @@ +#pragma once +#include + +namespace rage +{ + class rlQueryPresenceAttributesContext + { + public: + char m_presence_attribute_key[64]; //0x0000 + union + { + char m_presence_attribute_string_value[256]; //0x0040 + uint64_t m_presence_attribute_int_value; + }; + uint32_t m_presence_attibute_type; //0x0140 + char pad_0144[4]; //0x0144 + }; //Size: 0x0148 + static_assert(sizeof(rage::rlQueryPresenceAttributesContext) == 0x148); +} diff --git a/classes/src/rage/rlScHandle.hpp b/classes/src/rage/rlScHandle.hpp new file mode 100644 index 0000000000..054b1ad398 --- /dev/null +++ b/classes/src/rage/rlScHandle.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include + +namespace rage +{ +#pragma pack(push, 8) + class rlScHandle + { + public: + uint64_t m_rockstar_id; //0x0000 + int16_t unk_0008; + uint8_t m_platform; //0x000A + char pad[5]{}; //0x000B + + inline rlScHandle() = default; + + inline rlScHandle(uint64_t rockstar_id) : + m_rockstar_id(rockstar_id), + m_platform(3), + unk_0008(0) + { + } + }; //Size: 0x0010 + static_assert(sizeof(rlScHandle) == 0x10); +#pragma pack(pop) +} diff --git a/classes/src/rage/rlSessionByGamerTaskResult.hpp b/classes/src/rage/rlSessionByGamerTaskResult.hpp new file mode 100644 index 0000000000..0868e5ad82 --- /dev/null +++ b/classes/src/rage/rlSessionByGamerTaskResult.hpp @@ -0,0 +1,13 @@ +#pragma once +#include "rlGamerHandle.hpp" +#include "rlSessionInfo.hpp" + +namespace rage +{ + class rlSessionByGamerTaskResult + { + public: + rlGamerHandle m_gamer_handle{ 0 }; + rlSessionInfo m_session_info; + }; +} diff --git a/classes/src/rage/rlSessionInfo.hpp b/classes/src/rage/rlSessionInfo.hpp new file mode 100644 index 0000000000..0e81a06a69 --- /dev/null +++ b/classes/src/rage/rlSessionInfo.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include +#include "../rage/rlGamerInfoBase.hpp" + +namespace rage +{ + class rlSessionInfo + { + public: + uint64_t m_unk; //0x0000 + uint64_t m_session_token; //0x0008 + rlGamerInfoBase m_net_player_data; //0x0010 + }; + static_assert(sizeof(rlSessionInfo) == 0xD0); +} \ No newline at end of file diff --git a/classes/src/rage/rlTaskStatus.hpp b/classes/src/rage/rlTaskStatus.hpp new file mode 100644 index 0000000000..706b37617c --- /dev/null +++ b/classes/src/rage/rlTaskStatus.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace rage +{ + struct rlTaskStatus + { + int status = 0; + int unk = 0; + }; +} \ No newline at end of file diff --git a/classes/src/rage/scrValue.hpp b/classes/src/rage/scrValue.hpp new file mode 100644 index 0000000000..291f6668f6 --- /dev/null +++ b/classes/src/rage/scrValue.hpp @@ -0,0 +1,19 @@ +#pragma once +#include +using LPCSTR = const char*; //For Linux support, but I didn't want to make the class inaccurate + +namespace rage +{ + union scrValue + { + int Int; + unsigned int Uns; + float Float; + LPCSTR String; + scrValue* Reference; + uint64_t Any; + bool operator==(const scrValue& val) { + return Int == val.Int; + } + }; +} diff --git a/classes/src/rage/sysMemAllocator.hpp b/classes/src/rage/sysMemAllocator.hpp new file mode 100644 index 0000000000..54e8ea7f29 --- /dev/null +++ b/classes/src/rage/sysMemAllocator.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#include "base/atRTTI.hpp" + +namespace rage +{ + class sysMemAllocator + { + public: + DEFINE_RAGE_RTTI(rage::sysMemAllocator); + virtual void SetQuitOnFail(bool) = 0; + virtual void* Allocate(std::size_t size, std::size_t align, int subAllocator) = 0; + virtual void* TryAllocate(std::size_t size, std::size_t align, int subAllocator) = 0; + virtual void Free(void* pointer) = 0; + virtual void TryFree(void* pointer) = 0; + virtual void Resize(void* pointer, std::size_t size) = 0; + virtual sysMemAllocator* GetAllocator(int allocator) const = 0; + virtual sysMemAllocator* GetAllocator(int allocator) = 0; + virtual sysMemAllocator* GetPointerOwner(void* pointer) = 0; + virtual std::size_t GetSize(void* pointer) const = 0; + virtual std::size_t GetMemoryUsed(int memoryBucket) = 0; + virtual std::size_t GetMemoryAvailable() = 0; + + }; +} \ No newline at end of file diff --git a/classes/src/rage/vector.hpp b/classes/src/rage/vector.hpp new file mode 100644 index 0000000000..c83f9e5947 --- /dev/null +++ b/classes/src/rage/vector.hpp @@ -0,0 +1,87 @@ +#pragma once + +namespace rage +{ + template + union vector2 + { + T data[2]; + struct { T x, y; }; + + vector2(T x, T y) : + x(x), + y(y) + { + } + + vector2() : + x(), + y() + { + } + }; + + template + union vector3 + { + T data[3]; + struct { T x, y, z; }; + + vector3(T x, T y, T z) : + x(x), + y(y), + z(z) + { + } + + vector3() : + x(), + y(), + z() + { + } + }; + + template + union vector4 + { + T data[4]; + struct { T x, y, z, w; }; + + vector4(T x, T y, T z, T w) : + x(x), + y(y), + z(z), + w(w) + { + } + + vector4() : + x(), + y(), + z(), + w() + { + } + }; + + template + union matrix34 + { + T data[3][4]; + struct { struct { T x, y, z, w; } rows[3]; }; + }; + + template + union matrix44 + { + T data[4][4]; + struct { struct { T x, y, z, w; } rows[4]; }; + }; + + typedef vector2 fvector2; + typedef vector3 fvector3; + typedef vector4 fvector4; + typedef matrix34 fmatrix34; + typedef matrix44 fmatrix44; +} diff --git a/classes/src/script/CGameScriptObjInfo.hpp b/classes/src/script/CGameScriptObjInfo.hpp new file mode 100644 index 0000000000..b2b50743a7 --- /dev/null +++ b/classes/src/script/CGameScriptObjInfo.hpp @@ -0,0 +1,16 @@ +#pragma once +#include "scriptId.hpp" +#include "types.hpp" + +#pragma pack(push, 4) +class CGameScriptObjInfo +{ +public: + virtual ~CGameScriptObjInfo() = default; + + ScrHandle m_local_handle; // 0x8 + uint16_t m_network_handle; // 0xC + CGameScriptId m_script_id; // 0x10 +}; +static_assert(sizeof(CGameScriptObjInfo) == 0x50); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/script/GtaThread.hpp b/classes/src/script/GtaThread.hpp new file mode 100644 index 0000000000..da2a9e6d4e --- /dev/null +++ b/classes/src/script/GtaThread.hpp @@ -0,0 +1,26 @@ +#pragma once +#include "scrThread.hpp" + +class GtaThread : public rage::scrThread +{ +public: + rage::joaat_t m_script_hash; // 0x128 + int m_force_cleanup_ip; // 0x12C + int m_force_cleanup_fp; // 0x130 + int m_force_cleanup_sp; // 0x134 + int m_force_cleanup_filter; // 0x138 + int m_force_cleanup_cause; // 0x13C + std::int32_t m_instance_id; // 0x140 + char m_padding4[0x04]; // 0x144 + std::uint8_t m_flag1; // 0x148 + bool m_safe_for_network_game; // 0x149 + char m_padding5[0x02]; // 0x14A + bool m_is_minigame_script; // 0x14C + char m_padding6[0x02]; // 0x14D + bool m_can_be_paused; // 0x14F + bool m_can_remove_blips_from_other_scripts; // 0x150 + char m_padding7[0x2]; // 0x151 + std::uint8_t m_force_cleanup_state; // 0x153 + char m_padding8[0xC]; // 0x154 +}; +static_assert(sizeof(GtaThread) == 0x160); \ No newline at end of file diff --git a/classes/src/script/HudColor.hpp b/classes/src/script/HudColor.hpp new file mode 100644 index 0000000000..b0852ca0cf --- /dev/null +++ b/classes/src/script/HudColor.hpp @@ -0,0 +1,222 @@ +#pragma once +#include "types.hpp" + +enum class HudColor : std::uint32_t +{ + HUD_COLOUR_PURE_WHITE, + HUD_COLOUR_WHITE, + HUD_COLOUR_BLACK, + HUD_COLOUR_GREY, + HUD_COLOUR_GREYLIGHT, + HUD_COLOUR_GREYDARK, + HUD_COLOUR_RED, + HUD_COLOUR_REDLIGHT, + HUD_COLOUR_REDDARK, + HUD_COLOUR_BLUE, + HUD_COLOUR_BLUELIGHT, + HUD_COLOUR_BLUEDARK, + HUD_COLOUR_YELLOW, + HUD_COLOUR_YELLOWLIGHT, + HUD_COLOUR_YELLOWDARK, + HUD_COLOUR_ORANGE, + HUD_COLOUR_ORANGELIGHT, + HUD_COLOUR_ORANGEDARK, + HUD_COLOUR_GREEN, + HUD_COLOUR_GREENLIGHT, + HUD_COLOUR_GREENDARK, + HUD_COLOUR_PURPLE, + HUD_COLOUR_PURPLELIGHT, + HUD_COLOUR_PURPLEDARK, + HUD_COLOUR_PINK, + HUD_COLOUR_RADAR_HEALTH, + HUD_COLOUR_RADAR_ARMOUR, + HUD_COLOUR_RADAR_DAMAGE, + HUD_COLOUR_NET_PLAYER1, + HUD_COLOUR_NET_PLAYER2, + HUD_COLOUR_NET_PLAYER3, + HUD_COLOUR_NET_PLAYER4, + HUD_COLOUR_NET_PLAYER5, + HUD_COLOUR_NET_PLAYER6, + HUD_COLOUR_NET_PLAYER7, + HUD_COLOUR_NET_PLAYER8, + HUD_COLOUR_NET_PLAYER9, + HUD_COLOUR_NET_PLAYER10, + HUD_COLOUR_NET_PLAYER11, + HUD_COLOUR_NET_PLAYER12, + HUD_COLOUR_NET_PLAYER13, + HUD_COLOUR_NET_PLAYER14, + HUD_COLOUR_NET_PLAYER15, + HUD_COLOUR_NET_PLAYER16, + HUD_COLOUR_NET_PLAYER17, + HUD_COLOUR_NET_PLAYER18, + HUD_COLOUR_NET_PLAYER19, + HUD_COLOUR_NET_PLAYER20, + HUD_COLOUR_NET_PLAYER21, + HUD_COLOUR_NET_PLAYER22, + HUD_COLOUR_NET_PLAYER23, + HUD_COLOUR_NET_PLAYER24, + HUD_COLOUR_NET_PLAYER25, + HUD_COLOUR_NET_PLAYER26, + HUD_COLOUR_NET_PLAYER27, + HUD_COLOUR_NET_PLAYER28, + HUD_COLOUR_NET_PLAYER29, + HUD_COLOUR_NET_PLAYER30, + HUD_COLOUR_NET_PLAYER31, + HUD_COLOUR_NET_PLAYER32, + HUD_COLOUR_SIMPLEBLIP_DEFAULT, + HUD_COLOUR_MENU_BLUE, + HUD_COLOUR_MENU_GREY_LIGHT, + HUD_COLOUR_MENU_BLUE_EXTRA_DARK, + HUD_COLOUR_MENU_YELLOW, + HUD_COLOUR_MENU_YELLOW_DARK, + HUD_COLOUR_MENU_GREEN, + HUD_COLOUR_MENU_GREY, + HUD_COLOUR_MENU_GREY_DARK, + HUD_COLOUR_MENU_HIGHLIGHT, + HUD_COLOUR_MENU_STANDARD, + HUD_COLOUR_MENU_DIMMED, + HUD_COLOUR_MENU_EXTRA_DIMMED, + HUD_COLOUR_BRIEF_TITLE, + HUD_COLOUR_MID_GREY_MP, + HUD_COLOUR_NET_PLAYER1_DARK, + HUD_COLOUR_NET_PLAYER2_DARK, + HUD_COLOUR_NET_PLAYER3_DARK, + HUD_COLOUR_NET_PLAYER4_DARK, + HUD_COLOUR_NET_PLAYER5_DARK, + HUD_COLOUR_NET_PLAYER6_DARK, + HUD_COLOUR_NET_PLAYER7_DARK, + HUD_COLOUR_NET_PLAYER8_DARK, + HUD_COLOUR_NET_PLAYER9_DARK, + HUD_COLOUR_NET_PLAYER10_DARK, + HUD_COLOUR_NET_PLAYER11_DARK, + HUD_COLOUR_NET_PLAYER12_DARK, + HUD_COLOUR_NET_PLAYER13_DARK, + HUD_COLOUR_NET_PLAYER14_DARK, + HUD_COLOUR_NET_PLAYER15_DARK, + HUD_COLOUR_NET_PLAYER16_DARK, + HUD_COLOUR_NET_PLAYER17_DARK, + HUD_COLOUR_NET_PLAYER18_DARK, + HUD_COLOUR_NET_PLAYER19_DARK, + HUD_COLOUR_NET_PLAYER20_DARK, + HUD_COLOUR_NET_PLAYER21_DARK, + HUD_COLOUR_NET_PLAYER22_DARK, + HUD_COLOUR_NET_PLAYER23_DARK, + HUD_COLOUR_NET_PLAYER24_DARK, + HUD_COLOUR_NET_PLAYER25_DARK, + HUD_COLOUR_NET_PLAYER26_DARK, + HUD_COLOUR_NET_PLAYER27_DARK, + HUD_COLOUR_NET_PLAYER28_DARK, + HUD_COLOUR_NET_PLAYER29_DARK, + HUD_COLOUR_NET_PLAYER30_DARK, + HUD_COLOUR_NET_PLAYER31_DARK, + HUD_COLOUR_NET_PLAYER32_DARK, + HUD_COLOUR_BRONZE, + HUD_COLOUR_SILVER, + HUD_COLOUR_GOLD, + HUD_COLOUR_PLATINUM, + HUD_COLOUR_GANG1, + HUD_COLOUR_GANG2, + HUD_COLOUR_GANG3, + HUD_COLOUR_GANG4, + HUD_COLOUR_SAME_CREW, + HUD_COLOUR_FREEMODE, + HUD_COLOUR_PAUSE_BG, + HUD_COLOUR_FRIENDLY, + HUD_COLOUR_ENEMY, + HUD_COLOUR_LOCATION, + HUD_COLOUR_PICKUP, + HUD_COLOUR_PAUSE_SINGLEPLAYER, + HUD_COLOUR_FREEMODE_DARK, + HUD_COLOUR_INACTIVE_MISSION, + HUD_COLOUR_DAMAGE, + HUD_COLOUR_PINKLIGHT, + HUD_COLOUR_PM_MITEM_HIGHLIGHT, + HUD_COLOUR_SCRIPT_VARIABLE, + HUD_COLOUR_YOGA, + HUD_COLOUR_TENNIS, + HUD_COLOUR_GOLF, + HUD_COLOUR_SHOOTING_RANGE, + HUD_COLOUR_FLIGHT_SCHOOL, + HUD_COLOUR_NORTH_BLUE, + HUD_COLOUR_SOCIAL_CLUB, + HUD_COLOUR_PLATFORM_BLUE, + HUD_COLOUR_PLATFORM_GREEN, + HUD_COLOUR_PLATFORM_GREY, + HUD_COLOUR_FACEBOOK_BLUE, + HUD_COLOUR_INGAME_BG, + HUD_COLOUR_DARTS, + HUD_COLOUR_WAYPOINT, + HUD_COLOUR_MICHAEL, + HUD_COLOUR_FRANKLIN, + HUD_COLOUR_TREVOR, + HUD_COLOUR_GOLF_P1, + HUD_COLOUR_GOLF_P2, + HUD_COLOUR_GOLF_P3, + HUD_COLOUR_GOLF_P4, + HUD_COLOUR_WAYPOINTLIGHT, + HUD_COLOUR_WAYPOINTDARK, + HUD_COLOUR_PANEL_LIGHT, + HUD_COLOUR_MICHAEL_DARK, + HUD_COLOUR_FRANKLIN_DARK, + HUD_COLOUR_TREVOR_DARK, + HUD_COLOUR_OBJECTIVE_ROUTE, + HUD_COLOUR_PAUSEMAP_TINT, + HUD_COLOUR_PAUSE_DESELECT, + HUD_COLOUR_PM_WEAPONS_PURCHASABLE, + HUD_COLOUR_PM_WEAPONS_LOCKED, + HUD_COLOUR_END_SCREEN_BG, + HUD_COLOUR_CHOP, + HUD_COLOUR_PAUSEMAP_TINT_HALF, + HUD_COLOUR_NORTH_BLUE_OFFICIAL, + HUD_COLOUR_SCRIPT_VARIABLE_2, + HUD_COLOUR_H, + HUD_COLOUR_HDARK, + HUD_COLOUR_T, + HUD_COLOUR_TDARK, + HUD_COLOUR_HSHARD, + HUD_COLOUR_CONTROLLER_MICHAEL, + HUD_COLOUR_CONTROLLER_FRANKLIN, + HUD_COLOUR_CONTROLLER_TREVOR, + HUD_COLOUR_CONTROLLER_CHOP, + HUD_COLOUR_VIDEO_EDITOR_VIDEO, + HUD_COLOUR_VIDEO_EDITOR_AUDIO, + HUD_COLOUR_VIDEO_EDITOR_TEXT, + HUD_COLOUR_HB_BLUE, + HUD_COLOUR_HB_YELLOW, + HUD_COLOUR_VIDEO_EDITOR_SCORE, + HUD_COLOUR_VIDEO_EDITOR_AUDIO_FADEOUT, + HUD_COLOUR_VIDEO_EDITOR_TEXT_FADEOUT, + HUD_COLOUR_VIDEO_EDITOR_SCORE_FADEOUT, + HUD_COLOUR_HEIST_BACKGROUND, + HUD_COLOUR_VIDEO_EDITOR_AMBIENT, + HUD_COLOUR_VIDEO_EDITOR_AMBIENT_FADEOUT, + HUD_COLOUR_GB, + HUD_COLOUR_G, + HUD_COLOUR_B, + HUD_COLOUR_LOW_FLOW, + HUD_COLOUR_LOW_FLOW_DARK, + HUD_COLOUR_G1, + HUD_COLOUR_G2, + HUD_COLOUR_G3, + HUD_COLOUR_G4, + HUD_COLOUR_G5, + HUD_COLOUR_G6, + HUD_COLOUR_G7, + HUD_COLOUR_G8, + HUD_COLOUR_G9, + HUD_COLOUR_G10, + HUD_COLOUR_G11, + HUD_COLOUR_G12, + HUD_COLOUR_G13, + HUD_COLOUR_G14, + HUD_COLOUR_G15, + HUD_COLOUR_ADVERSARY, + HUD_COLOUR_DEGEN_RED, + HUD_COLOUR_DEGEN_YELLOW, + HUD_COLOUR_DEGEN_GREEN, + HUD_COLOUR_DEGEN_CYAN, + HUD_COLOUR_DEGEN_BLUE, + HUD_COLOUR_DEGEN_MAGENTA, + HUD_COLOUR_STUNT_1, + HUD_COLOUR_STUNT_2 +}; \ No newline at end of file diff --git a/classes/src/script/MPScriptData.hpp b/classes/src/script/MPScriptData.hpp new file mode 100644 index 0000000000..c9d22fb66e --- /dev/null +++ b/classes/src/script/MPScriptData.hpp @@ -0,0 +1,11 @@ +#pragma once +#include "types.hpp" + +struct MP_SCRIPT_DATA +{ + SCR_INT Index; // this is an enum + uint64_t Args[15]; + SCR_INT InstanceId; + uint64_t MoreArgs[4]; +}; +static_assert(sizeof(MP_SCRIPT_DATA) == 21 * 8); \ No newline at end of file diff --git a/classes/src/script/Timer.hpp b/classes/src/script/Timer.hpp new file mode 100644 index 0000000000..0f21f11ad4 --- /dev/null +++ b/classes/src/script/Timer.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "types.hpp" + +// this is named stopwatch in the decompiler but "timer" is probably a better name for it +struct TIMER +{ + SCR_INT Time; + SCR_BOOL IsInitialized; +}; +static_assert(sizeof(TIMER) == 2 * 8); \ No newline at end of file diff --git a/classes/src/script/dataList.hpp b/classes/src/script/dataList.hpp new file mode 100644 index 0000000000..bf6682cb75 --- /dev/null +++ b/classes/src/script/dataList.hpp @@ -0,0 +1,22 @@ +#pragma once +#include "../base/datBase.hpp" + +namespace rage +{ + template + class atDNode : public Base + { + public: + T m_data; + void *m_unk; + atDNode *m_next; + }; + + template + class atDList + { + public: + Node *m_head; + Node *m_tail; + }; +} \ No newline at end of file diff --git a/classes/src/script/globals/GPBD_FM.hpp b/classes/src/script/globals/GPBD_FM.hpp new file mode 100644 index 0000000000..2f06877056 --- /dev/null +++ b/classes/src/script/globals/GPBD_FM.hpp @@ -0,0 +1,659 @@ +#pragma once +#include "../types.hpp" +#include "../Timer.hpp" +#include "../MPScriptData.hpp" + +enum class eMissionDataFlags +{ + kMissionLaunched = 0, + kJobDownloaded = 2, + kStartingJob = 3, + kRequestingScript = 4, + kLaunchedScript = 6, // should be set if kMissionLaunched is set + kAutoStartOnProximity = 7, // used by gang attack + kNJVSQuickMatch = 8, + kVoteLiked = 10, + kVoteDisliked = 11, + kNoVote = 25 +}; // TODO + +enum class eTutorialBitset +{ + kInTutorialRace = 0, + kTutorialRaceActive = 2, + kShowCredits = 4, + kNeedFreeVehicle = 6 +}; + +enum class eGangCallServices +{ + kMugger = 0, + kMercenary = 1 +}; + +enum class eVehicleSelectionState +{ + NONE, + SELECTING, + SELECTED +}; + +enum class eStatState +{ + NONE, + LETHARGIC, + OUT_OF_SHAPE, + HEALTHY, + ATHLETE, + TRI_ATHLETE, + UNTRAINED, + SPRAY_AND_PRAY, + POLICE_TRAINING, + MILITARY_TRAINING, + DEAD_EYE, + FRAGILE, + WEAK, + AVERAGE, + TOUGH, + BODYBUILDER, + CLUMSY, + LOUD, + SNEAKY, + HUNTER, + NINJA, + DANGEROUS, + RC_PILOT, + COMMERCIAL_PILOT, + FIGHTER_PILOT, + ACE, + UNLICENSED, + SUNDAY_DRIVER, + COMMUTER, + STREET_RACER, + PRO_RACER, + NORMAL, + UNSTABLE, + DERANGED, + MANIAC, + PSYCHOPATH, + DRUNK +}; + +enum class ePropertyInteriorFlags +{ + kOwnerOfInterior = 0, + kVisitorOfInterior = 1, // mutually exclusive with above flag + kConcealWhenDead = 12, + kRenovatingProperty = 19, + kPreviewingDecor = 20, + kRenovatingClubhouse = 21, + kUsingYachtRmBath1 = 22, + kUsingYachtRmBath3 = 23, + kUsingYachtRmWeeBathroom = 25, + kGunLockerOpen = 27, + kOfficeSafeOpen = 28, + kOfficeAssistantMale = 29 +}; + +enum class eInteriorStyleFlags +{ + kGunLockerShowPumpShotgun = 0, + kGunLockerShowMicroSMG = 1, + kGunLockerShowC4 = 2, // proximity or sticky + kGunLockerShowGrenade = 3, + kGunLockerShowCombatMG = 4, + kGunLockerShowMarksmanRifle = 5, + kPurchasedSnacks = 6, + kPurchasedInteriorRenovations = 7, + kForceOfficeAssistantSpawn = 8, + kAssistantAnimationOver = 9, + kChangeInteriorDecorOfficeHelpShown = 11, + kChangeInteriorDecorApartmentHelpShown = 12, + kOwnsOfficeBedroom = 13, + kOwnsClubhouseBikeShop = 16, + kOwnsOfficeGunLocker = 17, + KOwnsClubhouseWalls = 18, // ??? + kOwnsClubhouseFurnishings = 19, + kOwnsClubhouseDecors = 20 +}; + +enum class eBusinessHubProductIndex +{ + CARGO, + WEAPONS, + COCAINE, + METH, + WEED, + FORGED_DOCUMENTS, + COUNTERFEIT_CASH +}; + +struct PLAYLIST_DATA +{ + PLAYER_INDEX Host; + SCR_INT Flags; + SCR_BOOL PAD_0002; + SCR_INT CurrentMission; + SCR_INT TotalMissions; + PLAYER_INDEX PAD_0006; +}; +static_assert(sizeof(PLAYLIST_DATA) == 6 * 8); + +// local copy can be found at Global_2680247 +struct JOB_SETTINGS +{ + SCR_ARRAY Settings; // indices vary based on job type. take a look at func_8988 in fmmc_launcher if you wish to change them + SCR_INT NumPlayers; // verify + SCR_INT PAD_0033; + SCR_INT SpawnSimpleInteriorIndex; + SCR_INT PAD_0035; // unused + SCR_BOOL MatchmakingOpen; + SCR_INT ContentHash; +}; +static_assert(sizeof(JOB_SETTINGS) == 38 * 8); + +struct VEHICLE_SELECTION +{ + SCR_BOOL Active; + SCR_BOOL Active2; + PLAYER_INDEX PAD_0002; // set to host by fmmc but not read at all + SCR_HASH VehicleModel; + SCR_INT CreatorIndex; + alignas(8) eVehicleSelectionState State; + SCR_INT PrimaryColor; + Color3 CustomPrimaryColor; + Color3 CustomSecondaryColor; + PLAYER_INDEX Partner; // for rally races? + GAMER_HANDLE PartnerHandle; + SCR_INT PreferredRole; // target assault races + SCR_INT PAD_0028; // TODO + SCR_INT ControlType; // 1 = kb&m 2 = controller + SCR_INT BettingFlags; + SCR_INT Team; + SCR_INT Flags; + SCR_INT JoinedMembers; // bitset of joined transition members set by the host + SCR_INT AdversaryOutfitIndex; + alignas(8) eStatState StatState; // see func_9142 in fmmc_launcher, shown to other players + SCR_INT CashWager; // shown to other players... + uint64_t PAD_0037[2]; // TODO + SCR_INT PAD_0039; // TODO random integer between 1 and 11 +}; +static_assert(sizeof(VEHICLE_SELECTION) == 40 * 8); + +struct STRIKE_TEAM +{ + PLAYER_INDEX Target; + TIMER Cooldown; + SCR_BOOL CancelStrikeTeam; // read but not written to + SCR_INT Level; +}; +static_assert(sizeof(STRIKE_TEAM) == 5 * 8); + +struct PLAYER_STATS +{ + SCR_INT Team; + SCR_INT RP; + SCR_INT CrewRP; + SCR_INT WalletBalance; + SCR_INT HeistBonus; + SCR_INT GlobalRP; + SCR_INT Rank; + TEXT_LABEL_31 CrewTitle; + SCR_INT TotalRacesWon; + SCR_INT TotalRacesLost; + SCR_INT TimesFinishRaceAsTop3; + SCR_INT TimesFinishRaceLast; + SCR_INT TimesRaceBestLap; + SCR_INT TotalDeathmatchesWon; + SCR_INT TotalDeathmatchesLost; + SCR_INT TotalTeamDeathmatchesWon; + SCR_INT TotalTeamDeathmatchesLost; + SCR_INT Shots; + SCR_INT Hits; + SCR_FLOAT KdRatio; + SCR_FLOAT DropoutRate; + SCR_INT KillsOnPlayers; + SCR_INT DeathsByPlayers; + SCR_INT TotalFinishDeathmatchAsTop3; + SCR_INT TotalFinishDeathmatchLast; + SCR_INT DartsTotalWins; + SCR_INT DartsTotalMatches; + SCR_INT ArmwrestlingTotalWins; + SCR_INT ArmwrestlingTotalMatches; + SCR_INT TennisMatchesWon; + SCR_INT TennisMatchesLost; + SCR_INT BaseJumpWins; + SCR_INT BaseJumpLosses; + SCR_INT GolfWins; + SCR_INT GolfLosses; + SCR_INT ShootingRangeWins; + SCR_INT ShootingRangeLosses; + SCR_INT ShootingAbility; + SCR_INT MissionWins; + SCR_INT TotalMissionsPlayed; + SCR_INT SurvivalWins; + SCR_INT TotalSurvivalsPlayed; + SCR_INT PAD_0049; // TODO + SCR_INT MissionsCreated; + SCR_INT CommunicationRestrictions; + SCR_BOOL CanSpectate; + SCR_INT MostFavoriteStation; + SCR_INT ProstitutesFrequented; + SCR_INT LapDancesBought; + SCR_INT Money; + SCR_FLOAT WeaponAccuracy; + SCR_HASH FavoriteVehicle; + SCR_HASH FavoriteWeapon; +}; +static_assert(sizeof(PLAYER_STATS) == 60 * 8); + +struct EXEC_WAREHOUSE_INFO +{ + SCR_INT Index; + SCR_INT Stock; + SCR_INT PAD_0002; // unused +}; +static_assert(sizeof(EXEC_WAREHOUSE_INFO) == 3 * 8); + +struct IE_WAREHOUSE_DATA +{ + SCR_INT Index; + SCR_INT NumVehicles; + SCR_ARRAY Vehicles; + SCR_INT PAD_0043; // set to zero and not read + SCR_INT OwnedWarehouseVariation; +}; +static_assert(sizeof(IE_WAREHOUSE_DATA) == 45 * 8); + +struct FACTORY_INFO +{ + SCR_INT Index; + SCR_INT TotalProduct; + SCR_INT TotalSupplies; + SCR_INT TotalSupplies2; // TODO: what's the difference? + uint64_t PAD_0004; + SCR_INT EquipmentUpgrades; + SCR_BOOL Running; + SCR_BOOL SetupDone; + SCR_BOOL PAD_0008; + SCR_INT Research; // valid only for factory index 5 (bunker) + SCR_INT StaffState; + SCR_INT ProductValue; // untested + SCR_INT StaffAssignmentType; // valid only for factory index 5 (bunker) 0 = manufacturing, 1 = research, 2 = both +}; +static_assert(sizeof(FACTORY_INFO) == 13 * 8); + +struct HANGAR_DATA +{ + SCR_INT Index; + SCR_INT AppearanceBitset; + SCR_INT PAD_0002; // unused + SCR_INT TotalContraband; + SCR_INT PAD_0004; // unused, a function tries to set it to something but is never called with the right parameters. it isn't read either + SCR_BOOL SetupDone; +}; +static_assert(sizeof(HANGAR_DATA) == 6 * 8); + +// facility +struct DEFUNCT_BASE_DATA +{ + SCR_INT Index; + SCR_INT AppearanceBitset; + SCR_INT AppearanceBitset2; + SCR_INT ObtainedAwards; + SCR_INT PAD_0004; // unused, a function tries to set it to something but is never called with the right parameters. it isn't read either + SCR_INT PAD_0005; + SCR_INT TotalContraband; // wat +}; +static_assert(sizeof(DEFUNCT_BASE_DATA) == 7 * 8); + +// nightclub +struct BUSINESS_HUB_DATA +{ + SCR_INT Index; + SCR_INT TotalContraband; // not read by the scripts + SCR_INT ProducingBusinesses; // bitset + SCR_INT ProducingFactories; // bitset + SCR_INT Upgrades; + SCR_INT PAD_0005; + SCR_INT PAD_0006; // not read by the scripts + SCR_INT SetupBitset; // includes owned DJs + SCR_ARRAY ProductStocks; // see eBusinessHubProductIndex + SCR_ARRAY PAD_0017; // have no clue what this is + SCR_ARRAY TotalSoldProduct; +}; +static_assert(sizeof(BUSINESS_HUB_DATA) == 43 * 8); + +// also the nightclub? strange +struct NIGHTCLUB_DATA +{ + SCR_INT Index; // same as BusinessHubData::Index + SCR_INT AppearanceBitset; + SCR_INT AppearanceBitset2; + SCR_INT AccessSettings; // TODO: figure out how this works + SCR_FLOAT Popularity; // 0.0 to 1.0 + SCR_INT SafeCashValue; + SCR_INT EntryCost; // can be set to any arbitrary value + SCR_INT CroudVariation; + SCR_INT DanceAwardProgress; // "Gold Dancer trophy unlocked." + SCR_INT DanceAward2Progress; // "Gold Battler trophy unlocked." + TIMER DJMusicChangeTimer; +}; +static_assert(sizeof(NIGHTCLUB_DATA) == 12 * 8); + +struct ARENA_GARAGE_DATA +{ + SCR_INT Index; // always one for obvious reasons + SCR_INT OwnedGarageFloorLevel; + SCR_INT AppearanceBitset; + SCR_INT AppearanceBitset2; + SCR_INT InteriorTypeA; + SCR_INT InteriorTypeB; + SCR_INT SpectatingIndex; + SCR_INT SpectatingType; + SCR_INT PAD_0008; // unused +}; +static_assert(sizeof(ARENA_GARAGE_DATA) == 9 * 8); + +struct INSIDE_TRACK +{ + TEXT_LABEL_63 PlayerName; // real name leak when playing inside track + SCR_INT BetHorseID; + SCR_INT BetChips; +}; +static_assert(sizeof(INSIDE_TRACK) == 18 * 8); + +// casino penthouse +struct CASINO_APARTMENT_DATA +{ + SCR_INT Index; // always one for obvious reasons + SCR_INT PAD_0001; // unused + SCR_INT AppearanceBitset; + SCR_INT AppearanceBitset2; + uint64_t PAD_0005[2]; + INSIDE_TRACK InsideTrack; +}; +static_assert(sizeof(CASINO_APARTMENT_DATA) == 24 * 8); + +struct ARCADE_DATA +{ + SCR_INT Index; + SCR_INT AppearanceBitset; + SCR_INT AppearanceBitset2; + SCR_INT AppearanceBitset3; + SCR_INT SafeCashValue; + SCR_INT PAD_0005; // unused +}; +static_assert(sizeof(ARCADE_DATA) == 6 * 8); + +struct ARCADE_MACHINES +{ + SCR_INT OrderedMachinesBitset; + SCR_INT ArrivedMachinesBitset; +}; +static_assert(sizeof(ARCADE_MACHINES) == 2 * 8); + +struct SUBMARINE_DATA +{ + SCR_INT AppearanceBitset; + SCR_HASH Model; // not read by the scripts, always set to HASH("kosatka") + SCR_INT Color; // "PACKED_MP_INT_KOSATKA_COLOUR" + SCR_INT Flag; // "PACKED_MP_INT_KOSATKA_FLAG" + SCR_INT LastGuidedMissileUseTime; + SCR_INT PAD_0005; // unused +}; +static_assert(sizeof(SUBMARINE_DATA) == 6 * 8); + +struct AUTOSHOP_DATA +{ + SCR_INT Index; + SCR_INT AccessSetting; + SCR_INT AppearanceBitset; + SCR_INT AppearanceBitset2; + SCR_INT PAD_0004; + SCR_ARRAY ModdingVehicles; // VEHICLE_INDEX, not NETWORK_INDEX +}; +static_assert(sizeof(AUTOSHOP_DATA) == 8 * 8); + +// LS car meet +struct CAR_CLUB_DATA +{ + SCR_INT Flags; + SCR_INT Reputation; + SCR_INT ReputationLevel; + SCR_INT TestTrackAccess; // unused? +}; +static_assert(sizeof(CAR_CLUB_DATA) == 4 * 8); + +// agency +struct FIXER_HQ_DATA +{ + SCR_INT Index; + SCR_INT AppearanceBitset; + SCR_INT SafeCashValue; +}; +static_assert(sizeof(FIXER_HQ_DATA) == 3 * 8); + +// eclipse blvd garage +struct MULTI_STOREY_GARAGE_DATA +{ + SCR_INT Index; // always one for obvious reasons + SCR_INT AppearanceBitset; + SCR_INT AppearanceBitset2; + SCR_ARRAY GarageTints; +}; +static_assert(sizeof(MULTI_STOREY_GARAGE_DATA) == 6 * 8); + +struct SALVAGE_YARD_DATA +{ + SCR_INT Index; + SCR_INT PAD_0001; + SCR_INT AppearanceBitset; + SCR_INT TowTruckColor; + SCR_INT TowTruckType; // TODO + SCR_INT VehicleRobVehicleIndex; + SCR_INT TotalEarnings; +}; +static_assert(sizeof(SALVAGE_YARD_DATA) == 7 * 8); + +struct PROPERTY_DATA +{ + SCR_ARRAY PropertyIds; // size 30 -> 31 b3095 + SCR_BITSETFlags; // I really don't want to indent everything again + SCR_INT RingingPlayers; // bitset of players requesting entry into property + SCR_INT Index; // the value you pass to the send to apartment TSE + SCR_INT Instance; + SCR_INT ExteriorIndex; + PLAYER_INDEX ExteriorOwner; + SCR_ARRAY RingingPlayersState; // 0 = ringing, 1 = accepted, 2 = denied + GAMER_HANDLE OwnerHandle; // can be used to bypass RID spoofing when player is inside interior + SCR_ARRAY EclipseTheme; // size 30 -> 31 b3095 + SCR_INT ApartmentType; // normal vs stilt vs eclipse + SCR_INT OwnerInstance; // same as Instance in most cases + SCR_ARRAY ExecutiveWarehouseInfos; + SCR_INT OfficeSafeMoneyMultiplier; + SCR_BITSET StyleFlags; + SCR_INT PAD_0134; // unused + SCR_INT AssistantGreetingChoice; + SCR_INT AssistantDialogBitset; + SCR_INT AssistantDialogBitset2; + SCR_INT LifetimeCargoMissionsComplete; // used for trophy type + SCR_INT CasinoChipsMultiplier; + SCR_INT AssistantDialogBitset3; + SCR_INT AssistantDialogBitset4; + SCR_INT AssistantDialogBitset5; + SCR_INT AssistantDialogBitset6; // do we REALLY need 6 bitsets for assistant dialog? + IE_WAREHOUSE_DATA IEWarehouseData; + SCR_INT Garage1DataBitset; + SCR_INT Garage2DataBitset; + SCR_INT Garage3DataBitset; + SCR_INT ModshopDataBitset; + SCR_ARRAY FactoryInfos; + SCR_INT TotalBunkerResearch; + SCR_INT CurrentBunkerResearchProgress; + SCR_INT BunkerDecorVariation; + SCR_INT MOCBitset; + SCR_INT MOCColor; // bitset for some reason + uint64_t PAD_0290[2]; // unused + SCR_INT GunShopFlags; + HANGAR_DATA HangarData; + SCR_INT PAD_0299; + DEFUNCT_BASE_DATA DefunctBaseData; + SCR_INT AvengerInteriorDecorFlags; // "PACKED_MP_INT_ARMORY_AIRCRAFT_INTERIOR_v0" + uint64_t PAD_0308[3]; + BUSINESS_HUB_DATA BusinessHubData; + NIGHTCLUB_DATA NightclubData; + SCR_INT PAD_0365; + SCR_INT TerrorbyteDesign; + SCR_INT PAD_0367; + SCR_INT AcidLabRadio; + SCR_INT TerrorbyteRadio; + SCR_INT NanoDroneCooldown; + PLAYER_INDEX HostOfInteriorScript; + ARENA_GARAGE_DATA ArenaGarageData; + SCR_INT ArcadeJukeboxStation; // for simple interior type 17 + SCR_INT JukeboxFavoritePlaylist; + SCR_INT ClubhouseBarCashAmount; + SCR_INT DefaultJukeboxStation; + SCR_INT FreakshopJukeboxStation; + SCR_INT PAD_0386; // TODO + SCR_HASH MOCModel; // used by the bunker script to detect exits with MOC + SCR_INT PAD_0388; // unused + SCR_HASH TerrorbyteModel; + SCR_ARRAY PAD_0390; // some property interior stuff + uint64_t PAD_0398[4]; + SCR_INT OfficeGarageModdingVehicleSlot; + SCR_INT CurrentOfficeGarageFloor; + CASINO_APARTMENT_DATA CasinoApartmentData; // @405 as of 1.67 + ARCADE_DATA ArcadeData; + ARCADE_MACHINES ArcadeMachines; + SCR_ARRAY ArcadeMachineSlots; + SCR_INT PAD_0478; // TODO + SUBMARINE_DATA SubmarineData; + AUTOSHOP_DATA AutoShopData; + SALVAGE_YARD_DATA SalvageYardData; + SCR_ARRAY AutoShopArcadeMachineSlots; + CAR_CLUB_DATA CarClubData; + FIXER_HQ_DATA FixerHQData; + SCR_INT PAD_0503; // not read by the scripts + SCR_INT PAD_0504; + VEHICLE_INDEX CurrentlyModdingVehicleFixerHQ; + MULTI_STOREY_GARAGE_DATA MultiStoreyGarageData; // @507 as of 1.67 + SCR_INT FreakshopBits; // 0: has weapon workshop, 1: radio enabled +}; +static_assert(sizeof(PROPERTY_DATA) == 523 * 8); + +struct BIKER_CONTRACTS +{ + SCR_ARRAY ActiveContractMissions; + SCR_INT SelectedContractMission; + SCR_BOOL Enabled; +}; +static_assert(sizeof(BIKER_CONTRACTS) == 7 * 8); + +struct NIGHTCLUB_SALE +{ + SCR_INT BuyerIndex; + SCR_INT NumSoldItems; + SCR_INT SaleAmount; + uint64_t PAD_0003[2]; +}; +static_assert(sizeof(NIGHTCLUB_SALE) == 5 * 8); + +struct ARENA_WAR_DATA +{ + SCR_INT PointsTier; + SCR_INT SkillLevel; + SCR_INT TrinketBitset; // MP_STAT_ARN_BS_TRINKET_SAVED +}; +static_assert(sizeof(ARENA_WAR_DATA) == 3 * 8); + +struct GPBD_FM_Entry +{ + SCR_INT CurrentActivity; + SCR_INT MissionScriptInstance; + SCR_INT PAD_0002; // TODO + SCR_INT NumFreeSpectatorSlots; + SCR_INT NumPlayersInTransition; // not really + SCR_INT NJVSVoteState; // voting screen shown after a mission ends + SCR_INT NJVSVoteContentBitset; + SCR_BOOL NJVSChoiceMade; + SCR_INT NJVSLeaveState; // network error or quit + SCR_INT JobPoints; // can be spoofed to change the "JP" value in the player list + PLAYER_INDEX NextHost; // transfer transition host when joining next job + PLAYLIST_DATA PlaylistData; + TEXT_LABEL_63 JobName; + SCR_ARRAY ActiveGunRange; // this should have really been an enum lol + MP_SCRIPT_DATA MissionScriptData; + JOB_SETTINGS JobSettings; + SCR_INT FMMCLauncherState; + VEHICLE_SELECTION VehicleSelection; + SCR_INT JobStartCloudTime; // this is a struct but too lazy to create one + SCR_INT ContentHash; + SCR_BOOL PAD_0138; // unused + SCR_BITSET TutorialBitset; + SCR_BITSET GangCallRequestedServices; + PLAYER_INDEX GangCallTarget; // can be used to send muggers/hit squad + SCR_BITSET GangCallSentServices; + SCR_INT TutorialBitset2; + TEXT_LABEL_23 PlayingContentUsedId; + TEXT_LABEL_23 MatchId; + uint64_t PAD_0156[8]; // unused + TEXT_LABEL_63 DisplayJobName; // as shown in the playerlist? + STRIKE_TEAM StrikeTeam; + uint64_t PAD_0185[7]; // pad + SCR_INT FMMCState; + SCR_INT PAD_0193; // TODO + SCR_INT KillStreak; + SCR_INT NumSuicides; // deducts RP reward in missions + SCR_INT DeathmatchBounty; // "You have been deducted $~1~ for being idle for too long, and you now have a bounty placed on you." + SCR_BOOL CollectedBounty; + SCR_INT AliveDeathmatchPlayers; + SCR_INT WantedLevelFlags; + SCR_ARRAY PAD_0201; + SCR_INT HairdoShopIndex; + SCR_INT PAD_0204; + PLAYER_STATS PlayerStats; + SCR_INT PAD_265; + SCR_INT Mood; + PROPERTY_DATA PropertyData; // @267 as of b3095 + uint64_t PAD_0779[4]; // TODO + uint64_t PAD_0783[12]; // no clue what it does but it looks rather interesting + SCR_INT AssistedKillFlags; + NETWORK_INDEX UnkNetworkId; + SCR_BOOL SpawningUnkVehicle; + SCR_BOOL MeltdownComplete; // yes, the singleplayer mission "Meltdown" (michael4) + SCR_INT UNK_0799; + SCR_INT GangAttackTarget; // triggers unique dialog from some phone NPCs + SCR_INT ActivePVSlot; + PLAYER_INDEX SpectatingPlayer; + SCR_INT PAD_0803; + SCR_ARRAY ActiveAmbientWeaponPickups; // size 2 -> 3 b3095 + SCR_ARRAY OfficeMapMarkers; + SCR_INT OfficeLargestMoneyThresholdIndex; + SCR_ARRAY EnabledOfficeCashPiles; + SCR_ARRAY EnabledClubhouseCashPiles; + BIKER_CONTRACTS BikerContracts; + SCR_INT CasinoWonBitset; // can be used to tamper with the casino PA system + uint64_t PAD_0829[2]; + SCR_BOOL CameraPositionOverriden; + SCR_VEC3 OverrideCameraPosition; + SCR_INT PAD_0835; + SCR_INT HeliRappelFlags; + SCR_INT PAD_0837; // some more aircraft flags + SCR_BOOL RespawningToPreviousCheckpoint; + NIGHTCLUB_SALE NightclubSale; + uint64_t PAD_844[11]; // unused, all of them + SCR_INT SeatingIndex; + ARENA_WAR_DATA ArenaWarData; // @858 as of 1.67 + uint64_t PAD_0861[2]; + SCR_INT ApartmentEnterFlags; + SCR_VEC3 AvengerMissionStartPosition; +}; +static_assert(sizeof(GPBD_FM_Entry) == 877 * 8); + +struct GPBD_FM +{ + SCR_ARRAY Entries; +}; +static_assert(sizeof(GPBD_FM) == 28065 * 8); diff --git a/classes/src/script/globals/GPBD_FM_3.hpp b/classes/src/script/globals/GPBD_FM_3.hpp new file mode 100644 index 0000000000..ad0509536a --- /dev/null +++ b/classes/src/script/globals/GPBD_FM_3.hpp @@ -0,0 +1,357 @@ +#pragma once +#include "../types.hpp" +#include "../Timer.hpp" +#include "../HudColor.hpp" +#include "../MPScriptData.hpp" + +enum class eActivityType +{ + HeistPrep = 233, + Gunrunning = 180, + Sightseer = 142, + HeadHunter = 166, + BuySpecialCargo = 167, + SellSpecialCargo = 168, + DefendSpecialCargo = 169, + StealVehicle = 178, + ExportVehicle = 188, + Gunrunning2 = 225, + GunrunningSell = 226, + GunrunningDefend = 227, + BikerSell = 190, + BikerDefend = 191, + BusinessResupply = 192, + Survival = 3, + Darts = 14, + ArmWresling = 15, + GangAttack = 6, + PilotSchool = 122, + Golf = 11, + ShootingRange = 13, + Tennis = 12, + BaseJump = 8, + Deathmatch = 1, + ImpromptuDeathmatch = 5, + Mission = 0, + Race = 2, + ExecutiveDeathmatch = 148, + MarkedForDeath = 151, + PiracyPrevention = 152, + MostWanted = 153, + AssetRecovery = 157, + HostileTakeover = 159, + Point2Point = 162, + AmphibiousAssault = 216, + Velocity = 219, + GunsForHire = 185, + ByThePound = 182, + RippingItUp = 194, + RaceToPoint = 189, + HitAndRide = 193, + CriminalMischief = 205, + WeaponOfChoice = 186, + FragileGoods = 207, + Torched = 208, + Outrider = 209, + WheelieRider = 210, + POW = 183, + ExecutiveSearch = 199, + StandYourGround = 201, + AutoBuyout = 163, + DueDiligence = 160, + MarketManipulation = 154, + CourierService = 155, + Skydive = 267 +}; + +enum class eBossGoonFlags +{ + kOneOnOneDM = 4, + kJoinSuccess = 7, + kJoinFail = 8, + kSpectating = 24 +}; + +enum class eGoonInviteType +{ + DEBUG, + NEARBY, + FRIENDS, + CREW, + INDIVIDUAL, + LOOKING_FOR_WORK +}; + +enum class eBossVehicleState +{ + NONE, + SPAWNED, + DESTROYED = 3 +}; + +enum class eMCRole +{ + PROSPECT = -1, + VICE_PRESIDENT, + ROAD_CAPTAIN, + SERGEANT_IN_ARMS, + ENFORCER +}; + +enum class eClubhouseActivity +{ + NONE = -1, + DARTS, + ARM_WRESTLING +}; + +struct MC_STYLE +{ + SCR_BOOL Enabled; + SCR_INT BossOutfitType; + SCR_INT GoonOutfitType; + SCR_ARRAY GoonOutfitIndices; // one outfit for each goon + SCR_ARRAY GoonOutfitIndicesOverride; + SCR_INT PAD_0019; + SCR_BOOL HeadgearEnabled; + SCR_BOOL EmblemEnabled; +}; +static_assert(sizeof(MC_STYLE) == 22 * 8); + +struct VEHICLE_EXPORT +{ + SCR_ARRAY SellingVehicleIndices; + SCR_INT PAD_0005; // this is set to zero in all export scripts and never read +}; +static_assert(sizeof(VEHICLE_EXPORT) == 6 * 8); + +struct HANGAR_CARGO +{ + SCR_INT PAD_0000; // unused? + SCR_ARRAY DeliverableTypes; + SCR_INT CargoType; +}; +static_assert(sizeof(HANGAR_CARGO) == 23 * 8); + +struct CASINO_HEIST_PREP +{ + SCR_INT PrepIndex; + SCR_INT SupportCrewMemberIndex; // only set on preps 1 through 3 + SCR_INT LoadoutIndex; // only set on prep 1 and 2 +}; +static_assert(sizeof(CASINO_HEIST_PREP) == 3 * 8); + +struct LEAVE_IN_HELI +{ + SCR_INT Flags; + PLAYER_INDEX Owner; + SCR_INT SeatIndex; +}; +static_assert(sizeof(LEAVE_IN_HELI) == 3 * 8); + +struct BOSS_GOON +{ + PLAYER_INDEX Boss; // leader of CEO/MC + SCR_INT TimeBecameBoss; + SCR_INT TimeBecameGoon; + SCR_INT LastPayTime; + SCR_BITSET Flags; + SCR_INT Flags2; // TODO + SCR_INT Flags3; // TODO + SCR_INT TotalBossGoonTime; + SCR_ARRAY BossGoonUUID; + SCR_ARRAY Goons; + SCR_INT GoonsRequestingJoin; // bitset + SCR_INT PayGrade; + SCR_INT InvitesByBosses; // bitset + SCR_INT TransitionBossPersistanceStage; + SCR_INT EndBeingGoonReason; + SCR_INT PAD_0025; // TODO + PLAYER_INDEX JoiningBoss; + alignas(8) eGoonInviteType JoinedInviteType; + SCR_INT NumBossDeathsSinceLastPay; + SCR_VEC3 PAD_0029; // TODO + alignas(8) eActivityType UnkActivity; + alignas(8) eActivityType CurrentActivity; + PLAYER_INDEX JoustTarget; + PLAYER_INDEX ExecutiveDeathmatchTarget; + MP_SCRIPT_DATA ActiveScript; + PLAYER_INDEX PAD_0057; + PLAYER_INDEX PAD_0058; + alignas(8) eBossVehicleState BossVehicleState; + SCR_INT BossVehicleSpawnState; + PLAYER_INDEX PlayerInsideBossVehicle; + SCR_HASH BossVehicleModel; + TIMER LastBossVehicleSpawnTimer; + TIMER BossVehicleInvincibleTimer; + SCR_VEC3 BossVehicleSpawnedPosition; + alignas(8) HudColor BossVehicleHudColor; + TEXT_LABEL_15 BossVehicleTextLabel; + SCR_INT BossVehicleNetId; + MC_STYLE MCStyle; + uint64_t PAD_0098[3]; // unused + SCR_INT FriendlyFireDisabledPlayers; + SCR_INT PiracyPreventionYachtIndex; // not used by the scripts + SCR_INT BossGoonMissionLaunchState; + SCR_INT ColorSlot; + TEXT_LABEL_63 MCName; + SCR_INT Language; // can be used to get the system language of player + SCR_INT SpawnableBossVehicles; + SCR_INT AutoBuyoutDeliveryLocationIndex; + SCR_INT AutoBuyoutDeliveryLocationSubIndex; + SCR_INT PAD_0125; // unused + SCR_ARRAY PAD_0126; // TODO + SCR_ARRAY ContrabandPositions; // positions of cargo used to notify players to destroy them when they get near + SCR_HASH ContrabandPickupModel; + PLAYER_INDEX StealingContrabandVehiclePlayerIndex; + SCR_INT PAD_0178; // TODO + SCR_HASH ContrabandPickupModel2; + SCR_BOOL DestroyedCargo; + SCR_INT VIPGameplayDisabledTimer; // @181 as of 1.67 + SCR_INT SettingUpBusiness; + uint64_t PAD_0183[4]; // TODO some unknown contraband struct + VEHICLE_EXPORT VehicleExport; + uint64_t PAD_0193[12]; // TODO + SCR_ARRAY ActiveFreemodeEvents; // force thunder + uint64_t PAD_0212[22]; // I'm not even going to bother with this one + HANGAR_CARGO HangarCargo; + uint64_t PAD_0236[23]; // not going to bother with this one either + SCR_ARRAY CasinoDeliverables; + SCR_INT CasinoLimoDestination; + SCR_BOOL CasinoLimoActive; + SCR_BOOL CasinoLuxuryCarActive; + SCR_HASH CasinoLuxuryCarModel; + CASINO_HEIST_PREP CasinoHeistPrep; + SCR_INT CayoPrepIndex; + SCR_INT CompanySUVDestination; + SCR_BOOL CompanySUVActive; + SCR_ARRAY ContrabandIndices; // type of selling cargo + SCR_ARRAY VehicleExportIndices; // not sure what this is + SCR_INT VehicleExportMissionType; // valid range is 2000 to 2010, 2000 = 0, 2001 = 1 etc + SCR_ARRAY VehicleExportSellingIndices; + SCR_BOOL PAD_0337; // TODO + TEXT_LABEL_63 GangName; // CEO Name + TEXT_LABEL_63 ClubhouseName; // cut content? + SCR_INT SourcingContrabandType; + SCR_INT FragileGoodsMissionType; + SCR_INT SalvageMissionType; + SCR_INT DoomsdayPrepIndex; + SCR_INT VehicleExportIndex; // another one... + SCR_INT PAD_0375; // unused + SCR_INT BunkerSourceIndex; // check gb_gunrunning func_1540 + SCR_ARRAY BunkerCargoIndices; + uint64_t PAD_0386[5]; + uint64_t PAD_0391[2]; // unused + uint64_t PAD_0393[15]; // smuggler data + SCR_INT LastBossWorkTime; // seconds since epoch + uint64_t PAD_0409[19]; + SCR_BOOL IsMC; + alignas(8) eMCRole MCRole; // applies to goons only, boss is always the MC president + SCR_BOOL FormationFlyingAssist; + SCR_INT PAD_0431; // always set to zero and not read + SCR_BOOL MCFormationActive; + SCR_BOOL MCFormationHelpShown; + TIMER MCFormationHealthBonusTimer; + TIMER MCFormationLastHealthBonusTimer; + TIMER MCFormationBreakTimer; + SCR_INT PAD_0440; // unused + SCR_BOOL MCFormationAssist; + SCR_BOOL MCRidingStyleRelaxed; + SCR_FLOAT PAD_0443; // set from a tunable + SCR_FLOAT PAD_0444; // set from a tunable + uint64_t PAD_0445[16]; // somewhat unused, a few fields are accessed in the business battle script + SCR_INT ClothingValue; // total value of equipped clothing used by criminal damage + PLAYER_INDEX Adversary; // for common adversary calculations? + SCR_HASH ContrabandType; // unknown HASH_ENUM + SCR_INT HitAndRideGangType; + SCR_BOOL IsMC2; + SCR_INT BossGoonVersion; + SCR_INT MCTotalContributionPoints; + SCR_INT MCContributionPoints; + SCR_INT FavoriteBikeStyle; // not read by the scripts + SCR_INT GreatestFormationTimeIndex; + SCR_INT FormationTime; + SCR_BOOL RidingFavoriteMotorcycle; + SCR_INT ContrabandSellLocation; + SCR_INT BusinessBattleType; + SCR_INT PAD_0475; + SCR_INT NightclubMissionIndex; + SCR_INT NightclubDefendMissionIndex; + uint64_t PAD_0478[18]; // TODO + SCR_BOOL DoubleActionCacheLocationRevealed; +}; +static_assert(sizeof(BOSS_GOON) == 498 * 8); + +struct MC_STATS +{ + SCR_INT FormationTime0; + SCR_INT FormationTime1; + SCR_INT FormationTime2; + SCR_INT FormationTime3; + SCR_INT MembersMarkedForDeath; + SCR_INT MCKills; + SCR_INT MCDeaths; + SCR_INT RivalPresidentKills; + SCR_INT RivalCEOAndVIPKills; + SCR_INT MeleeKills; + SCR_INT ClubhouseContractsComplete; + SCR_INT ClubhouseContractEarnings; + SCR_INT ClubworkCompleted; + SCR_INT ClubChallengesCompleted; + SCR_INT MemberChallengesCompleted; +}; +static_assert(sizeof(MC_STATS) == 15 * 8); + + +struct GBPD_FM_3_Entry +{ + alignas(8) eActivityType CurrentActivity; // enum is outdated + SCR_INT Flags; // TODO + alignas(8) eActivityType CurrentFreemodeActivity; // subset of CurrentActivity + SCR_INT SeatingFlags; + SCR_VEC3 CurrentFreemodeActivityObjectivePosition; + SCR_INT VehiclesNearbyActivityObjective; // only used by challenges and checkpoints + SCR_BOOL PassiveMode; + SCR_BOOL TimeTrialActive; // verify + BOSS_GOON BossGoon; + uint64_t PAD_507[3]; // unused + SCR_INT ScriptEventReplayProtectionCounter; + TIMER CoronaForcedLaunchTimer; + LEAVE_IN_HELI LeaveInHeli; + SCR_INT OfficeDesktopFlags; // bit 0 -> login, bit 1 -> map + uint64_t PAD_514[8]; // some IE stuff, most of it is unused + SCR_INT IlluminatedClothingState; + SCR_INT MatchHistoryId1; // used for telemetry + SCR_INT MatchHistoryId2; + alignas(8) eClubhouseActivity ClubhouseActivity; + SCR_INT ClubhouseFont; + SCR_INT ClubhouseColor; + SCR_INT ClubhouseEmblem; + SCR_BOOL ClubhouseHideSignage; + uint64_t PAD_0533[2]; // facility exit + uint64_t PAD_0535[6]; // no clue what this is + MC_STATS MCStats; + uint64_t PAD_0556[29]; + SCR_HASH ForcedWeapon; + SCR_INT HangarCargoMissionLocationIndex; + SCR_VEC3 AvengerPosition; + SCR_VEC3 TerrorbytePosition; + SCR_VEC3 AcidLabPosition; + PLAYER_INDEX DeliveringExportVehicleOwner; + uint64_t PAD_0597[2]; // TODO + SCR_INT BountyAmount; // values above 10000 will prevent payout + PLAYER_INDEX BountyPlacedBy; + SCR_INT PAD_0601; // unused, set to -1 by business_battles_sell and never read + SCR_INT CurrentlyUsingArenaTurretIndex; // works similar to the vars found in GlobalPlayerBD + SCR_INT CurrentlyUsingArenaTurretActivatedTime; + SCR_INT CasinoStoryProgress; + SCR_INT CasinoFlowProgress; + SCR_ARRAY DailyObjectiveFlags; // @607 as of 1.67 +}; +static_assert(sizeof(GBPD_FM_3_Entry) == 609 * 8); + +struct GPBD_FM_3 +{ + SCR_ARRAY Entries; +}; +static_assert(sizeof(GPBD_FM_3) == 19489 * 8); \ No newline at end of file diff --git a/classes/src/script/globals/GPBD_Kicking.hpp b/classes/src/script/globals/GPBD_Kicking.hpp new file mode 100644 index 0000000000..d926d33fd3 --- /dev/null +++ b/classes/src/script/globals/GPBD_Kicking.hpp @@ -0,0 +1,17 @@ +#pragma once +#include "../types.hpp" + +struct GPBD_KickingEntry +{ + SCR_ARRAY KickVotes; // players you are voting to kick (array of bool) + SCR_ARRAY KickWarningsShown; + SCR_BOOL WillBeKickedSoon; + SCR_ARRAY PlayersToBeKickedSoon; +}; +static_assert(sizeof(GPBD_KickingEntry) == 100 * 8); + +struct GPBD_Kicking +{ + SCR_ARRAY Entries; +}; +static_assert(sizeof(GPBD_Kicking) == 3201 * 8); \ No newline at end of file diff --git a/classes/src/script/globals/GPBD_MissionName.hpp b/classes/src/script/globals/GPBD_MissionName.hpp new file mode 100644 index 0000000000..22bb3f4bc4 --- /dev/null +++ b/classes/src/script/globals/GPBD_MissionName.hpp @@ -0,0 +1,8 @@ +#pragma once +#include "../types.hpp" + +struct GPBD_MissionName +{ + SCR_ARRAY MissionNames; +}; +static_assert(sizeof(GPBD_MissionName) == 513 * 8); \ No newline at end of file diff --git a/classes/src/script/globals/GSBD.hpp b/classes/src/script/globals/GSBD.hpp new file mode 100644 index 0000000000..f1ea0bada5 --- /dev/null +++ b/classes/src/script/globals/GSBD.hpp @@ -0,0 +1,94 @@ +#pragma once +#include "../types.hpp" +#include "GlobalPlayerBD.hpp" + +struct IMPOUND_VEHICLE_INFO +{ + SCR_INT ImpoundId; + SCR_BOOL OccupiedCheckDone; + SCR_INT EntityAreaHandle; + SCR_INT TimeCreated; +}; +static_assert(sizeof(IMPOUND_VEHICLE_INFO) == 4 * 8); + +struct CEO_COLOR +{ + PLAYER_INDEX Owner; + SCR_INT Color; +}; +static_assert(sizeof(CEO_COLOR) == 2 * 8); + +struct CEO_COLORS +{ + SCR_ARRAY CeoColorIndices; + SCR_ARRAY CeoColorIndices2; + SCR_ARRAY CeoColors; + SCR_INT PAD_0065; + uint64_t PAD_0066[19]; + SCR_INT PAD_0085; // added b3095 ("Press ~INPUT_CONTEXT~ to contact Jamal and begin stealing bolt cutters for The Cargo Ship Robbery" mission variation) +}; +static_assert(sizeof(CEO_COLORS) == 86 * 8); + +struct SMPL_INTERIOR_DATA_SERVER +{ + SCR_INT PAD_0000; // unused + SCR_ARRAY PlayerInteriorInstances; + SCR_ARRAY PlayerInteriorIds; // used solely for telemetry + SCR_INT PlayerInteriorCreationRequestBitset; + SCR_ARRAY PlayerOwnerBitset; + SCR_INT PlayerInteriorRemovalRequestBitset; + SCR_ARRAY PlayerInteriorCreationTimes; + SCR_ARRAY PlayerInteriorSimpleInteriorTypes; + SCR_ARRAY PlayerInteriorIsOwnerless; + SCR_ARRAY PlayerInteriorOwners; +}; +static_assert(sizeof(SMPL_INTERIOR_DATA_SERVER) == 234 * 8); + +struct LEAVE_CLUBHOUSE_SERVER +{ + SCR_ARRAY Identifiers; + SCR_ARRAY ExitLocations; + SCR_ARRAY ExitLocationSlots; +}; +static_assert(sizeof(LEAVE_CLUBHOUSE_SERVER) == 99 * 8); + +struct IE_DELIVERY_INFO +{ + PLAYER_INDEX Player_; + SCR_HASH VehicleModel; + PLAYER_INDEX ContrabandOwner; + SCR_INT TimeCreated; + SCR_BOOL PAD_0004; +}; +static_assert(sizeof(IE_DELIVERY_INFO) == 5 * 8); + +struct GSBD +{ + alignas(8) eFreemodeState FreemodeState; + SCR_INT SessionToken; // time when freemode had started for the script host + SCR_ARRAY ImpoundVehicleInfos; + SCR_ARRAY SpawnPositions; + SCR_ARRAY SpawnPositionCreationTimes; + SCR_ARRAY SpawnPositionsValid; + SCR_ARRAY PAD_0294; + SCR_ARRAY SpawnPositionTokens; + SCR_INT SpawnPositionCounter; + SCR_ARRAY RespawnVehicles; + SCR_ARRAY RespawnVehicleSeats; + SCR_ARRAY MorsMutualSpawnSlots; + SCR_INT MorsMutualSpawnPlayersBitset; + uint64_t PAD_0461[353]; // TODO + SCR_BOOL CopTimerOn; // cut CnC content + SCR_BOOL CrookTimerOn; + SCR_BOOL PAD_0816; // always set to FALSE + SCR_INT PAD_0817; // unused + CEO_COLORS CeoColors; + SMPL_INTERIOR_DATA_SERVER SimpleInteriorData; + LEAVE_CLUBHOUSE_SERVER LeaveClubhouse; + SCR_ARRAY IEDeliveryInfos; + SCR_INT PAD_1397; + NETWORK_INDEX IAATurretCameraVehicleId; // used by DDH act 1 + uint64_t PAD_1399[97]; + SCR_INT CayoPericoStrandedAnimalChoice; +}; +static_assert(sizeof(GSBD) == 1498 * 8); \ No newline at end of file diff --git a/classes/src/script/globals/GSBD_BlockB.hpp b/classes/src/script/globals/GSBD_BlockB.hpp new file mode 100644 index 0000000000..711648c88f --- /dev/null +++ b/classes/src/script/globals/GSBD_BlockB.hpp @@ -0,0 +1,96 @@ +#pragma once +#include "../types.hpp" + + +enum class eDeliverableState +{ + INVALID = -1, + INITIAL, + DELIVERED +}; + +struct PLAYER_MISSION_INFO +{ + SCR_INT State; + SCR_INT Index; // GSBD_MissionRequest index +}; +static_assert(sizeof(PLAYER_MISSION_INFO) == 2 * 8); + +struct CRATE_DROP +{ + SCR_INT PAD_0000; // unused + SCR_BOOL EnableCrateDrops; // tries to trigger strange last gen stuff unsuccessfully + uint64_t PAD_0003[2]; // unused +}; +static_assert(sizeof(CRATE_DROP) == 4 * 8); + +struct DELIVERABLE_ID +{ + PLAYER_INDEX Owner; + SCR_INT Id; // "FMDeliverableID" +}; +static_assert(sizeof(DELIVERABLE_ID) == 2 * 8); + +struct DELIVERABLE_SCRIPT_INFO +{ + SCR_HASH Hash_; + uint64_t PAD_0001[2]; // unused +}; +static_assert(sizeof(DELIVERABLE_SCRIPT_INFO) == 3 * 8); + +struct UNK_0962 +{ + PLAYER_INDEX PAD_0000; + SCR_ARRAY PAD_0001; + SCR_ARRAY PAD_0020; +}; +static_assert(sizeof(UNK_0962) == 75 * 8); + +struct DELIVERABLE +{ + alignas(8) eDeliverableState State; + DELIVERABLE_ID DeliverableId; + SCR_INT Type; + SCR_INT PAD_0004; // this is always set to zero + SCR_ARRAY DroppedOffLocations; // "activeDropOff is not the same as sctiptDropOff" + DELIVERABLE_SCRIPT_INFO ScriptInfo; + SCR_INT NumDropOffs; +}; +static_assert(sizeof(DELIVERABLE) == 15 * 8); + +// "FREEMODE_DELIVERY_SERVER_ADD_DELIVERABLE_ID" "_FREEMODE_DELIVERY_MAINTAIN_SERVER" +struct FREEMODE_DELIVERY +{ + SCR_BOOL Initialized; + SCR_ARRAY Deliverables; + SCR_ARRAY PAD_0962; // TODO +}; +static_assert(sizeof(FREEMODE_DELIVERY) == 1713 * 8); + +struct GLOBAL_CLUB_INFO +{ + uint64_t PAD_0000[16]; +}; +static_assert(sizeof(GLOBAL_CLUB_INFO) == 16 * 8); + +struct GSBD_BlockB +{ + SCR_INT MissionLauncherInitializedBitset; + PLAYER_INDEX ScriptHost; + SCR_INT PAD_0002; + SCR_BOOL PAD_0003; // forces a team update thingy + SCR_ARRAY PlayerMissionInfos; + SCR_INT HostMigrationCounter; + uint64_t PAD_0080[14]; // unused + CRATE_DROP CrateDrop; + uint64_t PAD_0088[6]; // unused + uint64_t PAD_0094[33]; // ??? + uint64_t PAD_0127[65]; // even more strange stuff (cut content?) + SCR_ARRAY TurretCooldownTimers; + FREEMODE_DELIVERY FreemodeDelivery; + SCR_ARRAY GlobalClubInfos; + SCR_ARRAY CarMeetModShopSlotIndices; + SCR_ARRAY CarMeetModShopOccupiedGoons; + SCR_ARRAY, 32>CarMeetModShopOccupiedVehicleSlots; +}; +static_assert(sizeof(GSBD_BlockB) == 2156 * 8); \ No newline at end of file diff --git a/classes/src/script/globals/GSBD_FM.hpp b/classes/src/script/globals/GSBD_FM.hpp new file mode 100644 index 0000000000..a0449ab3f0 --- /dev/null +++ b/classes/src/script/globals/GSBD_FM.hpp @@ -0,0 +1,66 @@ +#pragma once +#include "../types.hpp" + +struct PLAYER_BOUNTY +{ + SCR_BOOL HasBounty; + SCR_INT BountyAmount; + SCR_INT PAD_0002; // unused +}; +static_assert(sizeof(PLAYER_BOUNTY) == 3 * 8); + +struct ACTIVE_CONTACT_SERVICE +{ + SCR_INT Id; + PLAYER_INDEX Target; + SCR_BOOL Bounty; // unknown usage + SCR_INT Flags; +}; +static_assert(sizeof(ACTIVE_CONTACT_SERVICE) == 4 * 8); + +struct WEAPON_PICKUPS +{ + SCR_INT LastUnkWeaponPickupTime; + SCR_INT LastMeleeWeaponPickupTime; + SCR_INT LastProjectilePickupTime; + SCR_INT LastGunPickupTime; + SCR_ARRAY Indices; // size increased in b3095 (62 -> 95) + SCR_ARRAY Owners; + SCR_INT SpawnCounter; + SCR_INT AmmoCount; +}; +static_assert(sizeof(WEAPON_PICKUPS) == 198 * 8); + +struct BIKER_CONTRACTS_SERVER +{ + SCR_ARRAY ActiveContracts; + SCR_ARRAY ContractCompleteCount; + SCR_INT CompletedContractBitset; + SCR_INT LastContractRefreshTime; +}; +static_assert(sizeof(BIKER_CONTRACTS_SERVER) == 10 * 8); + +struct GSBD_FM +{ + SCR_ARRAY ModelSwapBits; + SCR_INT PAD_0003; // unused + SCR_ARRAY PlayerBounties; + uint64_t PAD_0101[5]; // unused + SCR_ARRAY MuggingPlayers; // 0 = mugger, 1 = merryweather mercs + SCR_ARRAY MuggedPlayers; + uint64_t PAD_0112[4]; // unused + SCR_ARRAY PAD_0116; // TODO + SCR_INT ShopProcessingBitset; + SCR_ARRAY ActiveContactServiceBitsets; + SCR_ARRAY ActiveContactServices; + PLAYER_INDEX SpectatorTVWantedPlayer; + SCR_BOOL SpectatorTVWantedClosing; + SCR_BOOL SpectatorTVWantedActive; + uint64_t PAD_0390[2]; // not read by the scripts + SCR_INT PAD_0392; // TODO + uint64_t PAD_0393[6]; // TODO + WEAPON_PICKUPS WeaponPickups; + BIKER_CONTRACTS_SERVER BikerContracts; + SCR_ARRAY DoubleActionCacheLocationRevealed; +}; +static_assert(sizeof(GSBD_FM) == 642 * 8); \ No newline at end of file diff --git a/classes/src/script/globals/GSBD_Kicking.hpp b/classes/src/script/globals/GSBD_Kicking.hpp new file mode 100644 index 0000000000..93d4367b85 --- /dev/null +++ b/classes/src/script/globals/GSBD_Kicking.hpp @@ -0,0 +1,8 @@ +#pragma once +#include "../types.hpp" + +struct GSBD_Kicking +{ + SCR_ARRAY KickedPlayers; +}; +static_assert(sizeof(GSBD_Kicking) == 33 * 8); \ No newline at end of file diff --git a/classes/src/script/globals/GSBD_PropertyInstances.hpp b/classes/src/script/globals/GSBD_PropertyInstances.hpp new file mode 100644 index 0000000000..1c44137ec1 --- /dev/null +++ b/classes/src/script/globals/GSBD_PropertyInstances.hpp @@ -0,0 +1,11 @@ +#pragma once +#include "../types.hpp" + +// this is why your apartment generally takes years to load +struct GSBD_PropertyInstances +{ + SCR_ARRAY PropertyOwners; + uint64_t PAD_0417[14]; // unused + SCR_ARRAY PropertyOwnerInstances; +}; +static_assert(sizeof(GSBD_PropertyInstances) == 464 * 8); \ No newline at end of file diff --git a/classes/src/script/globals/GlobalPlayerBD.hpp b/classes/src/script/globals/GlobalPlayerBD.hpp new file mode 100644 index 0000000000..706b326f18 --- /dev/null +++ b/classes/src/script/globals/GlobalPlayerBD.hpp @@ -0,0 +1,669 @@ +#pragma once +#include "../types.hpp" +#include "../MPScriptData.hpp" + +enum class eFreemodeState +{ + NONE = 0, + UNK_2 = 2, + RUNNING = 4, + CLOSING = 5, + UNK_10 = 10, + UNK_11 = 11 +}; + +enum class eMissionType +{ + NONE, + MISSION, + HEIST, + UNK_3, + ADVERSARY_MODE, + LAST_TEAM_STANDING, + CAPTURE, + HEIST_SETUP, + UNK_8, // FMMC_RSTAR_MCP + UNKNOWN // everything else +}; + +enum class eAnimationBitset +{ + kCashRainActive = 12, + kChampagneSprayActive = 13 +}; + +enum class eBlipFlags +{ + // 0 is unused + kVisibleOnCutscene = 1, + kFlashMinimapDisplay = 2, + kFlashBlip = 3, + kMicroLightOTRActive = 4, + kSkipTutorialSessionChecks = 5, + kHideOnMinimap = 6, // needs testing + kHideOnMinimapWhenInterior = 7, // needs testing + kHideOnMinimapWhenBigMapActive = 9, // needs testing + kDontUsePassiveBlip = 21, + kUseRampageBlip = 24, + kHideWhenFading = 25 +}; + +enum class eBlipType +{ + ON_FOOT, + TANK, + PLAYER_JET, + PLAYER_PLANE, + PLAYER_HELI, + PLAYER_GUNCAR, + PLAYER_BOAT, + ROCKET_VOLTIC, + TECHNICAL, + RUINER_2000, + DUNE_BUGGY, + PHANTOM_WEDGE, + ARMORED_BOXVILLE, // boxville5 + WASTELANDER, + QUAD, + APC, + OPPRESSOR_MK_1, + HALF_TRACK, + DUNE_FAV, + WEAPONIZED_TAMPA, + AA_TRAILER, + ALPHA_Z1, + BOMBUSHKA, + HAVOK, + HOWARD, + HUNTER, + MICROLIGHT, + MOGUL, + MOLOTOK, + NOKOTA, + PYRO, + ROGUE, + STARLING, + SEABREEZE, + TULA, + STROMBERG, + DELUXO, + THRUSTER, + KHANJALI, + RIOT_VAN, + VOLATOL, + BARRAGE, + AKULA, + CHERNOBOG, + AVENGER, + TURRETED_LIMO, + SEA_SPARROW, + CARACARA, + PARTY_BUS, + TERRORBYTE, + MENACER, + SCRAMJET, + POUNDER_CUSTOM, + MULE_CUSTOM, + SPEEDO_CUSTOM, + OPPRESSOR_MK_2, + STRIKEFORCE, + ARENA_BRUISER, + ARENA_BRUTUS, + ARENA_CERBERUS, + ARENA_DEATHBIKE, + ARENA_DOMINATOR, + ARENA_IMPALER, + ARENA_IMPERATOR, + ARENA_ISSI, + ARENA_SASQUATCH, + ARENA_SCARAB, + ARENA_SLAMVAN, + ARENA_ZR380, + MINI_SUB, + SPARROW, + FOLDING_WING_JET, + GANG_BIKE, + MILITARY_QUAD, + SQUADDIE, // SQUADEE + CAYO_DINGHY, + WINKY, + PATROL_BOAT, + ANNIHILATOR, + KART_RETRO, + KART_MODERN, + MILITARY_TRUCK, + SUBMARINE, + CHAMPION, + BUFFALO_STX, + DEITY, // why does this have a blip? + JUBILEE, + GRANGER_3600LX, + PATRIOT_MILSPEC, + ARMS_DEALING_AIR, // requires some flag to be set + BRICKADE_6X6 +}; + +enum class ePlayerStateFlags +{ + kScreenFadingOut = 0, + kScreenFadedOut = 1, + kCinematicNewsChannelActive = 2, + kRepeatingPreviousCheckpoint = 3, + kCarModIntro = 4, + kPlayerSwitchStateAscent = 5, + kPlayerSwitchStateInClouds = 6, + kPlayerSwitchStatePan = 7, + kPlayerSwitchStateDescent = 8, + kModshopActive = 9, + kModshopExitingVehicle = 10, + kSpectating = 28, + kBeastActive = 29, + kPlayerNotInSCTV = 30, + kPlayerInSCTV = 31 +}; + +enum class eActivityFlags +{ + kWatchingMovie = 0, + kInGangAttack = 1, + kImpromptuRace = 2, + kCrateDrop = 4, // tf is this? "~s~A plane is on its way to drop a Crate ~HUD_COLOUR_GREEN~~BLIP_CRATEDROP~ ~s~which contains useful equipment. Be the first to collect it." + kDeliveringSimeonVehicle = 6, + kInLapDance = 7, + kHoldUpTutorial = 8, + kJoyrider = 9, // uh what is this? + kCarModTutorial = 10, + kMissionLauncher = 11, // ??? + kLesterCutsceneActive = 12, + kTrevorCutsceneActive = 13, + kHeistIntro = 14, + kPlaneTakedown = 15, // not sure what this is + kDistractCops = 16, // "Great. Thank you for your help. Now some horrible criminals are in jail for a crime they did commit and it's all your fault!!" ??? + kDestroyVehicle = 17, // ??? + kPartakingInHotTarget = 18, + kPartakingInKillList = 19, + kTimeTrialStarted = 21, + kPartakingInCheckpoints = 22, + kPartakingInChallenge = 23, + kPennedInActive = 24, + kRCTimeTrialStarted = 25, + kPartakingInHotProperty = 27, + kPartakingInKingOfTheCastle = 29, + kPartakingInCriminalDamage = 30, + kLowriderIntro = 31 +}; + +enum class eGamerTagFlags +{ + kShowPackageCount = 13, + kFadeOutGamerTag = 17, + kGangCEO = 19, + kGangBiker = 20 +}; // TODO! + +enum class eOrbitalBitset +{ + kOrbitalCannonActive = 0, + kWatchingMovie = 1, // not a typo, the orbital cannon script needs to know if you are inside a movie theater for some strange reason + kCutsceneOrInterior = 2, + kTransactionPending = 3 +}; + +enum class eArcadeGameBitset +{ + kArcadeMachineActivated = 0, + kLoveMeterActivated = 1, + kLoveMeterAnimationGenderDecided = 2 +}; + +enum class eOutOfSightFlags +{ + kOutOfSightEnabled = 0, + kOutOfSightActive = 1, // this controls whether you appear on radar or not + kHelpDisplayed = 2, + kDamagedPlayerOutsideOrganization = 3 +}; + +enum class eSimpleInteriorIndex +{ + SIMPLE_INTERIOR_INVALID = -1, + SIMPLE_INTERIOR_WAREHOUSE_1, + SIMPLE_INTERIOR_WAREHOUSE_2, + SIMPLE_INTERIOR_WAREHOUSE_3, + SIMPLE_INTERIOR_WAREHOUSE_4, + SIMPLE_INTERIOR_WAREHOUSE_5, + SIMPLE_INTERIOR_WAREHOUSE_6, + SIMPLE_INTERIOR_WAREHOUSE_7, + SIMPLE_INTERIOR_WAREHOUSE_8, + SIMPLE_INTERIOR_WAREHOUSE_9, + SIMPLE_INTERIOR_WAREHOUSE_10, + SIMPLE_INTERIOR_WAREHOUSE_11, + SIMPLE_INTERIOR_WAREHOUSE_12, + SIMPLE_INTERIOR_WAREHOUSE_13, + SIMPLE_INTERIOR_WAREHOUSE_14, + SIMPLE_INTERIOR_WAREHOUSE_15, + SIMPLE_INTERIOR_WAREHOUSE_16, + SIMPLE_INTERIOR_WAREHOUSE_17, + SIMPLE_INTERIOR_WAREHOUSE_18, + SIMPLE_INTERIOR_WAREHOUSE_19, + SIMPLE_INTERIOR_WAREHOUSE_20, + SIMPLE_INTERIOR_WAREHOUSE_21, + SIMPLE_INTERIOR_WAREHOUSE_22, + SIMPLE_INTERIOR_FACTORY_METH_1, + SIMPLE_INTERIOR_FACTORY_WEED_1, + SIMPLE_INTERIOR_FACTORY_CRACK_1, + SIMPLE_INTERIOR_FACTORY_MONEY_1, + SIMPLE_INTERIOR_FACTORY_DOCUMENTS_1, + SIMPLE_INTERIOR_FACTORY_METH_2, + SIMPLE_INTERIOR_FACTORY_WEED_2, + SIMPLE_INTERIOR_FACTORY_CRACK_2, + SIMPLE_INTERIOR_FACTORY_MONEY_2, + SIMPLE_INTERIOR_FACTORY_DOCUMENTS_2, + SIMPLE_INTERIOR_FACTORY_METH_3, + SIMPLE_INTERIOR_FACTORY_WEED_3, + SIMPLE_INTERIOR_FACTORY_CRACK_3, + SIMPLE_INTERIOR_FACTORY_MONEY_3, + SIMPLE_INTERIOR_FACTORY_DOCUMENTS_3, + SIMPLE_INTERIOR_FACTORY_METH_4, + SIMPLE_INTERIOR_FACTORY_WEED_4, + SIMPLE_INTERIOR_FACTORY_CRACK_4, + SIMPLE_INTERIOR_FACTORY_MONEY_4, + SIMPLE_INTERIOR_FACTORY_DOCUMENTS_4, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_POLICE_STATION, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_MC_CLUBHOUSE, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_BANK_ROCKFORD, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_BANK_PILLBOX, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_BANK_ALTA, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_BANK_BURTON, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_BANK_PALETO, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_BANK_GRAND_SENORA, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_BANK_CHUMASH, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_ROCKCLUB, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_CHICKEN_FACTORY, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_CHICKEN_FACTORY_PART_2, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_CHICKEN_FACTORY_PART_3, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_CHICKEN_FACTORY_PART_4, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_FARMHOUSE, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_HEIST_YACHT, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_RECYCLING_PLANT, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_BIOLAB, + SIMPLE_INTERIOR_IE_WAREHOUSE_1, + SIMPLE_INTERIOR_IE_WAREHOUSE_2, + SIMPLE_INTERIOR_IE_WAREHOUSE_3, + SIMPLE_INTERIOR_IE_WAREHOUSE_4, + SIMPLE_INTERIOR_IE_WAREHOUSE_5, + SIMPLE_INTERIOR_IE_WAREHOUSE_6, + SIMPLE_INTERIOR_IE_WAREHOUSE_7, + SIMPLE_INTERIOR_IE_WAREHOUSE_8, + SIMPLE_INTERIOR_IE_WAREHOUSE_9, + SIMPLE_INTERIOR_IE_WAREHOUSE_10, + SIMPLE_INTERIOR_BUNKER_1, + SIMPLE_INTERIOR_BUNKER_2, + SIMPLE_INTERIOR_BUNKER_3, + SIMPLE_INTERIOR_BUNKER_4, + SIMPLE_INTERIOR_BUNKER_5, + SIMPLE_INTERIOR_BUNKER_6, + SIMPLE_INTERIOR_BUNKER_7, + SIMPLE_INTERIOR_BUNKER_9, + SIMPLE_INTERIOR_BUNKER_10, + SIMPLE_INTERIOR_BUNKER_11, + SIMPLE_INTERIOR_BUNKER_12, + SIMPLE_INTERIOR_ARMORY_TRUCK_1, + SIMPLE_INTERIOR_CREATOR_TRAILER_1, + SIMPLE_INTERIOR_HANGAR_1, + SIMPLE_INTERIOR_HANGAR_2, + SIMPLE_INTERIOR_HANGAR_3, + SIMPLE_INTERIOR_HANGAR_4, + SIMPLE_INTERIOR_HANGAR_5, + SIMPLE_INTERIOR_ARMORY_AIRCRAFT_1, + SIMPLE_INTERIOR_DEFUNCT_BASE_1, + SIMPLE_INTERIOR_DEFUNCT_BASE_2, + SIMPLE_INTERIOR_DEFUNCT_BASE_3, + SIMPLE_INTERIOR_DEFUNCT_BASE_4, + SIMPLE_INTERIOR_DEFUNCT_BASE_6, + SIMPLE_INTERIOR_DEFUNCT_BASE_7, + SIMPLE_INTERIOR_DEFUNCT_BASE_8, + SIMPLE_INTERIOR_DEFUNCT_BASE_9, + SIMPLE_INTERIOR_DEFUNCT_BASE_10, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_MEDIUM_GARAGE, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_LOWEND_STUDIO, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_MIDEND_APARTMENT, + SIMPLE_INTERIOR_CREATOR_AIRCRAFT_1, + SIMPLE_INTERIOR_HUB_LA_MESA, + SIMPLE_INTERIOR_HUB_MISSION_ROW, + SIMPLE_INTERIOR_HUB_STRAWBERRY_WAREHOUSE, + SIMPLE_INTERIOR_HUB_WEST_VINEWOOD, + SIMPLE_INTERIOR_HUB_CYPRESS_FLATS, + SIMPLE_INTERIOR_HUB_LSIA_WAREHOUSE, + SIMPLE_INTERIOR_HUB_ELYSIAN_ISLAND, + SIMPLE_INTERIOR_HUB_DOWNTOWN_VINEWOOD, + SIMPLE_INTERIOR_HUB_DEL_PERRO_BUILDING, + SIMPLE_INTERIOR_HUB_VESPUCCI_CANALS, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_SHERIFF, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_SHERIFF2, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_UNION_DEPOSITORY_CARPARK, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_SIMEON_SHOWROOM, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_ABATTOIR, + SIMPLE_INTERIOR_HACKER_TRUCK, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_JEWEL_STORE, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_LIFE_INVADER, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_DJ_YACHT, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_MELANOMA_GARAGE, + SIMPLE_INTERIOR_ARENA_GARAGE_1, + SIMPLE_INTERIOR_CASINO, + SIMPLE_INTERIOR_CASINO_APT, + SIMPLE_INTERIOR_CASINO_VAL_GARAGE, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_HAYES_AUTOS, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_METH_LAB, + SIMPLE_INTERIOR_ARCADE_PALETO_BAY, + SIMPLE_INTERIOR_ARCADE_GRAPESEED, + SIMPLE_INTERIOR_ARCADE_DAVIS, + SIMPLE_INTERIOR_ARCADE_WEST_VINEWOOD, + SIMPLE_INTERIOR_ARCADE_ROCKFORD_HILLS, + SIMPLE_INTERIOR_ARCADE_LA_MESA, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_FIB_BUILDING, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_BIOLAB_AND_TUNNEL, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_FOUNDRY, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_MAX_RENDA, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_AIRCRAFT_CARRIER, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_AIRCRAFT_CARRIER_PART_2, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_AIRCRAFT_CARRIER_PART_3, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_AIRCRAFT_CARRIER_PART_4, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_AIRCRAFT_CARRIER_PART_5, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_AIRCRAFT_CARRIER_PART_6, + SIMPLE_INTERIOR_RESTRICTED_INTERIOR_OMEGA, + SIMPLE_INTERIOR_SOLOMONS_OFFICE, + SIMPLE_INTERIOR_CASINO_NIGHTCLUB, + SIMPLE_INTERIOR_SUBMARINE, + SIMPLE_INTERIOR_MUSIC_STUDIO, + SIMPLE_INTERIOR_AUTO_SHOP_LA_MESA, + SIMPLE_INTERIOR_AUTO_SHOP_STRAWBERRY, + SIMPLE_INTERIOR_AUTO_SHOP_BURTON, + SIMPLE_INTERIOR_AUTO_SHOP_RANCHO, + SIMPLE_INTERIOR_AUTO_SHOP_MISSION_ROW, + SIMPLE_INTERIOR_CAR_MEET, + SIMPLE_INTERIOR_FIXER_HQ_HAWICK, + SIMPLE_INTERIOR_FIXER_HQ_ROCKFORD, + SIMPLE_INTERIOR_FIXER_HQ_SEOUL, + SIMPLE_INTERIOR_FIXER_HQ_VESPUCCI, + SIMPLE_INTERIOR_ACID_LAB, + SIMPLE_INTERIOR_JUGGALO_HIDEOUT, + SIMPLE_INTERIOR_MULTISTOREY_GARAGE, + SIMPLE_INTERIOR_SALVAGE_YARD_LA_PUERTA, + SIMPLE_INTERIOR_SALVAGE_YARD_MURIETTA_HEIGHTS, + SIMPLE_INTERIOR_SALVAGE_YARD_PALETO_BAY, + SIMPLE_INTERIOR_SALVAGE_YARD_SANDY_SHORES, + SIMPLE_INTERIOR_SALVAGE_YARD_STRAWBERRY, +}; + +struct JOB_STATS +{ + SCR_INT Wins; + SCR_INT Losses; + SCR_INT Kills; + SCR_INT Deaths; + SCR_INT PAD_0004; // unused +}; + +struct JOB_BET +{ + SCR_INT PAD_0000; // TODO + SCR_INT Amount; +}; + +struct MISSION_BETS +{ + SCR_INT Identifier; // a random integer between 100 and 10000000 + JOB_STATS Stats; + SCR_ARRAY PlacedBets; + SCR_BOOL CancelBetting; +}; +static_assert(sizeof(MISSION_BETS) == 72 * 8); + +struct PLAYER_BLIP +{ + SCR_INT PAD_0000; + SCR_INT NumPassengersInVehicle; + SCR_BITSET BlipFlags; + alignas(8) eBlipType PlayerVehicleBlipType; // can be used to spoof your blip as a tank, oppressor etc + SCR_INT IdleDurationUntilBlipIsVisible; + SCR_INT BlipVisibleDuration; + SCR_INT MissionInteriorIndex; // can be used to spoof blip position + SCR_VEC3 MissionInteriorBlipLocation; + SCR_FLOAT MissionInteriorBlipRotation; + SCR_BOOL UnknownOverride; // can also be used to spoof position + SCR_VEC3 UnknownOverridePosition; +}; +static_assert(sizeof(PLAYER_BLIP) == 15 * 8); + +struct YACHT_APPEARANCE +{ + SCR_INT PAD_0000; // TODO + SCR_INT PAD_0001; + SCR_INT PAD_0002; + SCR_INT PAD_0003; + SCR_INT PAD_0004; + TEXT_LABEL_63 Name; + SCR_HASH NameHash; +}; +static_assert(sizeof(YACHT_APPEARANCE) == 22 * 8); + +struct YACHT_DATA +{ + SCR_BOOL HasYacht; + SCR_VEC3 Position; + SCR_INT TravelStage; + SCR_BOOL TravelInProgress; + SCR_ARRAY VehicleNetIds; // the heli and the boats that spawn near the yacht + SCR_INT YachtIndexPlayerIsIn; // owned or unowned + SCR_INT UnkYachtIndex; // TODO + SCR_INT YachtIndexPlayerIsInCouldBeDriving; + SCR_ARRAY NearbyYachts; + SCR_INT ClosestYachtIndex; + SCR_INT TurbulenceState; // controls random camera shakes when on a yacht + SCR_INT DefenseSetting; + YACHT_APPEARANCE Appearance; + SCR_BOOL RemoveClothingWhileInHotTub; + SCR_HASH MissionYachtOwnerHandleHash; // always -1 or NETWORK::NETWORK_HASH_FROM_PLAYER_HANDLE(PLAYER::PLAYER_ID()) + SCR_BOOL SpawnAccess; // "spawn access"? + SCR_INT MissionYachtIndex; +}; +static_assert(sizeof(YACHT_DATA) == 49 * 8); + +struct SMPL_INTERIOR_DATA +{ + SCR_INT Flags; // TODO!!! + SCR_INT Flags2; + SCR_INT Flags3; + SCR_INT Flags4; + SCR_INT Flags5; + SCR_INT Flags6; + SCR_INT Flags7; + alignas(8) eSimpleInteriorIndex Index; + SCR_INT InstanceId; + SCR_INT AllowedGoons; + PLAYER_INDEX Owner; + PLAYER_INDEX VehicleOwner; + SCR_VEC3 SpecialVehicleSpawnPosition; + SCR_FLOAT SpecialVehicleSpawnHeading; + SCR_INT EnteringSimpleInteriorIndex; + SCR_INT SpecialVehicleSimpleInteriorIndex; // MOC, Terrorbyte etc + alignas(8) eSimpleInteriorIndex UnkSimpleInteriorIndex; + alignas(8) eSimpleInteriorIndex UnkSimpleInteriorIndex2; + SCR_VEC3 AvengerPosition; + SCR_VEC3 AvengerPosition2; // not sure how this is different from the field above + SCR_FLOAT AvengerHeading; + SCR_INT MissionSpawnSimpleInteriorIndex; + SCR_INT InteriorSubtype; // nightclub vs nightclub garage etc +}; +static_assert(sizeof(SMPL_INTERIOR_DATA) == 29 * 8); + +// yes there's a struct for leaving your clubhouse +struct LEAVE_CLUBHOUSE +{ + SCR_BOOL Active; + SCR_BOOL Active2; + SCR_INT Identifier; + SCR_INT ExitLocation; + SCR_ARRAY ParticipantHashes; +}; +static_assert(sizeof(LEAVE_CLUBHOUSE) == 37 * 8); + +struct ARCADE_GAME +{ + SCR_BITSET Bits; + SCR_INT CabinetIndex; + SCR_INT PAD_0002; // The only valid value is 0 so idk + SCR_INT CabinetGame; // TODO + SCR_INT GameStage; +}; +static_assert(sizeof(ARCADE_GAME) == 5 * 8); + +struct GlobalPlayerBDEntry +{ + alignas(8) eFreemodeState FreemodeState; + MP_SCRIPT_DATA CurrentScript; + uint64_t PAD_0022[11]; // unused + SCR_INT PlayersVisible; + SCR_INT PlayersTracked; + SCR_BITSET AnimationBitset; + SCR_INT NumSuccessfulHoldups; // resets every 12 minutes + SCR_INT PAD_0037; + NETWORK_INDEX PersonalVehicleNetId; + NETWORK_INDEX UnkVehicleNetId; + NETWORK_INDEX UnkVehicleNetId2; + SCR_ARRAY UnkVehicleNetIds; + NETWORK_INDEX DeliveryMechanicNetId; + NETWORK_INDEX DeliveryMechanicNetId2; + SCR_INT SpawningVehicleLiveryIndex; + SCR_INT SpawningVehiclePrimaryColor; + SCR_INT SpawningVehicleSecondaryColor; + NETWORK_INDEX AvengerNetId; + NETWORK_INDEX DeliveryMechanicNetId3; // wtf is this? + NETWORK_INDEX TerrorbyteNetId; // or is it the MOC? + NETWORK_INDEX SubmarineNetId; + NETWORK_INDEX DinghyNetId; + NETWORK_INDEX DeliveryMechanicNetId4; // another one... + NETWORK_INDEX AcidLabNetId; + NETWORK_INDEX DeliveryBikeNetId; + SCR_BOOL PAD_0057; + uint64_t PAD_0058[15]; // confirmed these are not used by PC scripts + PLAYER_BLIP PlayerBlip; + SCR_BOOL NeedToPopulateSessionStartTime; // the session start time is unused + uint64_t PAD_0089[32]; // TODO + alignas(8) eMissionType MissionType; + SCR_BOOL SpawningVehicle; + uint64_t PAD_0123[3]; // confirmed these are not used by PC scripts + MISSION_BETS MissionBets; + SCR_BOOL RadarBlipVisibliltyMechanicEnabled; + SCR_BITSET PlayerStateFlags; + SCR_INT PlayerStateFlags2; // TODO + SCR_INT PlayerStateFlags3; // TODO + SCR_INT CarMeetModShopSlotPreTakeover; + PLAYER_INDEX CurrentCarMeetSlotOwnerIndex; // can be player or player's CEO/MC leader + SCR_INT CarMeetModShopSlotPostTakeover; + SCR_HASH CarMeetModdingVehicleModel; + PLAYER_INDEX CarMeetCurrentlySeatedVehicleOwner; + SCR_VEC3 PlayerPosition; // updates every two seconds, used by spectate + SCR_BOOL OffRadarActive; + SCR_BOOL PassengerOfVehicleWithOffRadarDriver; + SCR_BOOL GoonOfBossWithOffRadar; + SCR_BOOL RevealPlayersActive; + PLAYER_INDEX RemoteWantedLevelPlayer; // cut content but still works + SCR_INT RemoteWantedLevelAmount; + PLAYER_INDEX RemoteWantedLevelRemovePlayer; // doesn't work at all + SCR_INT UnkTeleportStage; + SCR_BITSET ActivityFlags; + SCR_INT NumReservedMissionPeds; + SCR_INT NumReservedMissionVehicles; + SCR_INT NumReservedMissionObjects; + SCR_INT TransitionSessionState; // TODO reverse enum + SCR_VEC3 TransitionReturningPosition; // TODO + TEXT_LABEL_23 TransitionContentIDToLaunch; + SCR_INT RespawnState; + SCR_INT LastRespawnTime; + SCR_BOOL CollisionLoaded; + SCR_BOOL CommitingSuicide; + SCR_BOOL RespawningInVehicleAsDriver; + SCR_BOOL RespawningInVehicle; + SCR_BOOL PAD_0238; // this value is set but not read at all by any PC scripts + SCR_BITSET GamerTagFlags; + SCR_BOOL IsMale; + SCR_INT ArmwrestlingLocationFlags; + SCR_INT PAD_0242; // TODO + SCR_BOOL GamerTagShowArrow; + SCR_BOOL CarWashInProgress; + INTERIOR_INDEX CurrentInteriorIndex; + SCR_INT CurrentShopIndex; // things like clothing and tattoo stores + SCR_INT CurrentStoreIndex; // the stores in the map which can be held up + SCR_BOOL ShopActive; // any shop + SCR_BOOL InTaxi; + SCR_INT Haircut; // @250 as of 1.67 + SCR_INT PrimaryHairColor; + SCR_INT SecondaryHairColor; + SCR_INT FriendlyPlayers; // bitset of player team relgroups that obtain a Respect relationship with player + SCR_BOOL IsInvisible; + SCR_BOOL InImpromptuDeathmatch; + SCR_VEC3 ImpromptuDeatmatchStartPosition; + SCR_INT PAD_0569; // not read by scripts, impromptu DM related + SCR_INT MissionLoseAnimType; + SCR_INT MissionWinAnimType; // verify + SCR_INT MissionCrewAnimType; + SCR_INT RallyRaceAnim; + SCR_BOOL IsRallyRace; + SCR_BOOL JustGetsPulledOutWhenElectrocuted; + SCR_INT HeistCutSelectionStage; // the only valid values seem to be 6 and 7 + SCR_BOOL IsBadsport; + SCR_FLOAT MentalState; + SCR_BOOL IsRockstarDev; // dev dlc check and not the CNetGamePlayer flag so can be used to detect YimMenu + SCR_BOOL ScreenFadedOut; + SCR_BOOL TimeTrialActive; + YACHT_DATA YachtData; + SMPL_INTERIOR_DATA SimpleInteriorData; + SCR_BOOL PAD_0350; // TODO + SCR_INT PAD_0351; // unused vehicle/interior stuff + SCR_INT BlipShownBitset; + LEAVE_CLUBHOUSE LeaveClubhouse; // @353 as of 1.67 + SCR_INT Friends; // bitset of players that are friends + SCR_VEC3 InteriorVehiclePosition; // for terrorbyte and MOC, used to fake player blip position on map + SCR_FLOAT InteriorVehicleHeading; + SCR_VEC3 AcidLabPosition; // not read by the scripts + SCR_FLOAT AcidLabHeading; + SCR_INT VehicleTurretsActive; // bitset + SCR_ARRAY VehicleTurretsCameraPosition; // 3->4 in 1.67 + SCR_INT PAD_0416; // TODO + SCR_BOOL DozerDetected; // very shady stuff, anticheat? @414 as of 1.67 + SCR_ARRAY MissionTurretParticipants; + SCR_INT PAD_0425; // some seat index + SCR_INT MissionTurretSlot; + SCR_BITSET OrbitalBitset; + SCR_BOOL FacilityIntroCutsceneInProgress; + SCR_BOOL FacilityIntroCutsceneStarted; // like above but is enabled 2 stages earlier + SCR_BOOL PAD_0430; // todo + SCR_BOOL BeingSolicitedByProstitute; // why tf is this used by the orbital cannon? + SCR_VEC3 DronePosition; // updates every second + SCR_FLOAT DroneHeading; // @432 as of 1.67 + SCR_INT OrbitalBitset2; // ugh + SCR_INT CurrentlyUsingArenaTrapIndex; + SCR_INT CurrentlyUsingArenaTrapActivatedTime; + ARCADE_GAME ArcadeGame; + SCR_INT DancePartner; + SCR_INT CayoPericoFlags; + SCR_INT BeachPartyFlags; + uint64_t PAD_0477[10]; // I don't think we'll ever be able to figure out what this does + SCR_INT ThreeCardPokerStyle; + SCR_INT BlackjackStyle; + SCR_BITSET OutOfSightFlags; + SCR_VEC3 OutOfSightArea; + SCR_INT AmmunationWeaponPartFlags; + PLAYER_INDEX LastKilledBy; // @461 as of 1.67 + SCR_BOOL CanSpawnGunVan; +}; + +static_assert(sizeof(GlobalPlayerBDEntry) == 463 * 8); + +struct GlobalPlayerBD +{ + SCR_ARRAY Entries; +}; +static_assert(sizeof(GlobalPlayerBD) == 14817 * 8); \ No newline at end of file diff --git a/classes/src/script/globals/g_AMC_playerBD.hpp b/classes/src/script/globals/g_AMC_playerBD.hpp new file mode 100644 index 0000000000..4733f50181 --- /dev/null +++ b/classes/src/script/globals/g_AMC_playerBD.hpp @@ -0,0 +1,16 @@ +#pragma once +#include "../types.hpp" +#include "../Timer.hpp" + +struct g_AMC_playerBD_Entry +{ + SCR_ARRAY UsedContactServicesTimer; // only index 2 (mugger) is actually used by the scripts. the rest is just a waste of bandwidth + SCR_ARRAY ContactServiceCooldowns; // same as above +}; +static_assert(sizeof(g_AMC_playerBD_Entry) == 242 * 8); + +struct g_AMC_playerBD +{ + SCR_ARRAY Entries; +}; +static_assert(sizeof(g_AMC_playerBD) == 7745 * 8); \ No newline at end of file diff --git a/classes/src/script/scrNativeHandler.hpp b/classes/src/script/scrNativeHandler.hpp new file mode 100644 index 0000000000..cfda78803b --- /dev/null +++ b/classes/src/script/scrNativeHandler.hpp @@ -0,0 +1,61 @@ +#pragma once +#include +#include +#include + +namespace rage +{ + class scrNativeCallContext + { + public: + constexpr void reset() + { + m_arg_count = 0; + m_data_count = 0; + } + + template + constexpr void push_arg(T&& value) + { + static_assert(sizeof(T) <= sizeof(std::uint64_t)); + *reinterpret_cast>*>(reinterpret_cast(m_args) + (m_arg_count++)) = std::forward(value); + } + + template + constexpr T& get_arg(std::size_t index) + { + static_assert(sizeof(T) <= sizeof(std::uint64_t)); + return *reinterpret_cast(reinterpret_cast(m_args) + index); + } + + template + constexpr void set_arg(std::size_t index, T&& value) + { + static_assert(sizeof(T) <= sizeof(std::uint64_t)); + *reinterpret_cast>*>(reinterpret_cast(m_args) + index) = std::forward(value); + } + + template + constexpr T* get_return_value() + { + return reinterpret_cast(m_return_value); + } + + template + constexpr void set_return_value(T&& value) + { + *reinterpret_cast>*>(m_return_value) = std::forward(value); + } + + void* m_return_value; + std::uint32_t m_arg_count; + void* m_args; + std::int32_t m_data_count; + std::uint32_t m_data[48]; + }; + static_assert(sizeof(scrNativeCallContext) == 0xE0); + + using scrNativeHash = std::uint64_t; + using scrNativePair = std::pair; + using scrNativeHandler = void(*)(scrNativeCallContext*); +} diff --git a/classes/src/script/scrNativeRegistration.hpp b/classes/src/script/scrNativeRegistration.hpp new file mode 100644 index 0000000000..71a9737e28 --- /dev/null +++ b/classes/src/script/scrNativeRegistration.hpp @@ -0,0 +1,43 @@ +#pragma once +#include + +namespace rage +{ + class scrNativeRegistration + { + public: + uint64_t m_next_registration1; + uint64_t m_next_registration2; + void* m_handlers[7]; + uint32_t m_num_entries1; + uint32_t m_num_entries2; + uint64_t m_hashes; + scrNativeRegistration* get_next_registration() { + std::uintptr_t result; + auto nextReg = uintptr_t(&m_next_registration1); + auto newReg = nextReg ^ m_next_registration2; + auto charTableOfRegs = (char*)&result - nextReg; + for (auto i = 0; i < 3; i++) { + *(std::uint32_t*)&charTableOfRegs[nextReg] = static_cast(newReg) ^ *(std::uint32_t*)nextReg; + nextReg += 4; + } + return reinterpret_cast(result); + } + + std::uint32_t get_num_entries() { + return static_cast(((std::uintptr_t)&m_num_entries1) ^ m_num_entries1 ^ m_num_entries2); + } + + std::uint64_t get_hash(std::uint32_t index) { + auto nativeAddress = 16 * index + std::uintptr_t(&m_next_registration1) + 0x54; + std::uint64_t result; + auto charTableOfRegs = (char*)&result - nativeAddress; + auto addressIndex = nativeAddress ^ *(std::uint32_t*)(nativeAddress + 8); + for (auto i = 0; i < 3; i++) { + *(std::uint32_t*)&charTableOfRegs[nativeAddress] = static_cast(addressIndex ^ *(std::uint32_t*)(nativeAddress)); + nativeAddress += 4; + } + return result; + } + }; +} \ No newline at end of file diff --git a/classes/src/script/scrNativeRegistrationTable.hpp b/classes/src/script/scrNativeRegistrationTable.hpp new file mode 100644 index 0000000000..56b87d70d7 --- /dev/null +++ b/classes/src/script/scrNativeRegistrationTable.hpp @@ -0,0 +1,17 @@ +#pragma once +#include + +#include "scrNativeRegistration.hpp" + +#pragma pack(push, 1) +namespace rage +{ + class scrNativeRegistrationTable + { + public: + scrNativeRegistration *m_entries[0xFF]; + std::uint32_t m_unk; + bool m_initialized; + }; +} +#pragma pack(pop) diff --git a/classes/src/script/scrProgram.hpp b/classes/src/script/scrProgram.hpp new file mode 100644 index 0000000000..592ec213c6 --- /dev/null +++ b/classes/src/script/scrProgram.hpp @@ -0,0 +1,104 @@ +#pragma once +#include + +#include "../base/pgBase.hpp" +#include "../rage/scrValue.hpp" +#include "scrNativeHandler.hpp" + +#pragma pack(push, 1) +namespace rage +{ + class scrProgram : public pgBase + { + public: + std::uint8_t** m_code_blocks; // 0x10 + std::uint32_t m_hash; // 0x18 + std::uint32_t m_code_size; // 0x1C + std::uint32_t m_arg_count; // 0x20 + std::uint32_t m_local_count; // 0x24 + std::uint32_t m_global_count; // 0x28 + std::uint32_t m_native_count; // 0x2C + scrValue *m_local_data; // 0x30 + scrValue **m_global_data; // 0x38 + scrNativeHandler *m_native_entrypoints; // 0x40 + std::uint32_t m_proc_count; // 0x48 + char pad_004C[4]; // 0x4C + const char** m_proc_names; // 0x50 + std::uint32_t m_name_hash; // 0x58 + std::uint32_t m_ref_count; // 0x5C + const char* m_name; // 0x60 + const char** m_strings_data; // 0x68 + std::uint32_t m_strings_count; // 0x70 + char m_breakpoints[0x0C]; // 0x74 This is an atMap, which we don't have the class for ATM. + + bool is_valid() const + { + return m_code_size != 0; + } + + std::uint32_t get_num_code_pages() const + { + return (m_code_size + 0x3FFF) >> 14; + } + + std::uint32_t get_code_page_size(std::uint32_t page) const + { + auto num = get_num_code_pages(); + if (page < num) + { + if (page == num - 1) + return m_code_size & 0x3FFF; + return 0x4000; + } + + return 0; + } + + std::uint32_t get_full_code_size() const + { + auto numPages = get_num_code_pages(); + if (!numPages) + return 0; + if (numPages == 1) + --numPages; + + return (numPages * 0x4000) + (m_code_size & 0x3FFF); + } + + std::uint8_t* get_code_page(std::uint32_t page) const + { + return m_code_blocks[page]; + } + + std::uint8_t* get_code_address(std::uint32_t index) const + { + if (index < m_code_size) + return &m_code_blocks[index >> 14][index & 0x3FFF]; + + return nullptr; + } + + const char* get_string(std::uint32_t index) const + { + if (index < m_strings_count) + return &m_strings_data[index >> 14][index & 0x3FFF]; + + return nullptr; + } + + scrNativeHandler* get_address_of_native_entrypoint(scrNativeHandler entrypoint) + { + for (std::uint32_t i = 0; i < m_native_count; ++i) + { + if (m_native_entrypoints[i] == entrypoint) + { + return m_native_entrypoints + i; + } + } + + return nullptr; + } + }; + static_assert(sizeof(scrProgram) == 0x80); +} +#pragma pack(pop) diff --git a/classes/src/script/scrProgramTable.hpp b/classes/src/script/scrProgramTable.hpp new file mode 100644 index 0000000000..21e2b3f1e2 --- /dev/null +++ b/classes/src/script/scrProgramTable.hpp @@ -0,0 +1,39 @@ +#pragma once +#include "scrProgramTableEntry.hpp" + +#pragma pack(push, 1) +namespace rage +{ + class scrProgramTable + { + public: + scrProgramTableEntry* m_data; // 0x00 + char m_padding[0x10]; // 0x08 + std::uint32_t m_size; // 0x18 + + scrProgram* find_script(joaat_t hash) + { + for (std::uint32_t i = 0; i < m_size; ++i) + { + if (m_data[i].m_hash == hash) + { + return m_data[i].m_program; + } + } + + return nullptr; + } + + scrProgramTableEntry* begin() + { + return m_data; + } + + scrProgramTableEntry* end() + { + return m_data + m_size; + } + }; + static_assert(sizeof(scrProgramTable) == 0x1C); +} +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/script/scrProgramTableEntry.hpp b/classes/src/script/scrProgramTableEntry.hpp new file mode 100644 index 0000000000..e43df2e510 --- /dev/null +++ b/classes/src/script/scrProgramTableEntry.hpp @@ -0,0 +1,17 @@ +#pragma once +#include "scrProgram.hpp" +#include "../rage/joaat.hpp" + +#pragma pack(push, 1) +namespace rage +{ + class scrProgramTableEntry + { + public: + scrProgram* m_program; // 0x00 + char m_Pad1[0x04]; // 0x08 + joaat_t m_hash; // 0x0C + }; + static_assert(sizeof(scrProgramTableEntry) == 0x10); +} +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/script/scrThread.hpp b/classes/src/script/scrThread.hpp new file mode 100644 index 0000000000..9074191865 --- /dev/null +++ b/classes/src/script/scrThread.hpp @@ -0,0 +1,31 @@ +#pragma once +#include "scriptHandler.hpp" +#include "scriptHandlerNetComponent.hpp" +#include "scrThreadContext.hpp" +#include "../rage/scrValue.hpp" + +namespace rage +{ + class scrThread + { + public: + virtual ~scrThread() = default; // 0 (0x00) + virtual void reset(std::uint32_t script_hash, void* args, std::uint32_t arg_count) = 0; // 1 (0x08) + virtual eThreadState run() = 0; // 2 (0x10) + virtual eThreadState tick(std::uint32_t ops_to_execute) = 0; // 3 (0x18) + virtual void kill() = 0; + + public: + scrThreadContext m_context; // 0x08 + scrValue* m_stack; // 0xB0 + char m_padding[0x4]; // 0xB8 + uint32_t m_arg_size; // 0xBC + uint32_t m_arg_loc; // 0xC0 + char m_padding2[0x4]; // 0xC4 + const char* m_exit_message; // 0xC8 + char m_pad[0x4]; // 0xD0 + char m_name[0x40]; // 0xD4 + scriptHandler* m_handler; // 0x118 + scriptHandlerNetComponent* m_net_component; // 0x120 + }; +} diff --git a/classes/src/script/scrThreadContext.hpp b/classes/src/script/scrThreadContext.hpp new file mode 100644 index 0000000000..e47aed56cb --- /dev/null +++ b/classes/src/script/scrThreadContext.hpp @@ -0,0 +1,34 @@ +#pragma once +#include + +#include "../rage/joaat.hpp" + +namespace rage +{ + enum class eThreadState : std::uint32_t + { + idle, + running, + killed, + unk_3, + unk_4, + }; + + class scrThreadContext + { + public: + std::uint32_t m_thread_id; // 0x00 + joaat_t m_script_hash; // 0x04 + eThreadState m_state; // 0x08 + std::uint32_t m_instruction_pointer; // 0x0C + std::uint32_t m_frame_pointer; // 0x10 + std::uint32_t m_stack_pointer; // 0x14 + float m_timer_a; // 0x18 + float m_timer_b; // 0x1C + float m_wait_timer; // 0x20 + char m_padding1[0x2C]; // 0x24 + std::uint32_t m_stack_size; // 0x50 + char m_padding2[0x54]; // 0x54 + }; + static_assert(sizeof(scrThreadContext) == 0xA8); +} \ No newline at end of file diff --git a/classes/src/script/scrVector.hpp b/classes/src/script/scrVector.hpp new file mode 100644 index 0000000000..6aabff7d6c --- /dev/null +++ b/classes/src/script/scrVector.hpp @@ -0,0 +1,119 @@ +#pragma once +#include "../rage/vector.hpp" +#include +#include +#include + +namespace rage +{ + class scrVector + { + public: + scrVector() = default; + + scrVector(rage::fvector3 vec) : + x(vec.x), y(vec.y), z(vec.z) + { + } + + scrVector(float x, float y, float z) : + x(x), y(y), z(z) + { + } + + scrVector operator+(const scrVector& other) + { + scrVector vec; + vec.x = this->x + other.x; + vec.y = this->y + other.y; + vec.z = this->z + other.z; + return vec; + } + + scrVector operator-(const scrVector& other) + { + scrVector vec; + vec.x = this->x - other.x; + vec.y = this->y - other.y; + vec.z = this->z - other.z; + return vec; + } + + scrVector operator*(const scrVector& other) + { + scrVector vec; + vec.x = this->x * other.x; + vec.y = this->y * other.y; + vec.z = this->z * other.z; + return vec; + } + + scrVector operator*(const float& other) + { + scrVector vec; + vec.x = this->x * other; + vec.y = this->y * other; + vec.z = this->z * other; + return vec; + } + + bool operator==(const scrVector& other) + { + return this->x == other.x && this->y == other.y && this->z == other.z; + } + + bool operator!=(const scrVector& other) + { + return this->x != other.x || this->y != other.y || this->z != other.z; + } + + std::string to_string() const + { + std::stringstream ss; + ss << *this; + return ss.str(); + } + + friend std::ostream& operator<<(std::ostream& os, const scrVector& vec) + { + os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ")"; + return os; + } + + alignas(8) float x{}; + alignas(8) float y{}; + alignas(8) float z{}; + }; +} + +class Vector2 final +{ +public: + Vector2() = default; + + Vector2(float x, float y) + : x(x), y(y) + { + } + +public: + alignas(8) float x; + alignas(8) float y; +}; + +class Vector4 final +{ +public: + Vector4() = default; + + Vector4(float x, float y, float z, float w) + : x(x), y(y), z(z), w(w) + { + } + +public: + alignas(8) float x; + alignas(8) float y; + alignas(8) float z; + alignas(8) float w; +}; diff --git a/classes/src/script/scriptHandler.hpp b/classes/src/script/scriptHandler.hpp new file mode 100644 index 0000000000..5940c03b52 --- /dev/null +++ b/classes/src/script/scriptHandler.hpp @@ -0,0 +1,81 @@ +#pragma once +#include + +#include "dataList.hpp" +#include "scriptHandlerNetComponent.hpp" +#include "scriptId.hpp" +#include "scriptResource.hpp" +#include "scrThread.hpp" + +#pragma pack(push, 1) +namespace rage +{ + class scriptHandlerObject; + class scriptHandler + { + public: + class atDScriptObjectNode : public atDNode + { + }; + public: + virtual ~scriptHandler() = default; // 0 (0x00) + + virtual bool _0x08() = 0; // 1 (0x08) + + virtual void _0x10() = 0; // 2 (0x10) + + virtual void cleanup_objects() = 0; // 3 (0x18) + + virtual scriptId *_0x20() = 0; // 4 (0x20) + + virtual scriptId *get_id() = 0; // 5 (0x28) + + // Returns whether the script handler belongs to a networked script. + virtual bool is_networked() = 0; // 6 (0x30) + + // Initializes the network component for the script handler. + virtual void init_net_component() = 0; // 7 (0x38) + + // Deletes the script handler's network component, if it exists. + virtual void reset_net_component() = 0; // 8 (0x40) + + // Destroys the script handler. + virtual bool destroy() = 0; // 9 (0x48) + + // Adds the object to the script handler's list of objects. + virtual void add_object(scriptHandlerObject*, bool is_network, bool is_network_and_scriptcheck) = 0; // 10 (0x50) + + // Something related to reservations. + virtual void _0x58(void*) = 0; // 11 (0x58) + + virtual void register_resource(scriptResource*, void*) = 0; // 12 (0x60) + + virtual void _0x68() = 0; // 13 (0x68) + + virtual void _0x70() = 0; // 14 (0x70) + + virtual void _0x78() = 0; // 15 (0x78) + + virtual void _0x80() = 0; // 16 (0x80) + + virtual void _0x88() = 0; // 17 (0x88) + + virtual void _0x90() = 0; // 18 (0x90) + + virtual void _0x98() = 0; // 19 (0x98) + public: + void *m_0x08; // 0x08 + void *m_0x10; // 0x10 + scrThread *m_script_thread; // 0x18 + atDList m_objects; // 0x20 + scriptResource *m_resource_list_head; // 0x30 + scriptResource *m_resource_list_tail; // 0x38 + void *m_0x40; // 0x40 + scriptHandlerNetComponent *m_net_component; // 0x48 + std::uint32_t m_0x50; // 0x50 + std::uint32_t m_0x54; // 0x54 + std::uint32_t m_0x58; // 0x58 + std::uint32_t m_0x60; // 0x5C + }; +} +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/script/scriptHandlerMgr.hpp b/classes/src/script/scriptHandlerMgr.hpp new file mode 100644 index 0000000000..dce7f3506b --- /dev/null +++ b/classes/src/script/scriptHandlerMgr.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include "../network/netPlayer.hpp" +#include "scriptHandler.hpp" +#include "scrThread.hpp" + +#pragma pack(push, 1) +namespace rage +{ + class netLoggingInterface; + + class scriptHandlerMgr + { + public: + virtual ~scriptHandlerMgr() = default; + + // Initializes some scripting-related pools. + virtual bool initialize() = 0; // 1 (0x08) + + // Called every tick. + virtual void _0x10() = 0; // 2 (0x10) + + // Frees some scripting-related pools. + virtual void shutdown() = 0; // 3 (0x18) + + virtual void _0x20() = 0; // 4 (0x20) + virtual void _0x28() = 0; // 5 (0x28) + virtual void _0x30() = 0; // 6 (0x30) + + // Generates a rage::scriptId from the thread and copies it over to a global structure. + virtual void _0x38(scrThread*) = 0; // 7 (0x38) + + // Allocates and constructs a script handler. + virtual scriptHandler *create_script_handler() = 0; // 8 (0x40) + + // Finds the script handler for a given script id. + virtual scriptHandler *get_script_handler(scriptId*) = 0; // 9 (0x48) + + // Attaches a script thread. + virtual void attach_thread(scrThread*) = 0; // 10 (0x50) + + // Detaches a script thread. + virtual void detach_thread(scrThread*) = 0; // 11 (0x58) + + // Called when a player joins. + virtual void on_player_join(netPlayer*) = 0; // 12 (0x60) + + // Called when a player leaves. + virtual void on_player_left(netPlayer*) = 0; // 13 (0x68) + + virtual std::int32_t _0x70() = 0; // 14 (0x70) + virtual void *_0x78() = 0; // 15 (0x78) + public: + char m_padding1[0x28]; // 0x08 + bool m_initialized; // 0x30 + bool m_initialized2; // 0x31 + char m_padding2[0x0E]; // 0x32 + netLoggingInterface *m_logger; // 0x40 + }; +} +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/script/scriptHandlerNetComponent.hpp b/classes/src/script/scriptHandlerNetComponent.hpp new file mode 100644 index 0000000000..3f2d7bcad7 --- /dev/null +++ b/classes/src/script/scriptHandlerNetComponent.hpp @@ -0,0 +1,16 @@ +#pragma once + +#pragma pack(push, 1) +namespace rage +{ + class scriptHandler; + class scriptHandlerNetComponent + { + public: + virtual ~scriptHandlerNetComponent() = default; + + public: + scriptHandler *m_script_handler; // 0x08 + }; +} +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/script/scriptId.hpp b/classes/src/script/scriptId.hpp new file mode 100644 index 0000000000..4577bbfc2c --- /dev/null +++ b/classes/src/script/scriptId.hpp @@ -0,0 +1,26 @@ +#pragma once +#include "scriptIdBase.hpp" + +#pragma pack(push, 1) +namespace rage +{ + class scriptId : public scriptIdBase + { + public: + joaat_t m_hash; // 0x08 + char m_name[0x20]; // 0x0C + }; +} + +class CGameScriptId : public rage::scriptId +{ +public: + char m_padding[0x04]; // 0x2C + std::int32_t m_timestamp; // 0x30 + std::int32_t m_position_hash; // 0x34 + std::int32_t m_instance_id; // 0x38 + std::int32_t m_unk; // 0x3C +}; + +static_assert(sizeof(CGameScriptId) == 0x40); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/script/scriptIdBase.hpp b/classes/src/script/scriptIdBase.hpp new file mode 100644 index 0000000000..34a9083384 --- /dev/null +++ b/classes/src/script/scriptIdBase.hpp @@ -0,0 +1,57 @@ +#pragma once +#include + +#include "../rage/joaat.hpp" + +#pragma pack(push, 1) +namespace rage +{ + class datBitBuffer; + class netLoggingInterface; + class scrThread; + + class scriptIdBase + { + public: + virtual ~scriptIdBase() = default; // 0 (0x00) + + // Assumes the script thread's identity. + virtual void assume_thread_identity(scrThread*) {}; // 1 (0x08) + + // Returns whether the hash of the script id is valid. + virtual bool is_valid() { return false; }; // 2 (0x10) + + // Gets the hash of the script id. + virtual joaat_t* get_hash(joaat_t* out) { return 0; }; // 3 (0x18) + + // Gets an unknown value from the script id. + virtual std::uint32_t* get_hash2(std::uint32_t* out) { return 0; }; // 4 (0x20) + + // Gets the name of the script id. + virtual const char* get_name() { return nullptr; }; // 5 (0x28) + + // Serializes the script id from the buffer. + virtual void deserialize(datBitBuffer* buffer) {}; // 6 (0x30) + + // Serializes the script id to the buffer. + virtual void serialize(datBitBuffer* buffer) {}; // 7 (0x38) + + // Calculates some information with the position hash & instance id. + virtual std::uint32_t _0x40() { return 0; }; // 8 (0x40) + + // Calls _0x40 and returns it's value added to another value. + virtual std::uint32_t _0x48() { return 0; }; // 9 (0x48) + + // Logs some information about the script id. + virtual void log_information(netLoggingInterface* logger) {}; // 10 (0x50) + + // Copies the information of other to this object. + virtual void copy_data(scriptIdBase* other) {} // 11 (0x58) + + // Returns whether the other script id is equal. + virtual bool operator==(scriptIdBase*) { return false; }; // 12 (0x60) + + virtual bool _0x68(void*) { return false; }; // 13 (0x68) + }; +} +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/script/scriptResource.hpp b/classes/src/script/scriptResource.hpp new file mode 100644 index 0000000000..9379d6e396 --- /dev/null +++ b/classes/src/script/scriptResource.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace rage +{ + class scriptResource + { + public: + virtual ~scriptResource() = default; + }; +} \ No newline at end of file diff --git a/classes/src/script/tlsContext.hpp b/classes/src/script/tlsContext.hpp new file mode 100644 index 0000000000..1a774f02c8 --- /dev/null +++ b/classes/src/script/tlsContext.hpp @@ -0,0 +1,38 @@ +#pragma once +#include "../rage/sysMemAllocator.hpp" +#include "scrThread.hpp" + +#if _WIN32 +#include +#endif + +namespace rage +{ +#pragma pack(push, 1) + class tlsContext + { + public: + char gap0[180]; + std::uint8_t m_unk_byte; // 0xB4 + char gapB5[3]; + sysMemAllocator *m_allocator; // 0xB8 + sysMemAllocator *m_allocator2; // 0xC0 - Same as 0xB8 + sysMemAllocator *m_allocator3; // 0xC8 - Same as 0xB8 + uint32_t m_console_smth; // 0xD0 + char gapD4[188]; + uint64_t m_unk; // 0x190 + char gap198[1712]; + rage::scrThread *m_script_thread; // 0x848 + bool m_is_script_thread_active; // 0x850 + +#if _WIN32 + static tlsContext* get() + { + constexpr std::uint32_t TlsIndex = 0x0; + return *reinterpret_cast(__readgsqword(0x58) + TlsIndex); + } +#endif + }; + static_assert(sizeof(tlsContext) == 0x851); +#pragma pack(pop) +} \ No newline at end of file diff --git a/classes/src/script/types.hpp b/classes/src/script/types.hpp new file mode 100644 index 0000000000..34f5971c3c --- /dev/null +++ b/classes/src/script/types.hpp @@ -0,0 +1,103 @@ +#pragma once +#include +#include "scrVector.hpp" + +#ifndef BOOL +#define BOOL int +#endif + +using Void = void; +using Any = int; +using Hash = std::uint32_t; +using Entity = std::int32_t; +using Player = std::int32_t; +using FireId = std::int32_t; +using Interior = std::int32_t; +using Ped = Entity; +using Vehicle = Entity; +using Cam = std::int32_t; +using Object = Entity; +using Pickup = Object; +using Blip = std::int32_t; +using Camera = Entity; +using ScrHandle = Entity; +using Vector3 = rage::scrVector; + +#define PLAYER_INDEX alignas(8) Player +#define ENTITY_INDEX alignas(8) Entity +#define PED_INDEX alignas(8) Ped +#define VEHICLE_INDEX alignas(8) Vehicle +#define INTERIOR_INDEX alignas(8) Interior +#define NETWORK_INDEX alignas(8) int + +#define SCR_HASH alignas(8) Hash +#define SCR_INT alignas(8) int +#define SCR_BOOL alignas(8) BOOL +#define SCR_FLOAT alignas(8) float +#define SCR_VEC3 Vector3 + +template +struct SCR_TEXT_LABEL +{ + alignas(8) char Data[SIZE]; +private: + alignas(8) char _PAD[SIZE]; +public: + operator char* () { return Data; } +}; + +#define TEXT_LABEL_15 SCR_TEXT_LABEL<16> +#define TEXT_LABEL_23 SCR_TEXT_LABEL<24> +#define TEXT_LABEL_31 SCR_TEXT_LABEL<32> +#define TEXT_LABEL_63 SCR_TEXT_LABEL<64> + +template +struct SCR_ARRAY +{ + SCR_INT Size; + alignas(8) T Data[SIZE]; + + T& operator [](int index) + { + return Data[index]; + } +}; + +template +struct SCR_BITSET +{ + alignas(8) int Value; + + bool IsSet(T val) + { + return Value & (1 << (int)val); + } + + void Set(T val) + { + Value |= (1 << (int)val); + } + + void Clear(T val) + { + Value &= ~(1 << (int)val); + } +}; + +struct Color3 +{ + SCR_INT R; + SCR_INT G; + SCR_INT B; +}; +static_assert(sizeof(Color3) == 3 * 8); + +// serialized bitbuffer data of rage::rlGamerHandle + some padding for last gen compatibility +struct GAMER_HANDLE +{ +private: + uint64_t Data[13]; +}; +static_assert(sizeof(GAMER_HANDLE) == 13 * 8); + +#define NUM_CONTACTS 80 \ No newline at end of file diff --git a/classes/src/security/ObfVar.hpp b/classes/src/security/ObfVar.hpp new file mode 100644 index 0000000000..64aad18f17 --- /dev/null +++ b/classes/src/security/ObfVar.hpp @@ -0,0 +1,52 @@ +#pragma once +#include +#include + +namespace rage +{ + template + class ObfVar + { + private: + T m_unk1; + T m_unk2; + T m_unk3; + T m_unk4; + + public: + T getData() + { + auto v105 = m_unk4; + auto v28 = m_unk1 & v105; + auto v94 = m_unk2 & ~v105; + return v28 | v94; + } + + operator T () + { + return getData(); + } + +#if _WIN32 + void setData(T val) + { + auto seed = time(nullptr); + m_unk3 = seed; + seed = time(nullptr); + m_unk4 = seed; + + auto v48 = val & ~seed; + m_unk1 = seed & val; + m_unk2 = v48; + } + + void operator =(T val) + { + setData(val); + } +#endif + }; + + using Obf16 = ObfVar; + using Obf32 = ObfVar; +} \ No newline at end of file diff --git a/classes/src/security/RageSecurity.hpp b/classes/src/security/RageSecurity.hpp new file mode 100644 index 0000000000..b0bf0a1bde --- /dev/null +++ b/classes/src/security/RageSecurity.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "ObfVar.hpp" + +namespace rage +{ + class RageSecurity + { + public: + Obf32 m_lastRun; + Obf32 m_interval; + }; +} \ No newline at end of file diff --git a/classes/src/socialclub/FriendInfo.hpp b/classes/src/socialclub/FriendInfo.hpp new file mode 100644 index 0000000000..e2d27cd222 --- /dev/null +++ b/classes/src/socialclub/FriendInfo.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include + +#pragma pack(push, 1) +class FriendInfo +{ +public: + char m_name[20]; //0x0000 + char pad_0014[36]; //0x0014 + uint64_t m_rockstar_id; //0x0038 + uint8_t unk; //0x0040 + char pad_0041[3]; //0x0041 + uint32_t m_friend_state; //0x0044 + char pad_0048[304]; //0x0048 + uint32_t m_is_joinable; //0x0178 + char pad_017C[4]; //0x017C +}; //Size: 0x0180 +static_assert(sizeof(FriendInfo) == 0x180); +#pragma pack(pop) diff --git a/classes/src/socialclub/FriendRegistry.hpp b/classes/src/socialclub/FriendRegistry.hpp new file mode 100644 index 0000000000..28428abedb --- /dev/null +++ b/classes/src/socialclub/FriendRegistry.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "FriendInfo.hpp" + +#include + +#pragma pack(push, 4) +class FriendRegistry +{ +public: + uint32_t m_friend_count; //0x0000 + char pad_0004[8]; //0x0004 + FriendInfo (*m_friends)[250]; //0x000C + + inline FriendInfo* get(std::uint32_t idx) + { + return &(*m_friends)[idx]; + } +}; //Size: 0x0014 +static_assert(sizeof(FriendRegistry) == 0x14); +#pragma pack(pop) diff --git a/classes/src/socialclub/ScInfo.hpp b/classes/src/socialclub/ScInfo.hpp new file mode 100644 index 0000000000..3157daecdf --- /dev/null +++ b/classes/src/socialclub/ScInfo.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include + +#pragma pack(push, 1) +class ScInfo +{ +public: + char m_ticket[208]; //0x0000 + char pad_00D0[304]; //0x00D0 + char m_session_ticket[88]; //0x0200 - rlSessionInfo base64 serialized? + char pad_0258[40]; //0x0258 + uint32_t m_nonce; //0x0280 + char pad_0284[4]; //0x0284 + uint32_t m_account_id; //0x0288 + char pad_028C[16]; //0x028C + char m_profile_pic[128]; //0x029C + char pad_031C[32]; //0x031C + char m_country_code[4]; //0x033C + char pad_0340[31]; //0x0340 + char m_email_address[96]; //0x035F + char pad_03BF[6]; //0x03BF + char m_language_subtag[8]; //0x03C5 + char pad_03CD[2]; //0x03CD + char m_sc_name[20]; //0x03CF + char pad_03E3[533]; //0x03E3 + char m_session_key[16]; //0x05F8 + char pad_0608[2296]; //0x0608 +}; //Size: 0x0F00 +static_assert(sizeof(ScInfo) == 0xF00); +#pragma pack(pop) diff --git a/classes/src/stats/CPlayerCardStats.hpp b/classes/src/stats/CPlayerCardStats.hpp new file mode 100644 index 0000000000..51c2633d9d --- /dev/null +++ b/classes/src/stats/CPlayerCardStats.hpp @@ -0,0 +1,23 @@ +#pragma once +#include + +class CPlayerCardStats +{ +public: + uint32_t m_access_flags; //0x0000 + float m_kd_ratio; //0x0004 + float m_unk_ratio; //0x0008 + float m_rank; //0x000C + float m_can_spectate; //0x0010 + float m_is_spectating; //0x0014 + float m_current_crew_rank; //0x0018 + float m_overall_badsport; //0x001C + float m_stamina; //0x0020 + float m_strength; //0x0024 + float m_shooting_ability; //0x0028 + float m_stealth_ability; //0x002C + float m_flying_ability; //0x0030 + float m_wheelie_ability; //0x0034 + float m_mental_state; //0x0038 +}; //Size: 0x003C +static_assert(sizeof(CPlayerCardStats) == 0x3C); \ No newline at end of file diff --git a/classes/src/stats/CStatsSerializationContext.hpp b/classes/src/stats/CStatsSerializationContext.hpp new file mode 100644 index 0000000000..1fd685e996 --- /dev/null +++ b/classes/src/stats/CStatsSerializationContext.hpp @@ -0,0 +1,27 @@ +#pragma once +#include + +#pragma pack(push, 1) +class CStatsSerializationContext +{ +public: + bool m_compressed; //0x0000 + char pad_0001[7]; //0x0001 + class CStatSerializationEntry* m_entries; //0x0008 + uint16_t m_size; //0x0010 +}; //Size: 0x0012 +static_assert(sizeof(CStatsSerializationContext) == 0x12); + +class CStatSerializationEntry +{ +public: + uint32_t m_hash; //0x0000 + union //0x0004 + { + float m_float_value; //0x0000 + uint16_t m_short_value; //0x0000 + uint64_t m_int_value; //0x0000 + }; +}; //Size: 0x000C +static_assert(sizeof(CStatSerializationEntry) == 0xC); // can be 0x8 or 0xC +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/ui/CBlipEntry.hpp b/classes/src/ui/CBlipEntry.hpp new file mode 100644 index 0000000000..b0fe605492 --- /dev/null +++ b/classes/src/ui/CBlipEntry.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "blip_t.hpp" + +class CBlipEntry +{ +public: + rage::Blip_t* m_pBlip; //0x0000 + +};//Size=0x0008 \ No newline at end of file diff --git a/classes/src/ui/CBlipList.hpp b/classes/src/ui/CBlipList.hpp new file mode 100644 index 0000000000..92998b9a89 --- /dev/null +++ b/classes/src/ui/CBlipList.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "CBlipEntry.hpp" + +class CBlipList +{ +public: + CBlipEntry m_Blips[1500]; //0x0000 + +};//Size=0x2F18 \ No newline at end of file diff --git a/classes/src/ui/blip_t.hpp b/classes/src/ui/blip_t.hpp new file mode 100644 index 0000000000..785ed7818e --- /dev/null +++ b/classes/src/ui/blip_t.hpp @@ -0,0 +1,41 @@ +#pragma once + +namespace rage +{ + class Blip_t + { + public: + int32_t m_id; //0x0000 + uint16_t m_blip_array_index; //0x0004 + char pad_0006[4]; //0x0006 + bool m_active; //0x000A + uint8_t N00000197; //0x000B + int32_t m_entity_id; //0x000C + float m_x; //0x0010 + float m_y; //0x0014 + float m_z; //0x0018 + char pad_001C[4]; //0x001C + uint32_t m_display_bits; //0x0020 + uint32_t m_render_bits; //0x0024 + char* m_message; //0x0028 + char pad_0030[8]; //0x0030 + Hash m_description; //0x0038 + char pad_003C[4]; //0x003C + int32_t m_icon; //0x0040 + int16_t m_flash_interval; //0x0044 + int16_t m_flash_timer; //0x0046 + uint32_t m_color; //0x0048 + uint32_t m_secondary_color; //0x004C + float m_scale_x; //0x0050 + float m_scale_y; //0x0054 + float m_rotation; //0x0058 + uint8_t m_mission_bits; //0x005C + uint8_t m_priority; //0x005D + uint8_t m_display_id; //0x005E + uint8_t m_alpha; //0x005F + int8_t m_category; //0x0060 + int8_t m_show_number; //0x0061 + char pad_0062[14]; //0x0062 + }; //Size: 0x0070 + static_assert(sizeof(Blip_t) == 0x70, "Blip_t is not sized properly."); +} \ No newline at end of file diff --git a/classes/src/vehicle/CAdvancedData.hpp b/classes/src/vehicle/CAdvancedData.hpp new file mode 100644 index 0000000000..7de376f38d --- /dev/null +++ b/classes/src/vehicle/CAdvancedData.hpp @@ -0,0 +1,11 @@ +#pragma once + +class CAdvancedData +{ +public: + virtual ~CAdvancedData() = 0; + + int m_slot; + int m_index; + float m_value; +}; \ No newline at end of file diff --git a/classes/src/vehicle/CBaseSubHandlingData.hpp b/classes/src/vehicle/CBaseSubHandlingData.hpp new file mode 100644 index 0000000000..ba51dbb141 --- /dev/null +++ b/classes/src/vehicle/CBaseSubHandlingData.hpp @@ -0,0 +1,11 @@ +#pragma once +#include "CHandlingObject.hpp" +#include "../enums/eHandlingType.hpp" + +class CBaseSubHandlingData : public CHandlingObject +{ +public: + virtual eHandlingType GetHandlingType() = 0; + virtual void OnPostLoad() = 0; + +}; \ No newline at end of file diff --git a/classes/src/vehicle/CCarHandlingData.hpp b/classes/src/vehicle/CCarHandlingData.hpp new file mode 100644 index 0000000000..a268109d56 --- /dev/null +++ b/classes/src/vehicle/CCarHandlingData.hpp @@ -0,0 +1,61 @@ +#pragma once +#include + +#include "CAdvancedData.hpp" +#include "CBaseSubHandlingData.hpp" +#include "../rage/atArray.hpp" + +enum eAdvancedFlags +{ + NONE, + CF_DIFF_FRONT = 1 << 0, + CF_DIFF_REAR = 1 << 1, + CF_DIFF_CENTRE = 1 << 2, + CF_DIFF_LIMITED_FRONT = 1 << 3, + CF_DIFF_LIMITED_REAR = 1 << 4, + CF_DIFF_LIMITED_CENTRE = 1 << 5, + CF_DIFF_LOCKING_FRONT = 1 << 6, + CF_DIFF_LOCKING_REAR = 1 << 7, + CF_DIFF_LOCKING_CENTRE = 1 << 8, + CF_GEARBOX_FULL_AUTO = 1 << 9, + CF_GEARBOX_MANUAL = 1 << 10, + CF_GEARBOX_DIRECT_SHIFT = 1 << 11, + CF_GEARBOX_ELECTRIC = 1 << 12, + CF_ASSIST_TRACTION_CONTROL = 1 << 13, + CF_ASSIST_STABILITY_CONTROL = 1 << 14, + CF_ALLOW_REDUCED_SUSPENSION_FORCE = 1 << 15, + CF_HARD_REV_LIMIT = 1 << 16, + CF_HOLD_GEAR_WITH_WHEELSPIN = 1 << 17, + CF_INCREASE_SUSPENSION_FORCE_WITH_SPEED = 1 << 18, + CF_BLOCK_INCREASED_ROT_VELOCITY_WITH_DRIVE_FORCE = 1 << 19, + CF_REDUCED_SELF_RIGHTING_SPEED = 1 << 20, + CF_CLOSE_RATIO_GEARBOX = 1 << 21, + CF_FORCE_SMOOTH_RPM = 1 << 22, + CF_ALLOW_TURN_ON_SPOT = 1 << 23, + CF_CAN_WHEELIE = 1 << 24, + CF_ENABLE_WHEEL_BLOCKER_SIDE_IMPACTS = 1 << 25, + CF_FIX_OLD_BUGS = 1 << 26, + CF_USE_DOWNFORCE_BIAS = 1 << 27, + CF_REDUCE_BODY_ROLL_WITH_SUSPENSION_MODS = 1 << 28, + CF_ALLOWS_EXTENDED_MODS = 1 << 29 +}; + +class CCarHandlingData : public CBaseSubHandlingData +{ +public: + float m_back_end_popup_car_impulse_mult; //0x0008 + float m_back_end_popup_building_impulse_mult; //0x000C + float m_back_end_popup_max_delta_speed; //0x0010 + float m_toe_front; //0x0014 + float m_toe_rear; //0x0018 + float m_camber_front; //0x001C + float m_camber_rear; //0x0020 + float m_castor; //0x0024 + float m_engine_resistance; //0x0028 + float m_max_drive_bias_transfer; //0x002C + float m_jumpforce_scale; //0x0030 + float m_unk_034; //0x0034 + uint32_t m_unk_038; //0x0038 + uint32_t m_advanced_flags; //0x003C + rage::atArray m_advanced_data; //0x0040 +}; \ No newline at end of file diff --git a/classes/src/vehicle/CDriveByAnimInfo.hpp b/classes/src/vehicle/CDriveByAnimInfo.hpp new file mode 100644 index 0000000000..28fca61108 --- /dev/null +++ b/classes/src/vehicle/CDriveByAnimInfo.hpp @@ -0,0 +1,9 @@ +#include "CWeaponGroupNames.hpp" + +class CDriveByAnimInfo +{ +public: + char pad_0000[48]; //0x0000 + class CWeaponGroupNames* m_weapon_groups; //0x0030 +}; //Size: 0x0088 +static_assert(sizeof(CDriveByAnimInfo) == 0x38); \ No newline at end of file diff --git a/classes/src/vehicle/CDriveBySeatDefault.hpp b/classes/src/vehicle/CDriveBySeatDefault.hpp new file mode 100644 index 0000000000..850d6d3f27 --- /dev/null +++ b/classes/src/vehicle/CDriveBySeatDefault.hpp @@ -0,0 +1,14 @@ +#include "CVehicleDriveByAnimInfo.hpp" + +#pragma pack(push, 4) +class CDriveBySeatDefault +{ +private: + char pad_0000[320]; //0x0000 +public: + class CVehicleDriveByAnimInfo* m_driveby_standard_front_left; //0x0140 + class CVehicleDriveByAnimInfo* m_driveby_standard_front_right; //0x0148 + class CVehicleDriveByAnimInfo* m_driveby_standard_rear_left; //0x0150 + class CVehicleDriveByAnimInfo* m_driveby_standard_rear_right; //0x0158 +}; //Size: 0x0160 +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CDriveByWeaponGroupDefault.hpp b/classes/src/vehicle/CDriveByWeaponGroupDefault.hpp new file mode 100644 index 0000000000..dbd4f96975 --- /dev/null +++ b/classes/src/vehicle/CDriveByWeaponGroupDefault.hpp @@ -0,0 +1,105 @@ +#include "../rage/atArray.hpp" +#include "script/types.hpp" + +class CDriveByWeaponGroupDefault +{ +public: + Hash m_driveby_default_unarmed; //0x0000 +private: + char pad_0004[4]; //0x0004 +public: + rage::atArray m_driveby_default_unarmed_weapon_group_names; //0x0008 + rage::atArray m_driveby_default_unarmed_weapon_type_names; //0x0018 +private: + char pad_0028[8]; //0x0028 +public: + Hash m_driveby_default_one_handed; //0x0030 +private: + char pad_0034[4]; //0x0034 +public: + rage::atArray m_driveby_default_one_handed_weapon_group_names; //0x0038 + rage::atArray m_driveby_default_one_handed_weapon_type_names; //0x0048 +private: + char pad_0058[8]; //0x0058 +public: + Hash m_driveby_default_two_handed; //0x0060 +private: + char pad_0064[4]; //0x0064 +public: + rage::atArray m_driveby_default_two_handed_weapon_group_names; //0x0068 + rage::atArray m_driveby_default_two_handed_weapon_type_names; //0x0078 +private: + char pad_0088[8]; //0x0088 +public: + Hash m_driveby_heli_two_handed; //0x0090 +private: + char pad_0094[4]; //0x0094 +public: + rage::atArray m_driveby_heli_two_handed_weapon_group_names; //0x0098 + rage::atArray m_driveby_heli_two_handed_weapon_type_names; //0x00A8 +private: + char pad_00B8[56]; //0x00B8 +public: + Hash m_driveby_heli_rpg; //0x00F0 +private: + char pad_00F4[4]; //0x00F4 +public: + rage::atArray m_driveby_heli_rpg_weapon_group_names; //0x00F8 + rage::atArray m_driveby_heli_rpg_weapon_type_names; //0x0108 +private: + char pad_0118[8]; //0x0118 +public: + Hash m_driveby_default_rear_one_handed; //0x0120 +private: + char pad_0124[4]; //0x0124 +public: + rage::atArray m_driveby_default_rear_one_handed_weapon_group_names; //0x0128 + rage::atArray m_driveby_default_rear_one_handed_weapon_type_names; //0x0138 +private: + char pad_0148[8]; //0x0148 +public: + Hash m_driveby_bike_one_handed; //0x0150 +private: + char pad_0154[4]; //0x0154 +public: + rage::atArray m_driveby_bike_one_handed_weapon_group_names; //0x0158 + rage::atArray m_driveby_bike_one_handed_weapon_type_names; //0x0168 +private: + char pad_0178[56]; //0x0178 +public: + Hash m_driveby_bike_melee; //0x01B0 +private: + char pad_01B4[4]; //0x01B4 +public: + rage::atArray m_driveby_bike_melee_weapon_group_names; //0x01B8 + rage::atArray m_driveby_bike_melee_weapon_type_names; //0x01C8 +private: + char pad_01D8[56]; //0x01D8 +public: + Hash m_driveby_mounted_throw; //0x0210 +private: + char pad_0214[4]; //0x0214 +public: + rage::atArray m_driveby_mounted_throw_weapon_group_names; //0x0218 + rage::atArray m_driveby_mounted_throw_weapon_type_names; //0x0228 +private: + char pad_0238[8]; //0x0238 +public: + Hash m_driveby_throw; //0x0240 +private: + char pad_0244[4]; //0x0244 +public: + rage::atArray m_driveby_throw_weapon_group_names; //0x0248 + rage::atArray m_driveby_throw_weapon_type_names; //0x0258 +private: + char pad_0268[8]; //0x0268 +public: + Hash m_driveby_vehicle_weapon_group; //0x0270 +private: + char pad_0274[4]; //0x0274 +public: + rage::atArray m_driveby_vehicle_weapon_group_weapon_group_names; //0x0278 + rage::atArray m_driveby_vehicle_weapon_group_weapon_type_names; //0x0288 +private: + char pad_0298[8]; //0x0298 +}; //Size: 0x02A0 \ No newline at end of file diff --git a/classes/src/vehicle/CDrivebyWeaponGroups.hpp b/classes/src/vehicle/CDrivebyWeaponGroups.hpp new file mode 100644 index 0000000000..e7e0e411ba --- /dev/null +++ b/classes/src/vehicle/CDrivebyWeaponGroups.hpp @@ -0,0 +1,9 @@ +#include "CDriveByWeaponGroupDefault.hpp" + +#pragma pack(push, 4) +class CDrivebyWeaponGroups +{ +public: + class CDriveByWeaponGroupDefault* m_drive_by_default; //0x0000 +}; //Size: 0x0008 +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CGetPedSeatReturnClass.hpp b/classes/src/vehicle/CGetPedSeatReturnClass.hpp new file mode 100644 index 0000000000..a3f4b090aa --- /dev/null +++ b/classes/src/vehicle/CGetPedSeatReturnClass.hpp @@ -0,0 +1,9 @@ + +#pragma pack(push, 1) +class CGetPedSeatReturnClass +{ +public: + char padding[8]; + CVehicleDriveByAnimInfo* anim_info; +}; +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CHandlingData.hpp b/classes/src/vehicle/CHandlingData.hpp new file mode 100644 index 0000000000..73dedda1d1 --- /dev/null +++ b/classes/src/vehicle/CHandlingData.hpp @@ -0,0 +1,86 @@ +#pragma once + +#include "CBaseSubHandlingData.hpp" +#include "../rage/atArray.hpp" +#include "../rage/vector.hpp" + +#include + +class CHandlingData +{ +public: + uint64_t qword0; //0x0000 + uint32_t m_model_hash; //0x0008 + float m_mass; //0x000C + float m_initial_drag_coeff; //0x0010 + float m_downforce_multiplier; //0x0014 + float m_popup_light_rotation; //0x0018 + char pad_001C[4]; //0x001C + rage::fvector3 m_centre_of_mass; //0x0020 + char pad_002C[4]; //0x002C + rage::fvector3 m_inertia_mult; //0x0030 + char pad_003C[4]; //0x003C + float m_buoyancy; //0x0040 + float m_drive_bias_rear; //0x0044 + float m_drive_bias_front; //0x0048 + float m_acceleration; //0x004C + uint8_t m_initial_drive_gears; //0x0050 + char pad_0051[3]; //0x0051 + float m_drive_inertia; //0x0054 + float m_upshift; //0x0058 + float m_downshift; //0x005C + float m_initial_drive_force; //0x0060 + float m_drive_max_flat_velocity; //0x0064 + float m_initial_drive_max_flat_vel; //0x0068 + float m_brake_force; //0x006C + char pad_0070[4]; //0x0070 + float m_brake_bias_front; //0x0074 + float m_brake_bias_rear; //0x0078 + float m_handbrake_force; //0x007C + float m_steering_lock; //0x0080 + float m_steering_lock_ratio; //0x0084 + float m_traction_curve_max; //0x0088 + float m_traction_curve_lateral; //0x008C + float m_traction_curve_min; //0x0090 + float m_traction_curve_ratio; //0x0094 + float m_curve_lateral; //0x0098 + float m_curve_lateral_ratio; //0x009C + float m_traction_spring_delta_max; //0x00A0 + float m_traction_spring_delta_max_ratio; //0x00A4 + float m_low_speed_traction_loss_mult; //0x00A8 + float m_camber_stiffness; //0x00AC + float m_traction_bias_front; //0x00B0 + float m_traction_bias_rear; //0x00B4 + float m_traction_loss_mult; //0x00B8 + float m_suspension_force; //0x00BC + float m_suspension_comp_damp; //0x00C0 + float m_suspension_rebound_damp; //0x00C4 + float m_suspension_upper_limit; //0x00C8 + float m_suspension_lower_limit; //0x00CC + float m_suspension_raise; //0x00D0 + float m_suspension_bias_front; //0x00D4 + float m_suspension_bias_rear; //0x00D8 + float m_anti_rollbar_force; //0x00DC + float m_anti_rollbar_bias_front; //0x00E0 + float m_anti_rollbar_bias_rear; //0x00E4 + float m_roll_centre_height_front; //0x00E8 + float m_roll_centre_height_rear; //0x00EC + float m_collision_damage_mult; //0x00F0 + float m_weapon_damamge_mult; //0x00F4 + float m_deformation_mult; //0x00F8 + float m_engine_damage_mult; //0x00FC + float m_petrol_tank_volume; //0x0100 + float m_oil_volume; //0x0104 + char pad_0108[4]; //0x0108 + rage::fvector3 m_seat_offset_dist; //0x010C + uint32_t m_monetary_value; //0x0118 + char pad_011C[8]; //0x011C + uint32_t m_model_flags; //0x0124 + uint32_t m_handling_flags; //0x0128 + uint32_t m_damage_flags; //0x012C + char pad_0130[12]; //0x0130 + uint32_t m_ai_handling_hash; //0x013C + char pad_140[24]; //0x140 + rage::atArray m_sub_handling_data; // 0x158 +}; //Size: 0x0160 +static_assert(sizeof(CHandlingData) == 0x168); diff --git a/classes/src/vehicle/CHandlingObject.hpp b/classes/src/vehicle/CHandlingObject.hpp new file mode 100644 index 0000000000..b0bfef20bc --- /dev/null +++ b/classes/src/vehicle/CHandlingObject.hpp @@ -0,0 +1,8 @@ +#pragma once + +class CHandlingObject +{ +public: + virtual ~CHandlingObject() = 0; + virtual void* parser_GetStructure() = 0; //ret rage::parStructure +}; \ No newline at end of file diff --git a/classes/src/vehicle/CTrainConfig.hpp b/classes/src/vehicle/CTrainConfig.hpp new file mode 100644 index 0000000000..f571bd8489 --- /dev/null +++ b/classes/src/vehicle/CTrainConfig.hpp @@ -0,0 +1,35 @@ +#pragma once +#include "rage/atArray.hpp" + +#pragma pack(push, 4) +class CCarriageConfig +{ + uint32_t m_name_hash; // 0x00 + int m_max_peds_per_carriage; // 0x04 + char m_pad[4]; // 0x08 + bool m_flip_model_dir; // 0x0C + bool m_do_interior_lights; // 0x0D + float m_carriage_vert_offset; // 0x10 +}; +static_assert(sizeof(CCarriageConfig) == 0x14); + +class CTrainConfig +{ +public: + uint32_t m_name_hash; // 0x00 + float m_populate_train_dist; // 0x04 + int m_unk1; // 0x08 + int m_unk2; // 0x0C + int m_unk3; // 0x10 + bool m_announce_stations; // 0x14 + bool m_doors_beep; // 0x15 + bool m_carriages_hang; // 0x16 + bool m_carriages_swing; // 0x17 + bool m_no_carriage_gap; // 0x18 + bool m_link_tracks_with_adjacent_stations; // 0x19 + bool m_no_random_spawn; // 0x1A + float m_carriage_gap; // 0x1C + rage::atArray m_carraige_configs; // 0x20 +}; +static_assert(sizeof(CTrainConfig) == 0x30); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CVehicle.hpp b/classes/src/vehicle/CVehicle.hpp new file mode 100644 index 0000000000..4ba3e931d3 --- /dev/null +++ b/classes/src/vehicle/CVehicle.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include "../entities/CPhysical.hpp" +#include "CHandlingData.hpp" + +#include +#include + +#pragma pack(push, 1) +class CVehicle : public rage::CPhysical +{ +public: + char pad_02EC[12]; //0x02EC + bool m_boosting; //0x02F8 + char pad_02F9[2]; //0x02F9 + bool m_boost_allow_recharge; //0x02FB + char pad_02FC[4]; //0x02FC + float m_boost; //0x0300 + float m_rocket_recharge_speed; //0x0304 + char pad_0308[152]; //0x0308 + float m_jump_boost_charge; //0x03A0 + bool m_can_boost_jump; //0x03A4 + char pad_03A5[1163]; //0x03A5 + float m_body_health; //0x0830 + float m_petrol_tank_health; //0x0834 + char pad_0838[72]; //0x0838 + int16_t m_next_gear; //0x0880 + int16_t m_current_gear; //0x0882 + char pad_0884[2]; //0x0884 + int8_t m_top_gear; //0x0886 + char pad_0887[137]; //0x0887 + float m_engine_health; //0x0910 + char pad_0914[24]; //0x0914 + float m_kers_boost_max; //0x092C + float m_kers_boost; //0x0930 + char pad_0934[44]; //0x0934 + class CHandlingData* m_handling_data; //0x0960 + char pad_0968[2]; //0x0968 + uint8_t m_drivable_bitset; //0x096A + uint8_t m_tyre_burst_bitset; //0x096B + uint8_t m_deform_god; //0x096C + char pad_096D[179]; //0x096D + float m_dirt_level; //0x0A20 + char pad_0A24[202]; //0x0A24 + bool m_is_targetable; //0x0AEE + char pad_0AEF[297]; //0x0AEF + uint32_t m_gravity_state; //0x0C18 + char pad_0C1C[112]; //0x0C1C + float m_gravity; //0x0C8C + uint8_t m_max_passengers; //0x0C90 + char pad_0C91[1]; //0x0C91 + uint8_t m_num_of_passengers; //0x0C92 + char pad_0C93[5]; //0x0C93 + class CPed* m_driver; //0x0C98 + class CPed* m_passengers[15]; //0x0CA0 + class CPed* m_last_driver; //0x0D18 + char pad_0D20[1696]; //0x0D20 + uint32_t m_door_lock_status; //0x13C0 + char pad_13C4[2356]; //0x13C4 + +}; //Size: 0x1CF8 +static_assert(sizeof(CVehicle) == 0x1CF8); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CVehicleDriveByAnimInfo.hpp b/classes/src/vehicle/CVehicleDriveByAnimInfo.hpp new file mode 100644 index 0000000000..9c29dfa113 --- /dev/null +++ b/classes/src/vehicle/CVehicleDriveByAnimInfo.hpp @@ -0,0 +1,37 @@ +#include "../rage/atArray.hpp" +#include "CDriveByAnimInfo.hpp" + +#pragma once + +#pragma pack(push, 4) +class CVehicleDriveByAnimInfo +{ +public: + uint32_t m_name; //0x0000 + float m_min_aim_sweep_heading_angle_degs; //0x0004 + float m_max_aim_sweep_heading_angle_degs; //0x0008 + float m_first_person_min_aim_sweep_heading_angle_degs; //0x000C + float m_first_person_max_aim_sweep_heading_angle_degs; //0x0010 + float m_first_person_unarmed_min_aim_sweep_heading_angle_degs; //0x0014 + float m_first_person_unarmed_max_aim_sweep_heading_angle_degs; //0x0018 + uint64_t m_unk1; //0x001C + float m_min_restricted_aim_sweep_heading_angle_degs; //0x0024 + float m_max_restricted_aim_sweep_heading_angle_degs; //0x0028 + float m_min_smash_window_angle_degs; //0x002C + float m_max_smash_window_angle_degs; //0x0030 + float m_min_smash_window_angle_first_person_degs; //0x0034 + float m_max_smash_window_angle_first_person_degs; //0x0038 + float m_max_speed_param; //0x003C + float m_max_longitudinal_lean_blend_weight_delta; //0x0040 + float m_max_lateral_lean_blend_weight_delta; //0x0044 + float m_approach_speed_to_within_max_blend_delta; //0x0048 + float m_spine_additive_blend_in_delay; //0x004C + float m_spine_additive_blend_in_duration_still; //0x0050 + float m_spine_additive_blend_in_duration; //0x0054 + float m_spine_additive_blend_out_delay; //0x0058 + float m_spine_additive_blend_out_duration; //0x005C + float m_min_unarmed_driveby_yaw_if_window_rolled_up; //0x0060 + float m_max_unarmed_driveby_yaw_if_window_rolled_up; //0x0064 + rage::atArray m_drive_by_anim_infos; //0x0068 +}; //Size: 0x0078 +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CVehicleDriveByMetadataMgr.hpp b/classes/src/vehicle/CVehicleDriveByMetadataMgr.hpp new file mode 100644 index 0000000000..79f435591a --- /dev/null +++ b/classes/src/vehicle/CVehicleDriveByMetadataMgr.hpp @@ -0,0 +1,9 @@ +#include "CDrivebyWeaponGroups.hpp" + +#pragma pack(push, 4) +class CVehicleDriveByMetadataMgr +{ +public: + class CDrivebyWeaponGroups* m_drive_by_weapon_groups; //0x0000 +}; //Size: 0x0008 +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CVehicleLayoutMetaData.hpp b/classes/src/vehicle/CVehicleLayoutMetaData.hpp new file mode 100644 index 0000000000..d7e3587ef8 --- /dev/null +++ b/classes/src/vehicle/CVehicleLayoutMetaData.hpp @@ -0,0 +1,11 @@ +#include "CVehicleSeatAnimInfos.hpp" + +#pragma pack(push, 4) +class CVehicleLayoutMetaData +{ +private: + char pad_0000[8]; //0x0000 +public: + class CVehicleSeatAnimInfos* m_seat_info; //0x0008 +}; //Size: 0x0010 +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CVehicleModelInfo.hpp b/classes/src/vehicle/CVehicleModelInfo.hpp new file mode 100644 index 0000000000..6fa697c1fb --- /dev/null +++ b/classes/src/vehicle/CVehicleModelInfo.hpp @@ -0,0 +1,341 @@ +#pragma once + +#include "../base/CBaseModelInfo.hpp" +#include "vehicle/CVehicleModelInfoLayout.hpp" + +#include + +enum class eVehicleType : std::uint32_t +{ + VEHICLE_TYPE_NONE = 4294967295, + VEHICLE_TYPE_CAR = 0, + VEHICLE_TYPE_PLANE = 1, + VEHICLE_TYPE_TRAILER = 2, + VEHICLE_TYPE_QUADBIKE = 3, + VEHICLE_TYPE_DRAFT = 4, + VEHICLE_TYPE_SUBMARINECAR = 5, + VEHICLE_TYPE_AMPHIBIOUS_AUTOMOBILE = 6, + VEHICLE_TYPE_AMPHIBIOUS_QUADBIKE = 7, + VEHICLE_TYPE_HELI = 8, + VEHICLE_TYPE_BLIMP = 9, + VEHICLE_TYPE_AUTOGYRO = 10, + VEHICLE_TYPE_BIKE = 11, + VEHICLE_TYPE_BICYCLE = 12, + VEHICLE_TYPE_BOAT = 13, + VEHICLE_TYPE_TRAIN = 14, + VEHICLE_TYPE_SUBMARINE = 15, +}; + +enum class eVehicleClass : std::uint8_t +{ + VC_COMPACT = 0, + VC_SEDAN = 1, + VC_SUV = 2, + VC_COUPE = 3, + VC_MUSCLE = 4, + VC_SPORT_CLASSIC = 5, + VC_SPORT = 6, + VC_SUPER = 7, + VC_MOTORCYCLE = 8, + VC_OFF_ROAD = 9, + VC_INDUSTRIAL = 10, + VC_UTILITY = 11, + VC_VAN = 12, + VC_CYCLE = 13, + VC_BOAT = 14, + VC_HELICOPTER = 15, + VC_PLANE = 16, + VC_SERVICE = 17, + VC_EMERGENCY = 18, + VC_MILITARY = 19, + VC_COMMERCIAL = 20, + VC_RAIL = 21, + VC_OPEN_WHEEL = 22, +}; + +enum class CVehicleModelInfoFlags : std::uint16_t +{ + SMALL_WORKER, + BIG, + NO_BOOT, + ONLY_DURING_OFFICE_HOURS, + BOOT_IN_FRONT, + IS_VAN, + AVOID_TURNS, + HAS_LIVERY, + LIVERY_MATCH_EXTRA, + SPORTS, + DELIVERY, + UNK_0xB5A93F62, + ONLY_ON_HIGHWAYS, + TALL_SHIP, + SPAWN_ON_TRAILER, + SPAWN_BOAT_ON_TRAILER, + EXTRAS_GANG, + EXTRAS_CONVERTIBLE, + EXTRAS_TAXI, + EXTRAS_RARE, + EXTRAS_REQUIRE, + EXTRAS_STRONG, + EXTRAS_ONLY_BREAK_WHEN_DESTROYED, + EXTRAS_SCRIPT, + EXTRAS_ALL, + EXTRAS_MATCH_LIVERY, + DONT_ROTATE_TAIL_ROTOR, + PARKING_SENSORS, + PEDS_CAN_STAND_ON_TOP, + UNK_0x77C9F804, + GEN_NAVMESH, + LAW_ENFORCEMENT, + EMERGENCY_SERVICE, + DRIVER_NO_DRIVE_BY, + NO_RESPRAY, + IGNORE_ON_SIDE_CHECK, + RICH_CAR, + AVERAGE_CAR, + POOR_CAR, + ALLOWS_RAPPEL, + DONT_CLOSE_DOOR_UPON_EXIT, + USE_HIGHER_DOOR_TORQUE, + DISABLE_THROUGH_WINDSHIELD, + IS_ELECTRIC, + NO_BROKEN_DOWN_SCENARIO, + IS_JETSKI, + DAMPEN_STICKYBOMB_DAMAGE, + DONT_SPAWN_IN_CARGEN, + IS_OFFROAD_VEHICLE, + INCREASE_PED_COMMENTS, + EXPLODE_ON_CONTACT, + USE_FAT_INTERIOR_LIGHT, + HEADLIGHTS_USE_ACTUAL_BONE_POS, + FAKE_EXTRALIGHTS, + CANNOT_BE_MODDED, + DONT_SPAWN_AS_AMBIENT, + IS_BULKY, + BLOCK_FROM_ATTRACTOR_SCENARIO, + IS_BUS, + USE_STEERING_PARAM_FOR_LEAN, + CANNOT_BE_DRIVEN_BY_PLAYER, + SPRAY_PETROL_BEFORE_EXPLOSION, + ATTACH_TRAILER_ON_HIGHWAY, + ATTACH_TRAILER_IN_CITY, + HAS_NO_ROOF, + ALLOW_TARGETING_OF_OCCUPANTS, + RECESSED_HEADLIGHT_CORONAS, + RECESSED_TAILLIGHT_CORONAS, + IS_TRACKED_FOR_TRAILS, + HEADLIGHTS_ON_LANDINGGEAR, + CONSIDERED_FOR_VEHICLE_ENTRY_WHEN_STOOD_ON, + GIVE_SCUBA_GEAR_ON_EXIT, + IS_DIGGER, + IS_TANK, + USE_COVERBOUND_INFO_FOR_COVERGEN, + CAN_BE_DRIVEN_ON, + HAS_BULLETPROOF_GLASS, + CANNOT_TAKE_COVER_WHEN_STOOD_ON, + INTERIOR_BLOCKED_BY_BOOT, + DONT_TIMESLICE_WHEELS, + FLEE_FROM_COMBAT, + DRIVER_SHOULD_BE_FEMALE, + DRIVER_SHOULD_BE_MALE, + COUNT_AS_FACEBOOK_DRIVEN, + BIKE_CLAMP_PICKUP_LEAN_RATE, + PLANE_WEAR_ALTERNATIVE_HELMET, + USE_STRICTER_EXIT_COLLISION_TESTS, + TWO_DOORS_ONE_SEAT, + USE_LIGHTING_INTERIOR_OVERRIDE, + USE_RESTRICTED_DRIVEBY_HEIGHT, + CAN_HONK_WHEN_FLEEING, + PEDS_INSIDE_CAN_BE_SET_ON_FIRE_MP, + REPORT_CRIME_IF_STANDING_ON, + HELI_USES_FIXUPS_ON_OPEN_DOOR, + FORCE_ENABLE_CHASSIS_COLLISION, + CANNOT_BE_PICKUP_BY_CARGOBOB, + CAN_HAVE_NEONS, + HAS_INTERIOR_EXTRAS, + HAS_TURRET_SEAT_ON_VEHICLE, + ALLOW_OBJECT_LOW_LOD_COLLISION, + DISABLE_AUTO_VAULT_ON_VEHICLE, + USE_TURRET_RELATIVE_AIM_CALCULATION, + USE_FULL_ANIMS_FOR_MP_WARP_ENTRY_POINTS, + HAS_DIRECTIONAL_SHUFFLES, + DISABLE_WEAPON_WHEEL_IN_FIRST_PERSON, + USE_PILOT_HELMET, + USE_WEAPON_WHEEL_WITHOUT_HELMET, + PREFER_ENTER_TURRET_AFTER_DRIVER, + USE_SMALLER_OPEN_DOOR_RATIO_TOLERANCE, + USE_HEADING_ONLY_IN_TURRET_MATRIX, + DONT_STOP_WHEN_GOING_TO_CLIMB_UP_POINT, + HAS_REAR_MOUNTED_TURRET, + DISABLE_BUSTING, + IGNORE_RWINDOW_COLLISION, + HAS_GULL_WING_DOORS, + CARGOBOB_HOOK_UP_CHASSIS, + USE_FIVE_ANIM_THROW_FP, + ALLOW_HATS_NO_ROOF, + HAS_REAR_SEAT_ACTIVITIES, + HAS_LOWRIDER_HYDRAULICS, + HAS_BULLET_RESISTANT_GLASS, + HAS_INCREASED_RAMMING_FORCE, + HAS_CAPPED_EXPLOSION_DAMAGE, + HAS_LOWRIDER_DONK_HYDRAULICS, + HELICOPTER_WITH_LANDING_GEAR, + JUMPING_CAR, + HAS_ROCKET_BOOST, + RAMMING_SCOOP, + HAS_PARACHUTE, + RAMP, + HAS_EXTRA_SHUFFLE_SEAT_ON_VEHICLE, + FRONT_BOOT, + HALF_TRACK, + RESET_TURRET_SEAT_HEADING, + TURRET_MODS_ON_ROOF, + UPDATE_WEAPON_BATTERY_BONES, + DONT_HOLD_LOW_GEARS_WHEN_ENGINE_UNDER_LOAD, + HAS_GLIDER, + INCREASE_LOW_SPEED_TORQUE, + USE_AIRCRAFT_STYLE_WEAPON_TARGETING, + KEEP_ALL_TURRETS_SYNCHRONISED, + SET_WANTED_FOR_ATTACHED_VEH, + TURRET_ENTRY_ATTACH_TO_DRIVER_SEAT, + USE_STANDARD_FLIGHT_HELMET, + SECOND_TURRET_MOD, + THIRD_TURRET_MOD, + HAS_EJECTOR_SEATS, + UNK_0x2028D687, + HAS_JATO_BOOST_MOD, + IGNORE_TRAPPED_HULL_CHECK, + HOLD_TO_SHUFFLE, + TURRET_MOD_WITH_NO_STOCK_TURRET, + EQUIP_UNARMED_ON_ENTER, + DISABLE_CAMERA_PUSH_BEYOND, + HAS_VERTICAL_FLIGHT_MODE, + HAS_OUTRIGGER_LEGS, + CAN_NAVIGATE_TO_ON_VEHICLE_ENTRY, + DROP_SUSPENSION_WHEN_STOPPED, + DONT_CRASH_ABANDONED_NEAR_GROUND, + USE_INTERIOR_RED_LIGHT, + HAS_HELI_STRAFE_MODE, + HAS_VERTICAL_ROCKET_BOOST, + CREATE_WEAPON_MANAGER_ON_SPAWN, + USE_ROOT_AS_BASE_LOCKON_POS, + HEADLIGHTS_ON_TAP_ONLY, + CHECK_WARP_TASK_DURING_ENTER, + USE_RESTRICTED_DRIVEBY_HEIGHT_HIGH, + INCREASE_CAMBER_WITH_SUSPENSION_MOD, + NO_HEAVY_BRAKE_ANIMATION, + HAS_TWO_BONNET_BONES, + DONT_LINK_BOOT2, + HAS_INCREASED_RAMMING_FORCE_WITH_CHASSIS_MOD, + UNK_0x4C8630D9, + HAS_EXTENDED_COLLISION_MODS, + HAS_NITROUS_MOD, + HAS_JUMP_MOD, + HAS_RAMMING_SCOOP_MOD, + HAS_SUPER_BRAKES_MOD, + CRUSHES_OTHER_VEHICLES, + HAS_WEAPON_BLADE_MODS, + HAS_WEAPON_SPIKE_MODS, + FORCE_BONNET_CAMERA_INSTEAD_OF_POV, + RAMP_MOD, + HAS_TOMBSTONE, + HAS_SIDE_SHUNT, + HAS_FRONT_SPIKE_MOD, + HAS_RAMMING_BAR_MOD, + TURRET_MODS_ON_CHASSIS5, + HAS_SUPERCHARGER, + IS_TANK_WITH_FLAME_DAMAGE, + DISABLE_DEFORMATION, + ALLOW_RAPPEL_AI_ONLY, + USE_RESTRICTED_DRIVEBY_HEIGHT_MID_ONLY, + FORCE_AUTO_VAULT_ON_VEHICLE_WHEN_STUCK, + SPOILER_MOD_DOESNT_INCREASE_GRIP, + NO_REVERSING_ANIMATION, + IS_QUADBIKE_USING_BIKE_ANIMATIONS, + IS_FORMULA_VEHICLE, + LATCH_ALL_JOINTS, + REJECT_ENTRY_TO_VEHICLE_WHEN_STOOD_ON, + CHECK_IF_DRIVER_SEAT_IS_CLOSER_THAN_TURRETS_WITH_ON_BOARD_ENTER, + RENDER_WHEELS_WITH_ZERO_COMPRESSION, + USE_LENGTH_OF_VEHICLE_BOUNDS_FOR_PLAYER_LOCKON_POS, + PREFER_FRONT_SEAT +}; + +#pragma pack(push, 1) +class CVehicleModelInfo : public CBaseModelInfo +{ +public: + CVehicleModelInfoLayout* m_vehicle_layout; //0x00B0 + char pad_00B8[64]; //0x00B8 + uint8_t m_primary_color_combinations[25]; //0x00F8 + uint8_t m_secondary_color_combinations[25]; //0x0111 + uint8_t m_unk_color_combos1[25]; //0x012A + uint8_t m_unk_color_combos2[25]; //0x0143 + uint8_t m_interior_color_combinations[25]; //0x015C + uint8_t m_dashboard_color_combinations[25]; //0x0175 + char pad_018E[266]; //0x018E + char m_name[12]; //0x0298 + char m_manufacturer[12]; //0x02A4 + uint16_t* m_modkits; //0x02B0 + uint16_t m_modkits_count; //0x02B8 + char pad_02BA[30]; //0x02BA + uint8_t m_passenger_capacity; //0x02D8 + char pad_02D9[103]; //0x02D9 + eVehicleType m_vehicle_type; //0x0340 + uint32_t m_unk_vehicle_type; //0x0344 + uint16_t m_diffuse_tint; //0x0348 + int8_t m_max_seats; //0x034A + char pad_034B[5]; //0x034B + CVehicleLayoutMetaData* m_layout_metadata; //0x0350 + char pad_0358[8]; //0x0358 + rage::fvector3 m_first_person_driveby_ik_offset; //0x0360 + char pad_036C[4]; //0x036C + rage::fvector3 m_first_person_driveby_unarmed_ik_offset; //0x0370 + char pad_037C[20]; //0x037C + rage::fvector3 m_first_person_driveby_right_passenger_ik_offset; //0x0390 + char pad_039C[36]; //0x039C + rage::fvector3 m_first_person_driveby_right_passenger_unarmed_ik_offset; //0x03C0 + char pad_03CC[4]; //0x03CC + rage::fvector3 m_first_person_projectile_driveby_ik_offset; //0x03D0 + char pad_03DC[4]; //0x03DC + rage::fvector3 m_first_person_projectile_driveby_passenger_ik_offset; //0x03E0 + char pad_03EC[52]; //0x03EC + rage::fvector3 m_first_person_mobile_phone_offset; //0x0420 + char pad_042C[4]; //0x042C + rage::fvector3 m_first_person_passenger_mobile_phone_offset; //0x0430 + char pad_043C[20]; //0x043C + rage::fvector3 m_pov_camera_offset; //0x0450 + char pad_045C[36]; //0x045C + float m_pov_camera_vertical_adjustement_for_rollcage; //0x0480 + char pad_0484[8]; //0x0484 + float m_wheel_scale; //0x048C + float m_wheel_scale_rear; //0x0490 + float m_default_health; //0x0494 + char pad_0498[4]; //0x0498 + float m_steer_wheel_multiplier; //0x049C + char pad_04A0[168]; //0x04A0 + eVehicleClass m_vehicle_class; //0x0548 + char pad_0549[11]; + float m_min_seat_height; //0x0554 + char pad_0558[36]; //0x0558 + uint32_t m_vehicle_model_flags[7]; // 0x057C + + inline bool get_vehicle_model_flag(const CVehicleModelInfoFlags flag) + { + const auto index = static_cast(flag); + + return this->m_vehicle_model_flags[index / 32] & (1 << (index % 32)); + } + + inline void set_vehicle_model_flag(const CVehicleModelInfoFlags flag, bool toggle) + { + const auto index = static_cast(flag); + + if (toggle) + this->m_vehicle_model_flags[index / 32] |= (1 << (index % 32)); + else + this->m_vehicle_model_flags[index / 32] &= ~(1 << (index % 32)); + } +}; //Size: 0x0598 +static_assert(sizeof(CVehicleModelInfo) == 0x598); +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CVehicleModelInfoLayout.hpp b/classes/src/vehicle/CVehicleModelInfoLayout.hpp new file mode 100644 index 0000000000..2cbcbd6849 --- /dev/null +++ b/classes/src/vehicle/CVehicleModelInfoLayout.hpp @@ -0,0 +1,15 @@ +#include "CVehicleLayoutMetaData.hpp" + +#pragma pack(push, 4) +class CVehicleModelInfoLayout +{ +private: + char pad_0000[842]; //0x0000 +public: + int8_t m_max_seats; //0x034A +private: + char pad_034B[5]; //0x034B +public: + class CVehicleLayoutMetaData* m_layout_metadata; //0x0350 +}; //Size: 0x0358 +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CVehicleSeatAnimInfo.hpp b/classes/src/vehicle/CVehicleSeatAnimInfo.hpp new file mode 100644 index 0000000000..0a85228633 --- /dev/null +++ b/classes/src/vehicle/CVehicleSeatAnimInfo.hpp @@ -0,0 +1,13 @@ +#include "CVehicleDriveByAnimInfo.hpp" + +#pragma pack(push, 4) +class CVehicleSeatAnimInfo +{ +public: + uint32_t name; //0x0000 +private: + char pad_0004[4]; //0x0004 +public: + class CVehicleDriveByAnimInfo* m_drive_by_info; //0x0008 +}; //Size: 0x0010 +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CVehicleSeatAnimInfos.hpp b/classes/src/vehicle/CVehicleSeatAnimInfos.hpp new file mode 100644 index 0000000000..262289bf87 --- /dev/null +++ b/classes/src/vehicle/CVehicleSeatAnimInfos.hpp @@ -0,0 +1,23 @@ +#include "CVehicleSeatAnimInfo.hpp" + +#pragma pack(push, 4) +class CVehicleSeatAnimInfos +{ +private: + char pad_0000[8]; //0x0000 +public: + class CVehicleSeatAnimInfo* m_front_left; //0x0008 +private: + char pad_0010[8]; //0x0010 +public: + class CVehicleSeatAnimInfo* m_front_right; //0x0018 +private: + char pad_0020[8]; //0x0020 +public: + class CVehicleSeatAnimInfo* m_rear_left; //0x0028 +private: + char pad_0030[8]; //0x0030 +public: + class CVehicleSeatAnimInfo* m_rear_right; //0x0038 +}; //Size: 0x0040 +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CVehicleSeatMetadataMgr.hpp b/classes/src/vehicle/CVehicleSeatMetadataMgr.hpp new file mode 100644 index 0000000000..5a20dab2ac --- /dev/null +++ b/classes/src/vehicle/CVehicleSeatMetadataMgr.hpp @@ -0,0 +1,9 @@ +#include "vehicle/CDriveBySeatDefault.hpp" + +#pragma pack(push, 4) +class CVehicleSeatMetadataMgr +{ +public: + class CDriveBySeatDefault* m_drive_by_seat_defaults; //0x0000 +}; //Size: 0x0008 +#pragma pack(pop) \ No newline at end of file diff --git a/classes/src/vehicle/CWeaponGroupNames.hpp b/classes/src/vehicle/CWeaponGroupNames.hpp new file mode 100644 index 0000000000..95bf197aa7 --- /dev/null +++ b/classes/src/vehicle/CWeaponGroupNames.hpp @@ -0,0 +1,13 @@ +#include "../rage/atArray.hpp" + +#pragma pack(push, 1) +class CWeaponGroupNames +{ +public: + char pad_0000[8]; //0x0000 + rage::atArray m_groups; //0x0008 + char pad_0018[4]; //0x0018 + rage::atArray m_weapons; //0x001C +}; //Size: 0x002C +#pragma pack(pop) +static_assert(sizeof(CWeaponGroupNames) == 0x2C); \ No newline at end of file diff --git a/classes/src/weapon/CAmmoInfo.hpp b/classes/src/weapon/CAmmoInfo.hpp new file mode 100644 index 0000000000..f172ea0153 --- /dev/null +++ b/classes/src/weapon/CAmmoInfo.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "CItemInfo.hpp" + +#include + +enum class eAmmoSpecialType : int32_t +{ + None, + ArmorPiercing, + Explosive, + FMJ, + HollowPoint, + Incendiary, + Tracer +}; + +enum class eAmmoFlags : uint32_t +{ + InfiniteAmmo = 0, + AddSmokeOnExplosion = 1, + Fuse = 2, + FixedAfterExplosion = 3, +}; + +class CAmmoInfo : public CItemInfo +{ +public: + int32_t m_ammo_max; //0x0020 + int32_t m_ammo_max_50; //0x0024 + int32_t m_ammo_max_100; //0x0028 + int32_t m_ammo_max_mp; //0x002C + int32_t m_ammo_max_50_mp; //0x0030 + int32_t m_ammo_max_100_mp; //0x0034 + eAmmoFlags m_ammo_flags; //0x0038 + eAmmoSpecialType m_ammo_special_type; //0x003C +}; //Size: 0x040 +static_assert(sizeof(CAmmoInfo) == 0x40); diff --git a/classes/src/weapon/CAmmoProjectileInfo.hpp b/classes/src/weapon/CAmmoProjectileInfo.hpp new file mode 100644 index 0000000000..a5cb5a6b7b --- /dev/null +++ b/classes/src/weapon/CAmmoProjectileInfo.hpp @@ -0,0 +1,125 @@ +#pragma once + +#include "CAmmoInfo.hpp" +#include "CWeaponBoneId.hpp" +#include "../rage/vector.hpp" +#include "../enums/eExplosionTag.hpp" + +#include + +class CAmmoProjectileInfo : public CAmmoInfo +{ +public: + float m_damage; // 0x0040 + float m_lifetime; // 0x0044 + float m_from_vehicle_lifetime; //0x0048 + float m_lifetime_after_impact; //0x004C + float m_lifetime_after_explosion; //0x0050 + float m_explosion_time; //0x0054 + float m_launch_speed; //0x0058 + float m_separation_time; //0x005C + float m_time_to_reach_target; //0x0060 + float m_amping; //0x0064 + float m_gravity_factor; //0x0068 + float m_ricochet_tolerance; //0x006C + float m_ped_ricochet_tolerance; //0x0070 + float m_vehicle_ricochet_tolerance; //0x0074 + float m_friction_multiplier; //0x0078 + class sExplosion + { + public: + enum eExplosionTag m_default; //0x0000 + enum eExplosionTag m_hit_car; //0x0004 + enum eExplosionTag m_hit_truck; //0x0008 + enum eExplosionTag m_hit_bike; //0x000C + enum eExplosionTag m_hit_boat; //0x0010 + enum eExplosionTag m_hit_plane; //0x0014 + } m_explosion; + uint32_t m_m_fuse_fx_hash; //0x0094 + uint32_t m_m_proximity_fx_hash; //0x0098 + uint32_t m_m_trail_fx_hash; //0x009C + uint32_t m_trail_fx_under_water_hash; //0x00A0 + uint32_t m_primed_fx_hash; //0x00A4 + uint32_t m_fuse_fx_fp_hash; //0x00A8 + uint32_t m_primed_fx_fp_hash; //0x00AC + float m_trail_fx_fade_in_time; //0x00B0 + float m_trail_fx_fade_out_time; //0x00B4 + uint32_t m_disturb_fx_default_hash; //0x00B8 + uint32_t m_disturb_fx_sand_hash; //0x00BC + uint32_t m_disturb_fx_water_hash; //0x00C0 + uint32_t m_disturb_fx_dirt_hash; //0x00C4 + uint32_t m_disturb_fx_foliage_hash; //0x00C8 + float m_disturb_fx_probe_dist; //0x00CC + float m_disturb_fx_scale; //0x00D0 + float m_ground_fx_probe_distance; //0x00D4 + bool m_fx_alt_tint_colour; //0x00D8 + bool pad_00D9; + bool m_light_only_active_when_stuck; //0x00DA + bool m_light_flickers; //0x00DB + bool m_light_speeds_up; //0x00DC + bool pad_00DD; + class CWeaponBoneId m_light_bone; //0x00DE + rage::fvector4 m_light_colour; //0x00E0 + float m_light_intensity; //0x00F0 + float m_light_range; //0x00F4 + float m_light_falloff_exp; //0x00F8 + float m_light_frequency; //0x00FC + float m_light_power; //0x0100 + float m_corona_size; //0x0104 + float m_corona_intensity; //0x0108 + float m_corona_z_bias; //0x010C + bool m_proximity_affects_firing_player; //0x0110 + bool m_proximity_can_be_triggered_by_peds; //0x0111 + float m_proximity_activation_time; //0x0114 + float m_proximity_repeated_detonation_activation_time; //0x0118 + float m_proximity_trigger_radius; //0x011C + float m_proximity_fuse_time_ped; //0x0120 + float m_proximity_fuse_time_vehicle_min; //0x0124 + float m_proximity_fuse_time_vehicle_max; //0x0128 + float m_proximity_fuse_time_vehicle_speed; //0x012C + rage::fvector4 m_proximity_light_colour_untriggered; //0x0130 + float m_proximity_light_frequency_multiplier_triggered; //0x0140 + float m_time_to_ignore_owner; //0x0144 + float m_charged_launch_time; //0x0148 + float m_charged_launch_speed_mult; //0x014C + enum eExplosionTag m_cluster_explosion_tag; //0x0150 + uint32_t m_cluster_explosion_count; //0x0154 + float m_cluster_min_radius; //0x0158 + float m_cluster_max_radius; //0x015C + float m_cluster_initial_delay; //0x0160 + float m_cluster_inbetween_delay; //0x0164 + enum Flags : uint32_t + { + Sticky, + DestroyOnImpact, + ProcessImpacts, + HideDrawable, + TrailFxInactiveOnceWet, + TrailFxRemovedOnImpact, + DoGroundDisturbanceFx, + CanBePlaced, + NoPullPin, + DelayUntilSettled, + CanBeDestroyedByDamage, + CanBounce, + DoubleDamping, + StickToPeds, + _0x02E3F9CBA, + ThrustUnderwater, + ApplyDamageOnImpact, + SetOnFireOnImpact, + DontFireAnyEvents, + AlignWithTrajectory, + ExplodeAtTrailFxPos, + ProximityDetonation, + AlignWithTrajectoryYAxis, + HomingAttractor, + Cluster, + PreventMaxProjectileHelpText, + _0x08A7D429C, + UseGravityOutOfWater, + MissionThrowable + } m_projectile_flags; //0x0168 + char pad_016C[4]; //0x016C +}; +static_assert(sizeof(CAmmoProjectileInfo) == 0x170); diff --git a/classes/src/weapon/CAmmoRocketInfo.hpp b/classes/src/weapon/CAmmoRocketInfo.hpp new file mode 100644 index 0000000000..b22c720e70 --- /dev/null +++ b/classes/src/weapon/CAmmoRocketInfo.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "CAmmoProjectileInfo.hpp" +#include "CHomingRocketParams.hpp" + +#include + +class CAmmoRocketInfo : public CAmmoProjectileInfo +{ +public: + float m_forward_drag_coeff; //0x0170 + float m_side_drag_coeff; //0x0174 + float m_time_before_homing; //0x0178 + float m_time_before_switch_target_min; //0x017C + float m_time_before_switch_target_max; //0x0180 + float m_proximity_radius; //0x0184 + float m_pitch_change_rate; //0x0188 + float m_yaw_change_rate; //0x018C + float m_roll_change_rate; //0x0190 + float m_max_roll_angle_sin; //0x0194 + float m_lifetime_player_vehicle_locked_override_mp; //0x0198 + class CHomingRocketParams m_homing_rocket_params; //0x019C +}; // Size: 0x1C0 +static_assert(sizeof(CAmmoRocketInfo) == 0x1C0); \ No newline at end of file diff --git a/classes/src/weapon/CAmmoThrownInfo.hpp b/classes/src/weapon/CAmmoThrownInfo.hpp new file mode 100644 index 0000000000..5cc223edc6 --- /dev/null +++ b/classes/src/weapon/CAmmoThrownInfo.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "CAmmoProjectileInfo.hpp" + +#include + +class CAmmoThrownInfo : CAmmoProjectileInfo +{ + float m_thrown_force; //0x0170 + float m_thrown_force_from_vehicle; //0x0174 + int32_t m_ammo_max_mp_bonus; //0x0178 +}; // Size: 0x0180 +static_assert(sizeof(CAmmoThrownInfo) == 0x180); \ No newline at end of file diff --git a/classes/src/weapon/CHomingRocketParams.hpp b/classes/src/weapon/CHomingRocketParams.hpp new file mode 100644 index 0000000000..c28238aeef --- /dev/null +++ b/classes/src/weapon/CHomingRocketParams.hpp @@ -0,0 +1,16 @@ +#pragma once + +class CHomingRocketParams +{ +public: + bool m_should_use_homing_params_from_info; //0x0000 + bool m_should_ignore_owner_combat_behaviour; //0x0001 + float m_time_before_starting_homing; //0x0004 + float m_time_before_homing_angle_break; //0x0008 + float m_turn_rate_modifier; //0x000C + float m_pitch_yaw_roll_clamp; //0x0010 + float m_default_homing_rocket_break_lock_angle; //0x0014 + float m_default_homing_rocket_break_lock_angle_close; //0x0018 + float m_default_homing_rocket_break_lock_close_distance; //0x001C +}; // Size: 0x0020 +static_assert(sizeof(CHomingRocketParams) == 0x20); \ No newline at end of file diff --git a/classes/src/weapon/CItemInfo.hpp b/classes/src/weapon/CItemInfo.hpp new file mode 100644 index 0000000000..80b33d57e3 --- /dev/null +++ b/classes/src/weapon/CItemInfo.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include + +class parStructure; + +// https://github.com/Parik27/V.Rainbomizer/blob/0c70868626411a1d30483339003b9985b0ff1c98/lib/CItemInfo.hh +class CItemInfo +{ +public: + char pad_0000[8]; //0x0000 + uint32_t m_name; //0x0010 + uint32_t m_model; //0x0014 + uint32_t m_audio; //0x0018 + uint32_t m_slot; //0x001C + +private: + virtual void destructor(); + virtual bool GetIsClassId(uint32_t hash); + + // virtual uint32_t* GetClassId(); (older versions) + virtual uint32_t* _GetClassId(uint32_t* out); + + // Not present in older versions of GTA V + virtual uint32_t* GetBaseClassId(uint32_t& out); + + // as a result, these functions are shifted by 1 function in the vftable. + virtual uint32_t GetModel(); + + virtual parStructure* parser_GetStructure(); + +public: + uint32_t GetClassId() + { + return static_cast(uintptr_t(_GetClassId(nullptr))); + } +}; +static_assert(sizeof(CItemInfo) == 0x20); diff --git a/classes/src/weapon/CWeaponBoneId.hpp b/classes/src/weapon/CWeaponBoneId.hpp new file mode 100644 index 0000000000..1c39ec31f4 --- /dev/null +++ b/classes/src/weapon/CWeaponBoneId.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +class CWeaponBoneId +{ +public: + uint16_t m_bone_id; +}; // Size: 0x0002 +static_assert(sizeof(CWeaponBoneId) == 0x2); \ No newline at end of file diff --git a/classes/src/weapon/CWeaponInfo.hpp b/classes/src/weapon/CWeaponInfo.hpp new file mode 100644 index 0000000000..e1e3634b0f --- /dev/null +++ b/classes/src/weapon/CWeaponInfo.hpp @@ -0,0 +1,514 @@ +#pragma once + +#include "CAmmoInfo.hpp" +#include "CItemInfo.hpp" +#include "CWeaponBoneId.hpp" +#include "../rage/vector.hpp" +#include "../rage/atArray.hpp" +#include "../enums/eExplosionTag.hpp" + +#include +#include + +enum class eDamageType : int32_t +{ + Unknown, + None, + Melee, + Bullet, + BulletRubber, + Explosive, + Fire, + Collision, + Fall, + Drown, + Electric, + BarbedWire, + FireExtinguisher, + Smoke, + WaterCannon, + Tranquilizer +}; + +enum class eFireType : int32_t +{ + None, + Melee, + InstantHit, + DelayedHit, + ProjectTile, + VolumetricParticle +}; + +enum class eWeaponWheelSlot : int32_t +{ + Pistol, + SMG, + Rifle, + Sniper, + UnarmedMelee, + ShotGun, + Heavy, + ThrowableSpecial +}; + +class CAimingInfo +{ +public: + uint32_t m_name_hash;//0x00 + float m_heading_limit;//0x04 + float m_sweep_pitch_min;//0x08 + float m_sweep_pitch_max;//0x0C +}; +static_assert(sizeof(CAimingInfo) == 0x10); + +class sWeaponFx +{ +public: + enum class eEffectGroup : int32_t + { + PunchKick, + MeleeWood, + MeleeMetal, + MeleeSharp, + MeleeGeneric, + PistolSmall, + PistolLarge, + PistolSilenced, + Rubber, + SMG, + ShotGun, + RifleAssault, + RifleSniper, + Rocket, + Grenade, + Molotov, + Fire, + Explosion, + Laser, + Stungun, + HeavyMG, + VehicleMG + } m_effect_group; //0x00 + uint32_t m_flash_fx_hash; //0x04 + uint32_t m_flash_fx_alt_hash; //0x08 + uint32_t m_flash_fx_fp_hash; //0x0C + uint32_t m_flash_fx_fp_alt_hash; //0x10 + uint32_t m_smoke_fx_hash; //0x14 + uint32_t m_smoke_fx_fp_hash; //0x18 + float m_muzzle_smoke_fx_min_level; //0x1C + float m_muzzle_smoke_fx_inc_per_shot; //0x20 + float m_muzzle_smoke_fx_dec_per_sec; //0x24 + char pad_28[8]; + rage::fvector3 m_muzzle_override_offset; //0x30 + char pad_3C[8]; + uint32_t m_shell_fx_hash; //0x44 + uint32_t m_shell_fx_fp_hash; //0x48 + uint32_t m_tracer_fx_hash; //0x4C + uint32_t m_ped_damage_hash; //0x50 + float m_tracer_fx_chance_sp; //0x54 + float m_tracer_fx_chance_mp; //0x58 + char pad_5C[4]; + float m_flash_fx_chance_sp; //0x60 + float m_flash_fx_chance_mp; //0x64 + float m_flash_fx_alt_chance; //0x68 + float m_flash_fx_scale; //0x6C + bool m_flash_fx_light_enabled; //0x70 + bool m_flash_fx_light_casts_shadows; //0x71 + float m_flash_fx_light_offset_dist; //0x74 + char pad_78[8]; + rage::fvector3 m_flash_fx_light_rgba_min; //0x80 + char pad_8C[4]; + rage::fvector3 m_flash_fx_light_rgba_max; //0x90 + char pad_9C[4]; + rage::fvector2 m_flash_fx_light_intensity_minmax; //0xA0 + rage::fvector2 m_flash_fx_light_range_minmax; //0xA8 + rage::fvector2 m_flash_fx_light_falloff_minmax; //0xB0 + bool m_ground_disturb_fx_enabled; // 0xB8 + float m_ground_disturb_fx_dist; //0xBC + uint32_t m_ground_disturb_fx_name_default_hash; //0xC0 + uint32_t m_ground_disturb_fx_name_sand_hash; //0xC4 + uint32_t m_ground_disturb_fx_name_dirt_hash; //0xC8 + uint32_t m_ground_disturb_fx_name_water_hash; //0xCC + uint32_t m_ground_disturb_fx_name_foliage_hash; //0xD0 + char pad_D4[12]; +}; +static_assert(sizeof(sWeaponFx) == 0xE0); + +class CWeaponComponentPoint +{ +public: + uint32_t m_attach_bone_hash; //0x00 + char pad_04[4]; + class sComponent + { + public: + uint32_t m_name_hash; + bool m_default; + } m_components[12]; // 0x08 + static_assert(sizeof(sComponent) == 8); + int32_t m_component_count; // 0x68 +}; +static_assert(sizeof(CWeaponComponentPoint) == 0x6c); + +class CWeaponSpecValue +{ +public: + float m_spec_fresnel;//0x00 + float m_spec_falloff_mult;//0x04 + float m_spec_int_mult;//0x08 + float m_spec2_factor;//0x0c + float m_spec2_color_int;//0x10 + uint32_t m_spec2_color;//0x14 +}; +static_assert(sizeof(CWeaponSpecValue) == 0x18); + +class CWeaponTintSpecValues +{ +public: + uint32_t m_name_hash; //0x00 + rage::atArray m_tints; //0x08 +}; +static_assert(sizeof(CWeaponTintSpecValues) == 0x18); + +class CFiringPatternAlias +{ +public: + uint32_t m_firing_pattern_hash;//0x00 + uint32_t m_alias_hash;//0x04 +}; +static_assert(sizeof(CFiringPatternAlias) == 0x8); + +class CWeaponFiringPatternAliases +{ +public: + uint32_t m_name_hash; //0x00 + rage::atArray m_aliases; //0x08 +}; +static_assert(sizeof(CWeaponFiringPatternAliases) == 0x18); + +class CWeaponUpperBodyFixupExpressionData +{ +public: + uint32_t m_name_hash; //0x00 + class sData + { + public: + float m_idle;//0x00 + float m_walk;//0x04 + float m_run;//0x08 + } m_data[4];//0x04 +}; +static_assert(sizeof(CWeaponUpperBodyFixupExpressionData) == 0x34); + +class CCamoDiffuseTexIdxs +{ +public: + uint32_t m_key_hash; //0x00 + class sKeyValue + { + public: + uint32_t m_key;//0x0 + uint32_t m_value;//0x4 + }; + alignas(0x10) rage::atArray m_items; //0x10 +}; +static_assert(sizeof(CCamoDiffuseTexIdxs) == 0x20); + +class CWeaponInfo : public CItemInfo +{ +public: + eDamageType m_damage_type; //0x0020 + class sExplosion + { + public: + enum eExplosionTag m_default; //0x0000 + enum eExplosionTag m_hit_car; //0x0004 + enum eExplosionTag m_hit_truck; //0x0008 + enum eExplosionTag m_hit_bike; //0x000C + enum eExplosionTag m_hit_boat; //0x0010 + enum eExplosionTag m_hit_plane; //0x0014 + } m_explosion; //0x0024 + static_assert(sizeof(sExplosion) == 0x18); + struct sFrontClearTestParams + { + public: + bool m_should_perform_front_clear_test; //0x0000 + float m_forward_offset; //0x0004 + float m_vertical_offset; //0x0008 + float m_horizontal_offset; //0x000C + float m_capsule_radius; //0x0010 + float m_capsule_length; //0x0014 + } m_front_clear_test_params; //0x003C + static_assert(sizeof(sFrontClearTestParams) == 0x18); + eFireType m_fire_type; //0x0054 + eWeaponWheelSlot m_wheel_slot; //0x0058 + uint32_t m_group; //0x005C + CAmmoInfo *m_ammo_info; //0x0060 + CAimingInfo *m_aiming_info; //0x0068 + uint32_t m_clip_size; //0x0070 + float m_accuracy_spread; //0x0074 + float m_accurate_mode_accuracy_modifier; //0x0078 + float m_run_and_gun_accuracy; //0x007C + float m_run_and_gun_min_accuracy; //0x0080 + float m_recoil_accuracy_max; //0x0084 + float m_recoil_error_time; //0x0088 + float m_recoil_recovery_rate; //0x008C + float m_recoil_accuracy_to_allow_headshot_ai; //0x0090 + float m_min_headshot_distance_ai; //0x0094 + float m_max_headshot_distance_ai; //0x0098 + float m_headshot_damage_modifier_ai; //0x009C + float m_recoil_accuracy_to_allow_headshot_player; //0x00A0 + float m_min_headshot_distance_player; //0x00A4 + float m_max_headshot_distance_player; //0x00A8 + float m_headshot_damage_modifier_player; //0x00AC + float m_damage; //0x00B0 + float m_damage_time; //0x00B4 + float m_damage_time_in_vehicle; //0x00B8 + float m_damage_time_in_vehicle_headshot; //0x00BC + float m_endurance_damage; //0x00C0 + uint32_t N00000898; //0x00C4 + float m_hit_limbs_damage_modifier; //0x00C8 + float m_network_hit_limbs_damage_modifier; //0x00CC + float m_lightly_armoured_damage_modifier; //0x00D0 + float m_vehicle_damage_modifier; //0x00D4 + float m_force; //0x00D8 + float m_force_on_ped; //0x00DC + float m_force_on_vehicle; //0x00E0 + float m_force_on_heli; //0x00E4 + class sBoneForce + { + public: + int32_t m_bone_tag; //0x00 + float m_force_front;//0x04 + float m_force_back;//0x08 + }; + static_assert(sizeof(sBoneForce) == 0xc); + rage::atArray m_override_forces; //0x00E8 + float m_force_max_strength_mult; //0x00F8 + float m_force_falloff_range_start; //0x00FC + float m_force_falloff_range_end; //0x0100 + float m_force_falloff_range_min; //0x0104 + float m_project_force; //0x0108 + float m_frag_impulse; //0x010C + float m_penetration; //0x0110 + float m_vertical_launch_adjustment; //0x0114 + float m_drop_forward_velocity; //0x0118 + float m_speed; //0x011C + uint32_t m_bullets_in_batch; //0x0120 + float m_batch_spread; //0x0124 + float m_reload_time_mp; //0x0128 + float m_reload_time_sp; //0x012C + float m_vehicle_reload_time; //0x0130 + float m_anim_reload_time; //0x0134 + int32_t m_bullets_per_anime_loop; //0x0138 + float m_time_between_shots; //0x013C + float m_time_left_between_shots_where_should_fire_is_cached; //0x0140 + float m_spinup_time; //0x0144 + float m_spin_time; //0x0148 + float m_spindown_time; //0x014C + float m_alternate_wait_time; //0x0150 + float m_bullet_bending_near_radius; //0x0154 + float m_bullet_bending_far_radius; //0x0158 + float m_bullet_bending_zoom_radius; //0x015C + float m_first_person_bullet_bending_near_radius; //0x0160 + float m_first_person_bullet_bending_far_radius; //0x0164 + float m_first_person_bullet_bending_zoom_radius; //0x0168 + char pad_016C[4]; + sWeaponFx m_weapon_fx; //0x0170 + int32_t m_initial_rumble_duration; //0x0250 + float m_initial_rumble_intensity; //0x0254 + float m_initial_rumble_intensity_trigger; //0x0258 + int32_t m_rumble_duration; //0x025C + float m_rumble_intensity; //0x0260 + float m_rumble_intensity_trigger; //0x0264 + float m_rumble_damage_intensity; //0x0268 + int32_t m_initial_rumble_duration_fps; //0x026C + float m_initial_rumble_intensity_fps; //0x0270 + int32_t m_rumble_duration_fps; //0x0274 + float m_rumble_intensity_fps; //0x0278 + float m_network_player_damage_modifier; //0x027C + float m_network_ped_damage_modifier; //0x0280 + float m_network_headshot_modifier; //0x0284 + float m_lock_on_range; //0x0288 + float m_weapon_range; //0x028C + float m_ai_sound_range; //0x0290 + float m_ai_potential_blast_event_range; //0x0294 + float m_damage_fall_off_range_min; //0x0298 + float m_damage_fall_off_range_max; //0x029C + char pad_02A0[8]; + float m_damage_fall_off_modifier; //0x02A8 + char pad_02AC[8]; + uint32_t m_vehicle_weapon_hash; //0x02B4 + uint32_t m_default_camera_hash; //0x02B8 + uint32_t m_aim_camera_hash; //0x02BC + uint32_t m_fire_camera_hash; //0x02C0 + uint32_t m_cover_camera_hash; //0x02C4 + uint32_t m_cover_ready_to_fire_hash; //0x02C8 + uint32_t m_run_and_gun_camera_hash; //0x02CC + uint32_t m_cinematic_shooting_camera_hash; //0x02D0 + uint32_t m_alt_or_scoped_camera_hash; //0x02D4 + uint32_t m_run_and_gun_alt_or_scoped_camera_hash; //0x02D8 + uint32_t m_cinematic_shooting_alt_or_scoped_camera_hash; //0x02DC + uint32_t m_pov_turret_camera_hash; //0x02E0 + uint32_t m_recoil_shake_hash; //0x02E4 + uint32_t m_recoil_shake_hash_first_person; //0x02E8 + uint32_t m_accuracy_offset_shake_hash; //0x02EC + float m_min_time_between_recoil_shakes; //0x02F0 + float m_recoil_shake_amplitude; //0x02F4 + float m_explosion_shake_amplitude; //0x02F8 + float m_camera_fov; //0x02FC + float m_first_person_aim_fov_min; //0x0300 + float m_first_person_aim_fov_max; //0x0304 + float m_first_person_scope_fov; //0x0308 + float m_first_person_scope_attachment_fov; //0x030C + rage::fvector3 m_first_person_driveby_ik_offset; //0x0310 + char pad_031C[4]; + rage::fvector3 m_first_person_rng_offset; //0x0320 + char pad_032C[4]; + rage::fvector3 m_first_person_rng_rotation_offset; //0x0330 + char pad_033C[4]; + rage::fvector3 m_first_person_lt_offset; //0x0340 + char pad_034C[4]; + rage::fvector3 m_first_person_lt_rotation_offset; //0x0350 + char pad_035C[4]; + rage::fvector3 m_first_person_scope_offset; //0x0360 + char pad_036C[4]; + rage::fvector3 m_first_person_scope_attachment_offset; //0x0370 + char pad_037C[4]; + rage::fvector3 m_first_person_scope_rotation_offset; //0x0380 + char pad_038C[4]; + rage::fvector3 m_first_person_scope_attachment_rotation_offset; //0x0390 + char pad_039C[4]; + rage::fvector3 m_first_person_as_third_person_idle_offset; //0x03A0 + char pad_03AC[4]; + rage::fvector3 m_first_person_as_third_person_rng_offset; //0x03B0 + char pad_03BC[4]; + rage::fvector3 m_first_person_as_third_person_lt_offset; //0x03C0 + char pad_03CC[4]; + rage::fvector3 m_first_person_as_third_person_scope_offset; //0x03D0 + char pad_03DC[4]; + rage::fvector3 m_first_person_as_third_person_weapon_blocked_offset; //0x03E0 + char pad_03EC[4]; + float m_first_person_dof_subject_magnification_power_factor_near; //0x03F0 + float m_first_person_dof_max_near_in_focus_distance; //0x03F4 + float m_first_person_dof_max_near_in_focus_distance_blend_level; //0x03F8 + char pad_03FC[4]; + class sFirstPersonScopeAttachmentData + { + public: + uint32_t m_name_hash; //0x00 + float m_first_person_scope_attachment_fov; //0x04 + alignas(0x10) rage::fvector3 m_first_person_scope_attachment_offset; //0x10 + alignas(0x10) rage::fvector3 m_first_person_scope_attachment_rotation_offset; //0x20 + }; + static_assert(sizeof(sFirstPersonScopeAttachmentData) == 0x30); + rage::atArray m_first_person_scope_attachment_data; //0x0400 + float m_zoom_factor_for_accurate_mode; //0x0410 + char pad_0414[12]; + rage::fvector3 m_aim_offset_min; //0x0420 + char pad_042C[4]; + rage::fvector3 m_aim_offset_max; //0x0430 + char pad_043C[4]; + rage::fvector2 m_torso_aim_offset; //0x0440 + rage::fvector2 m_torso_crouched_aim_offset; //0x0448 + float m_aim_probe_length_min; //0x0450 + float m_aim_probe_length_max; //0x0454 + char pad_0458[8]; + rage::fvector3 m_aim_offset_min_fps_idle; //0x0460 + char pad_046C[4]; + rage::fvector3 m_aim_offset_med_fps_idle; //0x0470 + char pad_047C[4]; + rage::fvector3 m_aim_offset_max_fps_idle; //0x0480 + char pad_048C[4]; + rage::fvector3 m_aim_offset_min_fps_lt; //0x0490 + char pad_049C[4]; + rage::fvector3 m_aim_offset_max_fps_lt; //0x04A0 + char pad_04AC[4]; + rage::fvector3 m_aim_offset_min_fps_rng; //0x04B0 + char pad_04BC[4]; + rage::fvector3 m_aim_offset_max_fps_rng; //0x04C0 + char pad_04CC[4]; + rage::fvector3 m_aim_offset_min_fps_scope; //0x04D0 + char pad_04DC[4]; + rage::fvector3 m_aim_offset_max_fps_scope; //0x04E0 + char pad_04EC[4]; + rage::fvector3 m_aim_offset_end_pos_min_fps_idle; //0x04F0 + char pad_04FC[4]; + rage::fvector3 m_aim_offset_end_pos_med_fps_idle; //0x0500 + char pad_050C[4]; + rage::fvector3 m_aim_offset_end_pos_max_fps_idle; //0x0510 + char pad_051C[4]; + rage::fvector3 m_aim_offset_end_pos_min_fps_lt; //0x0520 + char pad_052C[4]; + rage::fvector3 m_aim_offset_end_pos_med_fps_lt; //0x0530 + char pad_053C[4]; + rage::fvector3 m_aim_offset_end_pos_max_fps_lt; //0x0540 + char pad_054C[4]; + float m_aim_probe_radius_override_fps_idle; // 0x0550 + float m_aim_probe_radius_override_fps_idle_stealth; // 0x0554 + float m_aim_probe_radius_override_fps_lt; // 0x0558 + float m_aim_probe_radius_override_fps_rng; // 0x055C + float m_aim_probe_radius_override_fps_scope; // 0x0560 + char pad_0564[12]; + rage::fvector3 m_left_hand_ik_offset; //0x0570 + char pad_057C[4]; + float m_ik_recoil_displacement; //0x0580 + float m_ik_recoil_displacement_scope; //0x0584 + float m_ik_recoil_displacement_scale_backward; //0x0588 + float m_ik_recoil_displacement_scale_vertical; //0x058C + rage::fvector2 m_reticule_hud_position; //0x0590 + rage::fvector2 m_reticule_hud_position_pov_turret; //0x0598 + float m_reticule_min_size_standing; //0x05A0 + float m_reticule_min_size_crouched; //0x05A4 + float m_reticule_scale; //0x05A8 + uint32_t m_reticule_style_hash; //0x05AC + uint32_t m_first_person_reticule_style_hash; //0x05B0 + uint32_t m_pickup_hash; //0x05B4 + uint32_t m_mp_pickup_hash; //0x05B8 + uint32_t m_human_name_hash; //0x05BC + uint32_t m_audio_collision_hash; //0x05C0 + uint32_t m_movement_mode_conditional_idle_hash; //0x05C4 + uint8_t m_ammo_diminishing_rate; //0x05C8 + int8_t m_hud_damage; //0x05C9 + int8_t m_hud_speed; //0x05CA + int8_t m_hud_capacity; //0x05CB + int8_t m_hud_accuracy; //0x05CC + int8_t m_hud_range; //0x05CD + float m_aiming_breathing_additive_weight; //0x05D0 + float m_firing_breathing_additive_weight; //0x05D4 + float m_stealth_aiming_breathing_additive_weight; //0x5D8 + float m_stealth_firing_breathing_additive_weight; //0x5DC + float m_aiming_lean_additive_weight; //0x05E0 + float m_firing_lean_additive_weight; //0x05E4 + float m_stealth_aiming_lean_additive_weight; //0x05E8 + float m_stealth_firing_lean_additive_weight; //0x05EC + char* m_stat_name; //0x05F0 + int32_t m_knockdown_count; //0x05F8 + float m_killshot_impulse_scale; //0x05FC + uint32_t m_nm_shot_tuning_set_hash; //0x0600 + CWeaponComponentPoint m_attach_points[7]; //0x0604 + int32_t m_attach_point_count; //0x08f8 + CWeaponBoneId m_gun_feed_bone; //0x08fc + std::bitset<192> m_weapon_flags; //0x0900 + CWeaponTintSpecValues *m_tint_spec_values; //0x0918 + CWeaponFiringPatternAliases *m_firing_pattern_aliases; //0x0920 + CWeaponUpperBodyFixupExpressionData *m_reload_upper_body_fixup_expression_data; //0x0928 + uint32_t m_target_sequence_group_hash; //0x0930 + float m_bullet_direction_offset_in_degrees; //0x0934 + float m_bullet_direction_pitch_offset; //0x0938 + float m_bullet_direction_pitch_homing_offset; //0x093C + char pad_0940[20]; + float m_expand_ped_capsule_radius; //0x0954 + float m_vehicle_attack_angle; //0x0958 + float m_torso_ik_angle_limit; //0x095C + float m_melee_damage_multiplier; //0x0960 + float m_melee_right_fist_target_health_damage_scaler; //0x0964 + float m_airborne_aircraft_lock_on_multiplier; //0x0968 + float m_armoured_vehicle_glass_damage_override; //0x096C + char pad_0970[8]; + rage::atArray m_camo_diffuse_tex_idxs;//0x0978 + CWeaponBoneId m_rotate_barrel_bone;//0x988 + CWeaponBoneId m_rotate_barrel_bone2;//0x98A +}; +static_assert(sizeof(CWeaponInfo) == 0x0990);