diff --git a/Client/multiplayer_sa/CMultiplayerSA.cpp b/Client/multiplayer_sa/CMultiplayerSA.cpp index d9502aae98b..0c6f173fbc7 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA.cpp @@ -1596,6 +1596,7 @@ void CMultiplayerSA::InitHooks() InitHooks_Postprocess(); InitHooks_Explosions(); + InitHooks_Tasks(); } // 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 6eee7e2f4ed..7a48e561061 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -82,6 +82,7 @@ class CMultiplayerSA : public CMultiplayer void InitHooks_Postprocess(); void InitHooks_DeviceSelection(); void InitHooks_Explosions(); + void InitHooks_Tasks(); CRemoteDataStorage* CreateRemoteDataStorage(); void DestroyRemoteDataStorage(CRemoteDataStorage* pData); void AddRemoteDataStorage(CPlayerPed* pPed, CRemoteDataStorage* pData); diff --git a/Client/multiplayer_sa/CMultiplayerSA_Tasks.cpp b/Client/multiplayer_sa/CMultiplayerSA_Tasks.cpp new file mode 100644 index 00000000000..69cce9ab046 --- /dev/null +++ b/Client/multiplayer_sa/CMultiplayerSA_Tasks.cpp @@ -0,0 +1,71 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: multiplayer_sa/CMultiplayerSA_Tasks.cpp + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ +#include "StdInc.h" + +////////////////////////////////////////////////////////////////////////////////////////// +// +// CTaskSimplePlayerOnFoot::MakeAbortable +// +// If ignorefirestate is enabled, we need this hook to avoid tweaking the aiming animation +// and the chainsaw turning off when entering fire +// +////////////////////////////////////////////////////////////////////////////////////////// +static bool __IsIgnoreFireStateEnabled() +{ + return pGameInterface->IsIgnoreFireStateEnabled(); +} + +#define HOOKPOS_CTaskSimplePlayerOnFoot__MakeAbortable 0x68584D +#define HOOKSIZE_CTaskSimplePlayerOnFoot__MakeAbortable 6 +static constexpr std::uintptr_t RETURN_CTaskSimplePlayerOnFoot__MakeAbortable = 0x68585F; +static constexpr std::uintptr_t SKIP_CTaskSimplePlayerOnFoot__MakeAbortable = 0x685855; +static void _declspec(naked) HOOK_CTaskSimplePlayerOnFoot__MakeAbortable() +{ + _asm + { + // return false and keep task alive + call dword ptr [eax+8] + cmp eax, 3Dh + jl skip + + // if eventPriority == 66 (EventOnFire) && IsIgnoreFireStateEnabled() + cmp eax, 42h + jne continue_logic + + call __IsIgnoreFireStateEnabled + test al, al + jz continue_logic + + // return true but keep task alive + pop edi + pop esi + pop ebx + mov al, 1 + retn 0Ch + + continue_logic: + jmp RETURN_CTaskSimplePlayerOnFoot__MakeAbortable + + skip: + jmp SKIP_CTaskSimplePlayerOnFoot__MakeAbortable + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// CMultiplayerSA::InitHooks_Tasks +// +// Setup hooks +// +////////////////////////////////////////////////////////////////////////////////////////// +void CMultiplayerSA::InitHooks_Tasks() +{ + EZHookInstall(CTaskSimplePlayerOnFoot__MakeAbortable); +}