[saco] Implement/match FUNC_10016370, the bullet sync handler; per-component float assignments keep the direct displacements a VECTOR copy would hide behind a lea

This commit is contained in:
ricardoofnl
2026-09-05 09:24:38 +07:00
parent 8d8b9e33d4
commit 10dddab97e
4 changed files with 86 additions and 10 deletions
-10
View File
@@ -2823,16 +2823,6 @@ NUDE CWeapon__FireInstantHit_Hook()
extern DWORD unnamed_10118990; // 0x10118990, lives in another translation unit extern DWORD unnamed_10118990; // 0x10118990, lives in another translation unit
// where a synced shot came from, snapshotted by CPlayerPed::FUNC_100AFA70
struct SHOT_SYNC_DATA
{
DWORD field_0;
VECTOR vecOrigin;
VECTOR vecColPoint;
VECTOR vecOffset;
ENTITY_TYPE *pAttachedTo;
};
// todo: implement sub_100A5410 // todo: implement sub_100A5410
void __stdcall sub_100A5410(VECTOR *vecOrigin, VECTOR *vecLine, VECTOR *colPoint, DWORD *pHitEntity); void __stdcall sub_100A5410(VECTOR *vecOrigin, VECTOR *vecLine, VECTOR *colPoint, DWORD *pHitEntity);
+10
View File
@@ -7,6 +7,16 @@
struct struc_13; struct struc_13;
// where a synced shot came from, snapshotted by CPlayerPed::FUNC_100AFA70
struct SHOT_SYNC_DATA
{
DWORD field_0;
VECTOR vecOrigin;
VECTOR vecColPoint;
VECTOR vecOffset;
ENTITY_TYPE *pAttachedTo;
};
DWORD __stdcall GamePool_Vehicle_GetIndex(VEHICLE_TYPE *pVehicle); DWORD __stdcall GamePool_Vehicle_GetIndex(VEHICLE_TYPE *pVehicle);
void FUNC_100AE520(); // .text:100AE520 void FUNC_100AE520(); // .text:100AE520
+64
View File
@@ -39,6 +39,8 @@ typedef char CRemotePlayer_offsets[(
offsetof(CRemotePlayer, field_1F9) == 0x1F9) ? 1 : -1]; offsetof(CRemotePlayer, field_1F9) == 0x1F9) ? 1 : -1];
typedef char CNetPlayer_offsets[(offsetof(CNetPlayer, m_PlayerName) == 0x14) ? 1 : -1]; typedef char CNetPlayer_offsets[(offsetof(CNetPlayer, m_PlayerName) == 0x14) ? 1 : -1];
typedef char BULLET_SYNC_offsets[(offsetof(BULLET_SYNC_DATA, byteWeaponID) == 0x27 &&
sizeof(BULLET_SYNC_DATA) == 0x28) ? 1 : -1];
typedef char struc_41_offsets[(offsetof(struc_41, field_30) == 0x30) ? 1 : -1]; typedef char struc_41_offsets[(offsetof(struc_41, field_30) == 0x30) ? 1 : -1];
typedef char WEAPON_SLOT_offsets[(offsetof(WEAPON_SLOT_TYPE, field_8) == 8 && typedef char WEAPON_SLOT_offsets[(offsetof(WEAPON_SLOT_TYPE, field_8) == 8 &&
sizeof(WEAPON_SLOT_TYPE) == 28) ? 1 : -1]; sizeof(WEAPON_SLOT_TYPE) == 28) ? 1 : -1];
@@ -411,6 +413,68 @@ void CRemotePlayer::FUNC_10017260(BYTE *pSync, int iTime)
//---------------------------------------------------- //----------------------------------------------------
void CRemotePlayer::FUNC_10016370(BULLET_SYNC_DATA *pSync)
{
if(!m_pPlayerPed) return;
if(!m_pPlayerPed->IsAdded()) return;
SHOT_SYNC_DATA shotSync;
memset(&shotSync, 0, sizeof(shotSync));
shotSync.vecOrigin.X = pSync->vecHitOrigin.X;
shotSync.vecOrigin.Y = pSync->vecHitOrigin.Y;
shotSync.vecOrigin.Z = pSync->vecHitOrigin.Z;
shotSync.vecColPoint.X = pSync->vecHitTarget.X;
shotSync.vecColPoint.Y = pSync->vecHitTarget.Y;
shotSync.vecColPoint.Z = pSync->vecHitTarget.Z;
shotSync.vecOffset.X = pSync->vecCenterOfHit.X;
shotSync.vecOffset.Y = pSync->vecCenterOfHit.Y;
shotSync.vecOffset.Z = pSync->vecCenterOfHit.Z;
if(pSync->byteHitType) {
if(shotSync.vecOffset.X > 300.0f || shotSync.vecOffset.X < -300.0f ||
shotSync.vecOffset.Y > 300.0f || shotSync.vecOffset.Y < -300.0f ||
shotSync.vecOffset.Z > 300.0f || shotSync.vecOffset.Z < -300.0f) return;
if(pSync->byteHitType == 1) {
CPlayerPool *pPlayerPool = pNetGame->GetPlayerPool();
if(pPlayerPool) {
PLAYERID playerId = pSync->wHitID;
if(playerId == pPlayerPool->m_LocalPlayerID) {
shotSync.pAttachedTo = (ENTITY_TYPE *)pGame->FindPlayerPed()->m_pPed;
} else if(playerId == m_PlayerID) return;
else if(pPlayerPool->GetSlotState(playerId)) {
CPlayerPed *pPlayerPed = pPlayerPool->GetAt(playerId)->m_pPlayerPed;
if(pPlayerPed) shotSync.pAttachedTo = (ENTITY_TYPE *)pPlayerPed->m_pPed;
}
}
} else if(pSync->byteHitType == 2) {
CVehiclePool *pVehiclePool = pNetGame->GetVehiclePool();
if(pVehiclePool) {
VEHICLEID VehicleID = pSync->wHitID;
if(pVehiclePool->GetSlotState(VehicleID))
shotSync.pAttachedTo =
(ENTITY_TYPE *)((CVehicle *)pVehiclePool->GetAt(VehicleID))->m_pVehicle;
}
}
}
if(m_pPlayerPed->IsAdded()) {
if(m_pPlayerPed->GetCurrentWeapon() != pSync->byteWeaponID) {
m_pPlayerPed->SetArmedWeapon(pSync->byteWeaponID, true);
if(m_pPlayerPed->GetCurrentWeapon() != pSync->byteWeaponID) {
m_pPlayerPed->GiveWeapon(pSync->byteWeaponID, 9999);
m_pPlayerPed->SetArmedWeapon(pSync->byteWeaponID, true);
}
}
}
m_pPlayerPed->FUNC_100AF280(&shotSync);
m_pPlayerPed->FUNC_100AFA70();
}
//----------------------------------------------------
void CRemotePlayer::FUNC_10014C40() void CRemotePlayer::FUNC_10014C40()
{ {
if(!m_pPlayerPed) return; if(!m_pPlayerPed) return;
+12
View File
@@ -3,6 +3,17 @@
//---------------------------------------------------- //----------------------------------------------------
// the bullet sync payload, 0x28 bytes on the wire
struct BULLET_SYNC_DATA
{
BYTE byteHitType;
WORD wHitID;
VECTOR vecHitOrigin;
VECTOR vecHitTarget;
VECTOR vecCenterOfHit;
BYTE byteWeaponID;
};
#pragma pack(1) #pragma pack(1)
class CRemotePlayer class CRemotePlayer
{ {
@@ -95,6 +106,7 @@ public:
void FUNC_10014FF0(); // .text:10014FF0 void FUNC_10014FF0(); // .text:10014FF0
void FUNC_10017260(BYTE *pSync, int iTime); // .text:10017260 void FUNC_10017260(BYTE *pSync, int iTime); // .text:10017260
void FUNC_10014C40(); // .text:10014C40 void FUNC_10014C40(); // .text:10014C40
void FUNC_10016370(BULLET_SYNC_DATA *pSync); // .text:10016370
void FUNC_10014E60(); // .text:10014E60 void FUNC_10014E60(); // .text:10014E60
void FUNC_10015460(); // .text:10015460 void FUNC_10015460(); // .text:10015460
void FUNC_10015760(BYTE *pAim); // .text:10015760 void FUNC_10015760(BYTE *pAim); // .text:10015760