From 4703ec5164acd169f4ce315a0f035bc6ab554f0b Mon Sep 17 00:00:00 2001
From: Nikolay Korolev <nickvnuk@gmail.com>
Date: Sun, 17 Jan 2021 16:03:37 +0300
Subject: sync

---
 src/control/Script5.cpp | 590 ++++++++++++++++++++++++++----------------------
 1 file changed, 317 insertions(+), 273 deletions(-)

(limited to 'src/control/Script5.cpp')

diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp
index c0e3ecad..65e85779 100644
--- a/src/control/Script5.cpp
+++ b/src/control/Script5.cpp
@@ -17,32 +17,20 @@
 #include "World.h"
 #include "main.h"
 
-void CRunningScript::UpdateCompareFlag(bool flag)
+// LCS: file done except TODOs
+
+uint32 CRunningScript::CollectLocateParameters(uint32* pIp, bool b3D)
 {
-	if (m_bNotFlag)
-		flag = !flag;
-	if (m_nAndOrState == ANDOR_NONE) {
-		m_bCondResult = flag;
-		return;
-	}
-	if (m_nAndOrState >= ANDS_1 && m_nAndOrState <= ANDS_8) {
-		m_bCondResult &= flag;
-		if (m_nAndOrState == ANDS_1) {
-			m_nAndOrState = ANDOR_NONE;
-			return;
-		}
-	}
-	else if (m_nAndOrState >= ORS_1 && m_nAndOrState <= ORS_8) {
-		m_bCondResult |= flag;
-		if (m_nAndOrState == ORS_1) {
-			m_nAndOrState = ANDOR_NONE;
-			return;
-		}
-	}
-	else {
-		return;
-	}
-	m_nAndOrState--;
+	CollectParameters(pIp, 1);
+	uint32 id = (uintptr)this + (*pIp - 16);
+	uint32 ip = *pIp;
+	uint8 type = CTheScripts::Read1ByteFromScript(&ip);
+	if (type >= ARGUMENT_LOCAL) {
+		ip--;
+		id = (uint32)GetPointerToScriptVariable(&ip, 0);
+	}
+	CollectParameters(pIp, b3D ? 7 : 5, &(ScriptParams[1]));
+	return id;
 }
 
 void CRunningScript::LocatePlayerCommand(int32 command, uint32* pIp)
@@ -62,8 +50,8 @@ void CRunningScript::LocatePlayerCommand(int32 command, uint32* pIp)
 		b3D = false;
 		break;
 	}
-	CollectParameters(pIp, b3D ? 8 : 6);
-	CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+	uint32 id = CollectLocateParameters(pIp, b3D);
+	CPlayerInfo* pPlayerInfo = &CWorld::Players[GET_INTEGER_PARAM(0)];
 	switch (command) {
 	case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_2D:
 	case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D:
@@ -79,37 +67,23 @@ void CRunningScript::LocatePlayerCommand(int32 command, uint32* pIp)
 	default:
 		break;
 	}
