code:
#define WITHWINDOWS
#include "common.h"
#include "crossplatform.h"

#include "DMAudio.h"
#include "Record.h"
#include "Timer.h"

uint32 CTimer::m_snTimeInMilliseconds;
uint32 CTimer::m_snTimeInMillisecondsPauseMode = 1;
uint32 CTimer::m_snTimeInMillisecondsNonClipped;
uint32 CTimer::m_snPreviousTimeInMilliseconds;
uint32 CTimer::m_FrameCounter;
float CTimer::ms_fTimeScale;
float CTimer::ms_fTimeStep;
float CTimer::ms_fTimeStepNonClipped;
bool  CTimer::m_UserPause;
bool  CTimer::m_CodePause;
#ifdef FIX_BUGS
uint32 CTimer::m_LogicalFrameCounter;
uint32 CTimer::m_LogicalFramesPassed;
#endif

uint32 _nCyclesPerMS = 1;

#ifdef _WIN32
LARGE_INTEGER _oldPerfCounter;
LARGE_INTEGER perfSuspendCounter;
#define RsTimerType uint32
#else
#define RsTimerType double
#endif

RsTimerType oldPcTimer;

RsTimerType suspendPcTimer;

uint32 suspendDepth;

void CTimer::Initialise(void)
{
	debug("Initialising CTimer...\n");

	ms_fTimeScale = 1.0f;
	ms_fTimeStep = 1.0f;
	suspendDepth = 0;
	m_UserPause = false;
	m_CodePause = false;
	m_snTimeInMillisecondsNonClipped = 0;
	m_snPreviousTimeInMilliseconds = 0;
	m_snTimeInMilliseconds = 1;
#ifdef FIX_BUGS
	m_LogicalFrameCounter = 0;
	m_LogicalFramesPassed = 0;
#endif

#ifdef _WIN32
	LARGE_INTEGER perfFreq;
	if ( QueryPerformanceFrequency(&perfFreq) )
	{
		OutputDebugString("Performance counter available\n");
		_nCyclesPerMS = uint32(perfFreq.QuadPart / 1000);
		QueryPerformanceCounter(&_oldPerfCounter);
	}
	else
#endif
	{
		OutputDebugString("Performance counter not available, using millesecond timer\n");
		_nCyclesPerMS = 0;
		oldPcTimer = RsTimer();
	}

	m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds;

	m_FrameCounter = 0;

	DMAudio.ResetTimers(m_snPreviousTimeInMilliseconds);

	debug("CTimer ready\n");
}

