From 0729ab5ae153a2ac6afd95a6e7bbfd61457e38cb Mon Sep 17 00:00:00 2001 From: Andreas Maerten Date: Wed, 25 Sep 2024 01:24:45 +0000 Subject: [PATCH] FUCK TAKE2 & FUCK ROCKSTAR --- .devcontainer/Dockerfile | 7 + .devcontainer/devcontainer.json | 20 + .github/workflows/build.yml | 20 + .gitignore | 12 + CMakeLists.txt | 32 + LICENSE | 21 + README.md | 94 +-- base/CBaseModelInfo.hpp | 44 ++ base/CNavigation.hpp | 28 + base/CObject.hpp | 26 + base/HashTable.hpp | 28 + base/atRTTI.hpp | 11 + base/datBase.hpp | 13 + base/fwArchetype.hpp | 36 + base/fwArchetypeDef.hpp | 43 ++ base/fwExtensibleBase.hpp | 22 + base/fwExtension.hpp | 18 + base/fwExtensionContainer.hpp | 16 + base/fwRefAwareBase.hpp | 14 + base/fwRefAwareBaseImpl.hpp | 13 + base/pgBase.hpp | 36 + base/pgDictionary.hpp | 87 +++ base/phArchetype.hpp | 31 + base/phBound.hpp | 41 ++ base/phBoundCapsule.hpp | 17 + base/phBoundComposite.hpp | 26 + camera/CCameraAngles.hpp | 17 + camera/CCameraManagerAngles.hpp | 10 + camera/CGameCameraAngles.hpp | 11 + classes.cpp | 219 ++++++ draw_handlers/CEntityDrawHandler.hpp | 13 + draw_handlers/CObjectDrawHandler.hpp | 11 + draw_handlers/CPedDrawHandler.hpp | 20 + draw_handlers/CVehicleDrawHandler.hpp | 86 +++ draw_handlers/fwDrawData.hpp | 21 + entities/CAttackers.hpp | 15 + entities/CDynamicEntity.hpp | 18 + entities/CEntity.hpp | 52 ++ entities/CPhysical.hpp | 33 + entities/fwEntity.hpp | 98 +++ enums/eExplosionTag.hpp | 92 +++ enums/eHandlingType.hpp | 16 + game_files/CGameConfig.hpp | 262 +++++++ graphics/CViewport.hpp | 14 + gtav.rcnet | Bin 0 -> 49188 bytes misc/CTunables.hpp | 22 + misc/vfx/TimecycleKeyframeData.hpp | 96 +++ netsync/CProjectBaseSyncDataNode.hpp | 46 ++ netsync/CProjectSyncTree.hpp | 10 + netsync/NodeCommonDataOperations.hpp | 23 + netsync/netSyncDataNode.hpp | 23 + netsync/netSyncNodeBase.hpp | 40 ++ netsync/netSyncParentNode.hpp | 14 + netsync/netSyncTree.hpp | 27 + netsync/nodes/CPedComponents.hpp | 47 ++ .../automobile/CAutomobileCreationNode.hpp | 10 + netsync/nodes/door/CDoorCreationDataNode.hpp | 18 + netsync/nodes/door/CDoorMovementDataNode.hpp | 17 + .../door/CDoorScriptGameStateDataNode.hpp | 18 + .../nodes/door/CDoorScriptInfoDataNode.hpp | 16 + .../CDynamicEntityGameStateDataNode.hpp | 26 + .../entity/CEntityOrientationDataNode.hpp | 11 + .../entity/CEntityScriptGameStateDataNode.hpp | 12 + .../entity/CEntityScriptInfoDataNode.hpp | 14 + netsync/nodes/heli/CHeliControlDataNode.hpp | 25 + netsync/nodes/heli/CHeliHealthDataNode.hpp | 25 + .../nodes/object/CObjectCreationDataNode.hpp | 45 ++ netsync/nodes/ped/CPedAIDataNode.hpp | 11 + netsync/nodes/ped/CPedAppearanceDataNode.hpp | 33 + netsync/nodes/ped/CPedAttachDataNode.hpp | 22 + .../ped/CPedComponentReservationDataNode.hpp | 14 + netsync/nodes/ped/CPedCreationDataNode.hpp | 28 + netsync/nodes/ped/CPedGameStateDataNode.hpp | 77 ++ netsync/nodes/ped/CPedHealthDataNode.hpp | 28 + netsync/nodes/ped/CPedInventoryDataNode.hpp | 22 + netsync/nodes/ped/CPedMovementDataNode.hpp | 17 + .../nodes/ped/CPedMovementGroupDataNode.hpp | 24 + netsync/nodes/ped/CPedOrientationDataNode.hpp | 14 + .../nodes/ped/CPedScriptCreationDataNode.hpp | 11 + .../nodes/ped/CPedTaskSequenceDataNode.hpp | 25 + .../nodes/ped/CPedTaskSpecificDataNode.hpp | 15 + netsync/nodes/ped/CPedTaskTreeDataNode.hpp | 26 + .../physical/CPhysicalAngVelocityDataNode.hpp | 14 + .../physical/CPhysicalAttachDataNode.hpp | 31 + .../physical/CPhysicalGameStateDataNode.hpp | 19 + .../physical/CPhysicalHealthDataNode.hpp | 17 + .../physical/CPhysicalMigrationDataNode.hpp | 12 + .../CPhysicalScriptGameStateDataNode.hpp | 36 + .../CPhysicalScriptMigrationDataNode.hpp | 14 + .../physical/CPhysicalVelocityDataNode.hpp | 14 + .../nodes/pickup/CPickupCreationDataNode.hpp | 27 + .../CPickupPlacementCreationDataNode.hpp | 24 + .../CPlayerAmbientModelStreamingNode.hpp | 16 + .../player/CPlayerAppearanceDataNode.hpp | 93 +++ .../nodes/player/CPlayerCameraDataNode.hpp | 27 + .../nodes/player/CPlayerCreationDataNode.hpp | 19 + .../player/CPlayerExtendedGameStateNode.hpp | 15 + .../nodes/player/CPlayerGameStateDataNode.hpp | 148 ++++ netsync/nodes/player/CPlayerGamerDataNode.hpp | 26 + .../nodes/player/CPlayerPedGroupDataNode.hpp | 35 + netsync/nodes/player/CPlayerSectorPosNode.hpp | 22 + .../player/CPlayerWantedAndLOSDataNode.hpp | 27 + .../CGlobalFlagsDataNode.hpp | 13 + .../CMigrationDataNode.hpp | 14 + .../proximity_migrateable/CSectorDataNode.hpp | 14 + .../CSectorPositionDataNode.hpp | 13 + .../nodes/task/CClonedGeneralSweepInfo.hpp | 23 + .../task/ClonedTakeOffPedVariationInfo.hpp | 34 + .../nodes/train/CTrainGameStateDataNode.hpp | 31 + .../CVehicleComponentReservationDataNode.hpp | 15 + .../nodes/vehicle/CVehicleControlDataNode.hpp | 41 ++ .../vehicle/CVehicleCreationDataNode.hpp | 21 + .../vehicle/CVehicleDamageStatusDataNode.hpp | 32 + .../nodes/vehicle/CVehicleGadgetDataNode.hpp | 38 + .../vehicle/CVehicleGameStateDataNode.hpp | 80 +++ .../nodes/vehicle/CVehicleHealthDataNode.hpp | 35 + .../CVehicleProximityMigrationDataNode.hpp | 20 + .../vehicle/CVehicleSteeringDataNode.hpp | 13 + .../nodes/vehicle/CVehicleTaskDataNode.hpp | 14 + netsync/trees/CDynamicEntitySyncTreeBase.hpp | 12 + netsync/trees/CEntitySyncTreeBase.hpp | 15 + netsync/trees/CPhysicalSyncTreeBase.hpp | 29 + .../CProximityMigrateableSyncTreeBase.hpp | 22 + network/CCommunications.hpp | 33 + network/CJoinRequestContext.hpp | 16 + network/CMsgJoinResponse.hpp | 18 + network/CMsgTextMessage.hpp | 13 + network/CNetComplaintMgr.hpp | 72 ++ network/CNetGamePlayer.hpp | 66 ++ network/CNetGamePlayerDataMsg.hpp | 38 + network/CNetworkPlayerMgr.hpp | 34 + network/ChatData.hpp | 25 + network/ClanData.hpp | 27 + network/Network.hpp | 288 ++++++++ network/RemoteGamerInfoMsg.hpp | 20 + network/netConnection.hpp | 187 +++++ network/netObject.hpp | 133 ++++ network/netPeerAddress.hpp | 32 + network/netPlayer.hpp | 42 ++ network/netPlayerMgrBase.hpp | 37 + network/netTime.hpp | 40 ++ network/snConnectToPeerTask.hpp | 21 + network/snSession.hpp | 195 +++++ ped/CPed.hpp | 75 ++ ped/CPedBoneInfo.hpp | 24 + ped/CPedFactory.hpp | 23 + ped/CPedIntelligence.hpp | 9 + ped/CPedInventory.hpp | 38 + ped/CPedModelInfo.hpp | 48 ++ ped/CPedWeaponManager.hpp | 19 + player/CNonPhysicalPlayerData.hpp | 30 + player/CPlayerAngles.hpp | 48 ++ player/CPlayerCameraData.hpp | 11 + player/CPlayerInfo.hpp | 61 ++ rage/atArray.hpp | 234 ++++++ rage/atReferenceCounter.hpp | 30 + rage/atSingleton.hpp | 22 + rage/gameSkeleton.hpp | 85 +++ rage/grcViewport.hpp | 15 + rage/joaat.hpp | 28 + rage/rlGamerHandle.hpp | 34 + rage/rlGamerInfo.hpp | 25 + rage/rlGamerInfoBase.hpp | 29 + rage/rlMetric.hpp | 25 + rage/rlQueryPresenceAttributesContext.hpp | 19 + rage/rlScHandle.hpp | 27 + rage/rlSessionByGamerTaskResult.hpp | 13 + rage/rlSessionInfo.hpp | 16 + rage/rlTaskStatus.hpp | 10 + rage/scrValue.hpp | 19 + rage/sysMemAllocator.hpp | 25 + rage/vector.hpp | 237 +++++++ script/CGameScriptObjInfo.hpp | 16 + script/GtaThread.hpp | 26 + script/HudColor.hpp | 222 ++++++ script/MPScriptData.hpp | 11 + script/Timer.hpp | 10 + script/dataList.hpp | 22 + script/globals/GPBD_FM.hpp | 659 +++++++++++++++++ script/globals/GPBD_FM_3.hpp | 357 ++++++++++ script/globals/GPBD_Kicking.hpp | 17 + script/globals/GPBD_MissionName.hpp | 8 + script/globals/GSBD.hpp | 94 +++ script/globals/GSBD_BlockB.hpp | 96 +++ script/globals/GSBD_FM.hpp | 66 ++ script/globals/GSBD_Kicking.hpp | 8 + script/globals/GSBD_PropertyInstances.hpp | 11 + script/globals/GlobalPlayerBD.hpp | 669 ++++++++++++++++++ script/globals/g_AMC_playerBD.hpp | 16 + script/scrNativeHandler.hpp | 61 ++ script/scrNativeRegistration.hpp | 43 ++ script/scrNativeRegistrationTable.hpp | 17 + script/scrProgram.hpp | 104 +++ script/scrProgramTable.hpp | 39 + script/scrProgramTableEntry.hpp | 17 + script/scrThread.hpp | 31 + script/scrThreadContext.hpp | 34 + script/scrVector.hpp | 119 ++++ script/scriptHandler.hpp | 81 +++ script/scriptHandlerMgr.hpp | 61 ++ script/scriptHandlerNetComponent.hpp | 16 + script/scriptId.hpp | 26 + script/scriptIdBase.hpp | 57 ++ script/scriptResource.hpp | 10 + script/tlsContext.hpp | 38 + script/types.hpp | 103 +++ security/ObfVar.hpp | 52 ++ security/RageSecurity.hpp | 12 + socialclub/FriendInfo.hpp | 20 + socialclub/FriendRegistry.hpp | 21 + socialclub/ScInfo.hpp | 31 + stats/CPlayerCardStats.hpp | 23 + stats/CStatsSerializationContext.hpp | 27 + ui/CBlipEntry.hpp | 10 + ui/CBlipList.hpp | 10 + ui/blip_t.hpp | 41 ++ vehicle/CAdvancedData.hpp | 11 + vehicle/CBaseSubHandlingData.hpp | 11 + vehicle/CCarHandlingData.hpp | 61 ++ vehicle/CDriveByAnimInfo.hpp | 9 + vehicle/CDriveBySeatDefault.hpp | 14 + vehicle/CDriveByWeaponGroupDefault.hpp | 105 +++ vehicle/CDrivebyWeaponGroups.hpp | 9 + vehicle/CGetPedSeatReturnClass.hpp | 10 + vehicle/CHandlingData.hpp | 86 +++ vehicle/CHandlingObject.hpp | 8 + vehicle/CTrainConfig.hpp | 35 + vehicle/CVehicle.hpp | 63 ++ vehicle/CVehicleDriveByAnimInfo.hpp | 37 + vehicle/CVehicleDriveByMetadataMgr.hpp | 9 + vehicle/CVehicleLayoutMetaData.hpp | 11 + vehicle/CVehicleModelInfo.hpp | 341 +++++++++ vehicle/CVehicleModelInfoLayout.hpp | 15 + vehicle/CVehicleSeatAnimInfo.hpp | 13 + vehicle/CVehicleSeatAnimInfos.hpp | 23 + vehicle/CVehicleSeatMetadataMgr.hpp | 9 + vehicle/CWeaponGroupNames.hpp | 13 + weapon/CAmmoInfo.hpp | 38 + weapon/CAmmoProjectileInfo.hpp | 125 ++++ weapon/CAmmoRocketInfo.hpp | 24 + weapon/CAmmoThrownInfo.hpp | 13 + weapon/CHomingRocketParams.hpp | 16 + weapon/CItemInfo.hpp | 38 + weapon/CWeaponBoneId.hpp | 10 + weapon/CWeaponInfo.hpp | 514 ++++++++++++++ 245 files changed, 11493 insertions(+), 87 deletions(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .github/workflows/build.yml create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 base/CBaseModelInfo.hpp create mode 100644 base/CNavigation.hpp create mode 100644 base/CObject.hpp create mode 100644 base/HashTable.hpp create mode 100644 base/atRTTI.hpp create mode 100644 base/datBase.hpp create mode 100644 base/fwArchetype.hpp create mode 100644 base/fwArchetypeDef.hpp create mode 100644 base/fwExtensibleBase.hpp create mode 100644 base/fwExtension.hpp create mode 100644 base/fwExtensionContainer.hpp create mode 100644 base/fwRefAwareBase.hpp create mode 100644 base/fwRefAwareBaseImpl.hpp create mode 100644 base/pgBase.hpp create mode 100644 base/pgDictionary.hpp create mode 100644 base/phArchetype.hpp create mode 100644 base/phBound.hpp create mode 100644 base/phBoundCapsule.hpp create mode 100644 base/phBoundComposite.hpp create mode 100644 camera/CCameraAngles.hpp create mode 100644 camera/CCameraManagerAngles.hpp create mode 100644 camera/CGameCameraAngles.hpp create mode 100644 classes.cpp create mode 100644 draw_handlers/CEntityDrawHandler.hpp create mode 100644 draw_handlers/CObjectDrawHandler.hpp create mode 100644 draw_handlers/CPedDrawHandler.hpp create mode 100644 draw_handlers/CVehicleDrawHandler.hpp create mode 100644 draw_handlers/fwDrawData.hpp create mode 100644 entities/CAttackers.hpp create mode 100644 entities/CDynamicEntity.hpp create mode 100644 entities/CEntity.hpp create mode 100644 entities/CPhysical.hpp create mode 100644 entities/fwEntity.hpp create mode 100644 enums/eExplosionTag.hpp create mode 100644 enums/eHandlingType.hpp create mode 100644 game_files/CGameConfig.hpp create mode 100644 graphics/CViewport.hpp create mode 100644 gtav.rcnet create mode 100644 misc/CTunables.hpp create mode 100644 misc/vfx/TimecycleKeyframeData.hpp create mode 100644 netsync/CProjectBaseSyncDataNode.hpp create mode 100644 netsync/CProjectSyncTree.hpp create mode 100644 netsync/NodeCommonDataOperations.hpp create mode 100644 netsync/netSyncDataNode.hpp create mode 100644 netsync/netSyncNodeBase.hpp create mode 100644 netsync/netSyncParentNode.hpp create mode 100644 netsync/netSyncTree.hpp create mode 100644 netsync/nodes/CPedComponents.hpp create mode 100644 netsync/nodes/automobile/CAutomobileCreationNode.hpp create mode 100644 netsync/nodes/door/CDoorCreationDataNode.hpp create mode 100644 netsync/nodes/door/CDoorMovementDataNode.hpp create mode 100644 netsync/nodes/door/CDoorScriptGameStateDataNode.hpp create mode 100644 netsync/nodes/door/CDoorScriptInfoDataNode.hpp create mode 100644 netsync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp create mode 100644 netsync/nodes/entity/CEntityOrientationDataNode.hpp create mode 100644 netsync/nodes/entity/CEntityScriptGameStateDataNode.hpp create mode 100644 netsync/nodes/entity/CEntityScriptInfoDataNode.hpp create mode 100644 netsync/nodes/heli/CHeliControlDataNode.hpp create mode 100644 netsync/nodes/heli/CHeliHealthDataNode.hpp create mode 100644 netsync/nodes/object/CObjectCreationDataNode.hpp create mode 100644 netsync/nodes/ped/CPedAIDataNode.hpp create mode 100644 netsync/nodes/ped/CPedAppearanceDataNode.hpp create mode 100644 netsync/nodes/ped/CPedAttachDataNode.hpp create mode 100644 netsync/nodes/ped/CPedComponentReservationDataNode.hpp create mode 100644 netsync/nodes/ped/CPedCreationDataNode.hpp create mode 100644 netsync/nodes/ped/CPedGameStateDataNode.hpp create mode 100644 netsync/nodes/ped/CPedHealthDataNode.hpp create mode 100644 netsync/nodes/ped/CPedInventoryDataNode.hpp create mode 100644 netsync/nodes/ped/CPedMovementDataNode.hpp create mode 100644 netsync/nodes/ped/CPedMovementGroupDataNode.hpp create mode 100644 netsync/nodes/ped/CPedOrientationDataNode.hpp create mode 100644 netsync/nodes/ped/CPedScriptCreationDataNode.hpp create mode 100644 netsync/nodes/ped/CPedTaskSequenceDataNode.hpp create mode 100644 netsync/nodes/ped/CPedTaskSpecificDataNode.hpp create mode 100644 netsync/nodes/ped/CPedTaskTreeDataNode.hpp create mode 100644 netsync/nodes/physical/CPhysicalAngVelocityDataNode.hpp create mode 100644 netsync/nodes/physical/CPhysicalAttachDataNode.hpp create mode 100644 netsync/nodes/physical/CPhysicalGameStateDataNode.hpp create mode 100644 netsync/nodes/physical/CPhysicalHealthDataNode.hpp create mode 100644 netsync/nodes/physical/CPhysicalMigrationDataNode.hpp create mode 100644 netsync/nodes/physical/CPhysicalScriptGameStateDataNode.hpp create mode 100644 netsync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp create mode 100644 netsync/nodes/physical/CPhysicalVelocityDataNode.hpp create mode 100644 netsync/nodes/pickup/CPickupCreationDataNode.hpp create mode 100644 netsync/nodes/pickup_placement/CPickupPlacementCreationDataNode.hpp create mode 100644 netsync/nodes/player/CPlayerAmbientModelStreamingNode.hpp create mode 100644 netsync/nodes/player/CPlayerAppearanceDataNode.hpp create mode 100644 netsync/nodes/player/CPlayerCameraDataNode.hpp create mode 100644 netsync/nodes/player/CPlayerCreationDataNode.hpp create mode 100644 netsync/nodes/player/CPlayerExtendedGameStateNode.hpp create mode 100644 netsync/nodes/player/CPlayerGameStateDataNode.hpp create mode 100644 netsync/nodes/player/CPlayerGamerDataNode.hpp create mode 100644 netsync/nodes/player/CPlayerPedGroupDataNode.hpp create mode 100644 netsync/nodes/player/CPlayerSectorPosNode.hpp create mode 100644 netsync/nodes/player/CPlayerWantedAndLOSDataNode.hpp create mode 100644 netsync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp create mode 100644 netsync/nodes/proximity_migrateable/CMigrationDataNode.hpp create mode 100644 netsync/nodes/proximity_migrateable/CSectorDataNode.hpp create mode 100644 netsync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp create mode 100644 netsync/nodes/task/CClonedGeneralSweepInfo.hpp create mode 100644 netsync/nodes/task/ClonedTakeOffPedVariationInfo.hpp create mode 100644 netsync/nodes/train/CTrainGameStateDataNode.hpp create mode 100644 netsync/nodes/vehicle/CVehicleComponentReservationDataNode.hpp create mode 100644 netsync/nodes/vehicle/CVehicleControlDataNode.hpp create mode 100644 netsync/nodes/vehicle/CVehicleCreationDataNode.hpp create mode 100644 netsync/nodes/vehicle/CVehicleDamageStatusDataNode.hpp create mode 100644 netsync/nodes/vehicle/CVehicleGadgetDataNode.hpp create mode 100644 netsync/nodes/vehicle/CVehicleGameStateDataNode.hpp create mode 100644 netsync/nodes/vehicle/CVehicleHealthDataNode.hpp create mode 100644 netsync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp create mode 100644 netsync/nodes/vehicle/CVehicleSteeringDataNode.hpp create mode 100644 netsync/nodes/vehicle/CVehicleTaskDataNode.hpp create mode 100644 netsync/trees/CDynamicEntitySyncTreeBase.hpp create mode 100644 netsync/trees/CEntitySyncTreeBase.hpp create mode 100644 netsync/trees/CPhysicalSyncTreeBase.hpp create mode 100644 netsync/trees/CProximityMigrateableSyncTreeBase.hpp create mode 100644 network/CCommunications.hpp create mode 100644 network/CJoinRequestContext.hpp create mode 100644 network/CMsgJoinResponse.hpp create mode 100644 network/CMsgTextMessage.hpp create mode 100644 network/CNetComplaintMgr.hpp create mode 100644 network/CNetGamePlayer.hpp create mode 100644 network/CNetGamePlayerDataMsg.hpp create mode 100644 network/CNetworkPlayerMgr.hpp create mode 100644 network/ChatData.hpp create mode 100644 network/ClanData.hpp create mode 100644 network/Network.hpp create mode 100644 network/RemoteGamerInfoMsg.hpp create mode 100644 network/netConnection.hpp create mode 100644 network/netObject.hpp create mode 100644 network/netPeerAddress.hpp create mode 100644 network/netPlayer.hpp create mode 100644 network/netPlayerMgrBase.hpp create mode 100644 network/netTime.hpp create mode 100644 network/snConnectToPeerTask.hpp create mode 100644 network/snSession.hpp create mode 100644 ped/CPed.hpp create mode 100644 ped/CPedBoneInfo.hpp create mode 100644 ped/CPedFactory.hpp create mode 100644 ped/CPedIntelligence.hpp create mode 100644 ped/CPedInventory.hpp create mode 100644 ped/CPedModelInfo.hpp create mode 100644 ped/CPedWeaponManager.hpp create mode 100644 player/CNonPhysicalPlayerData.hpp create mode 100644 player/CPlayerAngles.hpp create mode 100644 player/CPlayerCameraData.hpp create mode 100644 player/CPlayerInfo.hpp create mode 100644 rage/atArray.hpp create mode 100644 rage/atReferenceCounter.hpp create mode 100644 rage/atSingleton.hpp create mode 100644 rage/gameSkeleton.hpp create mode 100644 rage/grcViewport.hpp create mode 100644 rage/joaat.hpp create mode 100644 rage/rlGamerHandle.hpp create mode 100644 rage/rlGamerInfo.hpp create mode 100644 rage/rlGamerInfoBase.hpp create mode 100644 rage/rlMetric.hpp create mode 100644 rage/rlQueryPresenceAttributesContext.hpp create mode 100644 rage/rlScHandle.hpp create mode 100644 rage/rlSessionByGamerTaskResult.hpp create mode 100644 rage/rlSessionInfo.hpp create mode 100644 rage/rlTaskStatus.hpp create mode 100644 rage/scrValue.hpp create mode 100644 rage/sysMemAllocator.hpp create mode 100644 rage/vector.hpp create mode 100644 script/CGameScriptObjInfo.hpp create mode 100644 script/GtaThread.hpp create mode 100644 script/HudColor.hpp create mode 100644 script/MPScriptData.hpp create mode 100644 script/Timer.hpp create mode 100644 script/dataList.hpp create mode 100644 script/globals/GPBD_FM.hpp create mode 100644 script/globals/GPBD_FM_3.hpp create mode 100644 script/globals/GPBD_Kicking.hpp create mode 100644 script/globals/GPBD_MissionName.hpp create mode 100644 script/globals/GSBD.hpp create mode 100644 script/globals/GSBD_BlockB.hpp create mode 100644 script/globals/GSBD_FM.hpp create mode 100644 script/globals/GSBD_Kicking.hpp create mode 100644 script/globals/GSBD_PropertyInstances.hpp create mode 100644 script/globals/GlobalPlayerBD.hpp create mode 100644 script/globals/g_AMC_playerBD.hpp create mode 100644 script/scrNativeHandler.hpp create mode 100644 script/scrNativeRegistration.hpp create mode 100644 script/scrNativeRegistrationTable.hpp create mode 100644 script/scrProgram.hpp create mode 100644 script/scrProgramTable.hpp create mode 100644 script/scrProgramTableEntry.hpp create mode 100644 script/scrThread.hpp create mode 100644 script/scrThreadContext.hpp create mode 100644 script/scrVector.hpp create mode 100644 script/scriptHandler.hpp create mode 100644 script/scriptHandlerMgr.hpp create mode 100644 script/scriptHandlerNetComponent.hpp create mode 100644 script/scriptId.hpp create mode 100644 script/scriptIdBase.hpp create mode 100644 script/scriptResource.hpp create mode 100644 script/tlsContext.hpp create mode 100644 script/types.hpp create mode 100644 security/ObfVar.hpp create mode 100644 security/RageSecurity.hpp create mode 100644 socialclub/FriendInfo.hpp create mode 100644 socialclub/FriendRegistry.hpp create mode 100644 socialclub/ScInfo.hpp create mode 100644 stats/CPlayerCardStats.hpp create mode 100644 stats/CStatsSerializationContext.hpp create mode 100644 ui/CBlipEntry.hpp create mode 100644 ui/CBlipList.hpp create mode 100644 ui/blip_t.hpp create mode 100644 vehicle/CAdvancedData.hpp create mode 100644 vehicle/CBaseSubHandlingData.hpp create mode 100644 vehicle/CCarHandlingData.hpp create mode 100644 vehicle/CDriveByAnimInfo.hpp create mode 100644 vehicle/CDriveBySeatDefault.hpp create mode 100644 vehicle/CDriveByWeaponGroupDefault.hpp create mode 100644 vehicle/CDrivebyWeaponGroups.hpp create mode 100644 vehicle/CGetPedSeatReturnClass.hpp create mode 100644 vehicle/CHandlingData.hpp create mode 100644 vehicle/CHandlingObject.hpp create mode 100644 vehicle/CTrainConfig.hpp create mode 100644 vehicle/CVehicle.hpp create mode 100644 vehicle/CVehicleDriveByAnimInfo.hpp create mode 100644 vehicle/CVehicleDriveByMetadataMgr.hpp create mode 100644 vehicle/CVehicleLayoutMetaData.hpp create mode 100644 vehicle/CVehicleModelInfo.hpp create mode 100644 vehicle/CVehicleModelInfoLayout.hpp create mode 100644 vehicle/CVehicleSeatAnimInfo.hpp create mode 100644 vehicle/CVehicleSeatAnimInfos.hpp create mode 100644 vehicle/CVehicleSeatMetadataMgr.hpp create mode 100644 vehicle/CWeaponGroupNames.hpp create mode 100644 weapon/CAmmoInfo.hpp create mode 100644 weapon/CAmmoProjectileInfo.hpp create mode 100644 weapon/CAmmoRocketInfo.hpp create mode 100644 weapon/CAmmoThrownInfo.hpp create mode 100644 weapon/CHomingRocketParams.hpp create mode 100644 weapon/CItemInfo.hpp create mode 100644 weapon/CWeaponBoneId.hpp create mode 100644 weapon/CWeaponInfo.hpp diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..775e95f --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,7 @@ +FROM ubuntu:devel + +RUN apt clean && apt update && apt install gcc g++ cmake make -y + +WORKDIR /app + +COPY . . diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..eca9b92 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,20 @@ +{ + "name": "C++", + "build": { + "dockerfile": "Dockerfile", + "args": { } + }, + + "workspaceMount": "source=${localWorkspaceFolder},target=/app,type=bind,consistency=delegated", + "workspaceFolder": "/app", + + "runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined", "--network=host"], + "settings": {}, + "extensions": [ + "ms-vscode.cpptools", + "ms-vscode.cmake-tools", + "ms-vscode.cpptools-extension-pack", + "WakaTime.vscode-wakatime" + ], + //"remoteUser": "vscode", +} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..e0a7b21 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,20 @@ +name: Build + +on: [push, pull_request] + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + + steps: + - uses: actions/checkout@v3 + + - name: Configure + run: cmake -S ${{github.workspace}} -B ${{github.workspace}}/build + + - name: Build 64bit release DLL + run: cmake --build ${{github.workspace}}/build --config Release --target GTAV-Classes -- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..42ca560 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +.vscode +.vs +build/ +*.suo +*.db +*.db-shm +*.db-wal +*.opendb +*.sln +*.vcxproj +*.user +*.filters diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..636273d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.11) + +project(GTAV-Classes) + +include(CheckIncludeFileCXX) + +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_REQUIRED_QUIET ON) + +set(OK TRUE) + +file(GLOB_RECURSE HEADERS "**.hpp") +file(GLOB_RECURSE SRC_MAIN "classes.cpp") +source_group(FILES ${SRC_MAIN}) +add_library(GTAV-Classes MODULE "${SRC_MAIN}") + +add_compile_definitions(_CRT_SECURE_NO_WARNINGS) + +message(STATUS "") + +target_include_directories(GTAV-Classes PRIVATE + "${SRC_DIR}" +) + +if(NOT OK) + file(READ "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeError.log" LOG) + message(STATUS ${LOG}) +endif() + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c99a232 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-2022 Yimura + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index b77bed2..47481ed 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,13 @@ -# GTAV Classes +# GTA V Classes +This repository contains a few classes that I've reverse engineered. +They are in no way complete but contain some basics to get you started... -## Getting started +# Usage -To make it easy for you to get started with GitLab, here's a list of recommended next steps. +To modify the Reclass.NET file you have to build Reclass from source, the prebuild binaries will give you an error trying to open the project. -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! +## Disclaimer -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://gitlab.com/YimMenu/GTAV-Classes.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://gitlab.com/YimMenu/GTAV-Classes/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README - -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. +This code is provided purely for educational purposes, if there are objections please open an issue stating your reasoning. \ No newline at end of file diff --git a/base/CBaseModelInfo.hpp b/base/CBaseModelInfo.hpp new file mode 100644 index 0000000..f5acebd --- /dev/null +++ b/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/base/CNavigation.hpp b/base/CNavigation.hpp new file mode 100644 index 0000000..c1c8ae6 --- /dev/null +++ b/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/base/CObject.hpp b/base/CObject.hpp new file mode 100644 index 0000000..f825a50 --- /dev/null +++ b/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/base/HashTable.hpp b/base/HashTable.hpp new file mode 100644 index 0000000..93d9016 --- /dev/null +++ b/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/base/atRTTI.hpp b/base/atRTTI.hpp new file mode 100644 index 0000000..f3e8667 --- /dev/null +++ b/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/base/datBase.hpp b/base/datBase.hpp new file mode 100644 index 0000000..ebbe82e --- /dev/null +++ b/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/base/fwArchetype.hpp b/base/fwArchetype.hpp new file mode 100644 index 0000000..33b1fc2 --- /dev/null +++ b/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/base/fwArchetypeDef.hpp b/base/fwArchetypeDef.hpp new file mode 100644 index 0000000..ee5d052 --- /dev/null +++ b/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/base/fwExtensibleBase.hpp b/base/fwExtensibleBase.hpp new file mode 100644 index 0000000..56d5ed2 --- /dev/null +++ b/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/base/fwExtension.hpp b/base/fwExtension.hpp new file mode 100644 index 0000000..4fe5c79 --- /dev/null +++ b/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/base/fwExtensionContainer.hpp b/base/fwExtensionContainer.hpp new file mode 100644 index 0000000..7d31bfe --- /dev/null +++ b/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/base/fwRefAwareBase.hpp b/base/fwRefAwareBase.hpp new file mode 100644 index 0000000..662646e --- /dev/null +++ b/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/base/fwRefAwareBaseImpl.hpp b/base/fwRefAwareBaseImpl.hpp new file mode 100644 index 0000000..89987eb --- /dev/null +++ b/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/base/pgBase.hpp b/base/pgBase.hpp new file mode 100644 index 0000000..25dde4e --- /dev/null +++ b/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/base/pgDictionary.hpp b/base/pgDictionary.hpp new file mode 100644 index 0000000..2488012 --- /dev/null +++ b/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/base/phArchetype.hpp b/base/phArchetype.hpp new file mode 100644 index 0000000..a0186b4 --- /dev/null +++ b/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/base/phBound.hpp b/base/phBound.hpp new file mode 100644 index 0000000..b3a8d01 --- /dev/null +++ b/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/base/phBoundCapsule.hpp b/base/phBoundCapsule.hpp new file mode 100644 index 0000000..3346637 --- /dev/null +++ b/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/base/phBoundComposite.hpp b/base/phBoundComposite.hpp new file mode 100644 index 0000000..dc73bc9 --- /dev/null +++ b/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/camera/CCameraAngles.hpp b/camera/CCameraAngles.hpp new file mode 100644 index 0000000..0784e91 --- /dev/null +++ b/camera/CCameraAngles.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "../player/CPlayerAngles.hpp" + +class CCameraAngles +{ +private: + char pad_0000[704]; //0x0000 +public: + CPlayerAngles* m_vehicle; //0x02C0 + CPlayerAngles* m_vehicle_two; //0x02C8 +private: + char pad_02D0[240]; //0x02D0 +public: + CPlayerAngles* m_player_first_person; //0x03C0 +}; //Size: 0x03C8 +static_assert(sizeof(CCameraAngles) == 0x3C8); \ No newline at end of file diff --git a/camera/CCameraManagerAngles.hpp b/camera/CCameraManagerAngles.hpp new file mode 100644 index 0000000..88c8df1 --- /dev/null +++ b/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/camera/CGameCameraAngles.hpp b/camera/CGameCameraAngles.hpp new file mode 100644 index 0000000..141448d --- /dev/null +++ b/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.cpp b/classes.cpp new file mode 100644 index 0000000..7c3a655 --- /dev/null +++ b/classes.cpp @@ -0,0 +1,219 @@ +#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" + +// add your classes here \ No newline at end of file diff --git a/draw_handlers/CEntityDrawHandler.hpp b/draw_handlers/CEntityDrawHandler.hpp new file mode 100644 index 0000000..a586b82 --- /dev/null +++ b/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/draw_handlers/CObjectDrawHandler.hpp b/draw_handlers/CObjectDrawHandler.hpp new file mode 100644 index 0000000..0edb8f9 --- /dev/null +++ b/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/draw_handlers/CPedDrawHandler.hpp b/draw_handlers/CPedDrawHandler.hpp new file mode 100644 index 0000000..02ebcbf --- /dev/null +++ b/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/draw_handlers/CVehicleDrawHandler.hpp b/draw_handlers/CVehicleDrawHandler.hpp new file mode 100644 index 0000000..d4ccc9e --- /dev/null +++ b/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/draw_handlers/fwDrawData.hpp b/draw_handlers/fwDrawData.hpp new file mode 100644 index 0000000..7315f3f --- /dev/null +++ b/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/entities/CAttackers.hpp b/entities/CAttackers.hpp new file mode 100644 index 0000000..f087638 --- /dev/null +++ b/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/entities/CDynamicEntity.hpp b/entities/CDynamicEntity.hpp new file mode 100644 index 0000000..2d51bc7 --- /dev/null +++ b/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/entities/CEntity.hpp b/entities/CEntity.hpp new file mode 100644 index 0000000..14c7bb1 --- /dev/null +++ b/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/entities/CPhysical.hpp b/entities/CPhysical.hpp new file mode 100644 index 0000000..1bf416b --- /dev/null +++ b/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/entities/fwEntity.hpp b/entities/fwEntity.hpp new file mode 100644 index 0000000..fa03cfd --- /dev/null +++ b/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/enums/eExplosionTag.hpp b/enums/eExplosionTag.hpp new file mode 100644 index 0000000..4cfca5d --- /dev/null +++ b/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/enums/eHandlingType.hpp b/enums/eHandlingType.hpp new file mode 100644 index 0000000..7257da5 --- /dev/null +++ b/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/game_files/CGameConfig.hpp b/game_files/CGameConfig.hpp new file mode 100644 index 0000000..1df087b --- /dev/null +++ b/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/graphics/CViewport.hpp b/graphics/CViewport.hpp new file mode 100644 index 0000000..91e054e --- /dev/null +++ b/graphics/CViewport.hpp @@ -0,0 +1,14 @@ +#pragma once +#include "rage/grcViewport.hpp" + +struct CViewportGame +{ +public: + virtual ~CViewportGame() = 0; + +private: + char m_pad[8]; + +public: + rage::grcViewport viewport; +}; \ No newline at end of file diff --git a/gtav.rcnet b/gtav.rcnet new file mode 100644 index 0000000000000000000000000000000000000000..3fa9ec00bca0d423daeec3bd90eb17b81294c1d5 GIT binary patch literal 49188 zcmeFZ2UJu~wl9nbA|jw<1jK-%WXU` za)t(pO=|ibbpB!P%-or|@80jN@2$61!LN2W=k%#_s?M%md)G_3i+B_`I5?MaAP%0I zGTsp}WpErEjtnAzgM;(b@Qopdo2|`8J;HILGojLT^YV1dj&S5%(F=TUO8d7zIyf zW(n%-Pv24B^nQw6nKgeW;q&ZJChfa~$6>ly~dxo$9;U30R(Rmm9YtONJW!;Y=PMW#-4 zBt_2_NZ02=LA@AeWIm}G`-vff0r{z`<23KvWLa?9u|DLp#~CdrdL4Qr)wkML zwHZWK#kMOUc3rZNa8k^ zLt_!q>3yD@Ch*#PpW;+E8a-qX0@h!VxrS%m27QRz5C~VxHekZSl zbK=b>Uw<{?24a8xc)B~v*Pz&DXTYa!6M+iee?)Sht{_j;@CUReCap(co_;Uuc+|J2 z!N;Sl-lM_mjhvXT<8z7F-PVQqQOMpq-@UG`4&TFU!Q+Jmz1jqWHD4bgpVz7J8#q1Q zup-9Sw?)Ti7QWDi#P7BvT^?Dt=SWM;2M+d`wR05}H~OC0o=6->>s89AWRPF%BRD#h z%ax!M#RjqSk80SCyPP1mDU}+m4J6L8YhuI>Bdn0(628N|3aM#T;VHB0dk3xA`_-m{ zgTtme-a?nY@3A?LQ_9%QE@XWVcw(KJs^~hr#Xl;|r->et=WFx9Kpn!}-CcK!VF>R! zhbkrH*2PJiGZfkugF0y@*1NYh@G!H?(PSo0aieX35IMjaNc}#uzkdGUUX6Fp-X~Kr zUDLLgr?RAPwx-pPW?2OOcGGZQjUlLh`c}K=?9}Pj3QOhjV3p@bU)8ig-(5si%*X9= z{cD_zoqAAbNTn-!{_ytK@7kJ{fjc3w>zBxeu1G?z4SkS=&WaXY7OKL^6)B&*c91Tw~ znD96!7$k8vDRQHg@dYDE?A0e*jv&_)GYXO7VI*{-NIVQ7U%<-uZQ#cNY_m=GopuF$ z5-q??!)bwbt2?e3PnAITR@fbY5kmKxKV_(;!6naBU|N8mD0#DEhK%b{+}lUhcpsbYy}rtE!PuUVCdM0A z7q|VFWT7&5(WO9(XtMc36MG@eFTh*Sz};cJaP;}@=?h7pd$-_Zkp_gF#edE2)qmah z9rs*E``<18r`o@jMDJW48KQ+zvcHtL#cz>Xf1-a0G_LHh;vaqfHaEJ}AoMf?i9rc6 zK?pxBf4Jk&-3p<9_;j%~=SxaD$VlS7>f-%H@8=Vw;D!h7lTDnY4g2CGD7($&mAO0J z7$SkNmcwc0mhbYTWy#*PuG!A-r8F?56K2p&uu*-jc#W2*Ly&7HvR;-r|5HX-9=gtB z_>2DP^yxu89e$2|z?cKMfQ!jBS>^-W(T6>q>{bF-TeB?Y=Lg~Beb%X)qsyi~FM~t3 z{h1U4*CX7u+ml4xdH4&K247fLw!|e=J$ctX%)U#H?Cg)qFj%1y7Ujnq65XrrG|4q-Qzi7!z`Q+S!b4MD`b{1b%SGO!*OuCF!uwubr%193(;?aZ;JehS@?55{O6ypIa(uz7Dp=c zd$w7fg?w^2I*NxD4?ow^!^L12IP`!YK|0r0kem5DxJ;G1K%TAY-v@#~+%K02{+AZbd zM|I($#q~)4e-2Bx;F6(lhuZJFRwi1Yjvq|(7s5RJmw^`0^b^ATPe1~}PS3@oMZeRX z-`;w0;AJwZKY!u8A`SSVUCcm#I0Alt!QfYdqs4&J9jS8?kO7K}3voC?wt15*Knd0PwF5wUQmL_a5!rLj}LNXck!1YgIpTa2~ zAFF9;=QiB!r|2c#BWBK!wc(c=;)TFm-*Q-RmQMK6ip}SMaFEc-O6+gIX^JbH zcQ4)P#yFg;zn=91680O&y-$EPHdsArm1PIrj(Pjdi*V&@oTl(@g1g-#H-kc$k(=NR zN=&W@Ww?-rB^*;ytK8;Mtxc>^KcVNme#7#$%2m{&endiX<`f9quw@`ucQydxG>|#A znkIc)R^xOO%^Fh(WqU25m~``lt-6TX)jnz6Gz9NQv^LRv{YbN0F_de{n*Af%r;!0{ z3E(d_m5(-&PN5~cO=&K)q$YW!dC5^b)U)d1=1T=@hb@<%x;x1Bb1vNn+;gtq=^V*$ z1z?%{BFaQnc@&&+lb%2wJa+7>EX%MB`rhT9{eNKYY zsG5q0&G!p>W~;Ds1hd>d^S-`l&aKJ5DqoXk3>w|Oo-EHd6#89>72}Qiu{cD@c#rPG z%hgah(GK>tmd})mTKs>QtbG?_mmN&aDyT+?MI%Hg2eij#z|fK=HEY9wf{{7JK&r{5 z1Q0d-%*-5x1=#Jlj;75OE)d9{>=4c9>;kkN|P1p!-SNCTKa0#uNGCpmh*4rAD&#blV zo39nBxgbHBs34=4>b5-X+2ac%ij@#ez!OoRucjgGYdQK{r6kF8>dTP_O3>OS7T=8c z?%?dm?HAq}-Y;7)7z0$%=Q5G^0xrfy+)*RA!4Ljb$Scz|z0)_(LT<@UzYn@okn{7k6Cb{wd}~K8z?B0`>~Tqt zy?>-n6Z~tC6ma&-B==e$oDF!#b?G1@Mt9)jX` z?p96cSL*CXOCh}cZe13d)`#Hx_YYK!@^(cfj~0RA@Kt?RCQ#|e!QS)Wv5|EbPjGU3 z{n(Ql+43rw5VA|h)nq?+vXxwRM%ZWNQux*RiHAl?!Xeb{+_Ef?{r)vnQYocMRZpZ0 z>L>vpcGZ0z1yVz!Ix@XXGRzAEyjF)nYLp1Inl0M_FmWQ(s@A8xc4NaapE!R$!!)w+ zVU`$Ezy}_CimpxlmHC)MXFP7N*2o#L#R6A@C}6A$C~CJ$J|o%OSedzc5X=hc8`71~vUx2L$h6d0m#gXZ>Iw#uRNaU~9nNy2Q7s6$g;&0U%&H7->*o;js7fvg+r zHp6S~JU`Bj(x(3sn4^=b6?zeh(;N1#$4|Q&;QRq^V=QO=(#;L<*%pN-cTR&XY{2d(hTleg&CQ zBWu{?*>bXj#zx$fG70OADF>(b91&i;ZJdxDQ zMI-j>pyFK<$G)fuch{{qiG4(yQ-dc0-XdWbX#p=csG`#ZWzZTgvsE}hcdTs6p`x04 z$lZd+a{S7|%9mF)O!eFyoJW`Tf}OXe_or=>Hl+%-ti#1Q1U(*btu4!;jiM5*KPong zTw-2-B-rG$bWcK#wW7;L;=f0(F3!C0>Ssu%7oJ)YmX)NpSde42SUla z`uEAkS6~{+?uHyR^|z!v`3NTpWc&3M{12?iDl}r!>l5)%!%P;%_y1*4DPp|PC2bMk;*=gN^|hO@qFD}#H*aIoFDBzL%rLFs zFiQ~#5(+oU_Fqu+4_6r&fcBo=(UNc5LHX=jU}dpKUbAiUc*zng(}&wj)ZgmdIK)^= zgl73T;KfSZqgLZ6{JgL_1M_0DwW5HaCuF?z(do01c*MckVY88zURKB3y;dV_i(M&Y zPPO&UA$=W#adDNs_VbhPLxV=N$HwxZozytVs^ir(3BnVoT=`*JnI7T|KM%5sXVK|= z(Rh$3CW|m8DQhM|?Ypx5H)Q=so|El4ME#9O&YG#5sv2F1cLc>d!uKGN?RR?apZbJs z5BNRHk$7UkOe;c6Qhm1x|4k81&OH^tE29>P2k~dJpk!i)_08Ybanl5aGB1F z@aE(15WRs#r6a=dkRYZNm%CC`bcD6Y=l!T>{vZLee=LgrNPY45BP{1#c+SsMkr$ON z7WNhJ6ddr9{UY#CmP{5(ce?`a^rt@a|Bq}b&l`jjgU^2#5lVU{;#A}jvY{-$YSY7U z`=R%6^mP7x;EEN)F&@A87bsD6!->5@+Ss{^!$x`YZBFw=u9u=X7u)_0$ORI-&j0b7 z+HVIc&tA}E5ykmyA(zA5|G@c&>SLd-2r$X{uv7+sNdxV{1xB9vh1wP`ir;rKU!l51 z+K9VwA)b`t?UCefp!rr5hbWTZ^@SZAHp!cB@jEY;;JD-DZsMJDzLpU-vL*dDKs6hk z7`m-&7ulIRousT&H98EgpL7uu>{vc-XfUVJ?kUodsOxrdh2=JJ?9fibW!bYbzU1gd z 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 W`1zhUgYt4>Twv7%o(5(>Ain|2tw^E( literal 0 HcmV?d00001 diff --git a/misc/CTunables.hpp b/misc/CTunables.hpp new file mode 100644 index 0000000..d029c1e --- /dev/null +++ b/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/misc/vfx/TimecycleKeyframeData.hpp b/misc/vfx/TimecycleKeyframeData.hpp new file mode 100644 index 0000000..1a4e3fd --- /dev/null +++ b/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/netsync/CProjectBaseSyncDataNode.hpp b/netsync/CProjectBaseSyncDataNode.hpp new file mode 100644 index 0000000..920c11a --- /dev/null +++ b/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/netsync/CProjectSyncTree.hpp b/netsync/CProjectSyncTree.hpp new file mode 100644 index 0000000..4751bbd --- /dev/null +++ b/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/netsync/NodeCommonDataOperations.hpp b/netsync/NodeCommonDataOperations.hpp new file mode 100644 index 0000000..ee5b642 --- /dev/null +++ b/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/netsync/netSyncDataNode.hpp b/netsync/netSyncDataNode.hpp new file mode 100644 index 0000000..485dc91 --- /dev/null +++ b/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/netsync/netSyncNodeBase.hpp b/netsync/netSyncNodeBase.hpp new file mode 100644 index 0000000..6931aed --- /dev/null +++ b/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/netsync/netSyncParentNode.hpp b/netsync/netSyncParentNode.hpp new file mode 100644 index 0000000..ec0935a --- /dev/null +++ b/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/netsync/netSyncTree.hpp b/netsync/netSyncTree.hpp new file mode 100644 index 0000000..e7dc492 --- /dev/null +++ b/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/netsync/nodes/CPedComponents.hpp b/netsync/nodes/CPedComponents.hpp new file mode 100644 index 0000000..d6d75ec --- /dev/null +++ b/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/netsync/nodes/automobile/CAutomobileCreationNode.hpp b/netsync/nodes/automobile/CAutomobileCreationNode.hpp new file mode 100644 index 0000000..e486882 --- /dev/null +++ b/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/netsync/nodes/door/CDoorCreationDataNode.hpp b/netsync/nodes/door/CDoorCreationDataNode.hpp new file mode 100644 index 0000000..8600a9a --- /dev/null +++ b/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/netsync/nodes/door/CDoorMovementDataNode.hpp b/netsync/nodes/door/CDoorMovementDataNode.hpp new file mode 100644 index 0000000..739a0ec --- /dev/null +++ b/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/netsync/nodes/door/CDoorScriptGameStateDataNode.hpp b/netsync/nodes/door/CDoorScriptGameStateDataNode.hpp new file mode 100644 index 0000000..d1b4a60 --- /dev/null +++ b/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/netsync/nodes/door/CDoorScriptInfoDataNode.hpp b/netsync/nodes/door/CDoorScriptInfoDataNode.hpp new file mode 100644 index 0000000..44cf2f8 --- /dev/null +++ b/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/netsync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp b/netsync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp new file mode 100644 index 0000000..2a75c1d --- /dev/null +++ b/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 m_loads_collisions; // 0x00C4 + bool m_retained; // 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/netsync/nodes/entity/CEntityOrientationDataNode.hpp b/netsync/nodes/entity/CEntityOrientationDataNode.hpp new file mode 100644 index 0000000..9f1c4f0 --- /dev/null +++ b/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/netsync/nodes/entity/CEntityScriptGameStateDataNode.hpp b/netsync/nodes/entity/CEntityScriptGameStateDataNode.hpp new file mode 100644 index 0000000..ac12b91 --- /dev/null +++ b/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/netsync/nodes/entity/CEntityScriptInfoDataNode.hpp b/netsync/nodes/entity/CEntityScriptInfoDataNode.hpp new file mode 100644 index 0000000..0e39858 --- /dev/null +++ b/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/netsync/nodes/heli/CHeliControlDataNode.hpp b/netsync/nodes/heli/CHeliControlDataNode.hpp new file mode 100644 index 0000000..aaaaa1e --- /dev/null +++ b/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/netsync/nodes/heli/CHeliHealthDataNode.hpp b/netsync/nodes/heli/CHeliHealthDataNode.hpp new file mode 100644 index 0000000..4e65c99 --- /dev/null +++ b/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_has_custom_health; + 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_main_rotor_damage_scale; + float m_rear_rotor_damage_scale; + float m_tail_boom_damage_scale; +}; +static_assert(sizeof(CHeliHealthDataNode) == 0x118); +#pragma pack(pop) \ No newline at end of file diff --git a/netsync/nodes/object/CObjectCreationDataNode.hpp b/netsync/nodes/object/CObjectCreationDataNode.hpp new file mode 100644 index 0000000..0058d9f --- /dev/null +++ b/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/netsync/nodes/ped/CPedAIDataNode.hpp b/netsync/nodes/ped/CPedAIDataNode.hpp new file mode 100644 index 0000000..f008935 --- /dev/null +++ b/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/netsync/nodes/ped/CPedAppearanceDataNode.hpp b/netsync/nodes/ped/CPedAppearanceDataNode.hpp new file mode 100644 index 0000000..80338cc --- /dev/null +++ b/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/netsync/nodes/ped/CPedAttachDataNode.hpp b/netsync/nodes/ped/CPedAttachDataNode.hpp new file mode 100644 index 0000000..4c8c087 --- /dev/null +++ b/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/netsync/nodes/ped/CPedComponentReservationDataNode.hpp b/netsync/nodes/ped/CPedComponentReservationDataNode.hpp new file mode 100644 index 0000000..ac12d1c --- /dev/null +++ b/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/netsync/nodes/ped/CPedCreationDataNode.hpp b/netsync/nodes/ped/CPedCreationDataNode.hpp new file mode 100644 index 0000000..dc8c9f3 --- /dev/null +++ b/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/netsync/nodes/ped/CPedGameStateDataNode.hpp b/netsync/nodes/ped/CPedGameStateDataNode.hpp new file mode 100644 index 0000000..bd470da --- /dev/null +++ b/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/netsync/nodes/ped/CPedHealthDataNode.hpp b/netsync/nodes/ped/CPedHealthDataNode.hpp new file mode 100644 index 0000000..2fe33ed --- /dev/null +++ b/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/netsync/nodes/ped/CPedInventoryDataNode.hpp b/netsync/nodes/ped/CPedInventoryDataNode.hpp new file mode 100644 index 0000000..8e171f9 --- /dev/null +++ b/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 m_item_slot_tint[105]; + uint8_t m_item_slot_num_components[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/netsync/nodes/ped/CPedMovementDataNode.hpp b/netsync/nodes/ped/CPedMovementDataNode.hpp new file mode 100644 index 0000000..ae545df --- /dev/null +++ b/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/netsync/nodes/ped/CPedMovementGroupDataNode.hpp b/netsync/nodes/ped/CPedMovementGroupDataNode.hpp new file mode 100644 index 0000000..bf4c90c --- /dev/null +++ b/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/netsync/nodes/ped/CPedOrientationDataNode.hpp b/netsync/nodes/ped/CPedOrientationDataNode.hpp new file mode 100644 index 0000000..c2e5cd0 --- /dev/null +++ b/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/netsync/nodes/ped/CPedScriptCreationDataNode.hpp b/netsync/nodes/ped/CPedScriptCreationDataNode.hpp new file mode 100644 index 0000000..8d7e63e --- /dev/null +++ b/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/netsync/nodes/ped/CPedTaskSequenceDataNode.hpp b/netsync/nodes/ped/CPedTaskSequenceDataNode.hpp new file mode 100644 index 0000000..e7353d8 --- /dev/null +++ b/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/netsync/nodes/ped/CPedTaskSpecificDataNode.hpp b/netsync/nodes/ped/CPedTaskSpecificDataNode.hpp new file mode 100644 index 0000000..4f4bb7f --- /dev/null +++ b/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/netsync/nodes/ped/CPedTaskTreeDataNode.hpp b/netsync/nodes/ped/CPedTaskTreeDataNode.hpp new file mode 100644 index 0000000..f1bf38f --- /dev/null +++ b/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/netsync/nodes/physical/CPhysicalAngVelocityDataNode.hpp b/netsync/nodes/physical/CPhysicalAngVelocityDataNode.hpp new file mode 100644 index 0000000..74a115a --- /dev/null +++ b/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/netsync/nodes/physical/CPhysicalAttachDataNode.hpp b/netsync/nodes/physical/CPhysicalAttachDataNode.hpp new file mode 100644 index 0000000..99a3180 --- /dev/null +++ b/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/netsync/nodes/physical/CPhysicalGameStateDataNode.hpp b/netsync/nodes/physical/CPhysicalGameStateDataNode.hpp new file mode 100644 index 0000000..f2b9b0b --- /dev/null +++ b/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_alpha_type; // 0xC8 + int16_t m_custom_fade_duration; // 0xCC + bool m_unk5; // 0xCE +}; // 0x00CC +static_assert(sizeof(CPhysicalGameStateDataNode) == 0xD0); +#pragma pack(pop) diff --git a/netsync/nodes/physical/CPhysicalHealthDataNode.hpp b/netsync/nodes/physical/CPhysicalHealthDataNode.hpp new file mode 100644 index 0000000..066eb70 --- /dev/null +++ b/netsync/nodes/physical/CPhysicalHealthDataNode.hpp @@ -0,0 +1,17 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 8) +struct CPhysicalHealthDataNode : CSyncDataNodeInfrequent +{ + bool m_has_max_health; //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 m_last_damaged_material_id; //0x00D8 +}; +static_assert(sizeof(CPhysicalHealthDataNode) == 0xE0); +#pragma pack(pop) \ No newline at end of file diff --git a/netsync/nodes/physical/CPhysicalMigrationDataNode.hpp b/netsync/nodes/physical/CPhysicalMigrationDataNode.hpp new file mode 100644 index 0000000..65a9259 --- /dev/null +++ b/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/netsync/nodes/physical/CPhysicalScriptGameStateDataNode.hpp b/netsync/nodes/physical/CPhysicalScriptGameStateDataNode.hpp new file mode 100644 index 0000000..43ca261 --- /dev/null +++ b/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/netsync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp b/netsync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp new file mode 100644 index 0000000..79aaa7f --- /dev/null +++ b/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/netsync/nodes/physical/CPhysicalVelocityDataNode.hpp b/netsync/nodes/physical/CPhysicalVelocityDataNode.hpp new file mode 100644 index 0000000..83ee8cb --- /dev/null +++ b/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/netsync/nodes/pickup/CPickupCreationDataNode.hpp b/netsync/nodes/pickup/CPickupCreationDataNode.hpp new file mode 100644 index 0000000..f1ded50 --- /dev/null +++ b/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/netsync/nodes/pickup_placement/CPickupPlacementCreationDataNode.hpp b/netsync/nodes/pickup_placement/CPickupPlacementCreationDataNode.hpp new file mode 100644 index 0000000..7dab6ba --- /dev/null +++ b/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/netsync/nodes/player/CPlayerAmbientModelStreamingNode.hpp b/netsync/nodes/player/CPlayerAmbientModelStreamingNode.hpp new file mode 100644 index 0000000..51ae06a --- /dev/null +++ b/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/netsync/nodes/player/CPlayerAppearanceDataNode.hpp b/netsync/nodes/player/CPlayerAppearanceDataNode.hpp new file mode 100644 index 0000000..6338e46 --- /dev/null +++ b/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/netsync/nodes/player/CPlayerCameraDataNode.hpp b/netsync/nodes/player/CPlayerCameraDataNode.hpp new file mode 100644 index 0000000..190b669 --- /dev/null +++ b/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/netsync/nodes/player/CPlayerCreationDataNode.hpp b/netsync/nodes/player/CPlayerCreationDataNode.hpp new file mode 100644 index 0000000..cc430c2 --- /dev/null +++ b/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/netsync/nodes/player/CPlayerExtendedGameStateNode.hpp b/netsync/nodes/player/CPlayerExtendedGameStateNode.hpp new file mode 100644 index 0000000..14f4db1 --- /dev/null +++ b/netsync/nodes/player/CPlayerExtendedGameStateNode.hpp @@ -0,0 +1,15 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" + +#pragma pack(push, 1) +class CPlayerExtendedGameStateNode : CSyncDataNodeInfrequent +{ +public: + float waypoint_x; //0x00C0 + float waypoint_y; //0x00C4 + uint16_t waypoint_entity; //0x00C5 + bool has_active_waypoint; //0x00C6 + bool owns_waypoint; //0x00C7 +}; +#pragma pack(pop) diff --git a/netsync/nodes/player/CPlayerGameStateDataNode.hpp b/netsync/nodes/player/CPlayerGameStateDataNode.hpp new file mode 100644 index 0000000..532a320 --- /dev/null +++ b/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/netsync/nodes/player/CPlayerGamerDataNode.hpp b/netsync/nodes/player/CPlayerGamerDataNode.hpp new file mode 100644 index 0000000..c1f210a --- /dev/null +++ b/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/netsync/nodes/player/CPlayerPedGroupDataNode.hpp b/netsync/nodes/player/CPlayerPedGroupDataNode.hpp new file mode 100644 index 0000000..2f765ba --- /dev/null +++ b/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/netsync/nodes/player/CPlayerSectorPosNode.hpp b/netsync/nodes/player/CPlayerSectorPosNode.hpp new file mode 100644 index 0000000..b4608c0 --- /dev/null +++ b/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/netsync/nodes/player/CPlayerWantedAndLOSDataNode.hpp b/netsync/nodes/player/CPlayerWantedAndLOSDataNode.hpp new file mode 100644 index 0000000..d956e34 --- /dev/null +++ b/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/netsync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp b/netsync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp new file mode 100644 index 0000000..d72c5dc --- /dev/null +++ b/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/netsync/nodes/proximity_migrateable/CMigrationDataNode.hpp b/netsync/nodes/proximity_migrateable/CMigrationDataNode.hpp new file mode 100644 index 0000000..2dd2ef7 --- /dev/null +++ b/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/netsync/nodes/proximity_migrateable/CSectorDataNode.hpp b/netsync/nodes/proximity_migrateable/CSectorDataNode.hpp new file mode 100644 index 0000000..fd83204 --- /dev/null +++ b/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/netsync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp b/netsync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp new file mode 100644 index 0000000..27ba243 --- /dev/null +++ b/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/netsync/nodes/task/CClonedGeneralSweepInfo.hpp b/netsync/nodes/task/CClonedGeneralSweepInfo.hpp new file mode 100644 index 0000000..bfc1c39 --- /dev/null +++ b/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/netsync/nodes/task/ClonedTakeOffPedVariationInfo.hpp b/netsync/nodes/task/ClonedTakeOffPedVariationInfo.hpp new file mode 100644 index 0000000..1363566 --- /dev/null +++ b/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/netsync/nodes/train/CTrainGameStateDataNode.hpp b/netsync/nodes/train/CTrainGameStateDataNode.hpp new file mode 100644 index 0000000..6d1fba2 --- /dev/null +++ b/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/netsync/nodes/vehicle/CVehicleComponentReservationDataNode.hpp b/netsync/nodes/vehicle/CVehicleComponentReservationDataNode.hpp new file mode 100644 index 0000000..70ba08e --- /dev/null +++ b/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/netsync/nodes/vehicle/CVehicleControlDataNode.hpp b/netsync/nodes/vehicle/CVehicleControlDataNode.hpp new file mode 100644 index 0000000..ea297ea --- /dev/null +++ b/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/netsync/nodes/vehicle/CVehicleCreationDataNode.hpp b/netsync/nodes/vehicle/CVehicleCreationDataNode.hpp new file mode 100644 index 0000000..c654271 --- /dev/null +++ b/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/netsync/nodes/vehicle/CVehicleDamageStatusDataNode.hpp b/netsync/nodes/vehicle/CVehicleDamageStatusDataNode.hpp new file mode 100644 index 0000000..20740b9 --- /dev/null +++ b/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/netsync/nodes/vehicle/CVehicleGadgetDataNode.hpp b/netsync/nodes/vehicle/CVehicleGadgetDataNode.hpp new file mode 100644 index 0000000..73b4cd3 --- /dev/null +++ b/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/netsync/nodes/vehicle/CVehicleGameStateDataNode.hpp b/netsync/nodes/vehicle/CVehicleGameStateDataNode.hpp new file mode 100644 index 0000000..a24d51b --- /dev/null +++ b/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/netsync/nodes/vehicle/CVehicleHealthDataNode.hpp b/netsync/nodes/vehicle/CVehicleHealthDataNode.hpp new file mode 100644 index 0000000..228de38 --- /dev/null +++ b/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/netsync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp b/netsync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp new file mode 100644 index 0000000..0346401 --- /dev/null +++ b/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/netsync/nodes/vehicle/CVehicleSteeringDataNode.hpp b/netsync/nodes/vehicle/CVehicleSteeringDataNode.hpp new file mode 100644 index 0000000..525ae88 --- /dev/null +++ b/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/netsync/nodes/vehicle/CVehicleTaskDataNode.hpp b/netsync/nodes/vehicle/CVehicleTaskDataNode.hpp new file mode 100644 index 0000000..90d52d9 --- /dev/null +++ b/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/netsync/trees/CDynamicEntitySyncTreeBase.hpp b/netsync/trees/CDynamicEntitySyncTreeBase.hpp new file mode 100644 index 0000000..f1d696d --- /dev/null +++ b/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/netsync/trees/CEntitySyncTreeBase.hpp b/netsync/trees/CEntitySyncTreeBase.hpp new file mode 100644 index 0000000..45ced73 --- /dev/null +++ b/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/netsync/trees/CPhysicalSyncTreeBase.hpp b/netsync/trees/CPhysicalSyncTreeBase.hpp new file mode 100644 index 0000000..69854f3 --- /dev/null +++ b/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/netsync/trees/CProximityMigrateableSyncTreeBase.hpp b/netsync/trees/CProximityMigrateableSyncTreeBase.hpp new file mode 100644 index 0000000..38b525d --- /dev/null +++ b/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/network/CCommunications.hpp b/network/CCommunications.hpp new file mode 100644 index 0000000..3dbb2ba --- /dev/null +++ b/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/network/CJoinRequestContext.hpp b/network/CJoinRequestContext.hpp new file mode 100644 index 0000000..dae6526 --- /dev/null +++ b/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/network/CMsgJoinResponse.hpp b/network/CMsgJoinResponse.hpp new file mode 100644 index 0000000..c1fd254 --- /dev/null +++ b/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/network/CMsgTextMessage.hpp b/network/CMsgTextMessage.hpp new file mode 100644 index 0000000..bd2050d --- /dev/null +++ b/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/network/CNetComplaintMgr.hpp b/network/CNetComplaintMgr.hpp new file mode 100644 index 0000000..866956a --- /dev/null +++ b/network/CNetComplaintMgr.hpp @@ -0,0 +1,72 @@ +#pragma once +#include "rage/rlGamerHandle.hpp" + +#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/network/CNetGamePlayer.hpp b/network/CNetGamePlayer.hpp new file mode 100644 index 0000000..323fe67 --- /dev/null +++ b/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/network/CNetGamePlayerDataMsg.hpp b/network/CNetGamePlayerDataMsg.hpp new file mode 100644 index 0000000..18179ed --- /dev/null +++ b/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/network/CNetworkPlayerMgr.hpp b/network/CNetworkPlayerMgr.hpp new file mode 100644 index 0000000..52240e5 --- /dev/null +++ b/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/network/ChatData.hpp b/network/ChatData.hpp new file mode 100644 index 0000000..dc65b0e --- /dev/null +++ b/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/network/ClanData.hpp b/network/ClanData.hpp new file mode 100644 index 0000000..1136ba4 --- /dev/null +++ b/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/network/Network.hpp b/network/Network.hpp new file mode 100644 index 0000000..46c77aa --- /dev/null +++ b/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/network/RemoteGamerInfoMsg.hpp b/network/RemoteGamerInfoMsg.hpp new file mode 100644 index 0000000..7061dfc --- /dev/null +++ b/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/network/netConnection.hpp b/network/netConnection.hpp new file mode 100644 index 0000000..8e12e97 --- /dev/null +++ b/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/network/netObject.hpp b/network/netObject.hpp new file mode 100644 index 0000000..08f4467 --- /dev/null +++ b/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/network/netPeerAddress.hpp b/network/netPeerAddress.hpp new file mode 100644 index 0000000..0127e58 --- /dev/null +++ b/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/network/netPlayer.hpp b/network/netPlayer.hpp new file mode 100644 index 0000000..30b2937 --- /dev/null +++ b/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/network/netPlayerMgrBase.hpp b/network/netPlayerMgrBase.hpp new file mode 100644 index 0000000..1222670 --- /dev/null +++ b/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/network/netTime.hpp b/network/netTime.hpp new file mode 100644 index 0000000..c18e0e9 --- /dev/null +++ b/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/network/snConnectToPeerTask.hpp b/network/snConnectToPeerTask.hpp new file mode 100644 index 0000000..8edc25b --- /dev/null +++ b/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/network/snSession.hpp b/network/snSession.hpp new file mode 100644 index 0000000..2762151 --- /dev/null +++ b/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/ped/CPed.hpp b/ped/CPed.hpp new file mode 100644 index 0000000..a24b2d1 --- /dev/null +++ b/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/ped/CPedBoneInfo.hpp b/ped/CPedBoneInfo.hpp new file mode 100644 index 0000000..ba54b77 --- /dev/null +++ b/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/ped/CPedFactory.hpp b/ped/CPedFactory.hpp new file mode 100644 index 0000000..90856f5 --- /dev/null +++ b/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/ped/CPedIntelligence.hpp b/ped/CPedIntelligence.hpp new file mode 100644 index 0000000..3dd798e --- /dev/null +++ b/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/ped/CPedInventory.hpp b/ped/CPedInventory.hpp new file mode 100644 index 0000000..0f546f3 --- /dev/null +++ b/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/ped/CPedModelInfo.hpp b/ped/CPedModelInfo.hpp new file mode 100644 index 0000000..b1c7108 --- /dev/null +++ b/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/ped/CPedWeaponManager.hpp b/ped/CPedWeaponManager.hpp new file mode 100644 index 0000000..3e484a1 --- /dev/null +++ b/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/player/CNonPhysicalPlayerData.hpp b/player/CNonPhysicalPlayerData.hpp new file mode 100644 index 0000000..13cc735 --- /dev/null +++ b/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/player/CPlayerAngles.hpp b/player/CPlayerAngles.hpp new file mode 100644 index 0000000..0aca68f --- /dev/null +++ b/player/CPlayerAngles.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "../rage/vector.hpp" +#include "CPlayerCameraData.hpp" + +#pragma pack(push, 4) +class CPlayerAngles +{ +private: + char pad_0000[16]; //0x0000 +public: + CPlayerCameraData* m_cam_data; //0x0010 +private: + char pad_0018[24]; //0x0018 +public: + rage::fvector3 m_theta_angles; //0x0030 +private: + char pad_003C[4]; //0x003C +public: + rage::fvector3 m_camera_rotation_first_person; //0x0040 +private: + char pad_004C[4]; //0x004C +public: + rage::fvector3 m_omega_angles; //0x0050 +private: + char pad_005C[4]; //0x005C +public: + rage::fvector3 m_location; //0x0060 +private: + char pad_006C[36]; //0x006C +public: + float m_fov; //0x0090 +private: + char pad_0094[828]; //0x0094 +public: + rage::fvector3 m_camera_rotation; //0x03D0 + + void set_camera(rage::fvector3 new_angles) + { + m_camera_rotation = new_angles; + } + void set_fps_camera(rage::fvector3 new_angles) + { + m_camera_rotation_first_person = new_angles; + } +}; //Size: 0x03DC +#pragma pack(pop) +static_assert(sizeof(CPlayerAngles) == 0x3DC, "CPlayerAngles is not properly sized!"); \ No newline at end of file diff --git a/player/CPlayerCameraData.hpp b/player/CPlayerCameraData.hpp new file mode 100644 index 0000000..4570ada --- /dev/null +++ b/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/player/CPlayerInfo.hpp b/player/CPlayerInfo.hpp new file mode 100644 index 0000000..5b5a0bd --- /dev/null +++ b/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/rage/atArray.hpp b/rage/atArray.hpp new file mode 100644 index 0000000..b0b9ca1 --- /dev/null +++ b/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/rage/atReferenceCounter.hpp b/rage/atReferenceCounter.hpp new file mode 100644 index 0000000..e9bb2fa --- /dev/null +++ b/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/rage/atSingleton.hpp b/rage/atSingleton.hpp new file mode 100644 index 0000000..bd3f8d0 --- /dev/null +++ b/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/rage/gameSkeleton.hpp b/rage/gameSkeleton.hpp new file mode 100644 index 0000000..7e72884 --- /dev/null +++ b/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/rage/grcViewport.hpp b/rage/grcViewport.hpp new file mode 100644 index 0000000..88034b9 --- /dev/null +++ b/rage/grcViewport.hpp @@ -0,0 +1,15 @@ +#pragma once +#include "vector.hpp" + +namespace rage +{ + struct grcViewport + { + fmatrix44 m_world; + fmatrix44 m_worldView; + fmatrix44 m_worldViewProj; + fmatrix44 m_inverseView; + fmatrix44 m_view; + fmatrix44 m_projection; + }; +} \ No newline at end of file diff --git a/rage/joaat.hpp b/rage/joaat.hpp new file mode 100644 index 0000000..4823114 --- /dev/null +++ b/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/rage/rlGamerHandle.hpp b/rage/rlGamerHandle.hpp new file mode 100644 index 0000000..cfec4b5 --- /dev/null +++ b/rage/rlGamerHandle.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include + +namespace rage +{ + enum rlPlatforms : uint8_t + { + UNK0, + XBOX, + PLAYSTATION, + PC, + }; + +#pragma pack(push,8) + class rlGamerHandle + { + public: + int64_t m_rockstar_id; //0x0000 + uint8_t m_platform; //0x0008 + uint8_t m_padding; //0x0009 + + inline rlGamerHandle() = default; + + inline rlGamerHandle(int64_t rockstar_id) : + m_rockstar_id(rockstar_id), + m_platform(rlPlatforms::PC), + m_padding(0) + { + } + }; //Size: 0x0010 + static_assert(sizeof(rlGamerHandle) == 0x10); +#pragma pack(pop) +} \ No newline at end of file diff --git a/rage/rlGamerInfo.hpp b/rage/rlGamerInfo.hpp new file mode 100644 index 0000000..a061a49 --- /dev/null +++ b/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/rage/rlGamerInfoBase.hpp b/rage/rlGamerInfoBase.hpp new file mode 100644 index 0000000..d63a356 --- /dev/null +++ b/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/rage/rlMetric.hpp b/rage/rlMetric.hpp new file mode 100644 index 0000000..79dea88 --- /dev/null +++ b/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/rage/rlQueryPresenceAttributesContext.hpp b/rage/rlQueryPresenceAttributesContext.hpp new file mode 100644 index 0000000..5f94abe --- /dev/null +++ b/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/rage/rlScHandle.hpp b/rage/rlScHandle.hpp new file mode 100644 index 0000000..054b1ad --- /dev/null +++ b/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/rage/rlSessionByGamerTaskResult.hpp b/rage/rlSessionByGamerTaskResult.hpp new file mode 100644 index 0000000..0868e5a --- /dev/null +++ b/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/rage/rlSessionInfo.hpp b/rage/rlSessionInfo.hpp new file mode 100644 index 0000000..0e81a06 --- /dev/null +++ b/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/rage/rlTaskStatus.hpp b/rage/rlTaskStatus.hpp new file mode 100644 index 0000000..706b376 --- /dev/null +++ b/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/rage/scrValue.hpp b/rage/scrValue.hpp new file mode 100644 index 0000000..291f666 --- /dev/null +++ b/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/rage/sysMemAllocator.hpp b/rage/sysMemAllocator.hpp new file mode 100644 index 0000000..54e8ea7 --- /dev/null +++ b/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/rage/vector.hpp b/rage/vector.hpp new file mode 100644 index 0000000..ced7d56 --- /dev/null +++ b/rage/vector.hpp @@ -0,0 +1,237 @@ +#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) noexcept : x(x), + y(y), + z(z) + { + } + + vector3() noexcept : x(), + y(), + z() + { + } + + vector3 operator+(const vector3 &rhs) const + { + return vector3(x + rhs.x, y + rhs.y, z + rhs.z); + } + + vector3 operator-(const vector3 &rhs) const + { + return vector3(x - rhs.x, y - rhs.y, z - rhs.z); + } + + vector3 operator*(const vector3 &rhs) const + { + return vector3(x * rhs.x, y * rhs.y, z * rhs.z); + } + + vector3 operator/(const vector3 &rhs) const + { + return vector3(x / rhs.x, y / rhs.y, z / rhs.z); + } + + vector3 operator+(const float &rhs) const + { + return vector3(x + rhs, y + rhs, z + rhs); + } + + vector3 operator-(const float &rhs) const + { + return vector3(x - rhs, y - rhs, z - rhs); + } + + vector3 operator*(const float &rhs) const + { + return vector3(x * rhs, y * rhs, z * rhs); + } + + vector3 operator/(const float &rhs) const + { + return vector3(x / rhs, y / rhs, z / rhs); + } + + bool operator==(const vector3 &rhs) const + { + return x == rhs.x && y == rhs.y && z == rhs.z; + } + + vector3 &operator+=(const vector3 &rhs) + { + return *this = *this + rhs; + } + + vector3 &operator-=(const vector3 &rhs) + { + return *this = *this - rhs; + } + + vector3 &operator*=(const vector3 &rhs) + { + return *this = *this * rhs; + } + + vector3 &operator/=(const vector3 &rhs) + { + return *this = *this / rhs; + } + + vector3 &operator+=(const float &rhs) + { + return *this = *this + rhs; + } + + vector3 &operator-=(const float &rhs) + { + return *this = *this - rhs; + } + + vector3 &operator*=(const float &rhs) + { + return *this = *this * rhs; + } + + vector3 &operator/=(const float &rhs) + { + return *this = *this / rhs; + } + + T length() const + { + return sqrt(x * x + y * y + z * z); + } + + T magnitude() const + { + return length(); + } + + // This doesn't modify the vector inline. + vector3 normalize() const + { + T len = length(); + if (len) + { + return *this * (1 / len); + } + + return *this; + } + + // This doesn't modify the vector inline. + vector3 multiply(const vector3 rhs) const + { + return vector3(x * rhs.x, y * rhs.y, z * rhs.z); + } + + // This doesn't modify the vector inline. + vector3 invert() const + { + return *this * -1; + } + + // This doesn't modify the vector inline. + vector3 cross_product(const vector3 &rhs) const + { + return vector3(y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x); + } + + float dot_product(const vector3 &rhs) const + { + return x * rhs.x + y * rhs.y + z * rhs.z; + } + + float distance(const vector3 &rhs) const + { + return (*this - rhs).length(); + } + }; + + 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/script/CGameScriptObjInfo.hpp b/script/CGameScriptObjInfo.hpp new file mode 100644 index 0000000..b2b5074 --- /dev/null +++ b/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/script/GtaThread.hpp b/script/GtaThread.hpp new file mode 100644 index 0000000..da2a9e6 --- /dev/null +++ b/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/script/HudColor.hpp b/script/HudColor.hpp new file mode 100644 index 0000000..b0852ca --- /dev/null +++ b/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/script/MPScriptData.hpp b/script/MPScriptData.hpp new file mode 100644 index 0000000..c9d22fb --- /dev/null +++ b/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/script/Timer.hpp b/script/Timer.hpp new file mode 100644 index 0000000..0f21f11 --- /dev/null +++ b/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/script/dataList.hpp b/script/dataList.hpp new file mode 100644 index 0000000..bf6682c --- /dev/null +++ b/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/script/globals/GPBD_FM.hpp b/script/globals/GPBD_FM.hpp new file mode 100644 index 0000000..2f06877 --- /dev/null +++ b/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/script/globals/GPBD_FM_3.hpp b/script/globals/GPBD_FM_3.hpp new file mode 100644 index 0000000..ad05095 --- /dev/null +++ b/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/script/globals/GPBD_Kicking.hpp b/script/globals/GPBD_Kicking.hpp new file mode 100644 index 0000000..d926d33 --- /dev/null +++ b/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/script/globals/GPBD_MissionName.hpp b/script/globals/GPBD_MissionName.hpp new file mode 100644 index 0000000..22bb3f4 --- /dev/null +++ b/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/script/globals/GSBD.hpp b/script/globals/GSBD.hpp new file mode 100644 index 0000000..f1ea0ba --- /dev/null +++ b/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/script/globals/GSBD_BlockB.hpp b/script/globals/GSBD_BlockB.hpp new file mode 100644 index 0000000..711648c --- /dev/null +++ b/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/script/globals/GSBD_FM.hpp b/script/globals/GSBD_FM.hpp new file mode 100644 index 0000000..a0449ab --- /dev/null +++ b/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/script/globals/GSBD_Kicking.hpp b/script/globals/GSBD_Kicking.hpp new file mode 100644 index 0000000..93d4367 --- /dev/null +++ b/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/script/globals/GSBD_PropertyInstances.hpp b/script/globals/GSBD_PropertyInstances.hpp new file mode 100644 index 0000000..1c44137 --- /dev/null +++ b/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/script/globals/GlobalPlayerBD.hpp b/script/globals/GlobalPlayerBD.hpp new file mode 100644 index 0000000..706b326 --- /dev/null +++ b/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/script/globals/g_AMC_playerBD.hpp b/script/globals/g_AMC_playerBD.hpp new file mode 100644 index 0000000..4733f50 --- /dev/null +++ b/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/script/scrNativeHandler.hpp b/script/scrNativeHandler.hpp new file mode 100644 index 0000000..cfda788 --- /dev/null +++ b/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/script/scrNativeRegistration.hpp b/script/scrNativeRegistration.hpp new file mode 100644 index 0000000..71a9737 --- /dev/null +++ b/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/script/scrNativeRegistrationTable.hpp b/script/scrNativeRegistrationTable.hpp new file mode 100644 index 0000000..56b87d7 --- /dev/null +++ b/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/script/scrProgram.hpp b/script/scrProgram.hpp new file mode 100644 index 0000000..592ec21 --- /dev/null +++ b/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/script/scrProgramTable.hpp b/script/scrProgramTable.hpp new file mode 100644 index 0000000..21e2b3f --- /dev/null +++ b/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/script/scrProgramTableEntry.hpp b/script/scrProgramTableEntry.hpp new file mode 100644 index 0000000..e43df2e --- /dev/null +++ b/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/script/scrThread.hpp b/script/scrThread.hpp new file mode 100644 index 0000000..9074191 --- /dev/null +++ b/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/script/scrThreadContext.hpp b/script/scrThreadContext.hpp new file mode 100644 index 0000000..e47aed5 --- /dev/null +++ b/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/script/scrVector.hpp b/script/scrVector.hpp new file mode 100644 index 0000000..6aabff7 --- /dev/null +++ b/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/script/scriptHandler.hpp b/script/scriptHandler.hpp new file mode 100644 index 0000000..5940c03 --- /dev/null +++ b/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/script/scriptHandlerMgr.hpp b/script/scriptHandlerMgr.hpp new file mode 100644 index 0000000..dce7f35 --- /dev/null +++ b/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/script/scriptHandlerNetComponent.hpp b/script/scriptHandlerNetComponent.hpp new file mode 100644 index 0000000..3f2d7bc --- /dev/null +++ b/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/script/scriptId.hpp b/script/scriptId.hpp new file mode 100644 index 0000000..4577bbf --- /dev/null +++ b/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/script/scriptIdBase.hpp b/script/scriptIdBase.hpp new file mode 100644 index 0000000..34a9083 --- /dev/null +++ b/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/script/scriptResource.hpp b/script/scriptResource.hpp new file mode 100644 index 0000000..9379d6e --- /dev/null +++ b/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/script/tlsContext.hpp b/script/tlsContext.hpp new file mode 100644 index 0000000..be90fb5 --- /dev/null +++ b/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[1728]; + rage::scrThread* m_script_thread; // 0x858 + bool m_is_script_thread_active; // 0x860 + +#if _WIN32 + static tlsContext* get() + { + constexpr std::uint32_t TlsIndex = 0x0; + return *reinterpret_cast(__readgsqword(0x58) + TlsIndex); + } +#endif + }; + static_assert(sizeof(tlsContext) == 0x861); +#pragma pack(pop) +} \ No newline at end of file diff --git a/script/types.hpp b/script/types.hpp new file mode 100644 index 0000000..34f5971 --- /dev/null +++ b/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/security/ObfVar.hpp b/security/ObfVar.hpp new file mode 100644 index 0000000..64aad18 --- /dev/null +++ b/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/security/RageSecurity.hpp b/security/RageSecurity.hpp new file mode 100644 index 0000000..b0bf0a1 --- /dev/null +++ b/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/socialclub/FriendInfo.hpp b/socialclub/FriendInfo.hpp new file mode 100644 index 0000000..e2d27cd --- /dev/null +++ b/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/socialclub/FriendRegistry.hpp b/socialclub/FriendRegistry.hpp new file mode 100644 index 0000000..28428ab --- /dev/null +++ b/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/socialclub/ScInfo.hpp b/socialclub/ScInfo.hpp new file mode 100644 index 0000000..3157dae --- /dev/null +++ b/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/stats/CPlayerCardStats.hpp b/stats/CPlayerCardStats.hpp new file mode 100644 index 0000000..51c2633 --- /dev/null +++ b/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/stats/CStatsSerializationContext.hpp b/stats/CStatsSerializationContext.hpp new file mode 100644 index 0000000..1fd685e --- /dev/null +++ b/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/ui/CBlipEntry.hpp b/ui/CBlipEntry.hpp new file mode 100644 index 0000000..b0fe605 --- /dev/null +++ b/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/ui/CBlipList.hpp b/ui/CBlipList.hpp new file mode 100644 index 0000000..92998b9 --- /dev/null +++ b/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/ui/blip_t.hpp b/ui/blip_t.hpp new file mode 100644 index 0000000..785ed78 --- /dev/null +++ b/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/vehicle/CAdvancedData.hpp b/vehicle/CAdvancedData.hpp new file mode 100644 index 0000000..7de376f --- /dev/null +++ b/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/vehicle/CBaseSubHandlingData.hpp b/vehicle/CBaseSubHandlingData.hpp new file mode 100644 index 0000000..ba51dbb --- /dev/null +++ b/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/vehicle/CCarHandlingData.hpp b/vehicle/CCarHandlingData.hpp new file mode 100644 index 0000000..a268109 --- /dev/null +++ b/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/vehicle/CDriveByAnimInfo.hpp b/vehicle/CDriveByAnimInfo.hpp new file mode 100644 index 0000000..28fca61 --- /dev/null +++ b/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/vehicle/CDriveBySeatDefault.hpp b/vehicle/CDriveBySeatDefault.hpp new file mode 100644 index 0000000..850d6d3 --- /dev/null +++ b/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/vehicle/CDriveByWeaponGroupDefault.hpp b/vehicle/CDriveByWeaponGroupDefault.hpp new file mode 100644 index 0000000..dbd4f96 --- /dev/null +++ b/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/vehicle/CDrivebyWeaponGroups.hpp b/vehicle/CDrivebyWeaponGroups.hpp new file mode 100644 index 0000000..e7e0e41 --- /dev/null +++ b/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/vehicle/CGetPedSeatReturnClass.hpp b/vehicle/CGetPedSeatReturnClass.hpp new file mode 100644 index 0000000..c138dd2 --- /dev/null +++ b/vehicle/CGetPedSeatReturnClass.hpp @@ -0,0 +1,10 @@ +class CVehicleDriveByAnimInfo; + +#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/vehicle/CHandlingData.hpp b/vehicle/CHandlingData.hpp new file mode 100644 index 0000000..73dedda --- /dev/null +++ b/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/vehicle/CHandlingObject.hpp b/vehicle/CHandlingObject.hpp new file mode 100644 index 0000000..b0bfef2 --- /dev/null +++ b/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/vehicle/CTrainConfig.hpp b/vehicle/CTrainConfig.hpp new file mode 100644 index 0000000..f571bd8 --- /dev/null +++ b/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/vehicle/CVehicle.hpp b/vehicle/CVehicle.hpp new file mode 100644 index 0000000..4ba3e93 --- /dev/null +++ b/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/vehicle/CVehicleDriveByAnimInfo.hpp b/vehicle/CVehicleDriveByAnimInfo.hpp new file mode 100644 index 0000000..9c29dfa --- /dev/null +++ b/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/vehicle/CVehicleDriveByMetadataMgr.hpp b/vehicle/CVehicleDriveByMetadataMgr.hpp new file mode 100644 index 0000000..79f4355 --- /dev/null +++ b/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/vehicle/CVehicleLayoutMetaData.hpp b/vehicle/CVehicleLayoutMetaData.hpp new file mode 100644 index 0000000..d7e3587 --- /dev/null +++ b/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/vehicle/CVehicleModelInfo.hpp b/vehicle/CVehicleModelInfo.hpp new file mode 100644 index 0000000..6fa697c --- /dev/null +++ b/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/vehicle/CVehicleModelInfoLayout.hpp b/vehicle/CVehicleModelInfoLayout.hpp new file mode 100644 index 0000000..2cbcbd6 --- /dev/null +++ b/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/vehicle/CVehicleSeatAnimInfo.hpp b/vehicle/CVehicleSeatAnimInfo.hpp new file mode 100644 index 0000000..0a85228 --- /dev/null +++ b/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/vehicle/CVehicleSeatAnimInfos.hpp b/vehicle/CVehicleSeatAnimInfos.hpp new file mode 100644 index 0000000..262289b --- /dev/null +++ b/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/vehicle/CVehicleSeatMetadataMgr.hpp b/vehicle/CVehicleSeatMetadataMgr.hpp new file mode 100644 index 0000000..5a20dab --- /dev/null +++ b/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/vehicle/CWeaponGroupNames.hpp b/vehicle/CWeaponGroupNames.hpp new file mode 100644 index 0000000..95bf197 --- /dev/null +++ b/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/weapon/CAmmoInfo.hpp b/weapon/CAmmoInfo.hpp new file mode 100644 index 0000000..f172ea0 --- /dev/null +++ b/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/weapon/CAmmoProjectileInfo.hpp b/weapon/CAmmoProjectileInfo.hpp new file mode 100644 index 0000000..a5cb5a6 --- /dev/null +++ b/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/weapon/CAmmoRocketInfo.hpp b/weapon/CAmmoRocketInfo.hpp new file mode 100644 index 0000000..b22c720 --- /dev/null +++ b/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/weapon/CAmmoThrownInfo.hpp b/weapon/CAmmoThrownInfo.hpp new file mode 100644 index 0000000..5cc223e --- /dev/null +++ b/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/weapon/CHomingRocketParams.hpp b/weapon/CHomingRocketParams.hpp new file mode 100644 index 0000000..c28238a --- /dev/null +++ b/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/weapon/CItemInfo.hpp b/weapon/CItemInfo.hpp new file mode 100644 index 0000000..80b33d5 --- /dev/null +++ b/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/weapon/CWeaponBoneId.hpp b/weapon/CWeaponBoneId.hpp new file mode 100644 index 0000000..1c39ec3 --- /dev/null +++ b/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/weapon/CWeaponInfo.hpp b/weapon/CWeaponInfo.hpp new file mode 100644 index 0000000..e1e3634 --- /dev/null +++ b/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);