-	X = *(float*)&ScriptParams[1];
-	Y = *(float*)&ScriptParams[2];
+	X = GET_FLOAT_PARAM(1);
+	Y = GET_FLOAT_PARAM(2);
 	if (b3D) {
-		Z = *(float*)&ScriptParams[3];
-		dX = *(float*)&ScriptParams[4];
-		dY = *(float*)&ScriptParams[5];
-		dZ = *(float*)&ScriptParams[6];
-		debug = ScriptParams[7];
+		Z = GET_FLOAT_PARAM(3);
+		dX = GET_FLOAT_PARAM(4);
+		dY = GET_FLOAT_PARAM(5);
+		dZ = GET_FLOAT_PARAM(6);
+		debug = GET_INTEGER_PARAM(7);
 	} else {
-		dX = *(float*)&ScriptParams[3];
-		dY = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dX = GET_FLOAT_PARAM(3);
+		dY = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
+	CVector pos = pPlayerInfo->GetPos();
 	if (!decided) {
-		CVector pos = pPlayerInfo->GetPos();
 		result = false;
-		bool in_area;
-		if (b3D) {
-			in_area = X - dX <= pos.x &&
-				X + dX >= pos.x &&
-				Y - dY <= pos.y &&
-				Y + dY >= pos.y &&
-				Z - dZ <= pos.z &&
-				Z + dZ >= pos.z;
-		} else {
-			in_area = X - dX <= pos.x &&
-				X + dX >= pos.x &&
-				Y - dY <= pos.y &&
-				Y + dY >= pos.y;
-		}
-		if (in_area) {
+		if (Abs(pos.x - X) < dX && Abs(pos.y - Y) < dY && (!b3D || Abs(pos.z - Z) < dZ)) {
 			switch (command) {
 			case COMMAND_LOCATE_PLAYER_ANY_MEANS_2D:
 			case COMMAND_LOCATE_PLAYER_ANY_MEANS_3D:
@@ -136,14 +110,16 @@ void CRunningScript::LocatePlayerCommand(int32 command, uint32* pIp)
 		}
 	}
 	UpdateCompareFlag(result);
-	if (debug)
-		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	if (debug && Abs(pos.x - X) < 80.0f && Abs(pos.y - Y) < 80.0f)
+		CTheScripts::HighlightImportantArea(id, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocatePlayerCharCommand(int32 command, uint32* pIp)
@@ -161,8 +137,8 @@ void CRunningScript::LocatePlayerCharCommand(int32 command, uint32* pIp)
 		break;
 	}
 	CollectParameters(pIp, b3D ? 6 : 5);
-	CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
-	CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+	CPlayerInfo* pPlayerInfo = &CWorld::Players[GET_INTEGER_PARAM(0)];
+	CPed* pTarget = CPools::GetPedPool()->GetAt(GET_INTEGER_PARAM(1));
 	script_assert(pTarget);
 	CVector pos = pPlayerInfo->GetPos();
 	if (pTarget->bInVehicle) {
@@ -174,14 +150,14 @@ void CRunningScript::LocatePlayerCharCommand(int32 command, uint32* pIp)
 		Y = pTarget->GetPosition().y;
 		Z = pTarget->GetPosition().z;
 	}
-	dX = *(float*)&ScriptParams[2];
-	dY = *(float*)&ScriptParams[3];
+	dX = GET_FLOAT_PARAM(2);
+	dY = GET_FLOAT_PARAM(3);
 	if (b3D) {
-		dZ = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dZ = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	else {
-		debug = ScriptParams[4];
+		debug = GET_INTEGER_PARAM(4);
 	}
 	result = false;
 	bool in_area;
@@ -225,12 +201,14 @@ void CRunningScript::LocatePlayerCharCommand(int32 command, uint32* pIp)
 #else
 		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : MAP_Z_LOW_LIMIT);
 #endif
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocatePlayerCarCommand(int32 command, uint32* pIp)
@@ -248,21 +226,21 @@ void CRunningScript::LocatePlayerCarCommand(int32 command, uint32* pIp)
 		break;
 	}
 	CollectParameters(pIp, b3D ? 6 : 5);
-	CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
-	CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+	CPlayerInfo* pPlayerInfo = &CWorld::Players[GET_INTEGER_PARAM(0)];
+	CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(GET_INTEGER_PARAM(1));
 	script_assert(pTarget);
 	CVector pos = pPlayerInfo->GetPos();
 	X = pTarget->GetPosition().x;
 	Y = pTarget->GetPosition().y;
 	Z = pTarget->GetPosition().z;
-	dX = *(float*)&ScriptParams[2];
-	dY = *(float*)&ScriptParams[3];
+	dX = GET_FLOAT_PARAM(2);
+	dY = GET_FLOAT_PARAM(3);
 	if (b3D) {
-		dZ = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dZ = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	else {
-		debug = ScriptParams[4];
+		debug = GET_INTEGER_PARAM(4);
 	}
 	result = false;
 	bool in_area;
@@ -302,12 +280,14 @@ void CRunningScript::LocatePlayerCarCommand(int32 command, uint32* pIp)
 	UpdateCompareFlag(result);
 	if (debug)
 		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocateCharCommand(int32 command, uint32* pIp)
@@ -327,8 +307,8 @@ void CRunningScript::LocateCharCommand(int32 command, uint32* pIp)
 		b3D = false;
 		break;
 	}
-	CollectParameters(pIp, b3D ? 8 : 6);
-	CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+	uint32 id = CollectLocateParameters(pIp, b3D);
+	CPed* pPed = CPools::GetPedPool()->GetAt(GET_INTEGER_PARAM(0));
 	script_assert(pPed);
 	CVector pos = pPed->InVehicle() ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
 	switch (command) {
@@ -346,19 +326,19 @@ void CRunningScript::LocateCharCommand(int32 command, uint32* pIp)
 	default:
 		break;
 	}
-	X = *(float*)&ScriptParams[1];
-	Y = *(float*)&ScriptParams[2];
+	X = GET_FLOAT_PARAM(1);
+	Y = GET_FLOAT_PARAM(2);
 	if (b3D) {
-		Z = *(float*)&ScriptParams[3];
-		dX = *(float*)&ScriptParams[4];
-		dY = *(float*)&ScriptParams[5];
-		dZ = *(float*)&ScriptParams[6];
-		debug = ScriptParams[7];
+		Z = GET_FLOAT_PARAM(3);
+		dX = GET_FLOAT_PARAM(4);
+		dY = GET_FLOAT_PARAM(5);
+		dZ = GET_FLOAT_PARAM(6);
+		debug = GET_INTEGER_PARAM(7);
 	}
 	else {
-		dX = *(float*)&ScriptParams[3];
-		dY = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dX = GET_FLOAT_PARAM(3);
+		dY = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	if (!decided) {
 		result = false;
@@ -405,13 +385,15 @@ void CRunningScript::LocateCharCommand(int32 command, uint32* pIp)
 	}
 	UpdateCompareFlag(result);
 	if (debug)
-		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+		CTheScripts::HighlightImportantArea(id, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocateCharCharCommand(int32 command, uint32* pIp)
@@ -429,9 +411,9 @@ void CRunningScript::LocateCharCharCommand(int32 command, uint32* pIp)
 		break;
 	}
 	CollectParameters(pIp, b3D ? 6 : 5);
-	CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+	CPed* pPed = CPools::GetPedPool()->GetAt(GET_INTEGER_PARAM(0));
 	script_assert(pPed);
-	CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+	CPed* pTarget = CPools::GetPedPool()->GetAt(GET_INTEGER_PARAM(1));
 	script_assert(pTarget);
 	CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
 	if (pTarget->bInVehicle) {
@@ -444,14 +426,14 @@ void CRunningScript::LocateCharCharCommand(int32 command, uint32* pIp)
 		Y = pTarget->GetPosition().y;
 		Z = pTarget->GetPosition().z;
 	}
-	dX = *(float*)&ScriptParams[2];
-	dY = *(float*)&ScriptParams[3];
+	dX = GET_FLOAT_PARAM(2);
+	dY = GET_FLOAT_PARAM(3);
 	if (b3D) {
-		dZ = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dZ = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	else {
-		debug = ScriptParams[4];
+		debug = GET_INTEGER_PARAM(4);
 	}
 	result = false;
 	bool in_area;
@@ -495,12 +477,14 @@ void CRunningScript::LocateCharCharCommand(int32 command, uint32* pIp)
 #else
 		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : MAP_Z_LOW_LIMIT);
 #endif
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocateCharCarCommand(int32 command, uint32* pIp)
@@ -518,22 +502,22 @@ void CRunningScript::LocateCharCarCommand(int32 command, uint32* pIp)
 		break;
 	}
 	CollectParameters(pIp, b3D ? 6 : 5);
-	CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+	CPed* pPed = CPools::GetPedPool()->GetAt(GET_INTEGER_PARAM(0));
 	script_assert(pPed);
-	CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+	CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(GET_INTEGER_PARAM(1));
 	script_assert(pTarget);
 	CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
 	X = pTarget->GetPosition().x;
 	Y = pTarget->GetPosition().y;
 	Z = pTarget->GetPosition().z;
-	dX = *(float*)&ScriptParams[2];
-	dY = *(float*)&ScriptParams[3];
+	dX = GET_FLOAT_PARAM(2);
+	dY = GET_FLOAT_PARAM(3);
 	if (b3D) {
-		dZ = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dZ = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	else {
-		debug = ScriptParams[4];
+		debug = GET_INTEGER_PARAM(4);
 	}
 	result = false;
 	bool in_area;
@@ -573,12 +557,14 @@ void CRunningScript::LocateCharCarCommand(int32 command, uint32* pIp)
 	UpdateCompareFlag(result);
 	if (debug)
 		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocateCharObjectCommand(int32 command, uint32* pIp)
@@ -596,22 +582,22 @@ void CRunningScript::LocateCharObjectCommand(int32 command, uint32* pIp)
 		break;
 	}
 	CollectParameters(pIp, b3D ? 6 : 5);
-	CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+	CPed* pPed = CPools::GetPedPool()->GetAt(GET_INTEGER_PARAM(0));
 	script_assert(pPed);
-	CObject* pTarget = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+	CObject* pTarget = CPools::GetObjectPool()->GetAt(GET_INTEGER_PARAM(1));
 	script_assert(pTarget);
 	CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
 	X = pTarget->GetPosition().x;
 	Y = pTarget->GetPosition().y;
 	Z = pTarget->GetPosition().z;
-	dX = *(float*)&ScriptParams[2];
-	dY = *(float*)&ScriptParams[3];
+	dX = GET_FLOAT_PARAM(2);
+	dY = GET_FLOAT_PARAM(3);
 	if (b3D) {
-		dZ = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dZ = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	else {
-		debug = ScriptParams[4];
+		debug = GET_INTEGER_PARAM(4);
 	}
 	result = false;
 	bool in_area;
@@ -651,12 +637,14 @@ void CRunningScript::LocateCharObjectCommand(int32 command, uint32* pIp)
 	UpdateCompareFlag(result);
 	if (debug)
 		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocateCarCommand(int32 command, uint32* pIp)
@@ -672,8 +660,8 @@ void CRunningScript::LocateCarCommand(int32 command, uint32* pIp)
 		b3D = false;
 		break;
 	}
-	CollectParameters(pIp, b3D ? 8 : 6);
-	CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+	uint32 id = CollectLocateParameters(pIp, b3D);
+	CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(GET_INTEGER_PARAM(0));
 	script_assert(pVehicle);
 	CVector pos = pVehicle->GetPosition();
 	switch (command) {
@@ -687,19 +675,19 @@ void CRunningScript::LocateCarCommand(int32 command, uint32* pIp)
 	default:
 		break;
 	}
-	X = *(float*)&ScriptParams[1];
-	Y = *(float*)&ScriptParams[2];
+	X = GET_FLOAT_PARAM(1);
+	Y = GET_FLOAT_PARAM(2);
 	if (b3D) {
-		Z = *(float*)&ScriptParams[3];
-		dX = *(float*)&ScriptParams[4];
-		dY = *(float*)&ScriptParams[5];
-		dZ = *(float*)&ScriptParams[6];
-		debug = ScriptParams[7];
+		Z = GET_FLOAT_PARAM(3);
+		dX = GET_FLOAT_PARAM(4);
+		dY = GET_FLOAT_PARAM(5);
+		dZ = GET_FLOAT_PARAM(6);
+		debug = GET_INTEGER_PARAM(7);
 	}
 	else {
-		dX = *(float*)&ScriptParams[3];
-		dY = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dX = GET_FLOAT_PARAM(3);
+		dY = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	if (!decided) {
 		result = false;
@@ -722,13 +710,15 @@ void CRunningScript::LocateCarCommand(int32 command, uint32* pIp)
 	}
 	UpdateCompareFlag(result);
 	if (debug)
-		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+		CTheScripts::HighlightImportantArea(id, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocateObjectCommand(int32 command, uint32* pIp)
@@ -743,23 +733,23 @@ void CRunningScript::LocateObjectCommand(int32 command, uint32* pIp)
 		b3D = false;
 		break;
 	}
-	CollectParameters(pIp, b3D ? 8 : 6);
-	CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+	uint32 id = CollectLocateParameters(pIp, b3D);
+	CObject* pObject = CPools::GetObjectPool()->GetAt(GET_INTEGER_PARAM(0));
 	script_assert(pObject);
 	CVector pos = pObject->GetPosition();
-	X = *(float*)&ScriptParams[1];
-	Y = *(float*)&ScriptParams[2];
+	X = GET_FLOAT_PARAM(1);
+	Y = GET_FLOAT_PARAM(2);
 	if (b3D) {
-		Z = *(float*)&ScriptParams[3];
-		dX = *(float*)&ScriptParams[4];
-		dY = *(float*)&ScriptParams[5];
-		dZ = *(float*)&ScriptParams[6];
-		debug = ScriptParams[7];
+		Z = GET_FLOAT_PARAM(3);
+		dX = GET_FLOAT_PARAM(4);
+		dY = GET_FLOAT_PARAM(5);
+		dZ = GET_FLOAT_PARAM(6);
+		debug = GET_INTEGER_PARAM(7);
 	}
 	else {
-		dX = *(float*)&ScriptParams[3];
-		dY = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dX = GET_FLOAT_PARAM(3);
+		dY = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	result = false;
 	bool in_area;
@@ -780,13 +770,15 @@ void CRunningScript::LocateObjectCommand(int32 command, uint32* pIp)
 	result = in_area;
 	UpdateCompareFlag(result);
 	if (debug)
-		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+		CTheScripts::HighlightImportantArea(id, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocateSniperBulletCommand(int32 command, uint32* pIp)
@@ -802,30 +794,32 @@ void CRunningScript::LocateSniperBulletCommand(int32 command, uint32* pIp)
 		break;
 	}
 	CollectParameters(pIp, b3D ? 7 : 5);
-	X = *(float*)&ScriptParams[0];
-	Y = *(float*)&ScriptParams[1];
+	X = GET_FLOAT_PARAM(0);
+	Y = GET_FLOAT_PARAM(1);
 	if (b3D) {
-		Z = *(float*)&ScriptParams[2];
-		dX = *(float*)&ScriptParams[3];
-		dY = *(float*)&ScriptParams[4];
-		dZ = *(float*)&ScriptParams[5];
-		debug = ScriptParams[6];
+		Z = GET_FLOAT_PARAM(2);
+		dX = GET_FLOAT_PARAM(3);
+		dY = GET_FLOAT_PARAM(4);
+		dZ = GET_FLOAT_PARAM(5);
+		debug = GET_INTEGER_PARAM(6);
 	}
 	else {
-		dX = *(float*)&ScriptParams[2];
-		dY = *(float*)&ScriptParams[3];
-		debug = ScriptParams[4];
+		dX = GET_FLOAT_PARAM(2);
+		dY = GET_FLOAT_PARAM(3);
+		debug = GET_INTEGER_PARAM(4);
 	}
 	result = CBulletInfo::TestForSniperBullet(X - dX, X + dX, Y - dY, Y + dY, b3D ? Z - dZ : -1000.0f, b3D ? Z + dZ : 1000.0f);
 	UpdateCompareFlag(result);
 	if (debug)
 		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::PlayerInAreaCheckCommand(int32 command, uint32* pIp)
@@ -845,8 +839,8 @@ void CRunningScript::PlayerInAreaCheckCommand(int32 command, uint32* pIp)
 		b3D = false;
 		break;
 	}
-	CollectParameters(pIp, b3D ? 8 : 6);
-	CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+	uint32 id = CollectLocateParameters(pIp, b3D);
+	CPlayerInfo* pPlayerInfo = &CWorld::Players[GET_INTEGER_PARAM(0)];
 	switch (command) {
 	case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
 	case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
@@ -862,23 +856,23 @@ void CRunningScript::PlayerInAreaCheckCommand(int32 command, uint32* pIp)
 	default:
 		break;
 	}
-	infX = *(float*)&ScriptParams[1];
-	infY = *(float*)&ScriptParams[2];
+	infX = GET_FLOAT_PARAM(1);
+	infY = GET_FLOAT_PARAM(2);
 	if (b3D) {
-		infZ = *(float*)&ScriptParams[3];
-		supX = *(float*)&ScriptParams[4];
-		supY = *(float*)&ScriptParams[5];
-		supZ = *(float*)&ScriptParams[6];
+		infZ = GET_FLOAT_PARAM(3);
+		supX = GET_FLOAT_PARAM(4);
+		supY = GET_FLOAT_PARAM(5);
+		supZ = GET_FLOAT_PARAM(6);
 		if (infZ > supZ) {
-			infZ = *(float*)&ScriptParams[6];
-			supZ = *(float*)&ScriptParams[3];
+			infZ = GET_FLOAT_PARAM(6);
+			supZ = GET_FLOAT_PARAM(3);
 		}
-		debug = ScriptParams[7];
+		debug = GET_INTEGER_PARAM(7);
 	}
 	else {
-		supX = *(float*)&ScriptParams[3];
-		supY = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		supX = GET_FLOAT_PARAM(3);
+		supY = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	if (infX > supX) {
 		float tmp = infX;
@@ -937,12 +931,14 @@ void CRunningScript::PlayerInAreaCheckCommand(int32 command, uint32* pIp)
 	UpdateCompareFlag(result);
 	if (debug)
 		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
 		else
 			CTheScripts::DrawDebugSquare(infX, infY, supX, supY);
 	}
+	*/
 }
 
 void CRunningScript::PlayerInAngledAreaCheckCommand(int32 command, uint32* pIp)
@@ -963,7 +959,7 @@ void CRunningScript::PlayerInAngledAreaCheckCommand(int32 command, uint32* pIp)
 		break;
 	}
 	CollectParameters(pIp, b3D ? 9 : 7);
-	CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+	CPlayerInfo* pPlayerInfo = &CWorld::Players[GET_INTEGER_PARAM(0)];
 	switch (command) {
 	case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
 	case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
@@ -979,25 +975,25 @@ void CRunningScript::PlayerInAngledAreaCheckCommand(int32 command, uint32* pIp)
 	default:
 		break;
 	}
-	infX = *(float*)&ScriptParams[1];
-	infY = *(float*)&ScriptParams[2];
+	infX = GET_FLOAT_PARAM(1);
+	infY = GET_FLOAT_PARAM(2);
 	if (b3D) {
-		infZ = *(float*)&ScriptParams[3];
-		supX = *(float*)&ScriptParams[4];
-		supY = *(float*)&ScriptParams[5];
-		supZ = *(float*)&ScriptParams[6];
+		infZ = GET_FLOAT_PARAM(3);
+		supX = GET_FLOAT_PARAM(4);
+		supY = GET_FLOAT_PARAM(5);
+		supZ = GET_FLOAT_PARAM(6);
 		if (infZ > supZ) {
-			infZ = *(float*)&ScriptParams[6];
-			supZ = *(float*)&ScriptParams[3];
+			infZ = GET_FLOAT_PARAM(6);
+			supZ = GET_FLOAT_PARAM(3);
 		}
-		side2length = *(float*)&ScriptParams[7];
-		debug = ScriptParams[8];
+		side2length = GET_FLOAT_PARAM(7);
+		debug = GET_INTEGER_PARAM(8);
 	}
 	else {
-		supX = *(float*)&ScriptParams[3];
-		supY = *(float*)&ScriptParams[4];
-		side2length = *(float*)&ScriptParams[5];
-		debug = ScriptParams[6];
+		supX = GET_FLOAT_PARAM(3);
+		supY = GET_FLOAT_PARAM(4);
+		side2length = GET_FLOAT_PARAM(5);
+		debug = GET_INTEGER_PARAM(6);
 	}
 	float initAngle = CGeneral::GetRadianAngleBetweenPoints(infX, infY, supX, supY) + HALFPI;
 	while (initAngle < 0.0f)
@@ -1060,6 +1056,7 @@ void CRunningScript::PlayerInAngledAreaCheckCommand(int32 command, uint32* pIp)
 	if (debug)
 		CTheScripts::HighlightImportantAngledArea((uintptr)this + m_nIp, infX, infY, supX, supY,
 			rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugAngledCube(infX, infY, infZ, supX, supY, supZ,
@@ -1068,6 +1065,7 @@ void CRunningScript::PlayerInAngledAreaCheckCommand(int32 command, uint32* pIp)
 			CTheScripts::DrawDebugAngledSquare(infX, infY, supX, supY,
 				rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY);
 	}
+	*/
 }
 
 void CRunningScript::CharInAreaCheckCommand(int32 command, uint32* pIp)
@@ -1087,8 +1085,8 @@ void CRunningScript::CharInAreaCheckCommand(int32 command, uint32* pIp)
 		b3D = false;
 		break;
 	}
-	CollectParameters(pIp, b3D ? 8 : 6);
-	CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+	uint32 id = CollectLocateParameters(pIp, b3D);
+	CPed* pPed = CPools::GetPedPool()->GetAt(GET_INTEGER_PARAM(0));
 	script_assert(pPed);
 	CVector pos = pPed->InVehicle() ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
 	switch (command) {
@@ -1106,23 +1104,23 @@ void CRunningScript::CharInAreaCheckCommand(int32 command, uint32* pIp)
 	default:
 		break;
 	}
-	infX = *(float*)&ScriptParams[1];
-	infY = *(float*)&ScriptParams[2];
+	infX = GET_FLOAT_PARAM(1);
+	infY = GET_FLOAT_PARAM(2);
 	if (b3D) {
-		infZ = *(float*)&ScriptParams[3];
-		supX = *(float*)&ScriptParams[4];
-		supY = *(float*)&ScriptParams[5];
-		supZ = *(float*)&ScriptParams[6];
+		infZ = GET_FLOAT_PARAM(3);
+		supX = GET_FLOAT_PARAM(4);
+		supY = GET_FLOAT_PARAM(5);
+		supZ = GET_FLOAT_PARAM(6);
 		if (infZ > supZ) {
-			infZ = *(float*)&ScriptParams[6];
-			supZ = *(float*)&ScriptParams[3];
+			infZ = GET_FLOAT_PARAM(6);
+			supZ = GET_FLOAT_PARAM(3);
 		}
-		debug = ScriptParams[7];
+		debug = GET_INTEGER_PARAM(7);
 	}
 	else {
-		supX = *(float*)&ScriptParams[3];
-		supY = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		supX = GET_FLOAT_PARAM(3);
+		supY = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	if (infX > supX) {
 		float tmp = infX;
@@ -1179,13 +1177,15 @@ void CRunningScript::CharInAreaCheckCommand(int32 command, uint32* pIp)
 	}
 	UpdateCompareFlag(result);
 	if (debug)
-		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
+		CTheScripts::HighlightImportantArea(id, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
 		else
 			CTheScripts::DrawDebugSquare(infX, infY, supX, supY);
 	}
+	*/
 }
 
 void CRunningScript::CarInAreaCheckCommand(int32 command, uint32* pIp)
@@ -1201,8 +1201,8 @@ void CRunningScript::CarInAreaCheckCommand(int32 command, uint32* pIp)
 		b3D = false;
 		break;
 	}