void CTimer::Shutdown(void)
{
	;
}
#ifdef FIX_BUGS
void CTimer::Update(void)
{
	static double frameTimeLogical = 0.0;
	static double frameTimeFraction = 0.0;
	static double frameTimeFractionScaled = 0.0;
	double frameTime;
	double dblUpdInMs;

	m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;

#ifdef _WIN32
	if ( (double)_nCyclesPerMS != 0.0 )
	{
		LARGE_INTEGER pc;
		QueryPerformanceCounter(&pc);

		int32 updInCycles = (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless

		_oldPerfCounter = pc;

		// bugfix from VC
		double updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale;

		frameTime = updInCyclesScaled / (double)_nCyclesPerMS;

		dblUpdInMs = (double)updInCycles / (double)_nCyclesPerMS;
	}
	else
#endif
	{
		RsTimerType timer = RsTimer();

		RsTimerType updInMs = timer - oldPcTimer;

		// bugfix from VC
		frameTime = GetIsPaused() ? (double)updInMs : (double)updInMs * ms_fTimeScale;

		oldPcTimer = timer;

		dblUpdInMs = (double)updInMs;
	}

	// count frames as if we're running at 30 fps
	m_LogicalFramesPassed = 0;
	frameTimeLogical += dblUpdInMs;
	while(frameTimeLogical >= 1000.0 / 30.0) {
		frameTimeLogical -= 1000.0 / 30.0;
		m_LogicalFramesPassed++;
	}
	m_LogicalFrameCounter += m_LogicalFramesPassed;

	frameTimeFraction += dblUpdInMs;
	frameTimeFractionScaled += frameTime;

	m_snTimeInMillisecondsPauseMode += uint32(frameTimeFraction);

	if ( GetIsPaused() )
		ms_fTimeStep = 0.0f;
	else
	{
		m_snTimeInMilliseconds += uint32(frameTimeFractionScaled);
		m_snTimeInMillisecondsNonClipped += uint32(frameTimeFractionScaled);
		ms_fTimeStep = frameTime / 1000.0f * 50.0f;
	}
	frameTimeFraction -= uint32(frameTimeFraction);
	frameTimeFractionScaled -= uint32(frameTimeFractionScaled);

	if ( ms_fTimeStep < 0.01f && !GetIsPaused() )
		ms_fTimeStep = 0.01f;

	ms_fTimeStepNonClipped = ms_fTimeStep;

	if ( !CRecordDataForGame::IsPlayingBack() )
	{
		ms_fTimeStep = Min(3.0f, ms_fTimeStep);

		if ( (m_snTimeInMilliseconds - m_snPreviousTimeInMilliseconds) > 60 )
			m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 60;
	}

	if ( CRecordDataForChase::IsRecording() )
	{
		ms_fTimeStep = 1.0f;
		m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 16;
	}

	m_FrameCounter++;
}
#else
void CTimer::Update(void)
{
	m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;

#ifdef _WIN32
	if ( (double)_nCyclesPerMS != 0.0 )
	{
		LARGE_INTEGER pc;
		QueryPerformanceCounter(&pc);

		int32 updInCycles = (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless

		_oldPerfCounter = pc;

		float updInCyclesScaled = updInCycles * ms_fTimeScale;

		double frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
		m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime;

		if ( GetIsPaused() )
			ms_fTimeStep = 0.0f;
		else
		{
			m_snTimeInMilliseconds = m_snTimeInMilliseconds + frameTime;
			m_snTimeInMillisecondsNonClipped = m_snTimeInMillisecondsNonClipped + frameTime;
			ms_fTimeStep = frameTime / 1000.0f * 50.0f;
		}
	}
	else
#endif
	{
		RsTimerType timer = RsTimer();

		RsTimerType updInMs = timer - oldPcTimer;

		double frameTime = (double)updInMs * ms_fTimeScale;

		oldPcTimer = timer;

		m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime;

		if ( GetIsPaused() )
			ms_fTimeStep = 0.0f;
		else
		{
			m_snTimeInMilliseconds = m_snTimeInMilliseconds + frameTime;
			m_snTimeInMillisecondsNonClipped = m_snTimeInMillisecondsNonClipped + frameTime;
			ms_fTimeStep = frameTime / 1000.0f * 50.0f;
		}
	}

	if ( ms_fTimeStep < 0.01f && !GetIsPaused() )
		ms_fTimeStep = 0.01f;

	ms_fTimeStepNonClipped = ms_fTimeStep;

	if ( !CRecordDataForGame::IsPlayingBack() )
	{
		ms_fTimeStep = Min(3.0f, ms_fTimeStep);

		if ( (m_snTimeInMilliseconds - m_snPreviousTimeInMilliseconds) > 60 )
			m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 60;
	}

	if ( CRecordDataForChase::IsRecording() )
	{
		ms_fTimeStep = 1.0f;
		m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 16;
	}

	m_FrameCounter++;
}
#endif

void CTimer::Suspend(void)
{
	if ( ++suspendDepth > 1 )
		return;

#ifdef _WIN32
	if ( (double)_nCyclesPerMS != 0.0 )
		QueryPerformanceCounter(&perfSuspendCounter);
	else
#endif
		suspendPcTimer = RsTimer();
}

void CTimer::Resume(void)
{
	if ( --suspendDepth != 0 )
		return;

#ifdef _WIN32
	if ( (double)_nCyclesPerMS != 0.0 )
	{
		LARGE_INTEGER pc;
		QueryPerformanceCounter(&pc);

		_oldPerfCounter.LowPart += pc.LowPart - perfSuspendCounter.LowPart;
	}
	else
#endif
		oldPcTimer += RsTimer() - suspendPcTimer;
}

uint32 CTimer::GetCyclesPerMillisecond(void)
{
#ifdef _WIN32
	if (_nCyclesPerMS != 0)
		return _nCyclesPerMS;
	else
#endif
		return 1;
}

uint32 CTimer::GetCurrentTimeInCycles(void)
{
#ifdef _WIN32
	if ( _nCyclesPerMS != 0 )
	{
		LARGE_INTEGER pc;
		QueryPerformanceCounter(&pc);
		return (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless
	}
	else
#endif
		return RsTimer() - oldPcTimer;
}

bool CTimer::GetIsSlowMotionActive(void)
{
	return ms_fTimeScale < 1.0f;
}

void CTimer::Stop(void)
{
	m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
}

void CTimer::StartUserPause(void)
{
	m_UserPause = true;
}

void CTimer::EndUserPause(void)
{
	m_UserPause = false;
}

uint32 CTimer::GetCyclesPerFrame()
{
	return 20;
}


code:
#pragma once

class CTimer
{

	static uint32 m_snTimeInMilliseconds;
	static uint32 m_snTimeInMillisecondsPauseMode;
	static uint32 m_snTimeInMillisecondsNonClipped;
	static uint32 m_snPreviousTimeInMilliseconds;
	static uint32 m_FrameCounter;
	static float ms_fTimeScale;
	static float ms_fTimeStep;
	static float ms_fTimeStepNonClipped;
#ifdef FIX_BUGS
	static uint32 m_LogicalFrameCounter;
	static uint32 m_LogicalFramesPassed;
#endif
public:
	static bool  m_UserPause;
	static bool  m_CodePause;

	static const float &GetTimeStep(void) { return ms_fTimeStep; }
	static void SetTimeStep(float ts) { ms_fTimeStep = ts; }
	static float GetTimeStepInSeconds() { return ms_fTimeStep / 50.0f; }
	static uint32 GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.0f; }
	static const float &GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; }
	static float GetTimeStepNonClippedInSeconds(void) { return ms_fTimeStepNonClipped / 50.0f; }
	static float GetTimeStepNonClippedInMilliseconds(void) { return ms_fTimeStepNonClipped / 50.0f * 1000.0f; }
	static void SetTimeStepNonClipped(float ts) { ms_fTimeStepNonClipped = ts; }
	static const uint32 &GetFrameCounter(void) { return m_FrameCounter; }
	static void SetFrameCounter(uint32 fc) { m_FrameCounter = fc; }
	static const uint32 &GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; }
	static void SetTimeInMilliseconds(uint32 t) { m_snTimeInMilliseconds = t; }
	static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; }
	static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; }
	static uint32 GetTimeInMillisecondsPauseMode(void) { return m_snTimeInMillisecondsPauseMode; }
	static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; }
	static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; }
	static void SetPreviousTimeInMilliseconds(uint32 t) { m_snPreviousTimeInMilliseconds = t; }
	static const float &GetTimeScale(void) { return ms_fTimeScale; }
	static void SetTimeScale(float ts) { ms_fTimeScale = ts; }
	static uint32 GetCyclesPerFrame();

	static bool GetIsPaused() { return m_UserPause || m_CodePause; }
	static bool GetIsUserPaused() { return m_UserPause; }
	static bool GetIsCodePaused() { return m_CodePause; }
	static void SetCodePause(bool pause) { m_CodePause = pause; }

	static void Initialise(void);
	static void Shutdown(void);
	static void Update(void);
	static void Suspend(void);
	static void Resume(void);
	static uint32 GetCyclesPerMillisecond(void);
	static uint32 GetCurrentTimeInCycles(void);
	static bool GetIsSlowMotionActive(void);
	static void Stop(void);
	static void StartUserPause(void);
	static void EndUserPause(void);

	friend bool GenericLoad(void);
	friend bool GenericSave(int file);
	friend class CMemoryCard;

