From 2d3397df56827f7c218689873f8b4741ea9af44e Mon Sep 17 00:00:00 2001 From: FileEX Date: Wed, 1 Jan 2025 20:09:19 +0100 Subject: [PATCH] Fix crash by delaying ped recreation (PR #3914, Fixes #472) --- Client/mods/deathmatch/logic/CClientGame.cpp | 9 ++---- Client/mods/deathmatch/logic/CClientPed.cpp | 30 +++++++++++++------- Client/mods/deathmatch/logic/CClientPed.h | 2 ++ 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index cf80781971..b52270e22c 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -4404,12 +4404,9 @@ bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage, return false; } - if (pDamagedPed->IsLocalPlayer()) - { - // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) - fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); - fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); - } + // Reget values in case they have been changed during onClientPlayerDamage/onClientPedDamage event (Avoid AC#1 kick) + fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); + fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); bool bIsBeingShotWhilstAiming = (weaponUsed >= WEAPONTYPE_PISTOL && weaponUsed <= WEAPONTYPE_MINIGUN && pDamagedPed->IsUsingGun()); bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); diff --git a/Client/mods/deathmatch/logic/CClientPed.cpp b/Client/mods/deathmatch/logic/CClientPed.cpp index c3d2f27f91..74ff777d3b 100644 --- a/Client/mods/deathmatch/logic/CClientPed.cpp +++ b/Client/mods/deathmatch/logic/CClientPed.cpp @@ -2705,6 +2705,10 @@ void CClientPed::StreamedInPulse(bool bDoStandardPulses) return; } + // Re-create ped + if (m_shouldRecreate) + ReCreateGameEntity(); + // Grab some vars here, saves getting them twice CClientVehicle* pVehicle = GetOccupiedVehicle(); @@ -3974,11 +3978,7 @@ void CClientPed::_ChangeModel() { // ChrML: Changing the skin in certain cases causes player sliding. So we recreate instead. - // Kill the old player - _DestroyModel(); - - // Create the new with the new skin - _CreateModel(); + m_shouldRecreate = true; } // ReAttach satchels @@ -4012,11 +4012,7 @@ void CClientPed::ReCreateModel() m_pLoadedModelInfo->ModelAddRef(BLOCKING, "CClientPed::ReCreateModel"); } - // Destroy the old model - _DestroyModel(); - - // Create the new model - _CreateModel(); + m_shouldRecreate = true; // Remove the reference we temporarily added again if (bSameModel) @@ -4026,6 +4022,20 @@ void CClientPed::ReCreateModel() } } +void CClientPed::ReCreateGameEntity() +{ + if (!m_shouldRecreate || !m_pPlayerPed) + return; + + // Destroy current game entity + _DestroyModel(); + + // Create the new game entity + _CreateModel(); + + m_shouldRecreate = false; +} + void CClientPed::ModelRequestCallback(CModelInfo* pModelInfo) { // If we have a player loaded diff --git a/Client/mods/deathmatch/logic/CClientPed.h b/Client/mods/deathmatch/logic/CClientPed.h index 5c7b2cb4a6..2934990e05 100644 --- a/Client/mods/deathmatch/logic/CClientPed.h +++ b/Client/mods/deathmatch/logic/CClientPed.h @@ -566,6 +566,7 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule // Used to destroy the current game ped and create a new one in the same state. void ReCreateModel(); + void ReCreateGameEntity(); void _CreateModel(); void _CreateLocalModel(); @@ -725,6 +726,7 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule bool m_bPendingRebuildPlayer; uint m_uiFrameLastRebuildPlayer; bool m_bIsSyncing; + bool m_shouldRecreate{false}; bool m_bBulletImpactData; CClientEntityPtr m_pBulletImpactEntity;