-	CollectParameters(pIp, b3D ? 8 : 6);
-	CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+	uint32 id = CollectLocateParameters(pIp, b3D);
+	CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(GET_INTEGER_PARAM(0));
 	script_assert(pVehicle);
 	CVector pos = pVehicle->GetPosition();
 	switch (command) {
@@ -1216,23 +1216,23 @@ void CRunningScript::CarInAreaCheckCommand(int32 command, uint32* pIp)
 	default:
 		break;
 	}
-	infX = *(float*)&ScriptParams[1];
-	infY = *(float*)&ScriptParams[2];
+	infX = GET_FLOAT_PARAM(1);
+	infY = GET_FLOAT_PARAM(2);
 	if (b3D) {
-		infZ = *(float*)&ScriptParams[3];
-		supX = *(float*)&ScriptParams[4];
-		supY = *(float*)&ScriptParams[5];
-		supZ = *(float*)&ScriptParams[6];
+		infZ = GET_FLOAT_PARAM(3);
+		supX = GET_FLOAT_PARAM(4);
+		supY = GET_FLOAT_PARAM(5);
+		supZ = GET_FLOAT_PARAM(6);
 		if (infZ > supZ) {
-			infZ = *(float*)&ScriptParams[6];
-			supZ = *(float*)&ScriptParams[3];
+			infZ = GET_FLOAT_PARAM(6);
+			supZ = GET_FLOAT_PARAM(3);
 		}
-		debug = ScriptParams[7];
+		debug = GET_INTEGER_PARAM(7);
 	}
 	else {
-		supX = *(float*)&ScriptParams[3];
-		supY = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		supX = GET_FLOAT_PARAM(3);
+		supY = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	if (infX > supX) {
 		float tmp = infX;
@@ -1277,13 +1277,15 @@ void CRunningScript::CarInAreaCheckCommand(int32 command, uint32* pIp)
 	}
 	UpdateCompareFlag(result);
 	if (debug)
-		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
+		CTheScripts::HighlightImportantArea(id, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
 		else
 			CTheScripts::DrawDebugSquare(infX, infY, supX, supY);
 	}
+	*/
 }
 
 void CRunningScript::ObjectInAreaCheckCommand(int32 command, uint32* pIp)