#ifdef FIX_BUGS
	static float GetDefaultTimeStep(void) { return 50.0f / 30.0f; }
	static float GetTimeStepFix(void) { return GetTimeStep() / GetDefaultTimeStep(); }
	static uint32 GetLogicalFrameCounter(void) { return m_LogicalFrameCounter; }
	static uint32 GetLogicalFramesPassed(void) { return m_LogicalFramesPassed; }
#endif
};

license: mit


code:
#include "common.h"

#include "Hud.h"
#include "PlayerPed.h"
#include "Replay.h"
#include "Text.h"
#include "User.h"
#include "Vehicle.h"
#include "World.h"
#include "Zones.h"

CPlaceName CUserDisplay::PlaceName;
COnscreenTimer CUserDisplay::OnscnTimer;
CPager CUserDisplay::Pager;
CCurrentVehicle CUserDisplay::CurrentVehicle;

CPlaceName::CPlaceName()
{
	Init();
}

void
CPlaceName::Init()
{
	m_pZone = nil;
	m_pZone2 = nil;
	m_nAdditionalTimer = 0;
}

void
CPlaceName::Process()
{
	CVector pos = CWorld::Players[CWorld::PlayerInFocus].GetPos();
	CZone *navigZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_NAVIG);
	CZone *defaultZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_DEFAULT);

	if (navigZone == nil) m_pZone = nil;
	if (defaultZone == nil) m_pZone2 = nil;

	if (navigZone == m_pZone) {
		if (defaultZone == m_pZone2 || m_pZone != nil) {
			if (navigZone != nil || defaultZone != nil) {
				if (m_nAdditionalTimer != 0)
					m_nAdditionalTimer--;
			} else {
				m_nAdditionalTimer = 0;
				m_pZone = nil;
				m_pZone2 = nil;
			}
		} else {
			m_pZone2 = defaultZone;
			m_nAdditionalTimer = 250;
		}
	} else {
		m_pZone = navigZone;
		m_nAdditionalTimer = 250;
	}
	Display();
}

