Skip to content

Commit 2a2f31b

Browse files
FileEXTheNormalnijbotderDutchman101tederis
authored
Fix setPedOnFire(ped, false) doesn't cancel TASK_SIMPLE_PLAYER_ON_FIRE (again and again) (#4196)
* Fix bug * Review * Fix bug * Update Client/game_sa/CFireSA.cpp Co-authored-by: Uladzislau Nikalayevich <[email protected]> * Update CFireSA.cpp --------- Co-authored-by: Uladzislau Nikalayevich <[email protected]> Co-authored-by: Marek Kulik <[email protected]> Co-authored-by: Dutchman101 <[email protected]> Co-authored-by: TEDERIs <[email protected]>
1 parent c68f458 commit 2a2f31b

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

Client/game_sa/CFireSA.cpp

+48
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "CFireSA.h"
1515
#include "CGameSA.h"
1616
#include "CPoolsSA.h"
17+
#include <game/CTaskManager.h>
18+
#include <game/TaskTypes.h>
1719

1820
extern CGameSA* pGame;
1921

@@ -209,3 +211,49 @@ void CFireSA::SetNumGenerationsAllowed(char generations)
209211
{
210212
internalInterface->nNumGenerationsAllowed = generations;
211213
}
214+
215+
////////////////////////////////////////////////////////////////////////
216+
// CFire::Extinguish
217+
//
218+
// Fix GH #3249 (PLAYER_ON_FIRE task is not aborted after the fire is extinguished)
219+
////////////////////////////////////////////////////////////////////////
220+
static void AbortFireTask(CEntitySAInterface* entityOnFire, DWORD returnAddress)
221+
{
222+
// We can't and shouldn't remove the task if we're in CTaskSimplePlayerOnFire::ProcessPed. Otherwise we will crash.
223+
if (returnAddress == 0x633783)
224+
return;
225+
226+
auto* ped = pGame->GetPools()->GetPed(reinterpret_cast<DWORD*>(entityOnFire));
227+
if (!ped || !ped->pEntity)
228+
return;
229+
230+
CTaskManager* taskManager = ped->pEntity->GetPedIntelligence()->GetTaskManager();
231+
if (!taskManager)
232+
return;
233+
234+
taskManager->RemoveTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM, TASK_SIMPLE_PLAYER_ON_FIRE);
235+
}
236+
237+
#define HOOKPOS_CFire_Extinguish 0x539429
238+
#define HOOKSIZE_CFire_Extinguish 6
239+
static constexpr std::uintptr_t CONTINUE_CFire_Extinguish = 0x53942F;
240+
static void _declspec(naked) HOOK_CFire_Extinguish()
241+
{
242+
_asm
243+
{
244+
mov [eax+730h], edi
245+
mov ebx, [esp+8]
246+
247+
push ebx
248+
push eax
249+
call AbortFireTask
250+
add esp, 8
251+
252+
jmp CONTINUE_CFire_Extinguish
253+
}
254+
}
255+
256+
void CFireSA::StaticSetHooks()
257+
{
258+
EZHookInstall(CFire_Extinguish);
259+
}

Client/game_sa/CFireSA.h

+2
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,6 @@ class CFireSA : public CFire
6464
void SetStrength(float fStrength);
6565
void SetNumGenerationsAllowed(char generations);
6666
CFireSAInterface* GetInterface() { return internalInterface; }
67+
68+
static void StaticSetHooks();
6769
};

Client/game_sa/CGameSA.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ CGameSA::CGameSA()
247247
CVehicleSA::StaticSetHooks();
248248
CCheckpointSA::StaticSetHooks();
249249
CHudSA::StaticSetHooks();
250+
CFireSA::StaticSetHooks();
250251
CPtrNodeSingleLinkPoolSA::StaticSetHooks();
251252
CVehicleAudioSettingsManagerSA::StaticSetHooks();
252253
}

Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2522,7 +2522,7 @@ bool CLuaElementDefs::SetLowLodElement(lua_State* luaVM, CClientEntity* pEntity,
25222522

25232523
bool CLuaElementDefs::SetElementOnFire(CClientEntity* entity, bool onFire) noexcept
25242524
{
2525-
if (!entity->IsLocalEntity())
2525+
if (!entity->IsLocalEntity() && entity != CStaticFunctionDefinitions::GetLocalPlayer())
25262526
return false;
25272527

25282528
return entity->SetOnFire(onFire);

0 commit comments

Comments
 (0)