@@ -1298,27 +1300,27 @@ void CRunningScript::ObjectInAreaCheckCommand(int32 command, uint32* pIp)
 		b3D = false;
 		break;
 	}
-	CollectParameters(pIp, b3D ? 8 : 6);
-	CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+	uint32 id = CollectLocateParameters(pIp, b3D);
+	CObject* pObject = CPools::GetObjectPool()->GetAt(GET_INTEGER_PARAM(0));
 	script_assert(pObject);
 	CVector pos = pObject->GetPosition();
-	infX = *(float*)&ScriptParams[1];
-	infY = *(float*)&ScriptParams[2];
+	infX = GET_FLOAT_PARAM(1);
+	infY = GET_FLOAT_PARAM(2);
 	if (b3D) {
-		infZ = *(float*)&ScriptParams[3];
-		supX = *(float*)&ScriptParams[4];
-		supY = *(float*)&ScriptParams[5];
-		supZ = *(float*)&ScriptParams[6];
+		infZ = GET_FLOAT_PARAM(3);
+		supX = GET_FLOAT_PARAM(4);
+		supY = GET_FLOAT_PARAM(5);
+		supZ = GET_FLOAT_PARAM(6);
 		if (infZ > supZ) {
-			infZ = *(float*)&ScriptParams[6];
-			supZ = *(float*)&ScriptParams[3];
+			infZ = GET_FLOAT_PARAM(6);
+			supZ = GET_FLOAT_PARAM(3);
 		}
-		debug = ScriptParams[7];
+		debug = GET_INTEGER_PARAM(7);
 	}
 	else {
-		supX = *(float*)&ScriptParams[3];
-		supY = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		supX = GET_FLOAT_PARAM(3);
+		supY = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	if (infX > supX) {
 		float tmp = infX;
@@ -1359,13 +1361,15 @@ void CRunningScript::ObjectInAreaCheckCommand(int32 command, uint32* pIp)
 	}
 	UpdateCompareFlag(result);
 	if (debug)
-		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
+		CTheScripts::HighlightImportantArea(id, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
 		else
 			CTheScripts::DrawDebugSquare(infX, infY, supX, supY);
 	}
+	*/
 }
 
 void CRunningScript::DoDeatharrestCheck()