void
CPlaceName::Display()
{
	wchar *text;
	if (m_pZone != nil)
		text = m_pZone->GetTranslatedName();
	else if (m_pZone2 != nil)
		text = m_pZone2->GetTranslatedName();
#ifdef FIX_BUGS
	else
		text = nil;
#endif
	CHud::SetZoneName(text);
}

CCurrentVehicle::CCurrentVehicle()
{
	Init();
}

void
CCurrentVehicle::Init()
{
	m_pCurrentVehicle = nil;
}

void
CCurrentVehicle::Process()
{
	if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->InVehicle())
		m_pCurrentVehicle = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pMyVehicle;
	else
		m_pCurrentVehicle = nil;
	Display();
}

void
CCurrentVehicle::Display()
{
	wchar *text = nil;
	if (m_pCurrentVehicle != nil)
		text = TheText.Get(((CVehicleModelInfo*)CModelInfo::GetModelInfo(m_pCurrentVehicle->GetModelIndex()))->m_gameName);
	CHud::SetVehicleName(text);
}

void
CUserDisplay::Init()
{
	PlaceName.Init();
	OnscnTimer.Init();
	Pager.Init();
	CurrentVehicle.Init();
}

void
CUserDisplay::Process()
{
#ifdef FIX_BUGS
	if (CReplay::IsPlayingBack())
		return;
#endif
	PlaceName.Process();
	OnscnTimer.Process();
	Pager.Process();
	CurrentVehicle.Process();
}


code:
#pragma once

#include "Pager.h"
#include "OnscreenTimer.h"

class CZone;
class CVehicle;

class CPlaceName
{
	CZone *m_pZone;
	CZone *m_pZone2;
	int16 m_nAdditionalTimer;
public:
	CPlaceName();
	void Init();
	void Process();
	void Display();
};

class CCurrentVehicle
{
	CVehicle *m_pCurrentVehicle;
public:
	CCurrentVehicle();
	void Init();
	void Process();
	void Display();
};

class CUserDisplay
{
public:
	static CPlaceName PlaceName;
	static COnscreenTimer OnscnTimer;
	static CPager Pager;
	static CCurrentVehicle CurrentVehicle;

	static void Init();
	static void Process();
};


code:
#include "common.h"

#include "Pools.h"
#include "ModelIndices.h"
#include "Timer.h"
#include "World.h"
#include "ZoneCull.h"
#include "Darkel.h"
#include "DMAudio.h"
#include "CopPed.h"
#include "Wanted.h"
#include "General.h"

int32 CWanted::MaximumWantedLevel = 6;
int32 CWanted::nMaximumWantedLevel = 6400;

void
CWanted::Initialise()
{
	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 (int i = 0; i < ARRAY_SIZE(m_pCops); i++)
		m_pCops[i] = nil;

	ClearQdCrimes();
}

bool
CWanted::AreSwatRequired()
{
	return m_nWantedLevel == 4 || m_bSwatRequired;
}

bool
CWanted::AreFbiRequired()
{
	return m_nWantedLevel == 5 || m_bFbiRequired;
}

bool
CWanted::AreArmyRequired()
{
	return m_nWantedLevel == 6 || m_bArmyRequired;
}

int32
CWanted::NumOfHelisRequired()
{
	if (m_bIgnoredByCops || m_bIgnoredByEveryone)
		return 0;

	switch (m_nWantedLevel) {
	case 3:
	case 4:
		return 1;
	case 5:
	case 6:
		return 2;
	default:
		return 0;
	}
}

