diff --git a/README.md b/README.md
index ba6d04c3..0c509a16 100644
--- a/README.md
+++ b/README.md
@@ -63,7 +63,6 @@ CMotionBlurStreaks
 CObject
 CPacManPickups
 CPedPath
-CPopulation
 CRadar
 CRecordDataForChase
 CRoadBlocks
diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp
index ccba05c9..1e5b72c3 100644
--- a/src/control/GameLogic.cpp
+++ b/src/control/GameLogic.cpp
@@ -249,7 +249,7 @@ CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector
 	pPlayerPed->m_fHealth = 100.0f;
 	pPlayerPed->m_fArmour = 0.0f;
 	pPlayerPed->bIsVisible = true;
-	pPlayerPed->m_bloodyFootprintCount = 0;
+	pPlayerPed->m_bloodyFootprintCountOrDeathTime = 0;
 	pPlayerPed->bDoBloodyFootprints = false;
 	pPlayerPed->ClearAdrenaline();
 	pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index 05f3984c..e0c0259e 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -153,7 +153,7 @@ void
 CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
 {
 	if (!car || car == m_pPed->m_pMyVehicle) {
-		if (m_pPed->m_nPedState == PED_CARJACK || m_pPed->m_nPedState == PED_ENTER_CAR)
+		if (m_pPed->EnteringCar())
 			m_pPed->QuitEnteringCar();
 	}
 	if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index b0933063..3a830d37 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -1287,7 +1287,7 @@ CStreaming::StreamVehiclesAndPeds(void)
 	if(timeBeforeNextLoad >= 0)
 		timeBeforeNextLoad--;
 	else if(ms_numVehiclesLoaded <= desiredNumVehiclesLoaded){
-		for(i = 0; i <= 10; i++){
+		for(i = 1; i <= 10; i++){
 			model =  CCarCtrl::ChooseCarModel(modelQualityClass);
 			modelQualityClass++;
 			if(modelQualityClass >= NUM_VEHICLE_CLASSES)
@@ -1893,9 +1893,9 @@ CStreaming::AddModelsToRequestList(const CVector &pos)
 
 	CWorld::AdvanceCurrentScanCode();
 
-	for(iy = iymin; iy < iymax; iy++){
+	for(iy = iymin; iy <= iymax; iy++){
 		dy = iy - CWorld::GetSectorIndexY(pos.y);
-		for(ix = ixmin; ix < ixmax; ix++){
+		for(ix = ixmin; ix <= ixmax; ix++){
 
 			if(CRenderer::m_loadingPriority && ms_numModelsRequested > 5)
 				return;
@@ -2124,7 +2124,7 @@ CStreaming::DeleteRwObjectsAfterDeath(const CVector &pos)
 	CSector *sect;
 
 	ix = CWorld::GetSectorIndexX(pos.x);
-	iy = CWorld::GetSectorIndexX(pos.y);
+	iy = CWorld::GetSectorIndexY(pos.y);
 
 	for(x = 0; x < NUMSECTORS_X; x++)
 		for(y = 0; y < NUMSECTORS_Y; y++)
@@ -2153,13 +2153,13 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
 		return;
 
 	ix = CWorld::GetSectorIndexX(TheCamera.GetPosition().x);
-	iy = CWorld::GetSectorIndexX(TheCamera.GetPosition().y);
+	iy = CWorld::GetSectorIndexY(TheCamera.GetPosition().y);
 
 	if(Abs(TheCamera.GetForward().x) > Abs(TheCamera.GetForward().y)){
 		// looking west/east
 
 		ymin = max(iy - 10, 0);
-		ymax = min(iy + 10, NUMSECTORS_Y);
+		ymax = min(iy + 10, NUMSECTORS_Y - 1);
 		assert(ymin <= ymax);
 
 		// Delete a block of sectors that we know is behind the camera
@@ -2170,8 +2170,8 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
 			inc = 1;
 		}else{
 			// looking west
-			xmax = min(ix + 2, NUMSECTORS_X);
-			xmin = min(ix + 10, NUMSECTORS_X);
+			xmax = min(ix + 2, NUMSECTORS_X - 1);
+			xmin = min(ix + 10, NUMSECTORS_X - 1);
 			inc = -1;
 		}
 		for(y = ymin; y <= ymax; y++){
@@ -2192,8 +2192,8 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
 			inc = 1;
 		}else{
 			// looking west
-			xmax = min(ix - 10, NUMSECTORS_X);
-			xmin = min(ix + 2, NUMSECTORS_X);
+			xmax = min(ix - 10, NUMSECTORS_X - 1);
+			xmin = min(ix + 2, NUMSECTORS_X - 1);
 			inc = -1;
 		}
 		for(y = ymin; y <= ymax; y++){
@@ -2223,7 +2223,7 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
 		// looking north/south
 
 		xmin = max(ix - 10, 0);
-		xmax = min(ix + 10, NUMSECTORS_X);
+		xmax = min(ix + 10, NUMSECTORS_X - 1);
 		assert(xmin <= xmax);
 
 		// Delete a block of sectors that we know is behind the camera
@@ -2234,8 +2234,8 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
 			inc = 1;
 		}else{
 			// looking south
-			ymax = min(iy + 2, NUMSECTORS_Y);
-			ymin = min(iy + 10, NUMSECTORS_Y);
+			ymax = min(iy + 2, NUMSECTORS_Y - 1);
+			ymin = min(iy + 10, NUMSECTORS_Y - 1);
 			inc = -1;
 		}
 		for(x = xmin; x <= xmax; x++){
@@ -2256,8 +2256,8 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
 			inc = 1;
 		}else{
 			// looking south
-			ymax = min(iy - 10, NUMSECTORS_Y);
-			ymin = min(iy + 2, NUMSECTORS_Y);
+			ymax = min(iy - 10, NUMSECTORS_Y - 1);
+			ymin = min(iy + 2, NUMSECTORS_Y - 1);
 			inc = -1;
 		}
 		for(x = xmin; x <= xmax; x++){
diff --git a/src/core/World.cpp b/src/core/World.cpp
index f97f0ebf..f6106bb5 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -143,9 +143,9 @@ CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoi
 	dist = 1.0f;
 
 	xstart = GetSectorIndexX(point1.x);
-	ystart = GetSectorIndexX(point1.y);
+	ystart = GetSectorIndexY(point1.y);
 	xend = GetSectorIndexX(point2.x);
-	yend = GetSectorIndexX(point2.y);
+	yend = GetSectorIndexY(point2.y);
 
 #define LOSARGS CColLine(point1, point2), point, dist, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects
 
@@ -416,9 +416,9 @@ CWorld::GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool
 	AdvanceCurrentScanCode();
 
 	xstart = GetSectorIndexX(point1.x);
-	ystart = GetSectorIndexX(point1.y);
+	ystart = GetSectorIndexY(point1.y);
 	xend = GetSectorIndexX(point2.x);
-	yend = GetSectorIndexX(point2.y);
+	yend = GetSectorIndexY(point2.y);
 
 #define LOSARGS CColLine(point1, point2), checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects
 
@@ -638,20 +638,24 @@ void
 CWorld::FindObjectsInRange(CVector &centre, float distance, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies)
 {
 	int minX = GetSectorIndexX(centre.x - distance);
-	if (minX <= 0)
-		minX = 0;
+	if (minX <= 0) minX = 0;
 
 	int minY = GetSectorIndexY(centre.y - distance);
-	if (minY <= 0)
-		minY = 0;
+	if (minY <= 0) minY = 0;
 
 	int maxX = GetSectorIndexX(centre.x + distance);
-	if (maxX >= NUMSECTORS_X)
-		maxX = NUMSECTORS_X;
+#ifdef FIX_BUGS
+	if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
+#else
+	if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
+#endif
 
 	int maxY = GetSectorIndexY(centre.y + distance);
-	if (maxY >= NUMSECTORS_Y)
-		maxY = NUMSECTORS_Y;
+#ifdef FIX_BUGS
+	if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
+#else
+	if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
+#endif
 	
 	AdvanceCurrentScanCode();
 
@@ -689,20 +693,24 @@ CWorld::TestSphereAgainstWorld(CVector centre, float distance, CEntity *entityTo
 	CEntity* foundE = nil;
 
 	int minX = GetSectorIndexX(centre.x - distance);
-	if (minX <= 0)
-		minX = 0;
+	if (minX <= 0) minX = 0;
 
 	int minY = GetSectorIndexY(centre.y - distance);
-	if (minY <= 0)
-		minY = 0;
+	if (minY <= 0) minY = 0;
 
 	int maxX = GetSectorIndexX(centre.x + distance);
-	if (maxX >= NUMSECTORS_X)
-		maxX = NUMSECTORS_X;
+#ifdef FIX_BUGS
+	if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
+#else
+	if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
+#endif
 
 	int maxY = GetSectorIndexY(centre.y + distance);
-	if (maxY >= NUMSECTORS_Y)
-		maxY = NUMSECTORS_Y;
+#ifdef FIX_BUGS
+	if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
+#else
+	if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
+#endif
 
 	AdvanceCurrentScanCode();
 
@@ -1171,8 +1179,7 @@ CWorld::Process(void)
 		for (CPtrNode* node = ms_listMovingEntityPtrs.first; node; node = node->next) {
 			CPed* movingPed = (CPed*)node->item;
 			if (movingPed->IsPed()) {
-				if (movingPed->bInVehicle && movingPed->m_nPedState != PED_EXIT_TRAIN
-					|| movingPed->m_nPedState == PED_ENTER_CAR || movingPed->m_nPedState == PED_CARJACK) {
+				if (movingPed->bInVehicle && movingPed->m_nPedState != PED_EXIT_TRAIN || movingPed->EnteringCar()) {
 					CVehicle *movingCar = movingPed->m_pMyVehicle;
 					if (movingCar) {
 						if (movingCar->IsTrain()) {
diff --git a/src/objects/DummyObject.cpp b/src/objects/DummyObject.cpp
index 41b15129..9649cf7a 100644
--- a/src/objects/DummyObject.cpp
+++ b/src/objects/DummyObject.cpp
@@ -16,8 +16,12 @@ class CDummyObject_ : public CDummyObject
 {
 public:
 	void dtor(void) { CDummyObject::~CDummyObject(); }
+	CDummyObject *ctor(void) { return ::new (this) CDummyObject(); }
+	CDummyObject *ctor(CObject *obj) { return ::new (this) CDummyObject(obj); }
 };
 
 STARTPATCHES
+	InjectHook(0x4BAAF0, (CDummyObject* (CDummyObject::*)(void)) &CDummyObject_::ctor, PATCH_JUMP);
+	InjectHook(0x4BAB10, (CDummyObject* (CDummyObject::*)(CObject*)) &CDummyObject_::ctor, PATCH_JUMP);
 	InjectHook(0x4BAB70, &CDummyObject_::dtor, PATCH_JUMP);
-ENDPATCHES
+ENDPATCHES
\ No newline at end of file
diff --git a/src/objects/Object.h b/src/objects/Object.h
index 1c33b07f..b9c570f5 100644
--- a/src/objects/Object.h
+++ b/src/objects/Object.h
@@ -52,7 +52,7 @@ public:
   int8 field_17D;
   int8 field_17E;
   int8 field_17F;
-	int32 m_nEndOfLifeTime;
+	uint32 m_nEndOfLifeTime;
 	int16 m_nRefModelIndex;
   int8 field_186;
   int8 field_187;
diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp
index 40481ad9..bf0cc59c 100644
--- a/src/peds/CopPed.cpp
+++ b/src/peds/CopPed.cpp
@@ -1,10 +1,14 @@
 #include "common.h"
 #include "patcher.h"
+#include "World.h"
+#include "PlayerPed.h"
 #include "CopPed.h"
 #include "ModelIndices.h"
+#include "Vehicle.h"
+#include "RpAnimBlend.h"
+#include "General.h"
 
 WRAPPER void CCopPed::ProcessControl() { EAXJMP(0x4C1400);  }
-WRAPPER void CCopPed::SetArrestPlayer(CPed*) { EAXJMP(0x4C2B00); }
 
 CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
 {
@@ -66,7 +70,210 @@ CCopPed::~CCopPed()
 	ClearPursuit();
 }
 
-WRAPPER void CCopPed::ClearPursuit(void) { EAXJMP(0x4C28C0); }
+// Parameter should always be CPlayerPed, but it seems they considered making civilians arrestable at some point
+void
+CCopPed::SetArrestPlayer(CPed *player)
+{
+	if (!IsPedInControl() || !player)
+		return;
+
+	switch (m_nCopType) {
+		case COP_FBI:
+			Say(SOUND_PED_ARREST_FBI);
+			break;
+		case COP_SWAT:
+			Say(SOUND_PED_ARREST_SWAT);
+			break;
+		default:
+			Say(SOUND_PED_ARREST_COP);
+			break;
+	}
+	if (player->EnteringCar()) {
+		if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer)
+			return;
+
+		// why?
+		player->bGonnaKillTheCarJacker = true;
+
+		// Genius
+		FindPlayerPed()->m_bCanBeDamaged = false;
+		((CPlayerPed*)player)->m_pArrestingCop = this;
+		this->RegisterReference((CEntity**) &((CPlayerPed*)player)->m_pArrestingCop);
+
+	} else if (player->m_nPedState != PED_DIE && player->m_nPedState != PED_DEAD && player->m_nPedState != PED_ARRESTED) {
+		player->m_nLastPedState = player->m_nPedState;
+		player->m_nPedState = PED_ARRESTED;
+
+		FindPlayerPed()->m_bCanBeDamaged = false;
+		((CPlayerPed*)player)->m_pArrestingCop = this;
+		this->RegisterReference((CEntity**) &((CPlayerPed*)player)->m_pArrestingCop);
+	}
+
+	m_nPedState = PED_ARREST_PLAYER;
+	SetObjective(OBJECTIVE_NONE);
+	m_prevObjective = OBJECTIVE_NONE;
+	bIsPointingGunAt = false;
+	m_pSeekTarget = player;
+	m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
+	SetCurrentWeapon(WEAPONTYPE_COLT45);
+	if (player->InVehicle()) {
+		player->m_pMyVehicle->m_nNumGettingIn = 0;
+		player->m_pMyVehicle->m_nGettingInFlags = 0;
+		player->m_pMyVehicle->bIsHandbrakeOn = true;
+		player->m_pMyVehicle->m_status = STATUS_PLAYER_DISABLED;
+	}
+	if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
+		SetCurrentWeapon(WEAPONTYPE_COLT45);
+}
+
+void
+CCopPed::ClearPursuit(void)
+{
+	CPlayerPed *player = FindPlayerPed();
+	if (!player)
+		return;
+
+	CWanted *wanted = player->m_pWanted;
+	int ourCopId = 0;
+	bool foundMyself = false;
+	int biggestCopId = 0;
+	if (!m_bIsInPursuit)
+		return;
+
+	m_bIsInPursuit = false;
+	for (int i = 0; i < max(wanted->m_MaxCops, wanted->m_CurrentCops); ++i)  {
+		if (!foundMyself && wanted->m_pCops[i] == this) {
+			wanted->m_pCops[i] = nil;
+			--wanted->m_CurrentCops;
+			foundMyself = true;
+			ourCopId = i;
+			biggestCopId = i;
+		} else {
+			if (wanted->m_pCops[i])
+				biggestCopId = i;
+		}
+	}
+	if (foundMyself && biggestCopId > ourCopId) {
+		wanted->m_pCops[ourCopId] = wanted->m_pCops[biggestCopId];
+		wanted->m_pCops[biggestCopId] = nil;
+	}
+	m_objective = OBJECTIVE_NONE;
+	m_prevObjective = OBJECTIVE_NONE;
+	m_nLastPedState = PED_NONE;
+	bIsRunning = false;
+	bNotAllowedToDuck = false;
+	bKindaStayInSamePlace = false;
+	m_bZoneDisabledButClose = false;
+	m_bZoneDisabled = false;
+	ClearObjective();
+	if (IsPedInControl()) {
+		if (!m_pMyVehicle || wanted->m_nWantedLevel != 0)  {
+			if (m_pMyVehicle && (m_pMyVehicle->GetPosition() - GetPosition()).MagnitudeSqr() < sq(5.0f)) {
+				m_nLastPedState = PED_IDLE;
+				SetSeek((CEntity*)m_pMyVehicle, 2.5f);
+			} else {
+				m_nLastPedState = PED_WANDER_PATH;
+				SetFindPathAndFlee(FindPlayerPed()->GetPosition(), 10000, true);
+			}
+		} else {
+			SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
+		}
+	}
+}
+
+// TO-DO: m_MaxCops in for loop may be a bug, check it out after CopAI
+void
+CCopPed::SetPursuit(bool iMayAlreadyBeInPursuit)
+{
+	CWanted *wanted = FindPlayerPed()->m_pWanted;
+	if (m_bIsInPursuit || !IsPedInControl())
+		return;
+
+	if (wanted->m_CurrentCops < wanted->m_MaxCops || iMayAlreadyBeInPursuit) {
+		for (int i = 0; i < wanted->m_MaxCops; ++i) {
+			if (!wanted->m_pCops[i]) {
+				m_bIsInPursuit = true;
+				++wanted->m_CurrentCops;
+				wanted->m_pCops[i] = this;
+				break;
+			}
+		}
+		if (m_bIsInPursuit) {
+			ClearObjective();
+			m_prevObjective = OBJECTIVE_NONE;
+			SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, FindPlayerPed());
+			SetObjectiveTimer(0);
+			bNotAllowedToDuck = true;
+			bIsRunning = true;
+			m_bZoneDisabledButClose = false;
+		}
+	}
+}
+
+void
+CCopPed::ArrestPlayer(void)
+{
+	m_pVehicleAnim = nil;
+	CPed *suspect = (CPed*)m_pSeekTarget;
+	if (suspect) {
+		if (suspect->CanSetPedState())
+			suspect->m_nPedState = PED_ARRESTED;
+
+		if (suspect->bInVehicle && m_pMyVehicle && suspect->m_pMyVehicle == m_pMyVehicle) {
+
+			// BUG? I will never understand why they used LINE_UP_TO_CAR_2...
+			LineUpPedWithCar(LINE_UP_TO_CAR_2);
+		}
+
+		if (suspect && (suspect->m_nPedState == PED_ARRESTED || suspect->DyingOrDead() || suspect->EnteringCar())) {
+
+			CAnimBlendAssociation *arrestAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ARREST_GUN);
+			if (!arrestAssoc || arrestAssoc->blendDelta < 0.0f)
+				CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ARREST_GUN, 4.0f);
+
+			CVector suspMidPos;
+			suspect->m_pedIK.GetComponentPosition((RwV3d*)suspMidPos, PED_MID);
+			m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(suspMidPos.x, suspMidPos.y,
+				GetPosition().x, GetPosition().y);
+
+			m_fRotationCur = m_fRotationDest;
+			SetOrientation(0.0f, 0.0f, m_fRotationCur);
+		} else {
+			ClearPursuit();
+		}
+	} else {
+		ClearPursuit();
+	}
+}
+
+void
+CCopPed::ScanForCrimes(void)
+{
+	CVehicle *playerVeh = FindPlayerVehicle();
+
+	// Look for car alarms
+	if (playerVeh && playerVeh->IsCar()) {
+		if (playerVeh->IsAlarmOn()) {
+			if ((playerVeh->GetPosition() - GetPosition()).MagnitudeSqr() < sq(20.0f))
+				FindPlayerPed()->SetWantedLevelNoDrop(1);
+		}
+	}
+
+	// Look for stolen cop cars (it was broken until now)
+	if (!m_bIsInPursuit) {
+		CPlayerPed *player = FindPlayerPed();
+#ifdef FIX_BUGS
+		if ((player->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || player->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER)
+#else
+		if ((m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER)
+#endif
+			&& player->m_pWanted->m_nWantedLevel == 0 && player->m_pMyVehicle) {
+
+			if (player->m_pMyVehicle->bIsLawEnforcer)
+				player->SetWantedLevelNoDrop(1);
+		}
+	}
+}
 
 class CCopPed_ : public CCopPed
 {
@@ -78,4 +285,9 @@ public:
 STARTPATCHES
 	InjectHook(0x4C11B0, &CCopPed_::ctor, PATCH_JUMP);
 	InjectHook(0x4C13E0, &CCopPed_::dtor, PATCH_JUMP);
+	InjectHook(0x4C28C0, &CCopPed::ClearPursuit, PATCH_JUMP);
+	InjectHook(0x4C2B00, &CCopPed::SetArrestPlayer, PATCH_JUMP);
+	InjectHook(0x4C27D0, &CCopPed::SetPursuit, PATCH_JUMP);
+	InjectHook(0x4C2C90, &CCopPed::ArrestPlayer, PATCH_JUMP);
+	InjectHook(0x4C26A0, &CCopPed::ScanForCrimes, PATCH_JUMP);
 ENDPATCHES
diff --git a/src/peds/CopPed.h b/src/peds/CopPed.h
index e0f00b7e..7705eb12 100644
--- a/src/peds/CopPed.h
+++ b/src/peds/CopPed.h
@@ -37,6 +37,9 @@ public:
 	void ClearPursuit(void);
 	void ProcessControl(void);
 	void SetArrestPlayer(CPed*);
+	void SetPursuit(bool);
+	void ArrestPlayer(void);
+	void ScanForCrimes(void);
 };
 
 static_assert(sizeof(CCopPed) == 0x558, "CCopPed: error");
diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp
index fbccc8a0..ee559f57 100644
--- a/src/peds/EmergencyPed.cpp
+++ b/src/peds/EmergencyPed.cpp
@@ -303,7 +303,7 @@ CEmergencyPed::MedicAI(void)
 				if (!m_pRevivedPed || m_pRevivedPed->m_fHealth > 0.0f || m_pRevivedPed->bFadeOut) {
 					m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
 				} else {
-					m_pRevivedPed->m_bloodyFootprintCount = CTimer::GetTimeInMilliseconds();
+					m_pRevivedPed->m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds();
 					SetMoveState(PEDMOVE_STILL);
 					m_nPedState = PED_CPR;
 					m_nLastPedState = PED_CPR;
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index f4e7ce2f..3c62512e 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -49,19 +49,56 @@
 #include "ParticleObject.h"
 #include "Floater.h"
 
-#define FEET_OFFSET 1.04f
+#define CAN_SEE_ENTITY_ANGLE_THRESHOLD	DEGTORAD(60.0f)
 
 CPed *gapTempPedList[50];
 uint16 gnNumTempPedList;
 
-bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44;
-bool &CPed::bPedCheat2 = *(bool*)0x95CD5A;
-bool &CPed::bPedCheat3 = *(bool*)0x95CD59;
-
 CColPoint &aTempPedColPts = *(CColPoint*)0x62DB14;
 
-// TODO: CommentWaitTime should be hardcoded into exe, and it isn't reversed yet.
-CPedAudioData (&CPed::CommentWaitTime)[38] = *(CPedAudioData(*)[38]) * (uintptr*)0x5F94C4;
+// Corresponds to ped sounds (from SOUND_PED_DEATH to SOUND_PED_TAXI_CALL)
+PedAudioData CommentWaitTime[39] = {
+	{500, 800, 500, 2},
+	{500, 800, 500, 2},
+	{500, 800, 500, 2},
+	{500, 800, 500, 2},
+	{100, 2, 100, 2},
+	{700, 500, 1000, 500},
+	{700, 500, 1000, 500},
+	{5000, 2000, 15000, 3000},
+	{5000, 2000, 15000, 3000},
+	{5000, 2000, 15000, 3000},
+	{6000, 6000, 6000, 6000},
+	{1000, 1000, 2000, 2000},
+	{1000, 500, 2000, 1500},
+	{1000, 500, 2000, 1500},
+	{800, 200, 1000, 500},
+	{800, 200, 1000, 500},
+	{800, 400, 2000, 1000},
+	{800, 400, 2000, 1000},
+	{400, 300, 2000, 1000},
+	{2000, 1000, 2500, 1500},
+	{200, 200, 200, 200},
+	{6000, 3000, 5000, 6000},
+	{6000, 3000, 9000, 5000},
+	{6000, 3000, 9000, 5000},
+	{6000, 3000, 9000, 5000},
+	{400, 300, 4000, 1000},
+	{400, 300, 4000, 1000},
+	{400, 300, 4000, 1000},
+	{1000, 500, 3000, 1000},
+	{1000, 500, 1000, 1000},
+	{3000, 2000, 3000, 2000},
+	{1000, 500, 3000, 6000},
+	{1000, 500, 2000, 4000},
+	{1000, 500, 2000, 5000},
+	{1000, 500, 3000, 2000},
+	{1600, 1000, 2000, 2000},
+	{3000, 2000, 5000, 3000},
+	{1000, 1000, 1000, 1000},
+	{1000, 1000, 5000, 5000},
+};
+// *(CPedAudioData(*)[39]) * (uintptr*)0x5F94C4;
 
 uint16 nPlayerInComboMove;
 
@@ -106,6 +143,9 @@ CVector vecPedQuickDraggedOutCarAnimOffset;
 CVector vecPedDraggedOutCarAnimOffset;
 CVector vecPedTrainDoorAnimOffset;
 
+bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44;
+bool &CPed::bPedCheat2 = *(bool*)0x95CD5A;
+bool &CPed::bPedCheat3 = *(bool*)0x95CD59;
 CVector2D CPed::ms_vec2DFleePosition;
 
 void *CPed::operator new(size_t sz) { return CPools::GetPedPool()->New();  }
@@ -351,7 +391,7 @@ CPed::~CPed(void)
 			m_pMyVehicle->m_nGettingOutFlags &= ~door_flag;
 		bInVehicle = false;
 		m_pMyVehicle = nil;
-	} else if (m_nPedState == PED_ENTER_CAR || m_nPedState == PED_CARJACK){
+	} else if (EnteringCar()) {
 		QuitEnteringCar();
 	}
 	if (m_pFire)
@@ -745,8 +785,7 @@ CPed::UseGroundColModel(void)
 bool
 CPed::CanSetPedState(void)
 {
-	return m_nPedState != PED_DIE && m_nPedState != PED_ARRESTED &&
-		m_nPedState != PED_ENTER_CAR && m_nPedState != PED_DEAD && m_nPedState != PED_CARJACK && m_nPedState != PED_STEAL_CAR;
+	return !DyingOrDead() && m_nPedState != PED_ARRESTED && !EnteringCar() && m_nPedState != PED_STEAL_CAR;
 }
 
 bool
@@ -1912,7 +1951,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
 
 						// Smoothly change ped position
 						neededPos.z = (neededPos.z - currentZ) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep) + currentZ;
-					} else if (m_nPedState == PED_ENTER_CAR || m_nPedState == PED_CARJACK) {
+					} else if (EnteringCar()) {
 						neededPos.z = max(currentZ, autoZPos.z);
 					}
 #ifdef VC_PED_PORTS
@@ -1999,10 +2038,10 @@ void
 CPed::PlayFootSteps(void)
 {
 	if (bDoBloodyFootprints) {
-		if (m_bloodyFootprintCount > 0 && m_bloodyFootprintCount < 300) {
-			m_bloodyFootprintCount--;
+		if (m_bloodyFootprintCountOrDeathTime > 0 && m_bloodyFootprintCountOrDeathTime < 300) {
+			m_bloodyFootprintCountOrDeathTime--;
 
-			if (m_bloodyFootprintCount == 0)
+			if (m_bloodyFootprintCountOrDeathTime == 0)
 				bDoBloodyFootprints = false;
 		}
 	}
@@ -2055,11 +2094,11 @@ CPed::PlayFootSteps(void)
 					right.x, right.y,
 					255, 255, 0, 0, 4.0f, 3000.0f, 1.0f);
 
-				if (m_bloodyFootprintCount <= 20) {
-					m_bloodyFootprintCount = 0;
+				if (m_bloodyFootprintCountOrDeathTime <= 20) {
+					m_bloodyFootprintCountOrDeathTime = 0;
 					bDoBloodyFootprints = false;
 				} else {
-					m_bloodyFootprintCount -= 20;
+					m_bloodyFootprintCountOrDeathTime -= 20;
 				}
 			}
 			if (CWeather::Rain <= 0.1f || CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) {
@@ -2482,7 +2521,7 @@ CPed::CanPedReturnToState(void)
 }
 
 bool
-CPed::CanSeeEntity(CEntity *entity, float threshold)
+CPed::CanSeeEntity(CEntity *entity, float threshold = CAN_SEE_ENTITY_ANGLE_THRESHOLD)
 {
 	float neededAngle = CGeneral::GetRadianAngleBetweenPoints(
 		entity->GetPosition().x,
@@ -3353,7 +3392,7 @@ CPed::CheckForPointBlankPeds(CPed *pedToVerify)
 				if (nearPedState == PED_FALL || nearPedState == PED_GETUP || nearPedState == PED_DIE || nearPedState == PED_DEAD || nearPedState == PED_DIVE_AWAY)
 					return NO_POINT_BLANK_PED;
 
-				if (neededTurn < DEGTORAD(60.0f)) {
+				if (neededTurn < CAN_SEE_ENTITY_ANGLE_THRESHOLD) {
 					if (pedToVerify == nearPed)
 						return POINT_BLANK_FOR_WANTED_PED;
 					else
@@ -3415,6 +3454,13 @@ CPed::ClearAttack(void)
 	if (m_nPedState != PED_ATTACK || bIsDucking || m_nWaitState == WAITSTATE_PLAYANIM_DUCK)
 		return;
 
+#ifdef VC_PED_PORTS
+	// VC uses CCamera::Using1stPersonWeaponMode
+	if (FindPlayerPed() == this && (TheCamera.PlayerWeaponMode.Mode == CCam::MODE_SNIPER ||
+		TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_ROCKETLAUNCHER)) {
+		SetPointGunAt(nil);
+	} else
+#endif
 	if (bIsPointingGunAt) {
 		if (m_pLookTarget)
 			SetPointGunAt(m_pLookTarget);
@@ -3504,7 +3550,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
 	} else if (bInVehicle) {
 		if (m_pVehicleAnim)
 			m_pVehicleAnim->blendDelta = -1000.0f;
-	} else if (m_nPedState == PED_ENTER_CAR || m_nPedState == PED_CARJACK) {
+	} else if (EnteringCar()) {
 		QuitEnteringCar();
 	}
 
@@ -3529,8 +3575,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
 	if (!bInVehicle)
 		StopNonPartialAnims();
 
-	// BUG: This is not timer.
-	m_bloodyFootprintCount = CTimer::GetTimeInMilliseconds();
+	m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds();
 }
 
 bool
@@ -5924,8 +5969,7 @@ CPed::SetDead(void)
 		CreateDeadPedMoney();
 	}
 
-	// BUG: Is this count or timer?!
-	m_bloodyFootprintCount = CTimer::GetTimeInMilliseconds();
+	m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds();
 	m_deadBleeding = false;
 	bDoBloodyFootprints = false;
 	bVehExitWillBeInstant = false;
@@ -6066,7 +6110,7 @@ CPed::DuckAndCover(void)
 		CVector pos = GetPosition();
 		int16 lastVehicle;
 		CEntity *vehicles[8];
-		CWorld::FindObjectsInRange(pos, 15.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+		CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
 
 		for (int i = 0; i < lastVehicle; i++) {
 			CVehicle *veh = (CVehicle*) vehicles[i];
@@ -6971,11 +7015,11 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
 			0.14f * ped->GetRight().y,
 			255, 255, 0, 0, 4.0f, 3000, 1.0f);
 
-		if (ped->m_bloodyFootprintCount <= 40) {
-			ped->m_bloodyFootprintCount = 0;
+		if (ped->m_bloodyFootprintCountOrDeathTime <= 40) {
+			ped->m_bloodyFootprintCountOrDeathTime = 0;
 			ped->bDoBloodyFootprints = false;
 		} else {
-			ped->m_bloodyFootprintCount -= 40;
+			ped->m_bloodyFootprintCountOrDeathTime -= 40;
 		}
 	}
 }
@@ -8674,18 +8718,29 @@ CPed::LookForInterestingNodes(void)
 	bool found = false;
 	uint8 randVal = CGeneral::GetRandomNumber() % 256;
 
-	int minX = CWorld::GetSectorIndexX(GetPosition().x - 15.0f);
+	int minX = CWorld::GetSectorIndexX(GetPosition().x - CHECK_NEARBY_THINGS_MAX_DIST);
 	if (minX < 0) minX = 0;
-	int minY = CWorld::GetSectorIndexY(GetPosition().y - 15.0f);
+	int minY = CWorld::GetSectorIndexY(GetPosition().y - CHECK_NEARBY_THINGS_MAX_DIST);
 	if (minY < 0) minY = 0;
-	int maxX = CWorld::GetSectorIndexX(GetPosition().x + 15.0f);
-	if (maxX > NUMSECTORS_X) maxX = NUMSECTORS_X;
-	int maxY = CWorld::GetSectorIndexY(GetPosition().y + 15.0f);
-	if (maxY > NUMSECTORS_Y) maxY = NUMSECTORS_Y;
+	int maxX = CWorld::GetSectorIndexX(GetPosition().x + CHECK_NEARBY_THINGS_MAX_DIST);
+#ifdef FIX_BUGS
+	if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
+#else
+	if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
+#endif
+
+	int maxY = CWorld::GetSectorIndexY(GetPosition().y + CHECK_NEARBY_THINGS_MAX_DIST);
+#ifdef FIX_BUGS
+	if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
+#else
+	if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
+#endif
 
 	for (int curY = minY; curY <= maxY && !found; curY++) {
 		for (int curX = minX; curX <= maxX && !found; curX++) {
-			for (ptrNode = CWorld::GetSector(curX, curY)->m_lists[ENTITYLIST_VEHICLES].first; ptrNode && !found; ptrNode = ptrNode->next) {
+			CSector *sector = CWorld::GetSector(curX, curY);
+
+			for (ptrNode = sector->m_lists[ENTITYLIST_VEHICLES].first; ptrNode && !found; ptrNode = ptrNode->next) {
 				CVehicle *veh = (CVehicle*)ptrNode->item;
 				model = veh->GetModelInfo();
 				if (model->m_num2dEffects != 0) {
@@ -8703,7 +8758,7 @@ CPed::LookForInterestingNodes(void)
 					}
 				}
 			}
-			for (ptrNode = CWorld::GetSector(curX, curY)->m_lists[ENTITYLIST_OBJECTS].first; ptrNode && !found; ptrNode = ptrNode->next) {
+			for (ptrNode = sector->m_lists[ENTITYLIST_OBJECTS].first; ptrNode && !found; ptrNode = ptrNode->next) {
 				CObject *obj = (CObject*)ptrNode->item;
 				model = CModelInfo::GetModelInfo(obj->m_modelIndex);
 				if (model->m_num2dEffects != 0) {
@@ -8721,7 +8776,7 @@ CPed::LookForInterestingNodes(void)
 					}
 				}
 			}
-			for (ptrNode = CWorld::GetSector(curX, curY)->m_lists[ENTITYLIST_BUILDINGS].first; ptrNode && !found; ptrNode = ptrNode->next) {
+			for (ptrNode = sector->m_lists[ENTITYLIST_BUILDINGS].first; ptrNode && !found; ptrNode = ptrNode->next) {
 				CBuilding *building = (CBuilding*)ptrNode->item;
 				model = CModelInfo::GetModelInfo(building->m_modelIndex);
 				if (model->m_num2dEffects != 0) {
@@ -8739,7 +8794,7 @@ CPed::LookForInterestingNodes(void)
 					}
 				}
 			}
-			for (ptrNode = CWorld::GetSector(curX, curY)->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].first; ptrNode && !found; ptrNode = ptrNode->next) {
+			for (ptrNode = sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].first; ptrNode && !found; ptrNode = ptrNode->next) {
 				CBuilding *building = (CBuilding*)ptrNode->item;
 				model = CModelInfo::GetModelInfo(building->m_modelIndex);
 				if (model->m_num2dEffects != 0) {
@@ -8847,11 +8902,8 @@ CPed::LookForSexyPeds(void)
 		return;
 
 	for (int i = 0; i < m_numNearPeds; i++) {
-
-		if (CanSeeEntity(m_nearPeds[i], DEGTORAD(60.0f))) {
-
+		if (CanSeeEntity(m_nearPeds[i])) {
 			if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() < 10.0f) {
-
 				CPed *nearPed = m_nearPeds[i];
 				if ((nearPed->m_pedStats->m_sexiness > m_pedStats->m_sexiness)
 					&& nearPed->m_nPedType == PEDTYPE_CIVFEMALE) {
@@ -9097,7 +9149,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
 	if (!ped->IsNotInWreckedVehicle())
 		return;
 
-	if (ped->m_nPedState != PED_ENTER_CAR && ped->m_nPedState != PED_CARJACK) {
+	if (!ped->EnteringCar()) {
 		ped->QuitEnteringCar();
 		return;
 	}
@@ -9237,7 +9289,7 @@ CPed::ProcessControl(void)
 #else
 			if (CGame::nastyGame && !bIsInWater) {
 #endif
-				uint32 remainingBloodyFpTime = CTimer::GetTimeInMilliseconds() - m_bloodyFootprintCount;
+				uint32 remainingBloodyFpTime = CTimer::GetTimeInMilliseconds() - m_bloodyFootprintCountOrDeathTime;
 				float timeDependentDist;
 				if (remainingBloodyFpTime >= 2000) {
 					if (remainingBloodyFpTime <= 7000)
@@ -9253,7 +9305,7 @@ CPed::ProcessControl(void)
 					if (!nearPed->DyingOrDead()) {
 						CVector dist = nearPed->GetPosition() - GetPosition();
 						if (dist.MagnitudeSqr() < sq(timeDependentDist)) {
-							nearPed->m_bloodyFootprintCount = 200;
+							nearPed->m_bloodyFootprintCountOrDeathTime = 200;
 							nearPed->bDoBloodyFootprints = true;
 							if (nearPed->IsPlayer()) {
 								if (!nearPed->bIsLooking && nearPed->m_nPedState != PED_ATTACK) {
@@ -10313,7 +10365,7 @@ CPed::ProcessControl(void)
 					CPed::Chat();
 					break;
 				case PED_AIM_GUN:
-					if (m_pPointGunAt && m_pPointGunAt->IsPed() && ((CPed*)m_pPointGunAt)->CanSeeEntity(this, DEGTORAD(120.0f))) {
+					if (m_pPointGunAt && m_pPointGunAt->IsPed() && ((CPed*)m_pPointGunAt)->CanSeeEntity(this, CAN_SEE_ENTITY_ANGLE_THRESHOLD * 2)) {
 						((CPed*)m_pPointGunAt)->ReactToPointGun(this);
 					}
 					PointGunAt();
@@ -10588,7 +10640,7 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
 	if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
 		return;
 
-	if (ped->m_nPedState == PED_CARJACK || ped->m_nPedState == PED_ENTER_CAR) {
+	if (ped->EnteringCar()) {
 		bool isLow = veh->bLowVehicle;
 
 		if (!veh->bIsBus)
@@ -10681,7 +10733,7 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
 	if (!ped->IsNotInWreckedVehicle())
 		return;
 
-	if (ped->m_nPedState != PED_CARJACK && ped->m_nPedState != PED_ENTER_CAR) {
+	if (!ped->EnteringCar()) {
 		ped->QuitEnteringCar();
 		return;
 	}
@@ -10926,7 +10978,7 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
 	if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
 		return;
 
-	if (ped->m_nPedState != PED_CARJACK && ped->m_nPedState != PED_ENTER_CAR) {
+	if (!ped->EnteringCar()) {
 		ped->QuitEnteringCar();
 		return;
 	}
@@ -11018,7 +11070,10 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
 			if ((ped->m_nPedType != PEDTYPE_EMERGENCY || veh->pDriver->m_nPedType != PEDTYPE_EMERGENCY)
 				&& (ped->m_nPedType != PEDTYPE_COP || veh->pDriver->m_nPedType != PEDTYPE_COP)) {
 				veh->pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, veh);
-				veh->pDriver->Say(SOUND_PICKUP_WEAPON_BOUGHT);
+				veh->pDriver->Say(SOUND_PED_CAR_JACKED);
+#ifdef VC_PED_PORTS
+				veh->pDriver->SetRadioStation();
+#endif
 			} else {
 				ped->m_objective = OBJECTIVE_ENTER_CAR_AS_PASSENGER;
 			}
@@ -11063,7 +11118,7 @@ CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg)
 	if (animAssoc)
 		animAssoc->blendDelta = -1000.0f;
 
-	if (ped->m_nPedState == PED_CARJACK || ped->m_nPedState == PED_ENTER_CAR) {
+	if (ped->EnteringCar()) {
 		if (!ped->IsNotInWreckedVehicle())
 			return;
 
@@ -12809,10 +12864,10 @@ CPed::ProcessObjective(void)
 					if (distWithTargetSc > wepRange
 						|| m_pedInObjective->m_getUpTimer > CTimer::GetTimeInMilliseconds()
 						|| m_pedInObjective->m_nPedState == PED_ARRESTED
-						|| (m_pedInObjective->m_nPedState == PED_ENTER_CAR || m_pedInObjective->m_nPedState == PED_CARJACK) && distWithTargetSc < 3.0f
-						|| distWithTargetSc > m_distanceToCountSeekDone && !CanSeeEntity(m_pedInObjective, DEGTORAD(60.0f))) {
+						|| m_pedInObjective->EnteringCar() && distWithTargetSc < 3.0f
+						|| distWithTargetSc > m_distanceToCountSeekDone && !CanSeeEntity(m_pedInObjective)) {
 
-						if (m_pedInObjective->m_nPedState == PED_ENTER_CAR || m_pedInObjective->m_nPedState == PED_CARJACK)
+						if (m_pedInObjective->EnteringCar())
 							wepRangeAdjusted = 2.0f;
 
 						if (bUsePedNodeSeek) {
@@ -13110,7 +13165,7 @@ CPed::ProcessObjective(void)
 						break;
 					}
 					if (m_objectiveTimer && m_objectiveTimer < CTimer::GetTimeInMilliseconds()) {
-						if (m_nPedState != PED_CARJACK && m_nPedState != PED_ENTER_CAR) {
+						if (!EnteringCar()) {
 							bool foundSeat = false;
 							if (m_carInObjective->pPassengers[0] || m_carInObjective->m_nGettingInFlags & CAR_DOOR_FLAG_RF) {
 								if (m_carInObjective->pPassengers[1] || m_carInObjective->m_nGettingInFlags & CAR_DOOR_FLAG_LR) {
@@ -13452,7 +13507,7 @@ CPed::ProcessObjective(void)
 					SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_carInObjective);
 				} else {
 					CVehicle* trainToEnter = nil;
-					float closestCarDist = 15.0f;
+					float closestCarDist = CHECK_NEARBY_THINGS_MAX_DIST;
 					CVector pos = GetPosition();
 					int16 lastVehicle;
 					CEntity* vehicles[8];
@@ -13500,7 +13555,7 @@ CPed::ProcessObjective(void)
 					int16 lastVehicle;
 					CEntity *vehicles[8];
 
-					CWorld::FindObjectsInRange(pos, 15.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+					CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
 					for(int i = 0; i < lastVehicle; i++) {
 						CVehicle *nearVeh = (CVehicle*)vehicles[i];
 						if (nearVeh->VehicleCreatedBy != MISSION_VEHICLE) {
@@ -15497,7 +15552,7 @@ CPed::ScanForInterestingStuff(void)
 		}
 	}
 
-	if (m_nPedState == PEDTYPE_CIVFEMALE) {
+	if (m_nPedState == PED_WANDER_PATH) {
 #ifndef VC_PED_PORTS
 		if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
 
@@ -15509,7 +15564,7 @@ CPed::ScanForInterestingStuff(void)
 					else {
 						if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() >= 1.8f) {
 							m_standardTimer = CTimer::GetTimeInMilliseconds() + 30000;
-						} else if (CanSeeEntity(m_nearPeds[i], DEGTORAD(60.0f))) {
+						} else if (CanSeeEntity(m_nearPeds[i])) {
 							int time = CGeneral::GetRandomNumber() % 4000 + 10000;
 							SetChat(m_nearPeds[i], time);
 							m_nearPeds[i]->SetChat(this, time);
@@ -15525,10 +15580,10 @@ CPed::ScanForInterestingStuff(void)
 		} else {
 			if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
 				for (int i = 0; i < m_numNearPeds; i ++) {
-					if (m_nearPeds[i]->m_nPedState == PED_WANDER_PATH) {
+					if (m_nearPeds[i] && m_nearPeds[i]->m_nPedState == PED_WANDER_PATH) {
 						if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() < 1.8f
-							&& CanSeeEntity(m_nearPeds[i], DEGTORAD(60.0f)
-							&& m_nearPeds[i]->CanSeeEntity(this, DEGTORAD(60.0f)))
+							&& CanSeeEntity(m_nearPeds[i])
+							&& m_nearPeds[i]->CanSeeEntity(this)
 							&& WillChat(m_nearPeds[i])) {
 
 							int time = CGeneral::GetRandomNumber() % 4000 + 10000;
@@ -15550,7 +15605,7 @@ CPed::ScanForInterestingStuff(void)
 		CVector pos = GetPosition();
 		int16 lastVehicle;
 		CEntity* vehicles[8];
-		CWorld::FindObjectsInRange(pos, 15.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+		CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
 
 		for (int i = 0; i < lastVehicle; i++) {
 			CVehicle* veh = (CVehicle*)vehicles[i];
@@ -15570,7 +15625,7 @@ CPed::ScanForInterestingStuff(void)
 		CVector pos = GetPosition();
 		int16 lastVehicle;
 		CEntity* vehicles[8];
-		CWorld::FindObjectsInRange(pos, 15.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+		CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
 
 		for (int i = 0; i < lastVehicle; i++) {
 			CVehicle* veh = (CVehicle*)vehicles[i];
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index 4f159210..a19dc9f0 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -13,11 +13,14 @@
 #include "DMAudio.h"
 #include "EventList.h"
 
+#define FEET_OFFSET	1.04f
+#define CHECK_NEARBY_THINGS_MAX_DIST	15.0f
+
 struct CPathNode;
 class CAccident;
 class CObject;
 
-struct CPedAudioData
+struct PedAudioData
 {
 	int m_nFixedDelayTime;
 	int m_nOverrideFixedDelayTime;
@@ -81,7 +84,7 @@ struct FightMove
 };
 static_assert(sizeof(FightMove) == 0x18, "FightMove: error");
 
-// TO-DO: This is eFightState on mobile.
+// TODO: This is eFightState on mobile.
 enum PedFightMoves
 {
 	FIGHTMOVE_NULL,
@@ -359,7 +362,7 @@ public:
 	uint8 bStartWanderPathOnFoot : 1; // exits the car if he's in it, reset after path found
 	uint8 bOnBoat : 1; // not just driver, may be just standing
 	uint8 bBusJacked : 1;
-	uint8 bGonnaKillTheCarJacker : 1; // only set when car is jacked from right door
+	uint8 bGonnaKillTheCarJacker : 1; // only set when car is jacked from right door and when arrested by police
 	uint8 bFadeOut : 1;
 
 	uint8 bKnockedUpIntoAir : 1; // has ped been knocked up into the air by a car collision
@@ -496,7 +499,7 @@ public:
 	uint32 m_objectiveTimer;
 	uint32 m_duckTimer;
 	uint32 m_duckAndCoverTimer;
-	int32 m_bloodyFootprintCount;
+	uint32 m_bloodyFootprintCountOrDeathTime;	// Death time when bDoBloodyFootprints is false. Weird decision
 	uint8 m_panicCounter;
 	bool m_deadBleeding;
 	int8 m_bodyPartBleeding;		// PedNode, but -1 if there isn't
@@ -791,10 +794,13 @@ public:
 	CWeapon &GetWeapon(uint8 weaponType) { return m_weapons[weaponType]; }
 	CWeapon *GetWeapon(void) { return &m_weapons[m_currentWeapon]; }
 	RwFrame *GetNodeFrame(int nodeId) { return m_pFrames[nodeId]->frame; }
+
 	PedState GetPedState(void) { return m_nPedState; }
 	void SetPedState(PedState state) { m_nPedState = state; }
 	bool DyingOrDead(void) { return m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
 	bool InVehicle(void) { return bInVehicle && m_pMyVehicle; } // True when ped is sitting/standing in vehicle, not in enter/exit state.
+	bool EnteringCar(void) { return m_nPedState == PED_ENTER_CAR || m_nPedState == PED_CARJACK; }
+
 	void ReplaceWeaponWhenExitingVehicle(void);
 	void RemoveWeaponWhenEnteringVehicle(void);
 	bool IsNotInWreckedVehicle();
@@ -827,7 +833,6 @@ public:
 	static bool &bPedCheat2;
 	static bool &bPedCheat3;
 	static CVector2D ms_vec2DFleePosition;
-	static CPedAudioData (&CommentWaitTime)[38];
 
 #ifdef TOGGLEABLE_BETA_FEATURES
 	static bool bPopHeadsOnHeadshot;
diff --git a/src/peds/PedPlacement.cpp b/src/peds/PedPlacement.cpp
index 42cabbc2..b22e1d58 100644
--- a/src/peds/PedPlacement.cpp
+++ b/src/peds/PedPlacement.cpp
@@ -32,7 +32,7 @@ CPedPlacement::FindZCoorForPed(CVector* pos)
 	zForPed = max(foundColZ, foundColZ2);
 
 	if (zForPed > -99.0f)
-		pos->z = 1.04f + zForPed;
+		pos->z = FEET_OFFSET + zForPed;
 }
 
 CEntity*
diff --git a/src/peds/PedPlacement.h b/src/peds/PedPlacement.h
index cbdf8013..b1b5be93 100644
--- a/src/peds/PedPlacement.h
+++ b/src/peds/PedPlacement.h
@@ -1,7 +1,6 @@
 #pragma once
 
-class CVector;
-class CEntity;
+#include "Ped.h"
 
 class CPedPlacement {
 public:
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index 4aeae797..c6580d32 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -735,7 +735,7 @@ CPlayerPed::KeepAreaAroundPlayerClear(void)
 				if (nearPed->m_objective == OBJECTIVE_NONE) {
 					nearPed->SetFindPathAndFlee(this, 5000, true);
 				} else {
-					if (nearPed->m_nPedState == PED_ENTER_CAR || nearPed->m_nPedState == PED_CARJACK)
+					if (nearPed->EnteringCar())
 						nearPed->QuitEnteringCar();
 
 					nearPed->ClearObjective();
@@ -750,7 +750,7 @@ CPlayerPed::KeepAreaAroundPlayerClear(void)
 	CVector pos = GetPosition();
 	int16 lastVehicle;
 	CEntity *vehicles[8];
-	CWorld::FindObjectsInRange(pos, 15.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+	CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
 
 	for (int i = 0; i < lastVehicle; i++) {
 		CVehicle *veh = (CVehicle*)vehicles[i];
@@ -1181,7 +1181,7 @@ CPlayerPed::ProcessControl(void)
 	}
 	if (m_nPedState == PED_DIE) {
 		ClearWeaponTarget();
-		if (CTimer::GetTimeInMilliseconds() > (uint32)m_bloodyFootprintCount + 4000)
+		if (CTimer::GetTimeInMilliseconds() > m_bloodyFootprintCountOrDeathTime + 4000)
 			SetDead();
 		return;
 	}
diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp
index bcbe7794..496ece34 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -18,11 +18,13 @@
 #include "PedPlacement.h"
 #include "DummyObject.h"
 #include "Script.h"
+#include "Shadows.h"
 
-#define CREATION_DIST_MULT_TO_DIST 40.0f
-#define CREATION_RANGE 10.0f // Being added over the CREATION_DIST_MULT_TO_DIST.
-#define OFFSCREEN_CREATION_MULT 0.5f
-// Also there are some hardcoded values in GeneratePedsAtStartOfGame.
+#define MIN_CREATION_DIST		40.0f // not for start of the game (look at the GeneratePedsAtStartOfGame)
+#define CREATION_RANGE			10.0f // added over the MIN_CREATION_DIST.
+#define OFFSCREEN_CREATION_MULT	0.5f
+#define PED_REMOVE_DIST			(MIN_CREATION_DIST + CREATION_RANGE + 1.0f)
+#define PED_REMOVE_DIST_SPECIAL	(MIN_CREATION_DIST + CREATION_RANGE + 15.0f) // for peds with bCullExtraFarAway flag
 
 // TO-DO: These are hard-coded, reverse them.
 // More clearly they're transition areas between zones.
@@ -57,9 +59,6 @@ CVector &CPopulation::RegenerationPoint_a = *(CVector*)0x8E2AA4;
 CVector &CPopulation::RegenerationPoint_b = *(CVector*)0x8E2A98;
 CVector &CPopulation::RegenerationForward = *(CVector*)0x8F1AD4;
 
-WRAPPER void CPopulation::ManagePopulation(void) { EAXJMP(0x4F3B90); }
-WRAPPER bool CPopulation::TestSafeForRealObject(CDummyObject*) { EAXJMP(0x4F4700); }
-
 void
 CPopulation::Initialise()
 {
@@ -416,10 +415,10 @@ CPopulation::Update()
 				+ ms_nTotalGangPeds + ms_nNumCivFemale + ms_nNumCivMale;
 			if (!CCutsceneMgr::IsRunning()) {
 				float pcdm = PedCreationDistMultiplier();
-				AddToPopulation(pcdm * (CREATION_DIST_MULT_TO_DIST * TheCamera.GenerationDistMultiplier),
-					pcdm * ((CREATION_DIST_MULT_TO_DIST + CREATION_RANGE) * TheCamera.GenerationDistMultiplier),
-					pcdm * (CREATION_DIST_MULT_TO_DIST + CREATION_RANGE) * OFFSCREEN_CREATION_MULT - CREATION_RANGE,
-					pcdm * (CREATION_DIST_MULT_TO_DIST + CREATION_RANGE) * OFFSCREEN_CREATION_MULT);
+				AddToPopulation(pcdm * (MIN_CREATION_DIST * TheCamera.GenerationDistMultiplier),
+					pcdm * ((MIN_CREATION_DIST + CREATION_RANGE) * TheCamera.GenerationDistMultiplier),
+					pcdm * (MIN_CREATION_DIST + CREATION_RANGE) * OFFSCREEN_CREATION_MULT - CREATION_RANGE,
+					pcdm * (MIN_CREATION_DIST + CREATION_RANGE) * OFFSCREEN_CREATION_MULT);
 			}
 		}
 	}
@@ -437,8 +436,8 @@ CPopulation::GeneratePedsAtStartOfGame()
 			+ ms_nTotalGangPeds + ms_nNumCivFemale + ms_nNumCivMale;
 
 		// Min dist is 10.0f only for start of the game (naturally)
-		AddToPopulation(10.0f, PedCreationDistMultiplier() * (CREATION_DIST_MULT_TO_DIST + CREATION_RANGE),
-			10.0f, PedCreationDistMultiplier() * (CREATION_DIST_MULT_TO_DIST + CREATION_RANGE));
+		AddToPopulation(10.0f, PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE),
+			10.0f, PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE));
 	}
 }
 
@@ -570,13 +569,13 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
 				|| CCarCtrl::NumFiretrucksOnDuty + CCarCtrl::NumAmbulancesOnDuty + CCarCtrl::NumParkedCars
 				+ CCarCtrl::NumMissionCars + CCarCtrl::NumLawEnforcerCars + CCarCtrl::NumRandomCars >= CCarCtrl::MaxNumberOfCarsInUse)) {
 			addCop = true;
-			minDist = PedCreationDistMultiplier() * CREATION_DIST_MULT_TO_DIST;
-			maxDist = PedCreationDistMultiplier() * (CREATION_DIST_MULT_TO_DIST + CREATION_RANGE);
+			minDist = PedCreationDistMultiplier() * MIN_CREATION_DIST;
+			maxDist = PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE);
 		}
 	}
 	// Yeah, float
-	float maxPossiblePedsForArea = (zoneInfo.pedDensity + zoneInfo.carDensity) * playerInfo->m_fRoadDensity * PedDensityMultiplier * CIniFile::PedNumberMultiplier;
-	maxPossiblePedsForArea = min(maxPossiblePedsForArea, MaxNumberOfPedsInUse);
+	float maxPossiblePedsForArea = 10.0f * (zoneInfo.pedDensity + zoneInfo.carDensity) * playerInfo->m_fRoadDensity * PedDensityMultiplier * CIniFile::PedNumberMultiplier;
+	// maxPossiblePedsForArea = min(maxPossiblePedsForArea, MaxNumberOfPedsInUse);
 
 	if (ms_nTotalPeds < maxPossiblePedsForArea || addCop) {
 		int decisionThreshold = CGeneral::GetRandomNumberInRange(0, 1000);
@@ -689,7 +688,7 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
 			bool farEnoughToAdd = true;
 			CMatrix mat(TheCamera.GetCameraMatrix());
 			if (TheCamera.IsSphereVisible(generatedCoors, 2.0f, &mat)) {
-				if (PedCreationDistMultiplier() * CREATION_DIST_MULT_TO_DIST > (generatedCoors - playerCentreOfWorld).Magnitude2D())
+				if (PedCreationDistMultiplier() * MIN_CREATION_DIST > (generatedCoors - playerCentreOfWorld).Magnitude2D())
 					farEnoughToAdd = false;
 			}
 			if (!farEnoughToAdd)
@@ -927,7 +926,6 @@ CPopulation::ConvertAllObjectsToDummyObjects()
 	for (int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
 
 		CObject *obj = CPools::GetObjectPool()->GetSlot(poolIndex);
-
 		if (obj) {
 			if (obj->CanBeDeleted())
 				ConvertToDummyObject(obj);
@@ -970,8 +968,6 @@ void
 CPopulation::ConvertToDummyObject(CObject *obj)
 {
 	CDummyObject *dummy = new CDummyObject(obj);
-	if (!dummy)
-		return;
 
 	dummy->GetMatrix() = obj->m_objectMatrix;
 	dummy->GetMatrix().UpdateRW();
@@ -1005,6 +1001,163 @@ CPopulation::TestRoomForDummyObject(CObject *obj)
 	return collidingObjs == 0;
 }
 
+bool
+CPopulation::TestSafeForRealObject(CDummyObject *dummy)
+{
+	CPtrNode *ptrNode;
+	CColModel *dummyCol = dummy->GetColModel();
+	float colRadius = dummy->GetBoundRadius();
+	CVector colCentre = dummy->GetBoundCentre();
+
+	int minX = CWorld::GetSectorIndexX(dummy->GetPosition().x - colRadius);
+	if (minX < 0) minX = 0;
+	int minY = CWorld::GetSectorIndexY(dummy->GetPosition().y - colRadius);
+	if (minY < 0) minY = 0;
+	int maxX = CWorld::GetSectorIndexX(dummy->GetPosition().x + colRadius);
+#ifdef FIX_BUGS
+	if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
+#else
+	if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
+#endif
+
+	int maxY = CWorld::GetSectorIndexY(dummy->GetPosition().y + colRadius);
+#ifdef FIX_BUGS
+	if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
+#else
+	if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
+#endif
+
+	static CColPoint aTempColPoints;
+
+	for (int curY = minY; curY <= maxY; curY++) {
+		for (int curX = minX; curX <= maxX; curX++) {
+			CSector *sector = CWorld::GetSector(curX, curY);
+
+			for (ptrNode = sector->m_lists[ENTITYLIST_VEHICLES].first; ptrNode; ptrNode = ptrNode->next) {
+				CVehicle *veh = (CVehicle*)ptrNode->item;
+				if (veh->m_scanCode != CWorld::GetCurrentScanCode()) {
+					if (veh->GetIsTouching(colCentre, colRadius)) {
+						veh->m_scanCode = CWorld::GetCurrentScanCode();
+						if (CCollision::ProcessColModels(dummy->GetMatrix(), *dummyCol, veh->GetMatrix(), *veh->GetColModel(), &aTempColPoints, nil, nil) > 0)
+							return false;
+					}
+				}
+			}
+
+			for (ptrNode = sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP].first; ptrNode; ptrNode = ptrNode->next) {
+				CVehicle *veh = (CVehicle*)ptrNode->item;
+				if (veh->m_scanCode != CWorld::GetCurrentScanCode()) {
+					if (veh->GetIsTouching(colCentre, colRadius)) {
+						veh->m_scanCode = CWorld::GetCurrentScanCode();
+						if (CCollision::ProcessColModels(dummy->GetMatrix(), *dummyCol, veh->GetMatrix(), *veh->GetColModel(), &aTempColPoints, nil, nil) > 0)
+							return false;
+					}
+				}
+			}
+		}
+	}
+	return true;
+}
+
+void
+CPopulation::ManagePopulation(void)
+{
+	int frameMod32 = CTimer::GetFrameCounter() & 31;
+	CVector playerPos = FindPlayerCentreOfWorld(CWorld::PlayerInFocus);
+
+	// Why this code is here?! Delete temporary objects when they got too far, and convert others to "dummy" objects. (like lamp posts)
+	int objectPoolSize = CPools::GetObjectPool()->GetSize();
+	for (int i = objectPoolSize * frameMod32 / 32; i < objectPoolSize * (frameMod32 + 1) / 32; i++) {
+		CObject *obj = CPools::GetObjectPool()->GetSlot(i);
+		if (obj && obj->CanBeDeleted()) {
+			if ((obj->GetPosition() - playerPos).Magnitude() <= 80.0f ||
+				(obj->m_objectMatrix.GetPosition() - playerPos).Magnitude() <= 80.0f) {
+				if (obj->ObjectCreatedBy == TEMP_OBJECT && CTimer::GetTimeInMilliseconds() > obj->m_nEndOfLifeTime) {
+					CWorld::Remove(obj);
+					delete obj;
+				}
+			} else {
+				if (obj->ObjectCreatedBy == TEMP_OBJECT) {
+					CWorld::Remove(obj);
+					delete obj;
+				} else if (obj->ObjectCreatedBy != CUTSCENE_OBJECT && TestRoomForDummyObject(obj)) {
+					ConvertToDummyObject(obj);
+				}
+			}
+		}
+	}
+
+	// Convert them back to real objects. Dummy objects don't have collisions, so they need to be converted.
+	int dummyPoolSize = CPools::GetDummyPool()->GetSize();
+	for (int i = dummyPoolSize * frameMod32 / 32; i < dummyPoolSize * (frameMod32 + 1) / 32; i++) {
+		CDummy *dummy = CPools::GetDummyPool()->GetSlot(i);
+		if (dummy) {
+			if ((dummy->GetPosition() - playerPos).Magnitude() < 80.0f)
+				ConvertToRealObject((CDummyObject*)dummy);
+		}
+	}
+
+	int pedPoolSize = CPools::GetPedPool()->GetSize();
+	for (int poolIndex = pedPoolSize-1; poolIndex >= 0; poolIndex--) {
+		CPed *ped = CPools::GetPedPool()->GetSlot(poolIndex);
+
+		if (ped && !ped->IsPlayer() && ped->CanBeDeleted() && !ped->bInVehicle) {
+			if (ped->m_nPedState == PED_DEAD && CTimer::GetTimeInMilliseconds() - ped->m_bloodyFootprintCountOrDeathTime > 60000)
+				ped->bFadeOut = true;
+
+			if (ped->bFadeOut && CVisibilityPlugins::GetClumpAlpha(ped->GetClump()) == 0) {
+				RemovePed(ped);
+				continue;
+			}
+
+			float dist = (ped->GetPosition() - playerPos).Magnitude2D();
+			bool pedIsFarAway = false;
+			if (PedCreationDistMultiplier() * (PED_REMOVE_DIST_SPECIAL * TheCamera.GenerationDistMultiplier) < dist
+				|| (!ped->bCullExtraFarAway && PedCreationDistMultiplier() * PED_REMOVE_DIST * TheCamera.GenerationDistMultiplier < dist)
+				|| (PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE) * OFFSCREEN_CREATION_MULT < dist
+				&& !ped->GetIsOnScreen()
+				&& TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER
+				&& TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER_RUNABOUT
+				&& !TheCamera.Cams[TheCamera.ActiveCam].LookingLeft
+				&& !TheCamera.Cams[TheCamera.ActiveCam].LookingRight
+				&& !TheCamera.Cams[TheCamera.ActiveCam].LookingBehind))
+				pedIsFarAway = true;
+
+			if (!pedIsFarAway)
+				continue;
+
+			if (ped->m_nPedState == PED_DEAD && !ped->bFadeOut) {
+				CVector pedPos = ped->GetPosition();
+
+				float randAngle = (uint8) CGeneral::GetRandomNumber() * (3.14f / 128.0f); // Not PI, 3.14
+				switch (CGeneral::GetRandomNumber() % 3) {
+					case 0:
+						CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpOutline1Tex, &pedPos,
+							0.9f * Cos(randAngle), 0.9f * Sin(randAngle), 0.9f * Sin(randAngle), -0.9f * Cos(randAngle),
+							255, 255, 255, 255, 4.0f, 40000, 1.0f);
+						break;
+					case 1:
+						CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpOutline2Tex, &pedPos,
+							0.9f * Cos(randAngle), 0.9f * Sin(randAngle), 0.9f * Sin(randAngle), -0.9f * Cos(randAngle),
+							255, 255, 255, 255, 4.0f, 40000, 1.0f);
+						break;
+					case 2:
+						CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpOutline3Tex, &pedPos,
+							0.9f * Cos(randAngle), 0.9f * Sin(randAngle), 0.9f * Sin(randAngle), -0.9f * Cos(randAngle),
+							255, 255, 255, 255, 4.0f, 40000, 1.0f);
+						break;
+					default:
+						break;
+				}
+			}
+			if (ped->GetIsOnScreen())
+				ped->bFadeOut = true;
+			else
+				RemovePed(ped);
+		}
+	}
+}
+
 STARTPATCHES
 	InjectHook(0x4F3770, &CPopulation::Initialise, PATCH_JUMP);
 	InjectHook(0x4F5780, &CPopulation::ChooseGangOccupation, PATCH_JUMP);
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp
index be7329e2..b87f7c71 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -130,12 +130,9 @@ void CHud::Draw()
 			Draw Crosshairs
 		*/
 		if (TheCamera.Cams->Using3rdPersonMouseCam() && (!CPad::GetPad(0)->GetLookBehindForPed() || TheCamera.m_bPlayerIsInGarage) || Mode == CCam::MODE_1STPERSON_RUNABOUT) {
-			if (FindPlayerPed()) {
-				int32 State = FindPlayerPed()->m_nPedState;
-				if (State != PED_ENTER_CAR && State != PED_CARJACK) {
-					if ((WeaponType >= WEAPONTYPE_COLT45 && WeaponType <= WEAPONTYPE_M16) || WeaponType == WEAPONTYPE_FLAMETHROWER)
-						Mode_RunAround = 1;
-				}
+			if (FindPlayerPed() && !FindPlayerPed()->EnteringCar()) {
+				if ((WeaponType >= WEAPONTYPE_COLT45 && WeaponType <= WEAPONTYPE_M16) || WeaponType == WEAPONTYPE_FLAMETHROWER)
+					Mode_RunAround = 1;
 			}
 		}
 
diff --git a/src/render/Shadows.h b/src/render/Shadows.h
index 41404612..66df0273 100644
--- a/src/render/Shadows.h
+++ b/src/render/Shadows.h
@@ -179,3 +179,6 @@ extern RwTexture *&gpBloodPoolTex;
 extern RwTexture *&gpShadowExplosionTex;
 extern RwTexture *&gpShadowHeadLightsTex;
 extern RwTexture *&gpGoalTex;
+extern RwTexture *&gpOutline1Tex;
+extern RwTexture *&gpOutline2Tex;
+extern RwTexture *&gpOutline3Tex;
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 64f756ad..a05a1236 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -3002,9 +3002,9 @@ CAutomobile::RcbanditCheckHitWheels(void)
 	if(xmin < 0) xmin = 0;
 	xmax = CWorld::GetSectorIndexX(GetPosition().x + 2.0f);
 	if(xmax > NUMSECTORS_X-1) xmax = NUMSECTORS_X-1;
-	ymin = CWorld::GetSectorIndexX(GetPosition().y - 2.0f);
+	ymin = CWorld::GetSectorIndexY(GetPosition().y - 2.0f);
 	if(ymin < 0) ymin = 0;
-	ymax = CWorld::GetSectorIndexX(GetPosition().y + 2.0f);
+	ymax = CWorld::GetSectorIndexY(GetPosition().y + 2.0f);
 	if(ymax > NUMSECTORS_Y-1) ymax = NUMSECTORS_X-1;
 
 	CWorld::AdvanceCurrentScanCode();
diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp
index f3a669d6..1c73ed05 100644
--- a/src/vehicles/Train.cpp
+++ b/src/vehicles/Train.cpp
@@ -261,9 +261,9 @@ CTrain::ProcessControl(void)
 		if(xmin < 0) xmin = 0;
 		xmax = CWorld::GetSectorIndexX(front.x + 3.0f);
 		if(xmax > NUMSECTORS_X-1) xmax = NUMSECTORS_X-1;
-		ymin = CWorld::GetSectorIndexX(front.y - 3.0f);
+		ymin = CWorld::GetSectorIndexY(front.y - 3.0f);
 		if(ymin < 0) ymin = 0;
-		ymax = CWorld::GetSectorIndexX(front.y + 3.0f);
+		ymax = CWorld::GetSectorIndexY(front.y + 3.0f);
 		if(ymax > NUMSECTORS_Y-1) ymax = NUMSECTORS_X-1;
 
 		CWorld::AdvanceCurrentScanCode();