@@ -1386,7 +1390,8 @@ void CRunningScript::DoDeatharrestCheck()
 	script_assert(m_nStackPointer > 0);
 	while (m_nStackPointer > 1)
 		--m_nStackPointer;
-	m_nIp = m_anStack[--m_nStackPointer];
+	ReturnFromGosubOrFunction();
+	m_nLocalsPointer = 0;
 	CMessages::ClearSmallMessagesOnly();
 	*(int32*)&CTheScripts::ScriptSpace[CTheScripts::OnAMissionFlag] = 0;
 	m_bDeatharrestExecuted = true;
@@ -1440,24 +1445,24 @@ void CRunningScript::LocateCollectiveCommand(int32 command, uint32* pIp)
 		b3D = true;
 		break;
 	}
-	CollectParameters(pIp, b3D ? 8 : 6);
-	X = *(float*)&ScriptParams[1];
-	Y = *(float*)&ScriptParams[2];
+	uint32 id = CollectLocateParameters(pIp, b3D);
+	X = GET_FLOAT_PARAM(1);
+	Y = GET_FLOAT_PARAM(2);
 	if (b3D) {
-		Z = *(float*)&ScriptParams[3];
-		dX = *(float*)&ScriptParams[4];
-		dY = *(float*)&ScriptParams[5];
-		dZ = *(float*)&ScriptParams[6];
-		debug = ScriptParams[7];
+		Z = GET_FLOAT_PARAM(3);
+		dX = GET_FLOAT_PARAM(4);
+		dY = GET_FLOAT_PARAM(5);
+		dZ = GET_FLOAT_PARAM(6);
+		debug = GET_INTEGER_PARAM(7);
 	}
 	else {
-		dX = *(float*)&ScriptParams[3];
-		dY = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dX = GET_FLOAT_PARAM(3);
+		dY = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	result = true;
 	for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) {
-		if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex)
+		if (GET_INTEGER_PARAM(0) != CTheScripts::CollectiveArray[i].colIndex)
 			continue;
 		CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
 		if (!pPed) {
@@ -1518,13 +1523,15 @@ void CRunningScript::LocateCollectiveCommand(int32 command, uint32* pIp)
 	}
 	UpdateCompareFlag(result);
 	if (debug)