void
CWanted::SetWantedLevel(int32 level)
{
	if (level > MaximumWantedLevel)
		level = MaximumWantedLevel;

	ClearQdCrimes();
	switch (level) {
	case 0:
		m_nChaos = 0;
		break;
	case 1:
		m_nChaos = 60;
		break;
	case 2:
		m_nChaos = 220;
		break;
	case 3:
		m_nChaos = 420;
		break;
	case 4:
		m_nChaos = 820;
		break;
	case 5:
		m_nChaos = 1620;
		break;
	case 6:
		m_nChaos = 3220;
		break;
	default:
		break;
	}
	UpdateWantedLevel();
}

void
CWanted::SetWantedLevelNoDrop(int32 level)
{
	if (level > m_nWantedLevel)
		SetWantedLevel(level);
}

void
CWanted::SetMaximumWantedLevel(int32 level)
{
	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::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 defined FIX_SIGNIFICANT_BUGS || defined PEDS_REPORT_CRIMES_ON_PHONE
	if (!AddCrimeToQ(type, id, coors, true, policeDoesntCare))
#else
	if (!AddCrimeToQ(type, id, coors, false, policeDoesntCare))
#endif
		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;
	if (policeDoesntCare)
		chaos *= 0.333f;
	switch(type){
	case CRIME_POSSESSION_GUN:
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
		m_nChaos += 5.0f*chaos;
#endif
		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 > nMaximumWantedLevel)
		m_nChaos = nMaximumWantedLevel;

	if (m_nChaos >= 0 && m_nChaos < 40) {
		m_nWantedLevel = 0;
		m_MaximumLawEnforcerVehicles = 0;
		m_MaxCops = 0;
		m_RoadblockDensity = 0;
	}
	else if (m_nChaos >= 40 && m_nChaos < 200) {
		m_nWantedLevel = 1;
		m_MaximumLawEnforcerVehicles = 1;
		m_MaxCops = 1;
		m_RoadblockDensity = 0;
	}
	else if (m_nChaos >= 200 && m_nChaos < 400) {
		m_nWantedLevel = 2;
		m_MaximumLawEnforcerVehicles = 2;
		m_MaxCops = 3;
		m_RoadblockDensity = 0;
	}
	else if (m_nChaos >= 400 && m_nChaos < 800) {
		m_nWantedLevel = 3;
		m_MaximumLawEnforcerVehicles = 2;
		m_MaxCops = 4;
		m_RoadblockDensity = 4;
	}
	else if (m_nChaos >= 800 && m_nChaos < 1600) {
		m_nWantedLevel = 4;
		m_MaximumLawEnforcerVehicles = 2;
		m_MaxCops = 6;
		m_RoadblockDensity = 8;
	}
	else if (m_nChaos >= 1600 && m_nChaos < 3200) {
		m_nWantedLevel = 5;
		m_MaximumLawEnforcerVehicles = 3;
		m_MaxCops = 8;
		m_RoadblockDensity = 10;
	}
	else if (m_nChaos >= 3200) {
		m_nWantedLevel = 6;
		m_MaximumLawEnforcerVehicles = 3;
		m_MaxCops = 10;
		m_RoadblockDensity = 12;
	}

	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->GetStatus() != STATUS_ABANDONED && vehicle->GetStatus() != STATUS_WRECKED &&
		   (posn - vehicle->GetPosition()).Magnitude() < radius)
			numPolice++;
	}

	return numPolice;
}

void
CWanted::Update(void)
{
	if (CTimer::GetTimeInMilliseconds() - m_nLastUpdateTime > 1000) {
		if (m_nWantedLevel > 1) {
			m_nLastUpdateTime = CTimer::GetTimeInMilliseconds();
		} else {
			float radius = 18.0f;
			CVector playerPos = FindPlayerCoors();
			if (WorkOutPolicePresence(playerPos, radius) == 0) {
				m_nLastUpdateTime = CTimer::GetTimeInMilliseconds();
				m_nChaos = Max(0, m_nChaos - 1);
				UpdateWantedLevel();
			}
		}
		UpdateCrimesQ();
		bool orderMessedUp = false;
		int currCopNum = 0;
		bool foundEmptySlot = false;
		for (int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
			if (m_pCops[i]) {
				++currCopNum;
				if (foundEmptySlot)
					orderMessedUp = true;
			} else {
				foundEmptySlot = true;
			}
		}
		if (currCopNum != m_CurrentCops) {
			printf("CopPursuit total messed up: re-setting\n");
			m_CurrentCops = currCopNum;
		}
		if (orderMessedUp) {
			printf("CopPursuit pointer list messed up: re-sorting\n");
			bool fixed = true;
			for (int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
				if (!m_pCops[i]) {
					for (int j = i; j < ARRAY_SIZE(m_pCops); j++) {
						if (m_pCops[j]) {
							m_pCops[i] = m_pCops[j];
							m_pCops[j] = nil;
							fixed = false;
							break;
						}
					}
					if (fixed)
						break;
				}
			}
		}
	}
}

