more CWanted; added CEventList
This commit is contained in:
parent
0548476ba6
commit
60711154ba
@ -33,4 +33,5 @@ WRAPPER int32 cDMAudio::CreateEntity(int, void*) { EAXJMP(0x57C7C0); }
|
||||
WRAPPER void cDMAudio::SetEntityStatus(int32 id, uint8 enable) { EAXJMP(0x57C810); }
|
||||
WRAPPER void cDMAudio::SetRadioInCar(int32) { EAXJMP(0x57CE60); }
|
||||
WRAPPER void cDMAudio::DestroyEntity(int32) { EAXJMP(0x57C7F0); }
|
||||
WRAPPER void cDMAudio::ClearMissionAudio(void) { EAXJMP(0x57CE20); }
|
||||
WRAPPER void cDMAudio::ClearMissionAudio(void) { EAXJMP(0x57CE20); }
|
||||
WRAPPER void cDMAudio::ReportCrime(eCrimeType crime, const CVector &pos) { EAXJMP(0x57CAD0); }
|
||||
|
@ -173,6 +173,7 @@ enum eSound : int16
|
||||
};
|
||||
|
||||
class CEntity;
|
||||
enum eCrimeType;
|
||||
|
||||
class cDMAudio
|
||||
{
|
||||
@ -204,5 +205,6 @@ public:
|
||||
uint8 IsMP3RadioChannelAvailable();
|
||||
void DestroyEntity(int32);
|
||||
void ClearMissionAudio(void);
|
||||
void ReportCrime(eCrimeType crime, const CVector &pos);
|
||||
};
|
||||
extern cDMAudio &DMAudio;
|
||||
|
@ -300,7 +300,7 @@ void CDarkel::Update()
|
||||
|
||||
TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
FindPlayerPed()->m_pWanted->SetWantedLevel(NOTWANTED);
|
||||
FindPlayerPed()->m_pWanted->SetWantedLevel(0);
|
||||
|
||||
if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
|
||||
WeaponType = WEAPONTYPE_UZI;
|
||||
|
@ -124,8 +124,8 @@ void CMissionCleanup::Process()
|
||||
CHud::m_ItemToFlash = -1;
|
||||
CHud::SetHelpMessage(nil, false);
|
||||
CUserDisplay::OnscnTimer.m_bDisabled = false;
|
||||
CWorld::Players[0].m_pPed->m_pWanted->m_IsIgnoredByCops = false;
|
||||
CWorld::Players[0].m_pPed->m_pWanted->m_IsIgnoredByEveryOne = false;
|
||||
CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByCops = false;
|
||||
CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
|
||||
CWorld::Players[0].MakePlayerSafe(false);
|
||||
CTheScripts::StoreVehicleIndex = -1;
|
||||
CTheScripts::StoreVehicleWasRandom = true;
|
||||
|
238
src/core/EventList.cpp
Normal file
238
src/core/EventList.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Pools.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "World.h"
|
||||
#include "Wanted.h"
|
||||
#include "Eventlist.h"
|
||||
|
||||
int32 CEventList::ms_nFirstFreeSlotIndex;
|
||||
//CEvent gaEvent[NUMEVENTS];
|
||||
CEvent *gaEvent = (CEvent*)0x6EF830;
|
||||
|
||||
enum
|
||||
{
|
||||
EVENT_STATE_0,
|
||||
EVENT_STATE_CANDELETE,
|
||||
EVENT_STATE_CLEAR,
|
||||
};
|
||||
|
||||
void
|
||||
CEventList::Initialise(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
debug("Initialising CEventList...");
|
||||
for(i = 0; i < NUMEVENTS; i++){
|
||||
gaEvent[i].type = EVENT_NULL;
|
||||
gaEvent[i].entityType = EVENT_ENTITY_NONE;
|
||||
gaEvent[i].entityRef = 0;
|
||||
gaEvent[i].posn.x = 0.0f;
|
||||
gaEvent[i].posn.y = 0.0f;
|
||||
gaEvent[i].posn.z = 0.0f;
|
||||
gaEvent[i].timeout = 0;
|
||||
gaEvent[i].state = EVENT_STATE_0;
|
||||
}
|
||||
ms_nFirstFreeSlotIndex = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CEventList::Update(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
ms_nFirstFreeSlotIndex = 0;
|
||||
for(i = 0; i < NUMEVENTS; i++){
|
||||
if(gaEvent[i].type == EVENT_NULL)
|
||||
continue;
|
||||
if(CTimer::GetTimeInMilliseconds() > gaEvent[i].timeout || gaEvent[i].state == EVENT_STATE_CANDELETE){
|
||||
gaEvent[i].type = EVENT_NULL;
|
||||
gaEvent[i].state = EVENT_STATE_0;
|
||||
}
|
||||
if(gaEvent[i].state == EVENT_STATE_CLEAR)
|
||||
gaEvent[i].state = EVENT_STATE_CANDELETE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent, CPed *criminal, int32 timeout)
|
||||
{
|
||||
int i;
|
||||
int ref;
|
||||
bool copsDontCare;
|
||||
|
||||
copsDontCare = false;
|
||||
switch(entityType){
|
||||
case EVENT_ENTITY_PED:
|
||||
ref = CPools::GetPedRef((CPed*)ent);
|
||||
if(ent->GetModelIndex() >= MI_GANG01 && ent->GetModelIndex() <= MI_CRIMINAL02)
|
||||
copsDontCare = true;
|
||||
break;
|
||||
case EVENT_ENTITY_VEHICLE:
|
||||
ref = CPools::GetVehicleRef((CVehicle*)ent);
|
||||
break;
|
||||
case EVENT_ENTITY_OBJECT:
|
||||
ref = CPools::GetObjectRef((CObject*)ent);
|
||||
break;
|
||||
default:
|
||||
Error("Undefined entity type, RegisterEvent, EventList.cpp");
|
||||
ref = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// only update time if event exists already
|
||||
for(i = 0; i < NUMEVENTS; i++)
|
||||
if(gaEvent[i].type == type &&
|
||||
gaEvent[i].entityType == entityType &&
|
||||
gaEvent[i].entityRef == ref){
|
||||
gaEvent[i].timeout = CTimer::GetTimeInMilliseconds() + timeout;
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = ms_nFirstFreeSlotIndex; i < NUMEVENTS; i++)
|
||||
if(gaEvent[i].type == EVENT_NULL){
|
||||
ms_nFirstFreeSlotIndex = i;
|
||||
break;
|
||||
}
|
||||
if(i < NUMEVENTS){
|
||||
gaEvent[i].type = type;
|
||||
gaEvent[i].entityType = entityType;
|
||||
gaEvent[i].timeout = CTimer::GetTimeInMilliseconds() + timeout;
|
||||
gaEvent[i].entityRef = ref;
|
||||
gaEvent[i].posn = ent->GetPosition();
|
||||
gaEvent[i].criminal = criminal;
|
||||
if(gaEvent[i].criminal)
|
||||
gaEvent[i].criminal->RegisterReference((CEntity**)&gaEvent[i].criminal);
|
||||
if(type == EVENT_GUNSHOT)
|
||||
gaEvent[i].state = EVENT_STATE_CLEAR;
|
||||
else
|
||||
gaEvent[i].state = EVENT_STATE_0;
|
||||
}
|
||||
|
||||
if(criminal == FindPlayerPed())
|
||||
ReportCrimeForEvent(type, (uintptr)ent, copsDontCare);
|
||||
}
|
||||
|
||||
void
|
||||
CEventList::RegisterEvent(eEventType type, CVector posn, int32 timeout)
|
||||
{
|
||||
int i;
|
||||
|
||||
// only update time if event exists already
|
||||
for(i = 0; i < NUMEVENTS; i++)
|
||||
if(gaEvent[i].type == type &&
|
||||
gaEvent[i].posn.x == posn.x &&
|
||||
gaEvent[i].posn.y == posn.y &&
|
||||
gaEvent[i].posn.z == posn.z &&
|
||||
gaEvent[i].entityType == EVENT_ENTITY_NONE){
|
||||
gaEvent[i].timeout = CTimer::GetTimeInMilliseconds() + timeout;
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = ms_nFirstFreeSlotIndex; i < NUMEVENTS; i++)
|
||||
if(gaEvent[i].type == EVENT_NULL){
|
||||
ms_nFirstFreeSlotIndex = i;
|
||||
break;
|
||||
}
|
||||
if(i < NUMEVENTS){
|
||||
gaEvent[i].type = type;
|
||||
gaEvent[i].entityType = EVENT_ENTITY_NONE;
|
||||
gaEvent[i].timeout = CTimer::GetTimeInMilliseconds() + timeout;
|
||||
gaEvent[i].posn = posn;
|
||||
gaEvent[i].entityRef = 0;
|
||||
if(type == EVENT_GUNSHOT)
|
||||
gaEvent[i].state = EVENT_STATE_CLEAR;
|
||||
else
|
||||
gaEvent[i].state = EVENT_STATE_0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CEventList::GetEvent(eEventType type, int32 *event)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < NUMEVENTS; i++)
|
||||
if(gaEvent[i].type == type){
|
||||
*event = i;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CEventList::ClearEvent(int32 event)
|
||||
{
|
||||
if(gaEvent[event].state != EVENT_STATE_CANDELETE)
|
||||
gaEvent[event].state = EVENT_STATE_CLEAR;
|
||||
}
|
||||
|
||||
bool
|
||||
CEventList::FindClosestEvent(eEventType type, CVector posn, int32 *event)
|
||||
{
|
||||
int i;
|
||||
float dist;
|
||||
bool found = false;
|
||||
float mindist = 60.0f;
|
||||
|
||||
for(i = 0; i < NUMEVENTS; i++){
|
||||
if(gaEvent[i].type == EVENT_NULL)
|
||||
continue;
|
||||
dist = (posn - gaEvent[i].posn).Magnitude();
|
||||
if(dist < mindist){
|
||||
mindist = dist;
|
||||
found = true;
|
||||
*event = i;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void
|
||||
CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCare)
|
||||
{
|
||||
eCrimeType crime;
|
||||
switch(type){
|
||||
case EVENT_ASSAULT: crime = CRIME_HIT_PED; break;
|
||||
case EVENT_RUN_REDLIGHT: crime = CRIME_RUN_REDLIGHT; break;
|
||||
case EVENT_ASSAULT_POLICE: crime = CRIME_HIT_COP; break;
|
||||
case EVENT_GUNSHOT: crime = CRIME_POSSESSION_GUN; break;
|
||||
case EVENT_STEAL_CAR: crime = CRIME_STEAL_CAR; break;
|
||||
case EVENT_HIT_AND_RUN: crime = CRIME_RUNOVER_PED; break;
|
||||
case EVENT_HIT_AND_RUN_COP: crime = CRIME_RUNOVER_COP; break;
|
||||
case EVENT_SHOOT_PED: crime = CRIME_SHOOT_PED; break;
|
||||
case EVENT_SHOOT_COP: crime = CRIME_SHOOT_COP; break;
|
||||
case EVENT_PED_SET_ON_FIRE: crime = CRIME_PED_BURNED; break;
|
||||
case EVENT_COP_SET_ON_FIRE: crime = CRIME_COP_BURNED; break;
|
||||
case EVENT_CAR_SET_ON_FIRE: crime = CRIME_VEHICLE_BURNED; break;
|
||||
default: crime = CRIME_NONE; break;
|
||||
}
|
||||
|
||||
if(crime == CRIME_NONE)
|
||||
return;
|
||||
|
||||
CVector playerPedCoors = FindPlayerPed()->GetPosition();
|
||||
CVector playerCoors = FindPlayerCoors();
|
||||
|
||||
if(CWanted::WorkOutPolicePresence(playerCoors, 14.0f) != 0){
|
||||
FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(crime, playerPedCoors, crimeId, copsDontCare);
|
||||
FindPlayerPed()->m_pWanted->SetWantedLevelNoDrop(1);
|
||||
}else
|
||||
FindPlayerPed()->m_pWanted->RegisterCrime(crime, playerPedCoors, crimeId, copsDontCare);
|
||||
|
||||
if(type == EVENT_ASSAULT_POLICE)
|
||||
FindPlayerPed()->SetWantedLevelNoDrop(1);
|
||||
if(type == EVENT_SHOOT_COP)
|
||||
FindPlayerPed()->SetWantedLevelNoDrop(2);
|
||||
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x475B60, CEventList::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x475BE0, CEventList::Update, PATCH_JUMP);
|
||||
InjectHook(0x475C50, (void (*)(eEventType,eEventEntity,CEntity *,CPed *,int32))CEventList::RegisterEvent, PATCH_JUMP);
|
||||
InjectHook(0x475E10, (void (*)(eEventType,CVector,int32))CEventList::RegisterEvent, PATCH_JUMP);
|
||||
InjectHook(0x475F40, CEventList::GetEvent, PATCH_JUMP);
|
||||
InjectHook(0x475F70, CEventList::ClearEvent, PATCH_JUMP);
|
||||
InjectHook(0x475F90, CEventList::FindClosestEvent, PATCH_JUMP);
|
||||
InjectHook(0x476070, CEventList::ReportCrimeForEvent, PATCH_JUMP);
|
||||
ENDPATCHES
|
65
src/core/EventList.h
Normal file
65
src/core/EventList.h
Normal file
@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
class CEntity;
|
||||
class CPed;
|
||||
|
||||
enum eEventType
|
||||
{
|
||||
EVENT_NULL,
|
||||
EVENT_ASSAULT,
|
||||
EVENT_RUN_REDLIGHT,
|
||||
EVENT_ASSAULT_POLICE,
|
||||
EVENT_GUNSHOT,
|
||||
EVENT_INJURED_PED,
|
||||
EVENT_DEAD_PED,
|
||||
EVENT_FIRE,
|
||||
EVENT_STEAL_CAR,
|
||||
EVENT_HIT_AND_RUN,
|
||||
EVENT_HIT_AND_RUN_COP,
|
||||
EVENT_SHOOT_PED,
|
||||
EVENT_SHOOT_COP,
|
||||
EVENT_EXPLOSION,
|
||||
EVENT_PED_SET_ON_FIRE,
|
||||
EVENT_COP_SET_ON_FIRE,
|
||||
EVENT_CAR_SET_ON_FIRE,
|
||||
EVENT_ASSAULT_NASTYWEAPON,
|
||||
EVENT_ASSAULT_NASTYWEAPON_POLICE,
|
||||
EVENT_ICECREAM,
|
||||
EVENT_ATM,
|
||||
EVENT_SHOPSTALL,
|
||||
EVENT_SHOPWINDOW,
|
||||
EVENT_LAST_EVENT
|
||||
};
|
||||
|
||||
enum eEventEntity
|
||||
{
|
||||
EVENT_ENTITY_NONE,
|
||||
EVENT_ENTITY_PED,
|
||||
EVENT_ENTITY_VEHICLE,
|
||||
EVENT_ENTITY_OBJECT
|
||||
};
|
||||
|
||||
struct CEvent
|
||||
{
|
||||
eEventType type;
|
||||
eEventEntity entityType;
|
||||
int32 entityRef;
|
||||
CPed *criminal;
|
||||
CVector posn;
|
||||
uint32 timeout;
|
||||
int32 state;
|
||||
};
|
||||
|
||||
class CEventList
|
||||
{
|
||||
static int32 ms_nFirstFreeSlotIndex;
|
||||
public:
|
||||
static void Initialise(void);
|
||||
static void Update(void);
|
||||
static void RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent, CPed *criminal, int32 timeout);
|
||||
static void RegisterEvent(eEventType type, CVector posn, int32 timeout);
|
||||
static bool GetEvent(eEventType type, int32 *event);
|
||||
static void ClearEvent(int32 event);
|
||||
static bool FindClosestEvent(eEventType type, CVector posn, int32 *event);
|
||||
static void ReportCrimeForEvent(eEventType type, int32, bool);
|
||||
};
|
@ -14,6 +14,7 @@ void
|
||||
CPools::Initialise(void)
|
||||
{
|
||||
// TODO: unused right now
|
||||
assert(0);
|
||||
ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES);
|
||||
ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS);
|
||||
ms_pPedPool = new CPedPool(NUMPEDS);
|
||||
@ -23,3 +24,10 @@ CPools::Initialise(void)
|
||||
ms_pObjectPool = new CObjectPool(NUMOBJECTS);
|
||||
ms_pDummyPool = new CDummyPool(NUMDUMMIES);
|
||||
}
|
||||
|
||||
int32 CPools::GetPedRef(CPed *ped) { return ms_pPedPool->GetIndex(ped); }
|
||||
CPed *CPools::GetPed(int32 handle) { return ms_pPedPool->GetAt(handle); }
|
||||
int32 CPools::GetVehicleRef(CVehicle *vehicle) { return ms_pVehiclePool->GetIndex(vehicle); }
|
||||
CVehicle *CPools::GetVehicle(int32 handle) { return ms_pVehiclePool->GetAt(handle); }
|
||||
int32 CPools::GetObjectRef(CObject *object) { return ms_pObjectPool->GetIndex(object); }
|
||||
CObject *CPools::GetObject(int32 handle) { return ms_pObjectPool->GetAt(handle); }
|
||||
|
@ -40,4 +40,10 @@ public:
|
||||
static CDummyPool *GetDummyPool(void) { return ms_pDummyPool; }
|
||||
|
||||
static void Initialise(void);
|
||||
static int32 GetPedRef(CPed *ped);
|
||||
static CPed *GetPed(int32 handle);
|
||||
static int32 GetVehicleRef(CVehicle *vehicle);
|
||||
static CVehicle *GetVehicle(int32 handle);
|
||||
static int32 GetObjectRef(CObject *object);
|
||||
static CObject *GetObject(int32 handle);
|
||||
};
|
||||
|
@ -1,65 +1,102 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Pools.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "Timer.h"
|
||||
#include "World.h"
|
||||
#include "ZoneCull.h"
|
||||
#include "Darkel.h"
|
||||
#include "DMAudio.h"
|
||||
#include "Wanted.h"
|
||||
|
||||
int32 &CWanted::MaximumWantedLevel = *(int32*)0x5F7714;
|
||||
int32 &CWanted::MaximumWantedLevel = *(int32*)0x5F7714; // 6
|
||||
int32 &CWanted::nMaximumWantedLevel = *(int32*)0x5F7718; // 6400
|
||||
|
||||
bool CWanted::AreSwatRequired()
|
||||
void
|
||||
CWanted::Initialise()
|
||||
{
|
||||
int i;
|
||||
|
||||
m_nChaos = 0;
|
||||
m_nLastUpdateTime = 0;
|
||||
m_nLastWantedLevelChange = 0;
|
||||
m_CurrentCops = 0;
|
||||
m_MaxCops = 0;
|
||||
m_MaximumLawEnforcerVehicles = 0;
|
||||
m_RoadblockDensity = 0;
|
||||
m_bIgnoredByCops = false;
|
||||
m_bIgnoredByEveryone = false;
|
||||
m_bSwatRequired = false;
|
||||
m_bFbiRequired = false;
|
||||
m_bArmyRequired = false;
|
||||
m_fCrimeSensitivity = 1.0f;
|
||||
m_nWantedLevel = 0;
|
||||
m_CopsBeatingSuspect = 0;
|
||||
for(i = 0; i < 10; i++)
|
||||
m_pCops[i] = nil;
|
||||
ClearQdCrimes();
|
||||
}
|
||||
|
||||
bool
|
||||
CWanted::AreSwatRequired()
|
||||
{
|
||||
return m_nWantedLevel >= 4;
|
||||
}
|
||||
|
||||
bool CWanted::AreFbiRequired()
|
||||
bool
|
||||
CWanted::AreFbiRequired()
|
||||
{
|
||||
return m_nWantedLevel >= 5;
|
||||
}
|
||||
|
||||
bool CWanted::AreArmyRequired()
|
||||
bool
|
||||
CWanted::AreArmyRequired()
|
||||
{
|
||||
return m_nWantedLevel >= 6;
|
||||
}
|
||||
|
||||
int CWanted::NumOfHelisRequired()
|
||||
int32
|
||||
CWanted::NumOfHelisRequired()
|
||||
{
|
||||
if (m_IsIgnoredByCops)
|
||||
if (m_bIgnoredByCops)
|
||||
return 0;
|
||||
|
||||
// Return value is number of helicopters, no need to name them.
|
||||
switch (m_nWantedLevel) {
|
||||
case WANTEDLEVEL_3:
|
||||
case WANTEDLEVEL_4:
|
||||
case 3:
|
||||
case 4:
|
||||
return 1;
|
||||
case WANTEDLEVEL_5:
|
||||
case WANTEDLEVEL_6:
|
||||
case 5:
|
||||
case 6:
|
||||
return 2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CWanted::SetWantedLevel(int32 level)
|
||||
void
|
||||
CWanted::SetWantedLevel(int32 level)
|
||||
{
|
||||
ClearQdCrimes();
|
||||
switch (level) {
|
||||
case NOTWANTED:
|
||||
case 0:
|
||||
m_nChaos = 0;
|
||||
break;
|
||||
case WANTEDLEVEL_1:
|
||||
case 1:
|
||||
m_nChaos = 60;
|
||||
break;
|
||||
case WANTEDLEVEL_2:
|
||||
case 2:
|
||||
m_nChaos = 220;
|
||||
break;
|
||||
case WANTEDLEVEL_3:
|
||||
case 3:
|
||||
m_nChaos = 420;
|
||||
break;
|
||||
case WANTEDLEVEL_4:
|
||||
case 4:
|
||||
m_nChaos = 820;
|
||||
break;
|
||||
case WANTEDLEVEL_5:
|
||||
case 5:
|
||||
m_nChaos = 1620;
|
||||
break;
|
||||
case WANTEDLEVEL_6:
|
||||
case 6:
|
||||
m_nChaos = 3220;
|
||||
break;
|
||||
default:
|
||||
@ -70,61 +107,210 @@ void CWanted::SetWantedLevel(int32 level)
|
||||
UpdateWantedLevel();
|
||||
}
|
||||
|
||||
void CWanted::SetWantedLevelNoDrop(int32 level)
|
||||
void
|
||||
CWanted::SetWantedLevelNoDrop(int32 level)
|
||||
{
|
||||
if (level > m_nWantedLevel)
|
||||
SetWantedLevel(level);
|
||||
}
|
||||
|
||||
void CWanted::ClearQdCrimes()
|
||||
void
|
||||
CWanted::SetMaximumWantedLevel(int32 level)
|
||||
{
|
||||
for (int i = 0; i < 16; i++) {
|
||||
m_sCrimes[i].m_eCrimeType = CRIME_NONE;
|
||||
switch(level){
|
||||
case 0:
|
||||
nMaximumWantedLevel = 0;
|
||||
MaximumWantedLevel = 0;
|
||||
break;
|
||||
case 1:
|
||||
nMaximumWantedLevel = 120;
|
||||
MaximumWantedLevel = 1;
|
||||
break;
|
||||
case 2:
|
||||
nMaximumWantedLevel = 300;
|
||||
MaximumWantedLevel = 2;
|
||||
break;
|
||||
case 3:
|
||||
nMaximumWantedLevel = 600;
|
||||
MaximumWantedLevel = 3;
|
||||
break;
|
||||
case 4:
|
||||
nMaximumWantedLevel = 1200;
|
||||
MaximumWantedLevel = 4;
|
||||
break;
|
||||
case 5:
|
||||
nMaximumWantedLevel = 2400;
|
||||
MaximumWantedLevel = 5;
|
||||
break;
|
||||
case 6:
|
||||
nMaximumWantedLevel = 4800;
|
||||
MaximumWantedLevel = 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CWanted::UpdateWantedLevel()
|
||||
void
|
||||
CWanted::RegisterCrime(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare)
|
||||
{
|
||||
AddCrimeToQ(type, id, coors, false, policeDoesntCare);
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::RegisterCrime_Immediately(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare)
|
||||
{
|
||||
if(!AddCrimeToQ(type, id, coors, false, policeDoesntCare))
|
||||
ReportCrimeNow(type, coors, policeDoesntCare);
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::ClearQdCrimes()
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
m_aCrimes[i].m_nType = CRIME_NONE;
|
||||
}
|
||||
|
||||
// returns whether the crime had been reported already
|
||||
bool
|
||||
CWanted::AddCrimeToQ(eCrimeType type, int32 id, const CVector &coors, bool reported, bool policeDoesntCare)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
if(m_aCrimes[i].m_nType == type && m_aCrimes[i].m_nId == id){
|
||||
if(m_aCrimes[i].m_bReported)
|
||||
return true;
|
||||
if(reported)
|
||||
m_aCrimes[i].m_bReported = reported;
|
||||
return false;
|
||||
}
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
if(m_aCrimes[i].m_nType == CRIME_NONE)
|
||||
break;
|
||||
if(i < 16){
|
||||
m_aCrimes[i].m_nType = type;
|
||||
m_aCrimes[i].m_nId = id;
|
||||
m_aCrimes[i].m_vecPosn = coors;
|
||||
m_aCrimes[i].m_nTime = CTimer::GetTimeInMilliseconds();
|
||||
m_aCrimes[i].m_bReported = reported;
|
||||
m_aCrimes[i].m_bPoliceDoesntCare = policeDoesntCare;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesntCare)
|
||||
{
|
||||
float sensitivity, chaos;
|
||||
int wantedLevelDrop;
|
||||
|
||||
if(CDarkel::FrenzyOnGoing())
|
||||
sensitivity = m_fCrimeSensitivity*0.3f;
|
||||
else
|
||||
sensitivity = m_fCrimeSensitivity;
|
||||
|
||||
wantedLevelDrop = min(CCullZones::GetWantedLevelDrop(), 100);
|
||||
|
||||
chaos = (1.0f - wantedLevelDrop/100.0f) * sensitivity;
|
||||
switch(type){
|
||||
case CRIME_POSSESSION_GUN:
|
||||
break;
|
||||
case CRIME_HIT_PED:
|
||||
m_nChaos += 5.0f*chaos;
|
||||
break;
|
||||
case CRIME_HIT_COP:
|
||||
m_nChaos += 45.0f*chaos;
|
||||
break;
|
||||
case CRIME_SHOOT_PED:
|
||||
m_nChaos += 30.0f*chaos;
|
||||
break;
|
||||
case CRIME_SHOOT_COP:
|
||||
m_nChaos += 80.0f*chaos;
|
||||
break;
|
||||
case CRIME_STEAL_CAR:
|
||||
m_nChaos += 15.0f*chaos;
|
||||
break;
|
||||
case CRIME_RUN_REDLIGHT:
|
||||
m_nChaos += 10.0f*chaos;
|
||||
break;
|
||||
case CRIME_RECKLESS_DRIVING:
|
||||
m_nChaos += 5.0f*chaos;
|
||||
break;
|
||||
case CRIME_SPEEDING:
|
||||
m_nChaos += 5.0f*chaos;
|
||||
break;
|
||||
case CRIME_RUNOVER_PED:
|
||||
m_nChaos += 18.0f*chaos;
|
||||
break;
|
||||
case CRIME_RUNOVER_COP:
|
||||
m_nChaos += 80.0f*chaos;
|
||||
break;
|
||||
case CRIME_SHOOT_HELI:
|
||||
m_nChaos += 400.0f*chaos;
|
||||
break;
|
||||
case CRIME_PED_BURNED:
|
||||
m_nChaos += 20.0f*chaos;
|
||||
break;
|
||||
case CRIME_COP_BURNED:
|
||||
m_nChaos += 80.0f*chaos;
|
||||
break;
|
||||
case CRIME_VEHICLE_BURNED:
|
||||
m_nChaos += 20.0f*chaos;
|
||||
break;
|
||||
case CRIME_DESTROYED_CESSNA:
|
||||
m_nChaos += 500.0f*chaos;
|
||||
break;
|
||||
default:
|
||||
// Error("Undefined crime type, RegisterCrime, Crime.cpp"); // different file for some reason
|
||||
Error("Undefined crime type, RegisterCrime, Wanted.cpp");
|
||||
}
|
||||
DMAudio.ReportCrime(type, coors);
|
||||
UpdateWantedLevel();
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::UpdateWantedLevel()
|
||||
{
|
||||
int32 CurrWantedLevel = m_nWantedLevel;
|
||||
|
||||
if (m_nChaos >= 0 && m_nChaos < 40) {
|
||||
m_nWantedLevel = NOTWANTED;
|
||||
m_nWantedLevel = 0;
|
||||
m_MaximumLawEnforcerVehicles = 0;
|
||||
m_MaxCops = 0;
|
||||
m_RoadblockDensity = 0;
|
||||
}
|
||||
else if (m_nChaos >= 40 && m_nChaos < 200) {
|
||||
m_nWantedLevel = WANTEDLEVEL_1;
|
||||
m_nWantedLevel = 1;
|
||||
m_MaximumLawEnforcerVehicles = 1;
|
||||
m_MaxCops = 1;
|
||||
m_RoadblockDensity = 0;
|
||||
}
|
||||
else if (m_nChaos >= 200 && m_nChaos < 400) {
|
||||
m_nWantedLevel = WANTEDLEVEL_2;
|
||||
m_nWantedLevel = 2;
|
||||
m_MaximumLawEnforcerVehicles = 2;
|
||||
m_MaxCops = 3;
|
||||
m_RoadblockDensity = 0;
|
||||
}
|
||||
else if (m_nChaos >= 400 && m_nChaos < 800) {
|
||||
m_nWantedLevel = WANTEDLEVEL_3;
|
||||
m_nWantedLevel = 3;
|
||||
m_MaximumLawEnforcerVehicles = 2;
|
||||
m_MaxCops = 4;
|
||||
m_RoadblockDensity = 4;
|
||||
}
|
||||
else if (m_nChaos >= 800 && m_nChaos < 1600) {
|
||||
m_nWantedLevel = WANTEDLEVEL_4;
|
||||
m_nWantedLevel = 4;
|
||||
m_MaximumLawEnforcerVehicles = 2;
|
||||
m_MaxCops = 6;
|
||||
m_RoadblockDensity = 8;
|
||||
}
|
||||
else if (m_nChaos >= 1600 && m_nChaos < 3200) {
|
||||
m_nWantedLevel = WANTEDLEVEL_5;
|
||||
m_nWantedLevel = 5;
|
||||
m_MaximumLawEnforcerVehicles = 3;
|
||||
m_MaxCops = 8;
|
||||
m_RoadblockDensity = 10;
|
||||
}
|
||||
else if (m_nChaos >= 3200) {
|
||||
m_nWantedLevel = WANTEDLEVEL_6;
|
||||
m_nWantedLevel = 6;
|
||||
m_MaximumLawEnforcerVehicles = 3;
|
||||
m_MaxCops = 10;
|
||||
m_RoadblockDensity = 12;
|
||||
@ -132,4 +318,58 @@ void CWanted::UpdateWantedLevel()
|
||||
|
||||
if (CurrWantedLevel != m_nWantedLevel)
|
||||
m_nLastWantedLevelChange = CTimer::GetTimeInMilliseconds();
|
||||
}
|
||||
}
|
||||
|
||||
int32
|
||||
CWanted::WorkOutPolicePresence(CVector posn, float radius)
|
||||
{
|
||||
int i;
|
||||
CPed *ped;
|
||||
CVehicle *vehicle;
|
||||
int numPolice = 0;
|
||||
|
||||
i = CPools::GetPedPool()->GetSize();
|
||||
while(--i >= 0){
|
||||
ped = CPools::GetPedPool()->GetSlot(i);
|
||||
if(ped &&
|
||||
IsPolicePedModel(ped->GetModelIndex()) &&
|
||||
(posn - ped->GetPosition()).Magnitude() < radius)
|
||||
numPolice++;
|
||||
}
|
||||
|
||||
i = CPools::GetVehiclePool()->GetSize();
|
||||
while(--i >= 0){
|
||||
vehicle = CPools::GetVehiclePool()->GetSlot(i);
|
||||
if(vehicle &&
|
||||
vehicle->bIsLawEnforcer &&
|
||||
IsPoliceVehicleModel(vehicle->GetModelIndex()) &&
|
||||
vehicle != FindPlayerVehicle() &&
|
||||
vehicle->m_status != STATUS_ABANDONED && vehicle->m_status != STATUS_WRECKED &&
|
||||
(posn - vehicle->GetPosition()).Magnitude() < radius)
|
||||
numPolice++;
|
||||
}
|
||||
|
||||
return numPolice;
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x4AD6E0, &CWanted::Initialise, PATCH_JUMP);
|
||||
// InjectHook(0x4AD790, &CWanted::Reset, PATCH_JUMP);
|
||||
// InjectHook(0x4AD7B0, &CWanted::Update, PATCH_JUMP);
|
||||
InjectHook(0x4AD900, &CWanted::UpdateWantedLevel, PATCH_JUMP);
|
||||
InjectHook(0x4AD9F0, &CWanted::RegisterCrime, PATCH_JUMP);
|
||||
InjectHook(0x4ADA10, &CWanted::RegisterCrime_Immediately, PATCH_JUMP);
|
||||
InjectHook(0x4ADA50, &CWanted::SetWantedLevel, PATCH_JUMP);
|
||||
InjectHook(0x4ADAC0, &CWanted::SetWantedLevelNoDrop, PATCH_JUMP);
|
||||
InjectHook(0x4ADAE0, &CWanted::SetMaximumWantedLevel, PATCH_JUMP);
|
||||
InjectHook(0x4ADBA0, &CWanted::AreSwatRequired, PATCH_JUMP);
|
||||
InjectHook(0x4ADBC0, &CWanted::AreFbiRequired, PATCH_JUMP);
|
||||
InjectHook(0x4ADBE0, &CWanted::AreArmyRequired, PATCH_JUMP);
|
||||
InjectHook(0x4ADC00, &CWanted::NumOfHelisRequired, PATCH_JUMP);
|
||||
// InjectHook(0x4ADC40, &CWanted::ResetPolicePursuit, PATCH_JUMP);
|
||||
InjectHook(0x4ADD00, &CWanted::WorkOutPolicePresence, PATCH_JUMP);
|
||||
InjectHook(0x4ADF20, &CWanted::ClearQdCrimes, PATCH_JUMP);
|
||||
InjectHook(0x4ADFD0, &CWanted::AddCrimeToQ, PATCH_JUMP);
|
||||
// InjectHook(0x4AE090, &CWanted::UpdateCrimesQ, PATCH_JUMP);
|
||||
InjectHook(0x4AE110, &CWanted::ReportCrimeNow, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -1,16 +1,38 @@
|
||||
#pragma once
|
||||
#include "Entity.h"
|
||||
#include "math/Vector.h"
|
||||
#include "CopPed.h"
|
||||
|
||||
enum eWantedLevel {
|
||||
NOTWANTED,
|
||||
WANTEDLEVEL_1,
|
||||
WANTEDLEVEL_2,
|
||||
WANTEDLEVEL_3,
|
||||
WANTEDLEVEL_4,
|
||||
WANTEDLEVEL_5,
|
||||
WANTEDLEVEL_6,
|
||||
class CEntity;
|
||||
class CCopPed;
|
||||
|
||||
enum eCrimeType
|
||||
{
|
||||
CRIME_NONE,
|
||||
CRIME_POSSESSION_GUN,
|
||||
CRIME_HIT_PED,
|
||||
CRIME_HIT_COP,
|
||||
CRIME_SHOOT_PED,
|
||||
CRIME_SHOOT_COP,
|
||||
CRIME_STEAL_CAR,
|
||||
CRIME_RUN_REDLIGHT,
|
||||
CRIME_RECKLESS_DRIVING,
|
||||
CRIME_SPEEDING,
|
||||
CRIME_RUNOVER_PED,
|
||||
CRIME_RUNOVER_COP,
|
||||
CRIME_SHOOT_HELI,
|
||||
CRIME_PED_BURNED,
|
||||
CRIME_COP_BURNED,
|
||||
CRIME_VEHICLE_BURNED,
|
||||
CRIME_DESTROYED_CESSNA,
|
||||
};
|
||||
|
||||
class CCrimeBeingQd
|
||||
{
|
||||
public:
|
||||
eCrimeType m_nType;
|
||||
uint32 m_nId;
|
||||
int32 m_nTime;
|
||||
CVector m_vecPosn;
|
||||
bool m_bReported;
|
||||
bool m_bPoliceDoesntCare;
|
||||
};
|
||||
|
||||
class CWanted
|
||||
@ -23,28 +45,37 @@ public:
|
||||
uint8 m_CurrentCops;
|
||||
uint8 m_MaxCops;
|
||||
uint8 m_MaximumLawEnforcerVehicles;
|
||||
int8 field_19;
|
||||
uint8 m_CopsBeatingSuspect;
|
||||
int16 m_RoadblockDensity;
|
||||
uint8 m_IsIgnoredByCops : 1;
|
||||
uint8 m_IsIgnoredByEveryOne : 1;
|
||||
uint8 m_IsSwatRequired : 1;
|
||||
uint8 m_IsFbiRequired : 1;
|
||||
uint8 m_IdArmyRequired : 1;
|
||||
int8 field_23;
|
||||
uint8 m_bIgnoredByCops : 1;
|
||||
uint8 m_bIgnoredByEveryone : 1;
|
||||
uint8 m_bSwatRequired : 1;
|
||||
uint8 m_bFbiRequired : 1;
|
||||
uint8 m_bArmyRequired : 1;
|
||||
int32 m_nWantedLevel;
|
||||
CCrime m_sCrimes[16];
|
||||
CCrimeBeingQd m_aCrimes[16];
|
||||
CCopPed *m_pCops[10];
|
||||
|
||||
static int32 &MaximumWantedLevel;
|
||||
static int32 &nMaximumWantedLevel;
|
||||
|
||||
public:
|
||||
void Initialise();
|
||||
bool AreSwatRequired();
|
||||
bool AreFbiRequired();
|
||||
bool AreArmyRequired();
|
||||
int NumOfHelisRequired();
|
||||
int32 NumOfHelisRequired();
|
||||
void SetWantedLevel(int32);
|
||||
void SetWantedLevelNoDrop(int32 level);
|
||||
void RegisterCrime(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare);
|
||||
void RegisterCrime_Immediately(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare);
|
||||
void ClearQdCrimes();
|
||||
bool AddCrimeToQ(eCrimeType type, int32 id, const CVector &pos, bool reported, bool policeDoesntCare);
|
||||
void ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesntCare);
|
||||
void UpdateWantedLevel();
|
||||
|
||||
static int32 WorkOutPolicePresence(CVector posn, float radius);
|
||||
static void SetMaximumWantedLevel(int32 level);
|
||||
};
|
||||
|
||||
static_assert(sizeof(CWanted) == 0x204, "CWanted: error");
|
||||
|
@ -62,6 +62,7 @@ enum Config {
|
||||
NUMONSCREENTIMERENTRIES = 1,
|
||||
NUMRADARBLIPS = 32,
|
||||
NUMPICKUPS = 336,
|
||||
NUMEVENTS = 64,
|
||||
};
|
||||
|
||||
// We'll use this once we're ready to become independent of the game
|
||||
|
@ -465,3 +465,21 @@ IsPickupModel(int16 id)
|
||||
id == MI_PICKUP_KILLFRENZY ||
|
||||
id == MI_PICKUP_CAMERA;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsPolicePedModel(int16 id)
|
||||
{
|
||||
return id == MI_COP ||
|
||||
id == MI_SWAT ||
|
||||
id == MI_FBI ||
|
||||
id == MI_ARMY;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsPoliceVehicleModel(int16 id)
|
||||
{
|
||||
return id == MI_CHOPPER ||
|
||||
id == MI_PREDATOR ||
|
||||
id == MI_POLICE ||
|
||||
id == MI_ENFORCER;
|
||||
}
|
||||
|
@ -1,27 +1,6 @@
|
||||
#pragma once
|
||||
#include "Ped.h"
|
||||
|
||||
enum eCrimeType
|
||||
{
|
||||
CRIME_NONE,
|
||||
CRIME_POSSESSION_GUN,
|
||||
CRIME_HIT_PED,
|
||||
CRIME_HIT_COP,
|
||||
CRIME_SHOOT_PED,
|
||||
CRIME_SHOOT_COP,
|
||||
CRIME_STEAL_CAR,
|
||||
CRIME_RUN_REDLIGHT,
|
||||
CRIME_RECKLESS_DRIVING,
|
||||
CRIME_SPEEDING,
|
||||
CRIME_RUNOVER_PED,
|
||||
CRIME_RUNOVER_COP,
|
||||
CRIME_SHOOT_HELI,
|
||||
CRIME_PED_BURNED,
|
||||
CRIME_COP_BURNED,
|
||||
CRIME_VEHICLE_BURNED,
|
||||
CRIME_DESTROYED_CESSNA,
|
||||
};
|
||||
|
||||
enum eCopType
|
||||
{
|
||||
COP_STREET = 0,
|
||||
@ -30,18 +9,6 @@ enum eCopType
|
||||
COP_ARMY = 3,
|
||||
};
|
||||
|
||||
class CCrime
|
||||
{
|
||||
public:
|
||||
eCrimeType m_eCrimeType;
|
||||
CEntity *m_pVictim;
|
||||
int32 m_nCrimeTime;
|
||||
CVector m_vecCrimePos;
|
||||
int8 m_bReported;
|
||||
int8 m_bMultiplier;
|
||||
int8 pad_20[2];
|
||||
};
|
||||
|
||||
class CCopPed : public CPed
|
||||
{
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user