-		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+		CTheScripts::HighlightImportantArea(id, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocateCollectiveCharCommand(int32 command, uint32* pIp)
@@ -1542,7 +1549,7 @@ void CRunningScript::LocateCollectiveCharCommand(int32 command, uint32* pIp)
 		break;
 	}
 	CollectParameters(pIp, b3D ? 6 : 5);
-	CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+	CPed* pTarget = CPools::GetPedPool()->GetAt(GET_INTEGER_PARAM(1));
 	script_assert(pTarget);
 	if (pTarget->bInVehicle) {
 		X = pTarget->m_pMyVehicle->GetPosition().x;
@@ -1554,18 +1561,18 @@ void CRunningScript::LocateCollectiveCharCommand(int32 command, uint32* pIp)
 		Y = pTarget->GetPosition().y;
 		Z = pTarget->GetPosition().z;
 	}
-	dX = *(float*)&ScriptParams[2];
-	dY = *(float*)&ScriptParams[3];
+	dX = GET_FLOAT_PARAM(2);
+	dY = GET_FLOAT_PARAM(3);
 	if (b3D) {
-		dZ = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dZ = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	else {
-		debug = ScriptParams[4];
+		debug = GET_INTEGER_PARAM(4);
 	}
 	result = true;
 	for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) {
-		if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex)
+		if (GET_INTEGER_PARAM(0) != CTheScripts::CollectiveArray[i].colIndex)
 			continue;
 		CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
 		if (!pPed) {
@@ -1610,12 +1617,14 @@ void CRunningScript::LocateCollectiveCharCommand(int32 command, uint32* pIp)
 	UpdateCompareFlag(result);
 	if (debug)
 		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocateCollectiveCarCommand(int32 command, uint32* pIp)
@@ -1633,23 +1642,23 @@ void CRunningScript::LocateCollectiveCarCommand(int32 command, uint32* pIp)
 		break;
 	}
 	CollectParameters(pIp, b3D ? 6 : 5);
-	CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+	CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(GET_INTEGER_PARAM(1));
 	script_assert(pTarget);
 	X = pTarget->GetPosition().x;
 	Y = pTarget->GetPosition().y;
 	Z = pTarget->GetPosition().z;
-	dX = *(float*)&ScriptParams[2];
-	dY = *(float*)&ScriptParams[3];
+	dX = GET_FLOAT_PARAM(2);
+	dY = GET_FLOAT_PARAM(3);
 	if (b3D) {
-		dZ = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dZ = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	else {
-		debug = ScriptParams[4];
+		debug = GET_INTEGER_PARAM(4);
 	}
 	result = true;
 	for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) {
-		if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex)
+		if (GET_INTEGER_PARAM(0) != CTheScripts::CollectiveArray[i].colIndex)
 			continue;
 		CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
 		if (!pPed) {
@@ -1694,12 +1703,14 @@ void CRunningScript::LocateCollectiveCarCommand(int32 command, uint32* pIp)
 	UpdateCompareFlag(result);
 	if (debug)
 		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::LocateCollectivePlayerCommand(int32 command, uint32* pIp)
@@ -1717,22 +1728,22 @@ void CRunningScript::LocateCollectivePlayerCommand(int32 command, uint32* pIp)
 		break;
 	}
 	CollectParameters(pIp, b3D ? 6 : 5);