void
CWanted::ResetPolicePursuit(void)
{
	for(int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
		CCopPed *cop = m_pCops[i];
		if (!cop)
			continue;

		cop->m_bIsInPursuit = false;
		cop->m_objective = OBJECTIVE_NONE;
		cop->m_prevObjective = OBJECTIVE_NONE;
		cop->m_nLastPedState = PED_NONE;
		if (!cop->DyingOrDead()) {
			cop->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
		}
		m_pCops[i] = nil;
	}
	m_CurrentCops = 0;
}

void
CWanted::Reset(void)
{
	ResetPolicePursuit();
	Initialise();
}

#ifdef PEDS_REPORT_CRIMES_ON_PHONE
bool
CrimeShouldBeReportedOnPhone(eCrimeType crime)
{
	switch (crime) {
		case CRIME_POSSESSION_GUN:
		case CRIME_HIT_PED:
		case CRIME_HIT_COP:
		case CRIME_SHOOT_PED:
		case CRIME_SHOOT_COP:
		case CRIME_STEAL_CAR:
		case CRIME_RECKLESS_DRIVING:
		case CRIME_RUNOVER_PED:
		case CRIME_RUNOVER_COP:
		case CRIME_PED_BURNED:
		case CRIME_COP_BURNED:
		case CRIME_VEHICLE_BURNED:
			return true;
		default:
			return false;
	}
}
#endif

void
CWanted::UpdateCrimesQ(void)
{
	for(int i = 0; i < ARRAY_SIZE(m_aCrimes); i++) {

		CCrimeBeingQd &crime = m_aCrimes[i];
		if (crime.m_nType != CRIME_NONE) {
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
			if (!CrimeShouldBeReportedOnPhone(crime.m_nType))
#endif
			if (CTimer::GetTimeInMilliseconds() > crime.m_nTime + 500 && !crime.m_bReported) {
				ReportCrimeNow(crime.m_nType, crime.m_vecPosn, crime.m_bPoliceDoesntCare);
				crime.m_bReported = true;
			}
			if (CTimer::GetTimeInMilliseconds() > crime.m_nTime + 10000)
				crime.m_nType = CRIME_NONE;
		}
	}
}


code:
#pragma once

#include "Crime.h"

class CEntity;
class CCopPed;

class CWanted
{
public:
	int32 m_nChaos;
	int32 m_nLastUpdateTime;
	uint32 m_nLastWantedLevelChange;
	float m_fCrimeSensitivity;
	uint8 m_CurrentCops;
	uint8 m_MaxCops;
	uint8 m_MaximumLawEnforcerVehicles;
	uint8 m_CopsBeatingSuspect;
	int16 m_RoadblockDensity;
	uint8 m_bIgnoredByCops : 1;
	uint8 m_bIgnoredByEveryone : 1;
	uint8 m_bSwatRequired : 1;
	uint8 m_bFbiRequired : 1;
	uint8 m_bArmyRequired : 1;
	int32 m_nWantedLevel;
	CCrimeBeingQd m_aCrimes[16];
	CCopPed *m_pCops[10];

	static int32 MaximumWantedLevel;
	static int32 nMaximumWantedLevel;

public:
	void Initialise();
	bool AreSwatRequired();
	bool AreFbiRequired();
	bool AreArmyRequired();
	int32 NumOfHelisRequired();
	void SetWantedLevel(int32);
	void SetWantedLevelNoDrop(int32 level);
	int32 GetWantedLevel() { return m_nWantedLevel; }
	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();
	void Reset();
	void ResetPolicePursuit();
	void UpdateCrimesQ();
	void Update();

	bool IsIgnored(void) { return m_bIgnoredByCops || m_bIgnoredByEveryone; }

	static int32 WorkOutPolicePresence(CVector posn, float radius);
	static void SetMaximumWantedLevel(int32 level);
};

VALIDATE_SIZE(CWanted, 0x204);