Skip to content

Commit 3a0dc29

Browse files
authored
Fix setPedOnFire(ped, false) doesn't cancel TASK_SIMPLE_PLAYER_ON_FIRE (PR #3930, Fixes #3249)
1 parent 0102dd2 commit 3a0dc29

File tree

8 files changed

+61
-2
lines changed

8 files changed

+61
-2
lines changed

Client/game_sa/CFireSA.cpp

Lines changed: 42 additions & 0 deletions
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,43 @@ 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)
221+
{
222+
auto ped = pGame->GetPools()->GetPed(reinterpret_cast<DWORD*>(entityOnFire));
223+
if (!ped || !ped->pEntity)
224+
return;
225+
226+
CTaskManager* taskManager = ped->pEntity->GetPedIntelligence()->GetTaskManager();
227+
if (!taskManager)
228+
return;
229+
230+
taskManager->RemoveTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM, TASK_SIMPLE_PLAYER_ON_FIRE);
231+
}
232+
233+
#define HOOKPOS_CFire_Extinguish 0x539429
234+
#define HOOKSIZE_CFire_Extinguish 6
235+
static constexpr std::uintptr_t CONTINUE_CFire_Extinguish = 0x53942F;
236+
static void _declspec(naked) HOOK_CFire_Extinguish()
237+
{
238+
_asm
239+
{
240+
mov [eax+730h], edi
241+
242+
push eax
243+
call AbortFireTask
244+
add esp, 4
245+
246+
jmp CONTINUE_CFire_Extinguish
247+
}
248+
}
249+
250+
void CFireSA::StaticSetHooks()
251+
{
252+
EZHookInstall(CFire_Extinguish);
253+
}

Client/game_sa/CFireSA.h

Lines changed: 2 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ CGameSA::CGameSA()
246246
CVehicleSA::StaticSetHooks();
247247
CCheckpointSA::StaticSetHooks();
248248
CHudSA::StaticSetHooks();
249+
CFireSA::StaticSetHooks();
249250
CPtrNodeSingleLinkPoolSA::StaticSetHooks();
250251
}
251252
catch (const std::bad_alloc& e)

Client/game_sa/CTaskManagerSA.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,18 @@ void CTaskManagerSA::RemoveTaskSecondary(const int iTaskPriority)
151151
SetTaskSecondary(NULL, iTaskPriority);
152152
}
153153

154+
bool CTaskManagerSA::RemoveTaskSecondary(const int taskPriority, const int taskType)
155+
{
156+
CTask* task = GetTaskSecondary(taskPriority);
157+
if (task && task->GetTaskType() == taskType)
158+
{
159+
RemoveTaskSecondary(taskPriority);
160+
return true;
161+
}
162+
163+
return false;
164+
}
165+
154166
void CTaskManagerSA::SetTaskSecondary(CTaskSA* pTaskSecondary, const int iType)
155167
{
156168
DWORD dwFunc = FUNC_SetTaskSecondary;

Client/game_sa/CTaskManagerSA.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class CTaskManagerSA : public CTaskManager
5757
CTask* FindActiveTaskByType(const int iTaskType);
5858
CTask* FindTaskByType(const int iPriority, const int iTaskType);
5959
void RemoveTaskSecondary(const int iTaskPriority);
60+
bool RemoveTaskSecondary(const int taskPriority, const int taskType);
6061
void SetTaskSecondary(CTaskSA* pTaskSecondary, const int iType);
6162
CTask* GetTaskSecondary(const int iType); // code it
6263
bool HasTaskSecondary(const CTask* pTaskSecondary); // code it

Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2580,7 +2580,7 @@ bool CStaticFunctionDefinitions::SetPedOnFire(CClientEntity& Entity, bool bOnFir
25802580
{
25812581
if (IS_PED(&Entity))
25822582
{
2583-
if (!Entity.IsLocalEntity())
2583+
if (!Entity.IsLocalEntity() && &Entity != GetLocalPlayer())
25842584
return false;
25852585

25862586
CClientPed& Ped = static_cast<CClientPed&>(Entity);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2520,7 +2520,7 @@ bool CLuaElementDefs::SetLowLodElement(lua_State* luaVM, CClientEntity* pEntity,
25202520

25212521
bool CLuaElementDefs::SetElementOnFire(CClientEntity* entity, bool onFire) noexcept
25222522
{
2523-
if (!entity->IsLocalEntity())
2523+
if (!entity->IsLocalEntity() && entity != CStaticFunctionDefinitions::GetLocalPlayer())
25242524
return false;
25252525

25262526
return entity->SetOnFire(onFire);

Client/sdk/game/CTaskManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class CTaskManager
6060
virtual CTask* FindActiveTaskByType(const int iTaskType) = 0;
6161
virtual CTask* FindTaskByType(const int iPriority, const int iTaskType) = 0;
6262
virtual void RemoveTaskSecondary(const int iTaskPriority) = 0;
63+
virtual bool RemoveTaskSecondary(const int taskPriority, const int taskType) = 0;
6364
// virtual void SetTaskSecondary(CTask* pTaskSecondary, const int iType)=0;
6465
virtual CTask* GetTaskSecondary(const int iType) = 0;
6566
virtual bool HasTaskSecondary(const CTask* pTaskSecondary) = 0;

0 commit comments

Comments
 (0)