-	CVector pos = CWorld::Players[ScriptParams[1]].GetPos();
+	CVector pos = CWorld::Players[GET_INTEGER_PARAM(1)].GetPos();
 	X = pos.x;
 	Y = pos.y;
 	Z = pos.z;
-	dX = *(float*)&ScriptParams[2];
-	dY = *(float*)&ScriptParams[3];
+	dX = GET_FLOAT_PARAM(2);
+	dY = GET_FLOAT_PARAM(3);
 	if (b3D) {
-		dZ = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		dZ = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	else {
-		debug = ScriptParams[4];
+		debug = GET_INTEGER_PARAM(4);
 	}
 	result = true;
 	for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) {
-		if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex)
+		if (GET_INTEGER_PARAM(0) != CTheScripts::CollectiveArray[i].colIndex)
 			continue;
 		CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
 		if (!pPed) {
@@ -1777,12 +1788,14 @@ void CRunningScript::LocateCollectivePlayerCommand(int32 command, uint32* pIp)
 	UpdateCompareFlag(result);
 	if (debug)
 		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
 		else
 			CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
 	}
+	*/
 }
 
 void CRunningScript::CollectiveInAreaCheckCommand(int32 command, uint32* pIp)
@@ -1803,23 +1816,23 @@ void CRunningScript::CollectiveInAreaCheckCommand(int32 command, uint32* pIp)
 		break;
 	}
 	CollectParameters(pIp, b3D ? 8 : 6);
-	infX = *(float*)&ScriptParams[1];
-	infY = *(float*)&ScriptParams[2];
+	infX = GET_FLOAT_PARAM(1);
+	infY = GET_FLOAT_PARAM(2);
 	if (b3D) {
-		infZ = *(float*)&ScriptParams[3];
-		supX = *(float*)&ScriptParams[4];
-		supY = *(float*)&ScriptParams[5];
-		supZ = *(float*)&ScriptParams[6];
+		infZ = GET_FLOAT_PARAM(3);
+		supX = GET_FLOAT_PARAM(4);
+		supY = GET_FLOAT_PARAM(5);
+		supZ = GET_FLOAT_PARAM(6);
 		if (infZ > supZ) {
-			infZ = *(float*)&ScriptParams[6];
-			supZ = *(float*)&ScriptParams[3];
+			infZ = GET_FLOAT_PARAM(6);
+			supZ = GET_FLOAT_PARAM(3);
 		}
-		debug = ScriptParams[7];
+		debug = GET_INTEGER_PARAM(7);
 	}
 	else {
-		supX = *(float*)&ScriptParams[3];
-		supY = *(float*)&ScriptParams[4];
-		debug = ScriptParams[5];
+		supX = GET_FLOAT_PARAM(3);
+		supY = GET_FLOAT_PARAM(4);
+		debug = GET_INTEGER_PARAM(5);
 	}
 	if (infX > supX) {
 		float tmp = infX;
@@ -1833,7 +1846,7 @@ void CRunningScript::CollectiveInAreaCheckCommand(int32 command, uint32* pIp)
 	}
 	result = true;
 	for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) {
-		if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex)
+		if (GET_INTEGER_PARAM(0) != CTheScripts::CollectiveArray[i].colIndex)
 			continue;
 		CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
 		if (!pPed) {
@@ -1895,12 +1908,14 @@ void CRunningScript::CollectiveInAreaCheckCommand(int32 command, uint32* pIp)
 	UpdateCompareFlag(result);
 	if (debug)
 		CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
+	/*
 	if (CTheScripts::DbgFlag) {
 		if (b3D)
 			CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
 		else
 			CTheScripts::DrawDebugSquare(infX, infY, supX, supY);
 	}
+	*/
 }
 #endif
 
@@ -1987,8 +2002,9 @@ void CTheScripts::PrintListSizes()
 	debug("active: %d, idle: %d", active, idle);
 }
 
-uint32 DbgLineColour = 0x0000FFFF; // r = 0, g = 0, b = 255, a = 255
+//uint32 DbgLineColour = 0x0000FFFF; // r = 0, g = 0, b = 255, a = 255
 
+/*
 void CTheScripts::DrawDebugSquare(float infX, float infY, float supX, float supY)
 {
 	CColPoint tmpCP;
@@ -2095,6 +2111,7 @@ void CTheScripts::RenderTheScriptDebugLines()
 	NumScriptDebugLines = 0;
 	RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)0);
 }
+*/
 
 #define SCRIPT_DATA_SIZE sizeof(CTheScripts::OnAMissionFlag) +\
 	4 * sizeof(uint32) * MAX_NUM_BUILDING_SWAPS + 2 * sizeof(uint32) * MAX_NUM_INVISIBILITY_SETTINGS + 5 * sizeof(uint32)
@@ -2118,6 +2135,9 @@ INITSAVEBUF
 	WriteSaveBuf(buf, script_data_size);
 	WriteSaveBuf(buf, OnAMissionFlag);
 	WriteSaveBuf(buf, LastMissionPassedTime);
+	for (uint32 i = 0; i < MAX_NUM_COLLECTIVES; i++)
+		WriteSaveBuf(buf, CollectiveArray[i]);
+	WriteSaveBuf(buf, NextFreeCollectiveIndex);
 	for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) {
 		CBuilding* pBuilding = BuildingSwapArray[i].m_pBuilding;
 		uint32 type, handle;
@@ -2179,14 +2199,26 @@ INITSAVEBUF
 VALIDATESAVEBUF(*size)
 }
 
