Cancel the Drive By task of biker cops when losing the wanted level

This commit is contained in:
Silent 2024-01-31 22:35:59 +01:00
parent f521cba4dd
commit f63425cff0
No known key found for this signature in database
GPG Key ID: AE53149BB0C45AF1
3 changed files with 124 additions and 2 deletions

View File

@ -125,4 +125,16 @@ uint8_t CPed::GetWeaponSkillForRenderWeaponPedsForPC_SAMP()
uint8_t (CPed::*funcCall)();
Memory::ReadCall( 0x7330A2, funcCall );
return std::invoke( funcCall, this );
}
}
bool CTaskComplexSequence::Contains(int taskID) const
{
for (CTask* task : m_taskSequence)
{
if (task->GetTaskType() == taskID)
{
return true;
}
}
return false;
}

View File

@ -4,16 +4,77 @@
#include "GeneralSA.h"
class CEntryExit;
class CEvent;
class CPed;
// This structure is very incomplete, but it is good enough for now
class __declspec(novtable) CTask
{
public:
virtual ~CTask();
virtual CTask* Clone() const = 0;
virtual CTask* GetSubTask() const = 0;
virtual bool IsSimpleTask() const = 0;
virtual int GetTaskType() const = 0;
virtual void StopTimer(const CEvent*) { }
virtual bool MakeAbortable(CPed*, int, const CEvent*) = 0;
public:
CTask* m_parentTask;
};
static_assert(sizeof(CTask) == 0x8, "Wrong size: CTask");
class __declspec(novtable) CTaskSimple : public CTask
{
public:
virtual bool IsSimpleTask() const override { return true; }
virtual bool SetPedPosition(CPed*) { return false; }
};
class __declspec(novtable) CTaskComplex : public CTask
{
public:
virtual bool IsSimpleTask() const override { return false; }
virtual void SetSubTask(CTask*);
virtual CTask* CreateNextSubTask(CPed*) = 0;
virtual CTask* CreateFirstSubTask(CPed*) = 0;
virtual CTask* ControlSubTask(CPed*) = 0;
};
// Stub
class CTaskSimpleJetPack
class __declspec(novtable) CTaskSimpleJetPack : public CTaskSimple
{
public:
void RenderJetPack(class CPed* pPed);
};
class __declspec(novtable) CTaskComplexSequence : public CTaskComplex
{
public:
bool Contains(int taskID) const;
public:
std::byte __pad1[8];
CTask* m_taskSequence[8];
std::byte __pad2[16];
};
static_assert(sizeof(CTaskComplexSequence) == 0x40, "Wrong size: CTaskComplexSequence");
class CTaskManager
{
public:
CTask* m_primaryTasks[5];
CTask* m_secondaryTasks[6];
CPed* m_pPed;
};
static_assert(sizeof(CTaskManager) == 0x30, "Wrong size: CTaskManager");
class CPedIntelligence
{
public:
CPed* m_pPed;
CTaskManager m_taskManager;
public:
class CTaskSimpleJetPack* GetTaskJetPack() const;
};

View File

@ -1860,6 +1860,38 @@ namespace CameraCrosshairFix
}
}
// ============= Cancel the Drive By task of biker cops when losing the wanted level =============
namespace BikerCopsDriveByFix
{
static void (*orgJoinCarWithRoadSystem)(CVehicle* vehicle);
void JoinCarWithRoadSystem_AbortDriveByTask(CVehicle* vehicle)
{
orgJoinCarWithRoadSystem(vehicle);
CPed* driver = vehicle->GetDriver();
if (driver != nullptr)
{
CPedIntelligence* driverIntelligence = driver->GetPedIntelligencePtr();
if (driverIntelligence != nullptr)
{
// If the driver has a sequence, it's the fourth one
CTask* primaryTask = driverIntelligence->m_taskManager.m_primaryTasks[3];
if (primaryTask != nullptr && primaryTask->GetTaskType() == 244) // TASK_COMPLEX_SEQUENCE
{
// If the sequence contains a TASK_SIMPLE_GANG_DRIVEBY, abort it
CTaskComplexSequence* taskSequence = reinterpret_cast<CTaskComplexSequence*>(primaryTask);
if (taskSequence->Contains(1022))
{
taskSequence->MakeAbortable(driver, 1, nullptr);
}
}
}
}
}
}
// ============= LS-RP Mode stuff =============
namespace LSRPMode
{
@ -4488,6 +4520,14 @@ void Patch_SA_10()
}
// Cancel the Drive By task of biker cops when losing the wanted level
{
using namespace BikerCopsDriveByFix;
InterceptCall(0x41C00E, orgJoinCarWithRoadSystem, JoinCarWithRoadSystem_AbortDriveByTask);
}
#if FULL_PRECISION_D3D
// Test - full precision D3D device
Patch<uint8_t>( 0x7F672B+1, *(uint8_t*)(0x7F672B+1) | D3DCREATE_FPU_PRESERVE );
@ -6047,6 +6087,15 @@ void Patch_SA_NewBinaries_Common()
auto getWeaponInfo = get_pattern("E8 ? ? ? ? 8B 40 0C 83 C4 08 85 C0");
InterceptCall(getWeaponInfo, orgGetWeaponInfo, GetWeaponInfo_OrCamera);
}
// Cancel the Drive By task of biker cops when losing the wanted level
{
using namespace BikerCopsDriveByFix;
auto backToCruisingIfNoWantedLevel = get_pattern("56 E8 ? ? ? ? 80 A6 ? ? ? ? ? 83 C4 04", 1);
InterceptCall(backToCruisingIfNoWantedLevel, orgJoinCarWithRoadSystem, JoinCarWithRoadSystem_AbortDriveByTask);
}
}