From 9fb035efc9a9df301eea1b30a4aee1c90e3c20b4 Mon Sep 17 00:00:00 2001 From: FileEX Date: Fri, 2 May 2025 16:33:46 +0200 Subject: [PATCH] Fix bug --- Client/multiplayer_sa/CMultiplayerSA.cpp | 1 + Client/multiplayer_sa/CMultiplayerSA.h | 1 + .../CMultiplayerSA_Explosions.cpp | 78 +++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 Client/multiplayer_sa/CMultiplayerSA_Explosions.cpp diff --git a/Client/multiplayer_sa/CMultiplayerSA.cpp b/Client/multiplayer_sa/CMultiplayerSA.cpp index 33f22545419..d9502aae98b 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA.cpp @@ -1595,6 +1595,7 @@ void CMultiplayerSA::InitHooks() InitHooks_ObjectStreamerOptimization(); InitHooks_Postprocess(); + InitHooks_Explosions(); } // Used to store copied pointers for explosions in the FxSystem diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index 73bd1ef24eb..6eee7e2f4ed 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -81,6 +81,7 @@ class CMultiplayerSA : public CMultiplayer void InitHooks_ObjectStreamerOptimization(); void InitHooks_Postprocess(); void InitHooks_DeviceSelection(); + void InitHooks_Explosions(); CRemoteDataStorage* CreateRemoteDataStorage(); void DestroyRemoteDataStorage(CRemoteDataStorage* pData); void AddRemoteDataStorage(CPlayerPed* pPed, CRemoteDataStorage* pData); diff --git a/Client/multiplayer_sa/CMultiplayerSA_Explosions.cpp b/Client/multiplayer_sa/CMultiplayerSA_Explosions.cpp new file mode 100644 index 00000000000..87e5e3fd76d --- /dev/null +++ b/Client/multiplayer_sa/CMultiplayerSA_Explosions.cpp @@ -0,0 +1,78 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: multiplayer_sa/CMultiplayerSA_Explosions.cpp + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ +#include "StdInc.h" + +////////////////////////////////////////////////////////////////////////////////////////// +// +// CWorld::TriggerExplosion +// +// Fix for multiple damage instances in certain areas during explosions (GH #4125, #997) +// +////////////////////////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CWorld_TriggerExplosion 0x56B82E +#define HOOKSIZE_CWorld_TriggerExplosion 8 +static constexpr std::uintptr_t RETURN_CWorld_TriggerExplosion = 0x56B836; +static void _declspec(naked) HOOK_CWorld_TriggerExplosion() +{ + _asm + { + mov [esp+1Ch-8h], eax + mov [esp+1Ch-10h], ecx + + // Call SetNextScanCode + mov ecx, 0x4072E0 + call ecx + mov ecx, esi + + // SetNextScanCode overwrote the result of the cmp instruction at 0x56B82A + // so we call it again + cmp esi, eax + jmp RETURN_CWorld_TriggerExplosion + } +} + +#define HOOKPOS_CWorld_TriggerExplosionSectorList 0x5677F4 +#define HOOKSIZE_CWorld_TriggerExplosionSectorList 7 +static constexpr std::uintptr_t RETURN_CWorld_TriggerExplosionSectorList = 0x5677FB; +static constexpr std::uintptr_t SKIP_CWorld_TriggerExplosionSectorList = 0x568473; +static void _declspec(naked) HOOK_CWorld_TriggerExplosionSectorList() +{ + _asm + { + // check entity->m_nScanCode == CWorld::ms_nCurrentScanCode + mov ecx, dword ptr ds:[0xB7CD78] + cmp [esi+2Ch], ecx + jz skip + + // set entity current scan code + mov [esi+2Ch], ecx + + mov al, [esi+36h] + and al, 7 + cmp al, 4 + jmp RETURN_CWorld_TriggerExplosionSectorList + + skip: + jmp SKIP_CWorld_TriggerExplosionSectorList + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// CMultiplayerSA::InitHooks_Explosions +// +// Setup hooks +// +////////////////////////////////////////////////////////////////////////////////////////// +void CMultiplayerSA::InitHooks_Explosions() +{ + EZHookInstall(CWorld_TriggerExplosion); + EZHookInstall(CWorld_TriggerExplosionSectorList); +}