-void CTheScripts::LoadAllScripts(uint8* buf, uint32 size)
+// TODO: I don't really understand how script loading works, so I leave it the VC way for now.
+bool CTheScripts::LoadAllScripts(uint8* buf, uint32 size)
 {
-	Init();
+	Init(); // TODO: in LCS CTheScripts::Init call GenericLoad, which then calls LoadAllScripts
 INITSAVEBUF
 	CheckSaveHeader(buf, 'S', 'C', 'R', '\0', size - SAVE_HEADER_SIZE);
 	uint32 varSpace = ReadSaveBuf<uint32>(buf);
-	for (uint32 i = 0; i < varSpace; i++)
-		ScriptSpace[i] = ReadSaveBuf<uint8>(buf);
+	if (*(int32*)&ScriptSpace[0] != *(int32*)&buf[0] || *(int32*)&ScriptSpace[4] != *(int32*)&buf[4]) {
+		printf("\n===================================================\nSave Game Mismatch!!!\n");
+		return false;
+	}
+	for (uint32 i = 0; i < varSpace; i++) { // this is not exactly what function does
+		if (i < 8)
+			ScriptSpace[i] = ReadSaveBuf<uint8>(buf);
+		else if (GetSaveVarIndex(i / 4 * 4) != -1)
+			ScriptSpace[i] = ReadSaveBuf<uint8>(buf);
+		else
+			ReadSaveBuf<uint8>(buf);
+	}
+	// everything else is... gone? TODO
 	script_assert(ReadSaveBuf<uint32>(buf) == SCRIPT_DATA_SIZE);
 	OnAMissionFlag = ReadSaveBuf<uint32>(buf);
 	LastMissionPassedTime = ReadSaveBuf<uint32>(buf);
@@ -2246,6 +2278,7 @@ INITSAVEBUF
 	uint32 runningScripts = ReadSaveBuf<uint32>(buf);
 	for (uint32 i = 0; i < runningScripts; i++)
 		StartNewScript(0)->Load(buf);
+	return true;
 VALIDATESAVEBUF(size)
 }
 
@@ -2255,6 +2288,7 @@ void CRunningScript::Save(uint8*& buf)
 {
 #ifdef COMPATIBLE_SAVES
 	SkipSaveBuf(buf, 8);
+	WriteSaveBuf<int32>(buf, m_nId);
 	for (int i = 0; i < 8; i++)
 		WriteSaveBuf<char>(buf, m_abScriptName[i]);
 	WriteSaveBuf<uint32>(buf, m_nIp);
@@ -2266,10 +2300,11 @@ void CRunningScript::Save(uint8*& buf)
 	WriteSaveBuf<uint16>(buf, m_nStackPointer);
 	SkipSaveBuf(buf, 2);
 #ifdef CHECK_STRUCT_SIZES
-	static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
+	static_assert(NUM_LOCAL_VARS + 8 + NUM_TIMERS == 106, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 106");
 #endif
-	for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
+	for (int i = 0; i < NUM_LOCAL_VARS + 8 + NUM_TIMERS; i++)
 		WriteSaveBuf<int32>(buf, m_anLocalVariables[i]);
+	WriteSaveBuf<int32>(buf, m_nLocalsPointer);
 	WriteSaveBuf<bool>(buf, m_bIsActive);
 	WriteSaveBuf<bool>(buf, m_bCondResult);
 	WriteSaveBuf<bool>(buf, m_bIsMissionScript);
@@ -2290,6 +2325,7 @@ void CRunningScript::Load(uint8*& buf)
 {
 #ifdef COMPATIBLE_SAVES
 	SkipSaveBuf(buf, 8);
+	m_nId = ReadSaveBuf<int32>(buf);
 	for (int i = 0; i < 8; i++)
 		m_abScriptName[i] = ReadSaveBuf<char>(buf);
 	m_nIp = ReadSaveBuf<uint32>(buf);
@@ -2301,10 +2337,11 @@ void CRunningScript::Load(uint8*& buf)
 	m_nStackPointer = ReadSaveBuf<uint16>(buf);
 	SkipSaveBuf(buf, 2);
 #ifdef CHECK_STRUCT_SIZES
-	static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
+	static_assert(NUM_LOCAL_VARS + 8 + NUM_TIMERS == 106, "Compatibility loss: NUM_LOCAL_VARS + 8 + NUM_TIMERS != 106");
 #endif
-	for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
+	for (int i = 0; i < NUM_LOCAL_VARS + 8 + NUM_TIMERS; i++)
 		m_anLocalVariables[i] = ReadSaveBuf<int32>(buf);
+	m_nLocalsPointer = ReadSaveBuf<int32>(buf);
 	m_bIsActive = ReadSaveBuf<bool>(buf);
 	m_bCondResult = ReadSaveBuf<bool>(buf);
 	m_bIsMissionScript = ReadSaveBuf<bool>(buf);
@@ -2683,8 +2720,14 @@ void CTheScripts::CleanUpThisPed(CPed* pPed)
 		}
 		else {
 			if (pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR) {
-				pPed->SetObjective(OBJECTIVE_LEAVE_CAR, pPed->m_pMyVehicle);
-				pPed->bWanderPathAfterExitingCar = true;
+				if ((pPed->m_fHealth < 1.0f && !pPed->IsPedHeadAbovePos(-0.3f)) || pPed->bBodyPartJustCameOff) {
+					pPed->SetObjective(OBJECTIVE_LEAVE_CAR_AND_DIE, pPed->m_pMyVehicle);
+					pPed->bWanderPathAfterExitingCar = false;
+				}
+				else {
+					pPed->SetObjective(OBJECTIVE_LEAVE_CAR, pPed->m_pMyVehicle);
+					pPed->bWanderPathAfterExitingCar = true;
+				}
 			}
 		}
 	}
@@ -2697,6 +2740,7 @@ void CTheScripts::CleanUpThisPed(CPed* pPed)
 		flees = true;
 	}
 	pPed->ClearObjective();
+	pPed->SetWaitState(WAITSTATE_FALSE, nil); // third parameter is 0 TODO?
 	pPed->bRespondsToThreats = true;
 	pPed->bScriptObjectiveCompleted = false;
 	pPed->bKindaStayInSamePlace = false;
@@ -2741,7 +2785,7 @@ void CTheScripts::ReadObjectNamesFromScript()
 	int32 varSpace = GetSizeOfVariableSpace();
 	uint32 ip = varSpace + 8;
 	NumSaveVars = Read4BytesFromScript(&ip);
-	SavedVarIndices = (short*)&ScriptParams[ip];
+	SavedVarIndices = (short*)&ScriptSpace[ip];
 	ip += 2 * NumSaveVars;
 	NumberOfUsedObjects = Read2BytesFromScript(&ip);
 	ip += 2;
-- 
cgit v1.2.3