From aa5266b1b3b8a13057760f08ac9a86accca7c21f Mon Sep 17 00:00:00 2001
From: Nikolay Korolev <nickvnuk@gmail.com>
Date: Sun, 23 Feb 2020 02:29:38 +0300
Subject: [PATCH 1/8] some cosmetic stuff

---
 src/control/Script.cpp | 333 ++++++++++++++++++++++++++---------------
 src/control/Script.h   |  29 +++-
 2 files changed, 244 insertions(+), 118 deletions(-)

diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index f6db26ec..2bded19e 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -75,10 +75,10 @@
 #define SPHERE_MARKER_PULSE_FRACTION 0.1f
 
 #ifdef USE_PRECISE_MEASUREMENT_CONVERTION
-#define METERS_IN_FEET 0.3048f
+#define METERS_IN_FOOT 0.3048f
 #define FEET_IN_METER 3.28084f
 #else
-#define METERS_IN_FEET 0.3f
+#define METERS_IN_FOOT 0.3f
 #define FEET_IN_METER 3.33f
 #endif
 
@@ -510,27 +510,6 @@ int open_script()
 }
 #endif
 
-void CTextLine::Reset()
-{
-	m_fScaleX = 0.48f;
-	m_fScaleY = 1.12f;
-	m_sColor = CRGBA(225, 225, 225, 255);
-	m_bJustify = false;
-	m_bRightJustify = false;
-	m_bCentered = false;
-	m_bBackground = false;
-	m_bBackgroundOnly = false;
-	m_fWrapX = 182.0f; /* TODO: scaling as bugfix */
-	m_fCenterSize = 640.0f; /* --||-- */
-	m_sBackgroundColor = CRGBA(128, 128, 128, 128);
-	m_bTextProportional = true;
-	m_bTextBeforeFade = false;
-	m_nFont = 2; /* enum? */
-	m_fAtX = 0.0f;
-	m_fAtY = 0.0f;
-	memset(&m_Text, 0, sizeof(m_Text));
-}
-
 void CTheScripts::Init()
 {
 	for (int i = 0; i < SIZE_SCRIPT_SPACE; i++)
@@ -1434,33 +1413,6 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
 	return -1;
 }
 
-void CRunningScript::UpdateCompareFlag(bool flag)
-{
-	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--;
-}
-
-
 int8 CRunningScript::ProcessCommands100To199(int32 command)
 {
 	switch (command) {
@@ -8831,7 +8783,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
 	{
 		CollectParameters(&m_nIp, 1);
 		float fMeterValue = *(float*)&ScriptParams[0];
-		float fFeetValue = fMeterValue / METERS_IN_FEET;
+		float fFeetValue = fMeterValue / METERS_IN_FOOT;
 		*(float*)&ScriptParams[0] = fFeetValue;
 		StoreParameters(&m_nIp, 1);
 		return 0;
@@ -9716,33 +9668,13 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
 	return -1;
 }
 
-int16 CRunningScript::GetPadState(uint16 pad, uint16 button)
+int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index)
 {
-	CPad* pPad = CPad::GetPad(pad);
-	switch (button){
-	case 0: return pPad->NewState.LeftStickX;
-	case 1: return pPad->NewState.LeftStickY;
-	case 2: return pPad->NewState.RightStickX;
-	case 3: return pPad->NewState.RightStickY;
-	case 4: return pPad->NewState.LeftShoulder1;
-	case 5: return pPad->NewState.LeftShoulder2;
-	case 6: return pPad->NewState.RightShoulder1;
-	case 7: return pPad->NewState.RightShoulder2;
-	case 8: return pPad->NewState.DPadUp;
-	case 9: return pPad->NewState.DPadDown;
-	case 10: return pPad->NewState.DPadLeft;
-	case 11: return pPad->NewState.DPadRight;
-	case 12: return pPad->NewState.Start;
-	case 13: return pPad->NewState.Select;
-	case 14: return pPad->NewState.Square;
-	case 15: return pPad->NewState.Triangle;
-	case 16: return pPad->NewState.Cross;
-	case 17: return pPad->NewState.Circle;
-	case 18: return pPad->NewState.LeftShock;
-	case 19: return pPad->NewState.RightShock;
-	default: break;
-	}
-	return 0;
+	if (ScriptSphereArray[index].m_Index >= 0xFFFE)
+		ScriptSphereArray[index].m_Index = 1;
+	else
+		ScriptSphereArray[index].m_Index++;
+	return (uint16)index | ScriptSphereArray[index].m_Index << 16;
 }
 
 int32 CTheScripts::GetActualScriptSphereIndex(int32 index)
@@ -9757,6 +9689,15 @@ int32 CTheScripts::GetActualScriptSphereIndex(int32 index)
 	return array_idx;
 }
 
+void CTheScripts::DrawScriptSpheres()
+{
+	for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) {
+		if (ScriptSphereArray[i].m_bInUse)
+			C3dMarkers::PlaceMarkerSet(ScriptSphereArray[i].m_Id, 4, ScriptSphereArray[i].m_vecCenter, ScriptSphereArray[i].m_fRadius,
+				SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A, SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0);
+	}
+}
+
 int32 CTheScripts::AddScriptSphere(int32 id, CVector pos, float radius)
 {
 	int16 i = 0;
@@ -9775,15 +9716,6 @@ int32 CTheScripts::AddScriptSphere(int32 id, CVector pos, float radius)
 	return GetNewUniqueScriptSphereIndex(i);
 }
 
-int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index)
-{
-	if (ScriptSphereArray[index].m_Index >= 0xFFFE)
-		ScriptSphereArray[index].m_Index = 1;
-	else
-		ScriptSphereArray[index].m_Index++;
-	return (uint16)index | ScriptSphereArray[index].m_Index << 16;
-}
-
 void CTheScripts::RemoveScriptSphere(int32 index)
 {
 	index = GetActualScriptSphereIndex(index);
@@ -9793,9 +9725,39 @@ void CTheScripts::RemoveScriptSphere(int32 index)
 	ScriptSphereArray[index].m_Id = 0;
 }
 
-bool CTheScripts::IsVehicleStopped(CVehicle* pVehicle)
+void CTheScripts::AddToBuildingSwapArray(CBuilding* pBuilding, int32 old_model, int32 new_model)
 {
-	return 0.01f * CTimer::GetTimeStep() >= pVehicle->m_fDistanceTravelled;
+	int i = 0;
+	bool found = false;
+	while (i < MAX_NUM_BUILDING_SWAPS && !found) {
+		if (BuildingSwapArray[i].m_pBuilding == pBuilding)
+			found = true;
+		else
+			i++;
+	}
+	if (found) {
+		if (BuildingSwapArray[i].m_nOldModel == new_model) {
+			BuildingSwapArray[i].m_pBuilding = nil;
+			BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1;
+		}
+		else {
+			BuildingSwapArray[i].m_nNewModel = new_model;
+		}
+	}
+	else {
+		i = 0;
+		while (i < MAX_NUM_BUILDING_SWAPS && !found) {
+			if (BuildingSwapArray[i].m_pBuilding == nil)
+				found = true;
+			else
+				i++;
+		}
+		if (found) {
+			BuildingSwapArray[i].m_pBuilding = pBuilding;
+			BuildingSwapArray[i].m_nNewModel = new_model;
+			BuildingSwapArray[i].m_nOldModel = old_model;
+		}
+	}
 }
 
 void CTheScripts::AddToInvisibilitySwapArray(CEntity* pEntity, bool remove)
@@ -9825,41 +9787,138 @@ void CTheScripts::AddToInvisibilitySwapArray(CEntity* pEntity, bool remove)
 	}
 }
 
-void CTheScripts::AddToBuildingSwapArray(CBuilding* pBuilding, int32 old_model, int32 new_model)
+WRAPPER void CTheScripts::UndoBuildingSwaps() { EAXJMP(0x44FD10); }
+WRAPPER void CTheScripts::UndoEntityVisibilitySettings() { EAXJMP(0x44FD60); }
+
+void CRunningScript::UpdateCompareFlag(bool flag)
 {
-	int i = 0;
-	bool found = false;
-	while (i < MAX_NUM_BUILDING_SWAPS && !found) {
-		if (BuildingSwapArray[i].m_pBuilding == pBuilding)
-			found = true;
-		else
-			i++;
+	if (m_bNotFlag)
+		flag = !flag;
+	if (m_nAndOrState == ANDOR_NONE) {
+		m_bCondResult = flag;
+		return;
 	}
-	if (found) {
-		if (BuildingSwapArray[i].m_nOldModel == new_model) {
-			BuildingSwapArray[i].m_pBuilding = nil;
-			BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1;
-		}else{
-			BuildingSwapArray[i].m_nNewModel = new_model;
+	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 {
-		i = 0;
-		while (i < MAX_NUM_BUILDING_SWAPS && !found) {
-			if (BuildingSwapArray[i].m_pBuilding == nil)
-				found = true;
-			else
-				i++;
+		return;
+	}
+	m_nAndOrState--;
+}
+
+void CRunningScript::LocatePlayerCommand(int32 command, uint32* pIp)
+{
+	bool b3D, result, debug, decided = false;
+	float X, Y, Z, dX, dY, dZ;
+	switch (command) {
+	case COMMAND_LOCATE_PLAYER_ANY_MEANS_3D:
+	case COMMAND_LOCATE_PLAYER_ON_FOOT_3D:
+	case COMMAND_LOCATE_PLAYER_IN_CAR_3D:
+	case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D:
+	case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_3D:
+	case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 8 : 6);
+	CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+	switch (command) {
+	case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_2D:
+	case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D:
+	case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_2D:
+	case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_3D:
+	case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_2D:
+	case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_3D:
+		if (!CTheScripts::IsPlayerStopped(pPlayerInfo)) {
+			result = false;
+			decided = true;
 		}
-		if (found) {
-			BuildingSwapArray[i].m_pBuilding = pBuilding;
-			BuildingSwapArray[i].m_nNewModel = new_model;
-			BuildingSwapArray[i].m_nOldModel = old_model;
+		break;
+	default:
+		break;
+	}
+	X = *(float*)&ScriptParams[1];
+	Y = *(float*)&ScriptParams[2];
+	if (b3D) {
+		Z = *(float*)&ScriptParams[3];
+		dX = *(float*)&ScriptParams[4];
+		dY = *(float*)&ScriptParams[5];
+		dZ = *(float*)&ScriptParams[6];
+		debug = ScriptParams[7];
+	} else {
+		dX = *(float*)&ScriptParams[3];
+		dY = *(float*)&ScriptParams[4];
+		debug = ScriptParams[5];
+	}
+	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) {
+			switch (command) {
+			case COMMAND_LOCATE_PLAYER_ANY_MEANS_2D:
+			case COMMAND_LOCATE_PLAYER_ANY_MEANS_3D:
+			case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_2D:
+			case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D:
+				result = true;
+				break;
+			case COMMAND_LOCATE_PLAYER_ON_FOOT_2D:
+			case COMMAND_LOCATE_PLAYER_ON_FOOT_3D:
+			case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_2D:
+			case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_3D:
+				result = !pPlayerInfo->m_pPed->bInVehicle;
+				break;
+			case COMMAND_LOCATE_PLAYER_IN_CAR_2D:
+			case COMMAND_LOCATE_PLAYER_IN_CAR_3D:
+			case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_2D:
+			case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_3D:
+				result = pPlayerInfo->m_pPed->bInVehicle;
+				break;
+			default:
+				assert(false);
+				break;
+			}
+		}
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : -100.0f);
+	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);
 	}
 }
 
-WRAPPER void CRunningScript::LocatePlayerCommand(int32, uint32*) { EAXJMP(0x44FE10); }
 WRAPPER void CRunningScript::LocatePlayerCharCommand(int32, uint32*) { EAXJMP(0x4501E0); }
 WRAPPER void CRunningScript::LocatePlayerCarCommand(int32, uint32*) { EAXJMP(0x450540); }
 WRAPPER void CRunningScript::LocateCharCommand(int32, uint32*) { EAXJMP(0x450870); }
@@ -9872,22 +9931,62 @@ WRAPPER void CRunningScript::PlayerInAreaCheckCommand(int32, uint32*) { EAXJMP(0
 WRAPPER void CRunningScript::PlayerInAngledAreaCheckCommand(int32, uint32*) { EAXJMP(0x451E50); }
 WRAPPER void CRunningScript::CharInAreaCheckCommand(int32, uint32*) { EAXJMP(0x4523B0); }
 WRAPPER void CRunningScript::CarInAreaCheckCommand(int32, uint32*) { EAXJMP(0x452750); }
-
-WRAPPER void CTheScripts::DrawScriptSpheres() { EAXJMP(0x44FAC0); }
 WRAPPER void CRunningScript::DoDeatharrestCheck() { EAXJMP(0x452A30); }
+
+int16 CRunningScript::GetPadState(uint16 pad, uint16 button)
+{
+	CPad* pPad = CPad::GetPad(pad);
+	switch (button) {
+	case 0: return pPad->NewState.LeftStickX;
+	case 1: return pPad->NewState.LeftStickY;
+	case 2: return pPad->NewState.RightStickX;
+	case 3: return pPad->NewState.RightStickY;
+	case 4: return pPad->NewState.LeftShoulder1;
+	case 5: return pPad->NewState.LeftShoulder2;
+	case 6: return pPad->NewState.RightShoulder1;
+	case 7: return pPad->NewState.RightShoulder2;
+	case 8: return pPad->NewState.DPadUp;
+	case 9: return pPad->NewState.DPadDown;
+	case 10: return pPad->NewState.DPadLeft;
+	case 11: return pPad->NewState.DPadRight;
+	case 12: return pPad->NewState.Start;
+	case 13: return pPad->NewState.Select;
+	case 14: return pPad->NewState.Square;
+	case 15: return pPad->NewState.Triangle;
+	case 16: return pPad->NewState.Cross;
+	case 17: return pPad->NewState.Circle;
+	case 18: return pPad->NewState.LeftShock;
+	case 19: return pPad->NewState.RightShock;
+	default: break;
+	}
+	return 0;
+}
+
 WRAPPER void CTheScripts::DrawDebugSquare(float, float, float, float) { EAXJMP(0x452D00); }
+WRAPPER void CTheScripts::DrawDebugAngledSquare(float, float, float, float, float, float, float, float) { EAXJMP(0x452F00); }
 WRAPPER void CTheScripts::DrawDebugCube(float, float, float, float, float, float) { EAXJMP(0x453100); }
+WRAPPER void CTheScripts::DrawDebugAngledCube(float, float, float, float, float, float, float, float, float, float) { EAXJMP(0x4532F0); }
 WRAPPER void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2) { EAXJMP(0x4534E0); }
+WRAPPER void CTheScripts::RenderTheScriptDebugLines() { EAXJMP(0x453550); }
+WRAPPER void CTheScripts::SaveAllScripts(uint8*, uint32*) { EAXJMP(0x4535E0); }
+WRAPPER void CTheScripts::LoadAllScripts(uint8*, uint32) { EAXJMP(0x453B30); }
 WRAPPER void CTheScripts::ClearSpaceForMissionEntity(const CVector&, CEntity*) { EAXJMP(0x454060); }
 WRAPPER void CTheScripts::HighlightImportantArea(uint32, float, float, float, float, float) { EAXJMP(0x454320); }
+WRAPPER void CTheScripts::HighlightImportantAngledArea(uint32, float, float, float, float, float, float, float, float, float) { EAXJMP(0x454430); }
+WRAPPER bool CTheScripts::IsPedStopped(CPed*) { EAXJMP(0x454670); }
+WRAPPER bool CTheScripts::IsPlayerStopped(CPlayerInfo*) { EAXJMP(0x4546C0); }
+
+bool CTheScripts::IsVehicleStopped(CVehicle* pVehicle)
+{
+	return 0.01f * CTimer::GetTimeStep() >= pVehicle->m_fDistanceTravelled;
+}
+
 WRAPPER void CTheScripts::CleanUpThisVehicle(CVehicle*) { EAXJMP(0x4548D0); }
 WRAPPER void CTheScripts::CleanUpThisPed(CPed*) { EAXJMP(0x4547A0); }
 WRAPPER void CTheScripts::CleanUpThisObject(CObject*) { EAXJMP(0x454910); }
 WRAPPER void CTheScripts::ReadObjectNamesFromScript() { EAXJMP(0x454960); }
 WRAPPER void CTheScripts::UpdateObjectIndices() { EAXJMP(0x454AD0); }
 WRAPPER void CTheScripts::ReadMultiScriptFileOffsetsFromScript() { EAXJMP(0x454BC0); }
-WRAPPER bool CTheScripts::IsPedStopped(CPed*) { EAXJMP(0x454670); }
-WRAPPER bool CTheScripts::IsPlayerStopped(CPlayerInfo*) { EAXJMP(0x4546C0); }
 
 STARTPATCHES
 InjectHook(0x437AE0, &CMissionCleanup::Init, PATCH_JUMP);
diff --git a/src/control/Script.h b/src/control/Script.h
index aa6f7e58..1598fdb1 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -48,7 +48,26 @@ struct CTextLine
 	float m_fAtY;
 	wchar m_Text[SCRIPT_TEXT_MAX_LENGTH];
 
-	void Reset();
+	void Reset()
+	{
+		m_fScaleX = 0.48f;
+		m_fScaleY = 1.12f;
+		m_sColor = CRGBA(225, 225, 225, 255);
+		m_bJustify = false;
+		m_bRightJustify = false;
+		m_bCentered = false;
+		m_bBackground = false;
+		m_bBackgroundOnly = false;
+		m_fWrapX = 182.0f; /* TODO: scaling as bugfix */
+		m_fCenterSize = 640.0f; /* --||-- */
+		m_sBackgroundColor = CRGBA(128, 128, 128, 128);
+		m_bTextProportional = true;
+		m_bTextBeforeFade = false;
+		m_nFont = 2; /* enum? */
+		m_fAtX = 0.0f;
+		m_fAtY = 0.0f;
+		memset(&m_Text, 0, sizeof(m_Text));
+	}
 };
 
 static_assert(sizeof(CTextLine) == 0x414, "Script.h: error");
@@ -378,10 +397,18 @@ public:
 	static void DrawScriptSpheres();
 	static void ClearSpaceForMissionEntity(const CVector&, CEntity*);
 	static void HighlightImportantArea(uint32, float, float, float, float, float);
+	static void HighlightImportantAngledArea(uint32, float, float, float, float, float, float, float, float, float);
 	static void DrawDebugSquare(float, float, float, float);
+	static void DrawDebugAngledSquare(float, float, float, float, float, float, float, float);
 	static void DrawDebugCube(float, float, float, float, float, float);
+	static void DrawDebugAngledCube(float, float, float, float, float, float, float, float, float, float);
+	static void RenderTheScriptDebugLines();
+	static void SaveAllScripts(uint8*, uint32*);
+	static void LoadAllScripts(uint8*, uint32);
 	static void AddToInvisibilitySwapArray(CEntity*, bool);
 	static void AddToBuildingSwapArray(CBuilding*, int32, int32);
+	static void UndoBuildingSwaps();
+	static void UndoEntityVisibilitySettings();
 
 	static int32 GetActualScriptSphereIndex(int32 index);
 	static int32 AddScriptSphere(int32 id, CVector pos, float radius);

From 1ba696f5fca9dfc7c6f6d4f5f2537392b96cfc63 Mon Sep 17 00:00:00 2001
From: Nikolay Korolev <nickvnuk@gmail.com>
Date: Sun, 23 Feb 2020 13:12:44 +0300
Subject: [PATCH 2/8] some changes

---
 src/control/OnscreenTimer.cpp |  16 +-
 src/control/Script.cpp        | 288 +++++++++++++++-----------------
 src/control/Script.h          | 304 ++++++++++++++++++----------------
 src/core/Frontend.cpp         |   4 +-
 src/core/PlayerInfo.cpp       |   4 +-
 src/core/Radar.cpp            |   8 +-
 6 files changed, 315 insertions(+), 309 deletions(-)

diff --git a/src/control/OnscreenTimer.cpp b/src/control/OnscreenTimer.cpp
index 1677df06..5406522c 100644
--- a/src/control/OnscreenTimer.cpp
+++ b/src/control/OnscreenTimer.cpp
@@ -106,18 +106,18 @@ void COnscreenTimerEntry::Process() {
 		return;
 	}
 
-	uint32* timerPtr = (uint32*)&CTheScripts::ScriptSpace[m_nTimerOffset];
-	uint32 oldTime = *timerPtr;
-	int32 newTime = int32(oldTime - uint32(20.0f * CTimer::GetTimeStep()));
+	int32* timerPtr = CTheScripts::GetPointerToScriptVariable(m_nTimerOffset);
+	int32 oldTime = *timerPtr;
+	int32 newTime = oldTime - int32(CTimer::GetTimeStepInSeconds() * 1000);
 	if(newTime < 0) {
 		*timerPtr = 0;
 		m_bTimerProcessed = 0;
 		m_nTimerOffset = 0;
 		m_aTimerText[0] = 0;
 	} else {
-		*timerPtr = (uint32)newTime;
-		uint32 oldTimeSeconds = oldTime / 1000;
-		if(oldTimeSeconds <= 11 && newTime / 1000 != oldTimeSeconds) {
+		*timerPtr = newTime;
+		int32 oldTimeSeconds = oldTime / 1000;
+		if(oldTimeSeconds < 12 && newTime / 1000 != oldTimeSeconds) {
 			DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, newTime / 1000);
 		}
 	}
@@ -144,13 +144,13 @@ bool COnscreenTimerEntry::ProcessForDisplay() {
 }
 
 void COnscreenTimerEntry::ProcessForDisplayClock() {
-	uint32 time = *(uint32*)&CTheScripts::ScriptSpace[m_nTimerOffset];
+	uint32 time = *CTheScripts::GetPointerToScriptVariable(m_nTimerOffset);
 	sprintf(m_bTimerBuffer, "%02d:%02d", time / 1000 / 60,
 				   time / 1000 % 60);
 }
 
 void COnscreenTimerEntry::ProcessForDisplayCounter() {
-	uint32 counter = *(uint32*)&CTheScripts::ScriptSpace[m_nCounterOffset];
+	uint32 counter = *CTheScripts::GetPointerToScriptVariable(m_nCounterOffset);
 	sprintf(m_bCounterBuffer, "%d", counter);
 }
 
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 2bded19e..328a0ac2 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -383,25 +383,25 @@ void CRunningScript::CollectParameters(uint32* pIp, int16 total)
 {
 	for (int16 i = 0; i < total; i++){
 		float tmp;
-		switch (CTheScripts::Read1ByteFromScript(pIp))
+		switch (Read1ByteFromScript(pIp))
 		{
 		case ARGUMENT_INT32:
-			ScriptParams[i] = CTheScripts::Read4BytesFromScript(pIp);
+			ScriptParams[i] = Read4BytesFromScript(pIp);
 			break;
 		case ARGUMENT_GLOBALVAR:
-			ScriptParams[i] = *((int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)]);
+			ScriptParams[i] = *((int32*)&CTheScripts::ScriptSpace[Read2BytesFromScript(pIp)]);
 			break;
 		case ARGUMENT_LOCALVAR:
-			ScriptParams[i] = m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)];
+			ScriptParams[i] = m_anLocalVariables[Read2BytesFromScript(pIp)];
 			break;
 		case ARGUMENT_INT8:
-			ScriptParams[i] = CTheScripts::Read1ByteFromScript(pIp);
+			ScriptParams[i] = Read1ByteFromScript(pIp);
 			break;
 		case ARGUMENT_INT16:
-			ScriptParams[i] = CTheScripts::Read2BytesFromScript(pIp);
+			ScriptParams[i] = Read2BytesFromScript(pIp);
 			break;
 		case ARGUMENT_FLOAT:
-			tmp = CTheScripts::ReadFloatFromScript(pIp);
+			tmp = ReadFloatFromScript(pIp);
 			ScriptParams[i] = *(int32*)&tmp;
 			break;
 		default:
@@ -415,20 +415,20 @@ int32 CRunningScript::CollectNextParameterWithoutIncreasingPC(uint32 ip)
 {
 	uint32* pIp = &ip;
 	float tmp;
-	switch (CTheScripts::Read1ByteFromScript(pIp))
+	switch (Read1ByteFromScript(pIp))
 	{
 	case ARGUMENT_INT32:
-		return CTheScripts::Read4BytesFromScript(pIp);
+		return Read4BytesFromScript(pIp);
 	case ARGUMENT_GLOBALVAR:
-		return *((int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)]);
+		return *((int32*)&CTheScripts::ScriptSpace[Read2BytesFromScript(pIp)]);
 	case ARGUMENT_LOCALVAR:
-		return m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)];
+		return m_anLocalVariables[Read2BytesFromScript(pIp)];
 	case ARGUMENT_INT8:
-		return CTheScripts::Read1ByteFromScript(pIp);
+		return Read1ByteFromScript(pIp);
 	case ARGUMENT_INT16:
-		return CTheScripts::Read2BytesFromScript(pIp);
+		return Read2BytesFromScript(pIp);
 	case ARGUMENT_FLOAT:
-		tmp = CTheScripts::ReadFloatFromScript(pIp);
+		tmp = ReadFloatFromScript(pIp);
 		return *(int32*)&tmp;
 	default:
 		assert(0);
@@ -439,12 +439,12 @@ int32 CRunningScript::CollectNextParameterWithoutIncreasingPC(uint32 ip)
 void CRunningScript::StoreParameters(uint32* pIp, int16 number)
 {
 	for (int16 i = 0; i < number; i++){
-		switch (CTheScripts::Read1ByteFromScript(pIp)) {
+		switch (Read1ByteFromScript(pIp)) {
 		case ARGUMENT_GLOBALVAR:
-			*(int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)] = ScriptParams[i];
+			*(int32*)&CTheScripts::ScriptSpace[Read2BytesFromScript(pIp)] = ScriptParams[i];
 			break;
 		case ARGUMENT_LOCALVAR:
-			m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)] = ScriptParams[i];
+			m_anLocalVariables[Read2BytesFromScript(pIp)] = ScriptParams[i];
 			break;
 		default:
 			assert(0);
@@ -454,14 +454,14 @@ void CRunningScript::StoreParameters(uint32* pIp, int16 number)
 
 int32 *CRunningScript::GetPointerToScriptVariable(uint32* pIp, int16 type)
 {
-	switch (CTheScripts::Read1ByteFromScript(pIp))
+	switch (Read1ByteFromScript(pIp))
 	{
 	case ARGUMENT_GLOBALVAR:
 		assert(type == VAR_GLOBAL);
-		return (int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)];
+		return (int32*)&CTheScripts::ScriptSpace[Read2BytesFromScript(pIp)];
 	case ARGUMENT_LOCALVAR:
 		assert(type == VAR_LOCAL);
-		return &m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)];
+		return &m_anLocalVariables[Read2BytesFromScript(pIp)];
 	default:
 		assert(0);
 	}
@@ -472,7 +472,7 @@ void CRunningScript::Init()
 {
 	strcpy(m_abScriptName, "noname");
 	next = prev = nil;
-	m_nIp = 0;
+	SetIP(0);
 	for (int i = 0; i < MAX_STACK_DEPTH; i++)
 		m_anStack[i] = 0;
 	m_nStackPointer = 0;
@@ -677,7 +677,7 @@ void CRunningScript::Process()
 	if (m_bIsMissionScript)
 		DoDeatharrestCheck();
 	if (m_bMissionFlag && CTheScripts::FailCurrentMission == 1 && m_nStackPointer == 1)
-		m_nIp = m_anStack[--m_nStackPointer];
+		SetIP(m_anStack[--m_nStackPointer]);
 	if (CTimer::GetTimeInMilliseconds() >= m_nWakeTime){
 		while (!ProcessOneCommand())
 			;
@@ -699,7 +699,7 @@ void CRunningScript::Process()
 int8 CRunningScript::ProcessOneCommand()
 {
 	++CTheScripts::CommandsExecuted;
-	int32 command = CTheScripts::Read2BytesFromScript(&m_nIp);
+	int32 command = Read2BytesFromScript(&m_nIp);
 	m_bNotFlag = (command & 0x8000);
 	command &= 0x7FFF;
 	if (command < 100)
@@ -1227,27 +1227,27 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
 		CollectParameters(&m_nIp, 1);
 		assert(ScriptParams[0] >= 0);
 		CRunningScript* pNew = CTheScripts::StartNewScript(ScriptParams[0]);
-		int8 type = CTheScripts::Read1ByteFromScript(&m_nIp);
+		int8 type = Read1ByteFromScript(&m_nIp);
 		float tmp;
-		for (int i = 0; type != ARGUMENT_END; type = CTheScripts::Read1ByteFromScript(&m_nIp), i++) {
+		for (int i = 0; type != ARGUMENT_END; type = Read1ByteFromScript(&m_nIp), i++) {
 			switch (type) {
 			case ARGUMENT_INT32:
-				pNew->m_anLocalVariables[i] = CTheScripts::Read4BytesFromScript(&m_nIp);
+				pNew->m_anLocalVariables[i] = Read4BytesFromScript(&m_nIp);
 				break;
 			case ARGUMENT_GLOBALVAR:
-				pNew->m_anLocalVariables[i] = *(int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(&m_nIp)];
+				pNew->m_anLocalVariables[i] = *(int32*)&CTheScripts::ScriptSpace[Read2BytesFromScript(&m_nIp)];
 				break;
 			case ARGUMENT_LOCALVAR:
-				pNew->m_anLocalVariables[i] = m_anLocalVariables[CTheScripts::Read2BytesFromScript(&m_nIp)];
+				pNew->m_anLocalVariables[i] = m_anLocalVariables[Read2BytesFromScript(&m_nIp)];
 				break;
 			case ARGUMENT_INT8:
-				pNew->m_anLocalVariables[i] = CTheScripts::Read1ByteFromScript(&m_nIp);
+				pNew->m_anLocalVariables[i] = Read1ByteFromScript(&m_nIp);
 				break;
 			case ARGUMENT_INT16:
-				pNew->m_anLocalVariables[i] = CTheScripts::Read2BytesFromScript(&m_nIp);
+				pNew->m_anLocalVariables[i] = Read2BytesFromScript(&m_nIp);
 				break;
 			case ARGUMENT_FLOAT:
-				tmp = CTheScripts::ReadFloatFromScript(&m_nIp);
+				tmp = ReadFloatFromScript(&m_nIp);
 				pNew->m_anLocalVariables[i] = *(int32*)&tmp;
 				break;
 			default:
@@ -1275,7 +1275,7 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
 		CollectParameters(&m_nIp, 4);
 		int32 index = ScriptParams[0];
 		assert(index < 1); /* Constant? Also no more double player glitch */
-		debug("&&&&&&&&&&&&&Creating player: %d\n", index);
+		printf("&&&&&&&&&&&&&Creating player: %d\n", index);
 		if (!CStreaming::HasModelLoaded(MI_PLAYER)) {
 			CStreaming::RequestSpecialModel(MI_PLAYER, "player", STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
 			CStreaming::LoadAllRequestedModels(false);
@@ -2669,7 +2669,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
 		CollectParameters(&m_nIp, 1);
 		CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]];
 		char label[12];
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
+		ReadTextLabelFromScript(&m_nIp, label);
 		int zoneToCheck = CTheZones::FindZoneByLabelAndReturnIndex(label);
 		if (zoneToCheck != -1)
 			m_nIp += KEY_LENGTH_IN_SCRIPT; /* why only if zone != 1? */
@@ -2960,7 +2960,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	}
 	case COMMAND_ADD_PAGER_MESSAGE:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 3);
 		CUserDisplay::Pager.AddMessage(text, ScriptParams[0], ScriptParams[1], ScriptParams[2]);
 		return 0;
@@ -2969,21 +2969,21 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
 		m_nIp++;
-		CUserDisplay::OnscnTimer.AddClock(CTheScripts::Read2BytesFromScript(&m_nIp), nil);
+		CUserDisplay::OnscnTimer.AddClock(Read2BytesFromScript(&m_nIp), nil);
 		return 0;
 	}
 	case COMMAND_CLEAR_ONSCREEN_TIMER:
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
 		m_nIp++;
-		CUserDisplay::OnscnTimer.ClearClock(CTheScripts::Read2BytesFromScript(&m_nIp));
+		CUserDisplay::OnscnTimer.ClearClock(Read2BytesFromScript(&m_nIp));
 		return 0;
 	}
 	case COMMAND_DISPLAY_ONSCREEN_COUNTER:
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
 		m_nIp++;
-		int32 counter = CTheScripts::Read2BytesFromScript(&m_nIp);
+		int32 counter = Read2BytesFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 1);
 		CUserDisplay::OnscnTimer.AddCounter(counter, ScriptParams[0], nil);
 		return 0;
@@ -2992,13 +2992,13 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
 		m_nIp++;
-		CUserDisplay::OnscnTimer.ClearCounter(CTheScripts::Read2BytesFromScript(&m_nIp));
+		CUserDisplay::OnscnTimer.ClearCounter(Read2BytesFromScript(&m_nIp));
 		return 0;
 	}
 	case COMMAND_SET_ZONE_CAR_INFO:
 	{
 		char label[12];
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
+		ReadTextLabelFromScript(&m_nIp, label);
 		m_nIp += KEY_LENGTH_IN_SCRIPT;
 		CollectParameters(&m_nIp, 16);
 		int zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
@@ -3021,7 +3021,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 		CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
 		assert(pPed);
 		char label[12];
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
+		ReadTextLabelFromScript(&m_nIp, label);
 		int zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
 		if (zone != -1)
 			m_nIp += KEY_LENGTH_IN_SCRIPT;
@@ -3032,7 +3032,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	case COMMAND_SET_CAR_DENSITY:
 	{
 		char label[12];
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
+		ReadTextLabelFromScript(&m_nIp, label);
 		int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
 		m_nIp += 8;
 		CollectParameters(&m_nIp, 2);
@@ -3046,7 +3046,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	case COMMAND_SET_PED_DENSITY:
 	{
 		char label[12];
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
+		ReadTextLabelFromScript(&m_nIp, label);
 		int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
 		m_nIp += KEY_LENGTH_IN_SCRIPT;
 		CollectParameters(&m_nIp, 2);
@@ -3089,7 +3089,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	case COMMAND_SET_ZONE_PED_INFO:
 	{
 		char label[12];
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
+		ReadTextLabelFromScript(&m_nIp, label);
 		m_nIp += KEY_LENGTH_IN_SCRIPT;
 		CollectParameters(&m_nIp, 10);
 		int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
@@ -3381,11 +3381,11 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	case COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE:
 	*/
 	case COMMAND_DECLARE_MISSION_FLAG:
-		CTheScripts::OnAMissionFlag = CTheScripts::Read2BytesFromScript(&++m_nIp);
+		CTheScripts::OnAMissionFlag = Read2BytesFromScript(&++m_nIp);
 		return 0;
 	case COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT:
 		CollectParameters(&m_nIp, 1);
-		CTheScripts::OnAMissionForContactFlag[ScriptParams[0]] = CTheScripts::Read2BytesFromScript(&++m_nIp);
+		CTheScripts::OnAMissionForContactFlag[ScriptParams[0]] = Read2BytesFromScript(&++m_nIp);
 		return 0;
 	case COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT:
 		CollectParameters(&m_nIp, 2);
@@ -4191,21 +4191,21 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
 	}
 	case COMMAND_PRINT_WITH_NUMBER_BIG:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 3);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[1], ScriptParams[2] - 1, ScriptParams[0], -1, -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_NUMBER:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 3);
 		CMessages::AddMessageWithNumber(text, ScriptParams[1], ScriptParams[2], ScriptParams[0], -1, -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_NUMBER_NOW:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 3);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[1], ScriptParams[2], ScriptParams[0], -1, -1, -1, -1, -1);
 		return 0;
@@ -4395,7 +4395,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
 	}
 	case COMMAND_ADD_PAGER_MESSAGE_WITH_NUMBER:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 4);
 		CUserDisplay::Pager.AddMessageWithNumber(text, ScriptParams[0], -1, -1, -1, -1, -1,
 			ScriptParams[1], ScriptParams[2], ScriptParams[3]);
@@ -4403,7 +4403,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
 	}
 	case COMMAND_START_KILL_FRENZY:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CDarkel::StartFrenzy((eWeaponType)ScriptParams[0], ScriptParams[1], ScriptParams[2],
 			ScriptParams[3], text, ScriptParams[4], ScriptParams[5],
@@ -4580,14 +4580,14 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
 	}
 	case COMMAND_PRINT_BIG_Q:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 2);
 		CMessages::AddBigMessageQ(text, ScriptParams[0], ScriptParams[1] - 1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_NUMBER_BIG_Q:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 3);
 		CMessages::AddBigMessageWithNumberQ(text, ScriptParams[1], ScriptParams[2] - 1,
 			ScriptParams[0], -1, -1, -1, -1, -1);
@@ -5104,14 +5104,14 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
 	case COMMAND_SET_REPEATED_PHONE_MESSAGE:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text, nil, nil, nil, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_PHONE_MESSAGE:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text, nil, nil, nil, nil, nil);
 		return 0;
 	}
@@ -5668,7 +5668,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
 		CollectParameters(&m_nIp, 2);
 		assert(m_nStackPointer < MAX_STACK_DEPTH);
 		m_anStack[m_nStackPointer++] = m_nIp;
-		m_nIp = ScriptParams[0];
+		SetIP(ScriptParams[0]);
 		// ScriptParams[1] == filename
 		return 0;
 	}
@@ -6181,105 +6181,105 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
 	}
 	case COMMAND_PRINT_WITH_2_NUMBERS:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 4);
 		CMessages::AddMessageWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_2_NUMBERS_NOW:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 4);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_2_NUMBERS_SOON:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 4);
 		CMessages::AddMessageSoonWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_3_NUMBERS:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 5);
 		CMessages::AddMessageWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_3_NUMBERS_NOW:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 5);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_3_NUMBERS_SOON:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 5);
 		CMessages::AddMessageSoonWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_4_NUMBERS:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 6);
 		CMessages::AddMessageWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_4_NUMBERS_NOW:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 6);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_4_NUMBERS_SOON:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 6);
 		CMessages::AddMessageSoonWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_5_NUMBERS:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 7);
 		CMessages::AddMessageWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_5_NUMBERS_NOW:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 7);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_5_NUMBERS_SOON:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 7);
 		CMessages::AddMessageSoonWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_6_NUMBERS:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CMessages::AddMessageWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_6_NUMBERS_NOW:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_6_NUMBERS_SOON:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CMessages::AddMessageSoonWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]);
 		return 0;
@@ -6475,7 +6475,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	case COMMAND_SET_ZONE_GROUP:
 	{
 		char zone[KEY_LENGTH_IN_SCRIPT];
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
+		ReadTextLabelFromScript(&m_nIp, zone);
 		m_nIp += KEY_LENGTH_IN_SCRIPT;
 		CollectParameters(&m_nIp, 2);
 		int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone);
@@ -6537,7 +6537,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	case COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_ZONE:
 	{
 		char zone[KEY_LENGTH_IN_SCRIPT];
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
+		ReadTextLabelFromScript(&m_nIp, zone);
 		int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone);
 		if (zone_id != -1)
 			m_nIp += KEY_LENGTH_IN_SCRIPT;
@@ -6736,7 +6736,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	case COMMAND_DISPLAY_TEXT:
 	{
 		CollectParameters(&m_nIp, 2);
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
 		uint16 len = CMessages::GetWideStringLength(text);
@@ -6981,7 +6981,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 		CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
 		assert(pPed);
 		char name[KEY_LENGTH_IN_SCRIPT];
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, name);
+		ReadTextLabelFromScript(&m_nIp, name);
 		for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
 			name[i] = tolower(name[i]);
 		int mi = pPed->GetModelIndex();
@@ -7043,7 +7043,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	{
 		CollectParameters(&m_nIp, 1);
 		char zone[KEY_LENGTH_IN_SCRIPT];
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
+		ReadTextLabelFromScript(&m_nIp, zone);
 		int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone);
 		if (zone_id != -1)
 			m_nIp += KEY_LENGTH_IN_SCRIPT;
@@ -7224,7 +7224,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	}
 	case COMMAND_START_KILL_FRENZY_HEADSHOT:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CDarkel::StartFrenzy((eWeaponType)ScriptParams[0], ScriptParams[1], ScriptParams[2],
 			ScriptParams[3], text, ScriptParams[4], ScriptParams[5],
@@ -7278,35 +7278,35 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	//case COMMAND_SET_AUDIO_STREAM:
 	case COMMAND_PRINT_WITH_2_NUMBERS_BIG:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 4);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[2], ScriptParams[3] - 1, ScriptParams[0], ScriptParams[1], -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_3_NUMBERS_BIG:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 5);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[3], ScriptParams[4] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_4_NUMBERS_BIG:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 6);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[4], ScriptParams[5] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_5_NUMBERS_BIG:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 7);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[5], ScriptParams[6] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_6_NUMBERS_BIG:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[6], ScriptParams[7] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]);
 		return 0;
@@ -7328,8 +7328,8 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 		return 0;
 	case COMMAND_PRINT_STRING_IN_STRING:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* string = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* string = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 2);
 		CMessages::AddMessageWithString(text, ScriptParams[0], ScriptParams[1], string);
 		return 0;
@@ -7384,54 +7384,54 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	case COMMAND_SET_2_REPEATED_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, nil, nil, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_2_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, nil, nil, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_3_REPEATED_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, nil, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_3_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, nil, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_4_REPEATED_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_4_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, nil, nil);
 		return 0;
 	}
@@ -7508,8 +7508,8 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 	switch (command) {
 	case COMMAND_PRINT_STRING_IN_STRING_NOW:
 	{
-		wchar* source = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* pstr = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* source = GetTextByKeyFromScript(&m_nIp);
+		wchar* pstr = GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 2);
 		CMessages::AddMessageJumpQWithString(source, ScriptParams[0], ScriptParams[1], pstr);
 		return 0;
@@ -7518,46 +7518,46 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 	case COMMAND_SET_5_REPEATED_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text5 = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, text5, nil);
 		return 0;
 	}
 	case COMMAND_SET_5_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text5 = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, text5, nil);
 		return 0;
 	}
 	case COMMAND_SET_6_REPEATED_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text6 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text5 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text6 = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, text5, text6);
 		return 0;
 	}
 	case COMMAND_SET_6_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
-		wchar* text6 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text5 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text6 = GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, text5, text6);
 		return 0;
 	}
@@ -8061,7 +8061,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 	case COMMAND_DISPLAY_ONSCREEN_TIMER_WITH_STRING:
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR);
-		int16 var = CTheScripts::Read2BytesFromScript(&m_nIp);
+		int16 var = Read2BytesFromScript(&m_nIp);
 		wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ???
 		strncpy(onscreen_str, (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
 		m_nIp += KEY_LENGTH_IN_SCRIPT;
@@ -8071,7 +8071,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 	case COMMAND_DISPLAY_ONSCREEN_COUNTER_WITH_STRING:
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR);
-		int16 var = CTheScripts::Read2BytesFromScript(&m_nIp);
+		int16 var = Read2BytesFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 1);
 		wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ???
 		strncpy(onscreen_str, (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
@@ -8287,13 +8287,13 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 	}
 	case COMMAND_CLEAR_THIS_PRINT:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CMessages::ClearThisPrint(text);
 		return 0;
 	}
 	case COMMAND_CLEAR_THIS_BIG_PRINT:
 	{
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CMessages::ClearThisBigPrint(text);
 		return 0;
 	}
@@ -8383,7 +8383,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 			m_nIp += KEY_LENGTH_IN_SCRIPT;
 			return 0;
 		}
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CHud::SetHelpMessage(text, false);
 		return 0;
 	}
@@ -9124,7 +9124,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
 		CTimer::Update();
 		return 0;
 	case COMMAND_LOAD_SPLASH_SCREEN:
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp);
+		ReadTextLabelFromScript(&m_nIp, tmp);
 		for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
 			tmp[i] = tolower(tmp[i]);
 		m_nIp += 8;
@@ -9226,7 +9226,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
 	}
 	case COMMAND_TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME:
 	{
-		CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp);
+		ReadTextLabelFromScript(&m_nIp, tmp);
 		for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
 			tmp[i] = tolower(tmp[i]);
 		m_nIp += 8;
@@ -9244,7 +9244,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
 	case COMMAND_DISPLAY_TEXT_WITH_NUMBER:
 	{
 		CollectParameters(&m_nIp, 2);
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
 		CollectParameters(&m_nIp, 1);
@@ -9255,7 +9255,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
 	case COMMAND_DISPLAY_TEXT_WITH_2_NUMBERS:
 	{
 		CollectParameters(&m_nIp, 2);
-		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text = GetTextByKeyFromScript(&m_nIp);
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
 		CollectParameters(&m_nIp, 2);
@@ -9989,27 +9989,7 @@ WRAPPER void CTheScripts::UpdateObjectIndices() { EAXJMP(0x454AD0); }
 WRAPPER void CTheScripts::ReadMultiScriptFileOffsetsFromScript() { EAXJMP(0x454BC0); }
 
 STARTPATCHES
-InjectHook(0x437AE0, &CMissionCleanup::Init, PATCH_JUMP);
-InjectHook(0x437BA0, &CMissionCleanup::AddEntityToList, PATCH_JUMP);
-InjectHook(0x437BD0, &CMissionCleanup::RemoveEntityFromList, PATCH_JUMP);
-InjectHook(0x437C10, &CMissionCleanup::Process, PATCH_JUMP);
-InjectHook(0x437DC0, &CUpsideDownCarCheck::Init, PATCH_JUMP);
-InjectHook(0x437EE0, &CUpsideDownCarCheck::UpdateTimers, PATCH_JUMP);
-InjectHook(0x437F80, &CUpsideDownCarCheck::AreAnyCarsUpsideDown, PATCH_JUMP);
-InjectHook(0x437FB0, &CUpsideDownCarCheck::AddCarToCheck, PATCH_JUMP);
-InjectHook(0x437FE0, &CUpsideDownCarCheck::RemoveCarFromCheck, PATCH_JUMP);
-InjectHook(0x438010, &CUpsideDownCarCheck::HasCarBeenUpsideDownForAWhile, PATCH_JUMP);
-InjectHook(0x438050, &CStuckCarCheck::Init, PATCH_JUMP);
-InjectHook(0x4380A0, &CStuckCarCheck::Process, PATCH_JUMP);
-InjectHook(0x4381C0, &CStuckCarCheck::AddCarToCheck, PATCH_JUMP);
-InjectHook(0x438240, &CStuckCarCheck::RemoveCarFromCheck, PATCH_JUMP);
-InjectHook(0x4382A0, &CStuckCarCheck::HasCarBeenStuckForAWhile, PATCH_JUMP);
-InjectHook(0x4382E0, &CRunningScript::CollectParameters, PATCH_JUMP);
-InjectHook(0x438460, &CRunningScript::CollectNextParameterWithoutIncreasingPC, PATCH_JUMP);
-InjectHook(0x4385A0, &CRunningScript::StoreParameters, PATCH_JUMP);
-InjectHook(0x438640, &CRunningScript::GetPointerToScriptVariable, PATCH_JUMP);
 InjectHook(0x438790, &CTheScripts::Init, PATCH_JUMP);
-InjectHook(0x439000, &CTheScripts::StartNewScript, PATCH_JUMP);
 InjectHook(0x439040, &CTheScripts::Process, PATCH_JUMP);
 InjectHook(0x439400, &CTheScripts::StartTestScript, PATCH_JUMP);
 InjectHook(0x439410, &CTheScripts::IsPlayerOnAMission, PATCH_JUMP);
diff --git a/src/control/Script.h b/src/control/Script.h
index 1598fdb1..fcbd8395 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -11,6 +11,8 @@ class CPed;
 class CObject;
 class CPlayerInfo;
 
+class CRunningScript;
+
 #define KEY_LENGTH_IN_SCRIPT 8
 
 struct CScriptRectangle 
@@ -81,123 +83,6 @@ struct CScriptSphere
 	float m_fRadius;
 };
 
-enum {
-	MAX_STACK_DEPTH = 6,
-	NUM_LOCAL_VARS = 16,
-	NUM_TIMERS = 2
-};
-
-class CRunningScript
-{
-	CRunningScript *next;
-	CRunningScript *prev;
-	char m_abScriptName[8];
-	uint32 m_nIp;
-	uint32 m_anStack[MAX_STACK_DEPTH];
-	uint16 m_nStackPointer;
-	int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS];
-	bool m_bCondResult;
-	bool m_bIsMissionScript;
-	bool m_bSkipWakeTime;
-	uint32 m_nWakeTime;
-	uint16 m_nAndOrState;
-	bool m_bNotFlag;
-	bool m_bDeatharrestEnabled;
-	bool m_bDeatharrestExecuted;
-	bool m_bMissionFlag;
-
-public:
-	void SetIP(uint32 ip) { m_nIp = ip; }
-	CRunningScript* GetNext() { return next; }
-	void UpdateTimers(float timeStep){
-		m_anLocalVariables[NUM_LOCAL_VARS] += timeStep;
-		m_anLocalVariables[NUM_LOCAL_VARS + 1] += timeStep;
-	}
-
-	bool ThisIsAValidRandomPed(uint32 pedtype){
-		switch (pedtype){
-		case PEDTYPE_CIVMALE:
-		case PEDTYPE_CIVFEMALE:
-		case PEDTYPE_GANG1:
-		case PEDTYPE_GANG2:
-		case PEDTYPE_GANG3:
-		case PEDTYPE_GANG4:
-		case PEDTYPE_GANG5:
-		case PEDTYPE_GANG6:
-		case PEDTYPE_GANG7:
-		case PEDTYPE_GANG8:
-		case PEDTYPE_GANG9:
-		case PEDTYPE_CRIMINAL:
-		case PEDTYPE_PROSTITUTE:
-			return true;
-		default:
-			return false;
-		}
-	}
-
-	float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; }
-
-	void CollectParameters(uint32*, int16);
-	int32 CollectNextParameterWithoutIncreasingPC(uint32);
-	int32* GetPointerToScriptVariable(uint32*, int16);
-	void StoreParameters(uint32*, int16);
-	void Init();
-	void RemoveScriptFromList(CRunningScript**);
-	void AddScriptToList(CRunningScript**);
-	void Process();
-	int8 ProcessOneCommand();
-	void DoDeatharrestCheck();
-	int8 ProcessCommands0To99(int32);
-	int8 ProcessCommands100To199(int32);
-	int8 ProcessCommands200To299(int32);
-	int8 ProcessCommands300To399(int32);
-	int8 ProcessCommands400To499(int32);
-	int8 ProcessCommands500To599(int32);
-	int8 ProcessCommands600To699(int32);
-	int8 ProcessCommands700To799(int32);
-	int8 ProcessCommands800To899(int32);
-	int8 ProcessCommands900To999(int32);
-	int8 ProcessCommands1000To1099(int32);
-#ifndef GTA_PS2
-	int8 ProcessCommands1100To1199(int32);
-#endif
-	void UpdateCompareFlag(bool);
-	int16 GetPadState(uint16, uint16);
-	void LocatePlayerCommand(int32, uint32*);
-	void LocatePlayerCharCommand(int32, uint32*);
-	void LocatePlayerCarCommand(int32, uint32*);
-	void LocateCharCommand(int32, uint32*);
-	void LocateCharCharCommand(int32, uint32*);
-	void LocateCharCarCommand(int32, uint32*);
-	void LocateCharObjectCommand(int32, uint32*);
-	void LocateCarCommand(int32, uint32*);
-	void LocateSniperBulletCommand(int32, uint32*);
-	void PlayerInAreaCheckCommand(int32, uint32*);
-	void PlayerInAngledAreaCheckCommand(int32, uint32*);
-	void CharInAreaCheckCommand(int32, uint32*);
-	void CarInAreaCheckCommand(int32, uint32*);
-private:
-	enum {
-		ANDOR_NONE = 0,
-		ANDS_1 = 1,
-		ANDS_2,
-		ANDS_3,
-		ANDS_4,
-		ANDS_5,
-		ANDS_6,
-		ANDS_7,
-		ANDS_8,
-		ORS_1 = 21,
-		ORS_2,
-		ORS_3,
-		ORS_4,
-		ORS_5,
-		ORS_6,
-		ORS_7,
-		ORS_8
-	};
-};
-
 enum {
 	CLEANUP_UNUSED = 0,
 	CLEANUP_CAR,
@@ -337,7 +222,6 @@ enum {
 
 class CTheScripts
 {
-public:
 	static uint8(&ScriptSpace)[SIZE_SCRIPT_SPACE];
 	static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS];
 	static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS];
@@ -377,16 +261,34 @@ public:
 	static bool &UseTextCommands;
 	static uint16 &CommandsExecuted;
 	static uint16 &ScriptsUpdated;
+
 public:
+	static void Init();
+	static void Process();
+
+	static CRunningScript* StartTestScript();
+	static bool IsPlayerOnAMission();
+	static void ClearSpaceForMissionEntity(const CVector&, CEntity*);
 	static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2);
+	static void UndoBuildingSwaps();
+	static void UndoEntityVisibilitySettings();
+
+	static bool IsDebugOn() { return DbgFlag; };
+	static void InvertDebugFlag() { DbgFlag = !DbgFlag; }
+
+	static int32* GetPointerToScriptVariable(int32 offset) { return (int32*)&ScriptSpace[offset]; }
+
+	static void ResetCountdownToMakePlayerUnsafe() { CountdownToMakePlayerUnsafe = 0; }
+	static bool IsCountdownToMakePlayerUnsafeOn() { return CountdownToMakePlayerUnsafe != 0; }
+
+private:
+
+	static CRunningScript* StartNewScript(uint32);
+
 	static void CleanUpThisVehicle(CVehicle*);
 	static void CleanUpThisPed(CPed*);
 	static void CleanUpThisObject(CObject*);
-	static void Init();
-	static CRunningScript* StartNewScript(uint32);
-	static void Process();
-	static CRunningScript* StartTestScript();
-	static bool IsPlayerOnAMission();
+
 	static bool IsPedStopped(CPed*);
 	static bool IsPlayerStopped(CPlayerInfo*);
 	static bool IsVehicleStopped(CVehicle*);
@@ -395,7 +297,6 @@ public:
 	static void UpdateObjectIndices();
 	static void ReadMultiScriptFileOffsetsFromScript();
 	static void DrawScriptSpheres();
-	static void ClearSpaceForMissionEntity(const CVector&, CEntity*);
 	static void HighlightImportantArea(uint32, float, float, float, float, float);
 	static void HighlightImportantAngledArea(uint32, float, float, float, float, float, float, float, float, float);
 	static void DrawDebugSquare(float, float, float, float);
@@ -407,44 +308,169 @@ public:
 	static void LoadAllScripts(uint8*, uint32);
 	static void AddToInvisibilitySwapArray(CEntity*, bool);
 	static void AddToBuildingSwapArray(CBuilding*, int32, int32);
-	static void UndoBuildingSwaps();
-	static void UndoEntityVisibilitySettings();
 
 	static int32 GetActualScriptSphereIndex(int32 index);
 	static int32 AddScriptSphere(int32 id, CVector pos, float radius);
 	static int32 GetNewUniqueScriptSphereIndex(int32 index);
 	static void RemoveScriptSphere(int32 index);
 
-	static int32 Read4BytesFromScript(uint32* pIp){
+	friend class CRunningScript;
+	friend class CHud;
+	friend void CMissionCleanup::Process();
+};
+
+
+enum {
+	MAX_STACK_DEPTH = 6,
+	NUM_LOCAL_VARS = 16,
+	NUM_TIMERS = 2
+};
+
+class CRunningScript
+{
+	enum {
+		ANDOR_NONE = 0,
+		ANDS_1 = 1,
+		ANDS_2,
+		ANDS_3,
+		ANDS_4,
+		ANDS_5,
+		ANDS_6,
+		ANDS_7,
+		ANDS_8,
+		ORS_1 = 21,
+		ORS_2,
+		ORS_3,
+		ORS_4,
+		ORS_5,
+		ORS_6,
+		ORS_7,
+		ORS_8
+	};
+
+	CRunningScript* next;
+	CRunningScript* prev;
+	char m_abScriptName[8];
+	uint32 m_nIp;
+	uint32 m_anStack[MAX_STACK_DEPTH];
+	uint16 m_nStackPointer;
+	int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS];
+	bool m_bCondResult;
+	bool m_bIsMissionScript;
+	bool m_bSkipWakeTime;
+	uint32 m_nWakeTime;
+	uint16 m_nAndOrState;
+	bool m_bNotFlag;
+	bool m_bDeatharrestEnabled;
+	bool m_bDeatharrestExecuted;
+	bool m_bMissionFlag;
+
+public:
+	void SetIP(uint32 ip) { m_nIp = ip; }
+	CRunningScript* GetNext() const { return next; }
+	void UpdateTimers(float timeStep) {
+		m_anLocalVariables[NUM_LOCAL_VARS] += timeStep;
+		m_anLocalVariables[NUM_LOCAL_VARS + 1] += timeStep;
+	}
+
+	static int32 Read4BytesFromScript(uint32* pIp) {
 		int32 retval = 0;
-		for (int i = 0; i < 4; i++){
-			retval |= ScriptSpace[(*pIp)++] << (8 * i);
+		for (int i = 0; i < 4; i++) {
+			retval |= CTheScripts::ScriptSpace[(*pIp)++] << (8 * i);
 		}
 		return retval;
 	}
-	static int16 Read2BytesFromScript(uint32* pIp){
+	static int16 Read2BytesFromScript(uint32* pIp) {
 		int16 retval = 0;
-		for (int i = 0; i < 2; i++){
-			retval |= ScriptSpace[(*pIp)++] << (8 * i);
+		for (int i = 0; i < 2; i++) {
+			retval |= CTheScripts::ScriptSpace[(*pIp)++] << (8 * i);
 		}
 		return retval;
 	}
-	static int8 Read1ByteFromScript(uint32* pIp){
+	static int8 Read1ByteFromScript(uint32* pIp) {
 		int8 retval = 0;
-		for (int i = 0; i < 1; i++){
-			retval |= ScriptSpace[(*pIp)++] << (8 * i);
+		for (int i = 0; i < 1; i++) {
+			retval |= CTheScripts::ScriptSpace[(*pIp)++] << (8 * i);
 		}
 		return retval;
 	}
-	static float ReadFloatFromScript(uint32* pIp){
+	static float ReadFloatFromScript(uint32* pIp) {
 		return Read2BytesFromScript(pIp) / 16.0f;
 	}
-	static void ReadTextLabelFromScript(uint32* pIp, char* buf){
-		strncpy(buf, (const char*)&ScriptSpace[*pIp], KEY_LENGTH_IN_SCRIPT);
+	static void ReadTextLabelFromScript(uint32* pIp, char* buf) {
+		strncpy(buf, (const char*)&CTheScripts::ScriptSpace[*pIp], KEY_LENGTH_IN_SCRIPT);
 	}
 	static wchar* GetTextByKeyFromScript(uint32* pIp) {
-		wchar* text = TheText.Get((const char*)&ScriptSpace[*pIp]);
+		wchar* text = TheText.Get((const char*)&CTheScripts::ScriptSpace[*pIp]);
 		*pIp += KEY_LENGTH_IN_SCRIPT;
 		return text;
 	}
+
+	void Init();
+	void Process();
+
+	void RemoveScriptFromList(CRunningScript**);
+	void AddScriptToList(CRunningScript**);
+
+private:
+	void CollectParameters(uint32*, int16);
+	int32 CollectNextParameterWithoutIncreasingPC(uint32);
+	int32* GetPointerToScriptVariable(uint32*, int16);
+	void StoreParameters(uint32*, int16);
+
+	int8 ProcessOneCommand();
+	void DoDeatharrestCheck();
+	void UpdateCompareFlag(bool);
+	int16 GetPadState(uint16, uint16);
+
+	int8 ProcessCommands0To99(int32);
+	int8 ProcessCommands100To199(int32);
+	int8 ProcessCommands200To299(int32);
+	int8 ProcessCommands300To399(int32);
+	int8 ProcessCommands400To499(int32);
+	int8 ProcessCommands500To599(int32);
+	int8 ProcessCommands600To699(int32);
+	int8 ProcessCommands700To799(int32);
+	int8 ProcessCommands800To899(int32);
+	int8 ProcessCommands900To999(int32);
+	int8 ProcessCommands1000To1099(int32);
+#ifndef GTA_PS2
+	int8 ProcessCommands1100To1199(int32);
+#endif
+	void LocatePlayerCommand(int32, uint32*);
+	void LocatePlayerCharCommand(int32, uint32*);
+	void LocatePlayerCarCommand(int32, uint32*);
+	void LocateCharCommand(int32, uint32*);
+	void LocateCharCharCommand(int32, uint32*);
+	void LocateCharCarCommand(int32, uint32*);
+	void LocateCharObjectCommand(int32, uint32*);
+	void LocateCarCommand(int32, uint32*);
+	void LocateSniperBulletCommand(int32, uint32*);
+	void PlayerInAreaCheckCommand(int32, uint32*);
+	void PlayerInAngledAreaCheckCommand(int32, uint32*);
+	void CharInAreaCheckCommand(int32, uint32*);
+	void CarInAreaCheckCommand(int32, uint32*);
+
+	float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; }
+
+	bool ThisIsAValidRandomPed(uint32 pedtype) {
+		switch (pedtype) {
+		case PEDTYPE_CIVMALE:
+		case PEDTYPE_CIVFEMALE:
+		case PEDTYPE_GANG1:
+		case PEDTYPE_GANG2:
+		case PEDTYPE_GANG3:
+		case PEDTYPE_GANG4:
+		case PEDTYPE_GANG5:
+		case PEDTYPE_GANG6:
+		case PEDTYPE_GANG7:
+		case PEDTYPE_GANG8:
+		case PEDTYPE_GANG9:
+		case PEDTYPE_CRIMINAL:
+		case PEDTYPE_PROSTITUTE:
+			return true;
+		default:
+			return false;
+		}
+	}
 };
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 751ca23f..181ceb60 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -732,7 +732,7 @@ void CMenuManager::Draw()
 				textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(gString);
 				break;
 			case MENUACTION_SETDBGFLAG:
-				textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(CTheScripts::DbgFlag ? "FEM_ON" : "FEM_OFF");
+				textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(CTheScripts::IsDebugOn() ? "FEM_ON" : "FEM_OFF");
 				break;
 			case MENUACTION_SWITCHBIGWHITEDEBUGLIGHT:
 				textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(gbBigWhiteDebugLightSwitchedOn ? "FEM_ON" : "FEM_OFF");
@@ -2150,7 +2150,7 @@ void CMenuManager::ProcessOnOffMenuOptions()
 		SaveSettings();
 		break;
 	case MENUACTION_SETDBGFLAG:
-		CTheScripts::DbgFlag = !CTheScripts::DbgFlag;
+		CTheScripts::InvertDebugFlag();
 		DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
 		break;
 	case MENUACTION_SWITCHBIGWHITEDEBUGLIGHT:
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index a01c1398..633be810 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -164,7 +164,7 @@ void
 CPlayerInfo::MakePlayerSafe(bool toggle)
 {
 	if (toggle) {
-		CTheScripts::CountdownToMakePlayerUnsafe = 0;
+		CTheScripts::ResetCountdownToMakePlayerUnsafe();
 		m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
 		CWorld::StopAllLawEnforcersInTheirTracks();
 		CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20;
@@ -185,7 +185,7 @@ CPlayerInfo::MakePlayerSafe(bool toggle)
 		CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
 		CReplay::DisableReplays();
 
-	} else if (!CGame::playingIntro && !CTheScripts::CountdownToMakePlayerUnsafe) {
+	} else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) {
 		m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
 		CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20;
 		m_pPed->bBulletProof = false;
diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp
index ab7de13e..6a1446da 100644
--- a/src/core/Radar.cpp
+++ b/src/core/Radar.cpp
@@ -325,7 +325,7 @@ void CRadar::DrawBlips()
 						if (blipEntity) {
 							uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
 							if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
-								if (CTheScripts::DbgFlag) {
+								if (CTheScripts::IsDebugOn()) {
 									ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius);
 									ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
 									if (ms_RadarTrace[blipId].m_Radius < 1.0f)
@@ -364,7 +364,7 @@ void CRadar::DrawBlips()
 
 						uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
 						if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
-							if (CTheScripts::DbgFlag) {
+							if (CTheScripts::IsDebugOn()) {
 								ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius);
 								ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
 								if (ms_RadarTrace[blipId].m_Radius < 1.0f)
@@ -429,7 +429,7 @@ void CRadar::DrawBlips()
 						if (blipEntity) {
 							uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
 							if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
-								if (CTheScripts::DbgFlag) {
+								if (CTheScripts::IsDebugOn()) {
 									ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius);
 									ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
 									if (ms_RadarTrace[blipId].m_Radius < 1.0f)
@@ -478,7 +478,7 @@ void CRadar::DrawBlips()
 
 						uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
 						if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
-							if (CTheScripts::DbgFlag) {
+							if (CTheScripts::IsDebugOn()) {
 								ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius);
 								ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
 								if (ms_RadarTrace[blipId].m_Radius < 1.0f)

From 1721a74466ff28b6ac92bdec63965784adecd5fa Mon Sep 17 00:00:00 2001
From: Nikolay Korolev <nickvnuk@gmail.com>
Date: Sun, 23 Feb 2020 13:30:37 +0300
Subject: [PATCH 3/8] stuff

---
 src/control/Script.cpp |  2 ++
 src/control/Script.h   | 12 ++++++++----
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 328a0ac2..1d2e011f 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -9993,4 +9993,6 @@ InjectHook(0x438790, &CTheScripts::Init, PATCH_JUMP);
 InjectHook(0x439040, &CTheScripts::Process, PATCH_JUMP);
 InjectHook(0x439400, &CTheScripts::StartTestScript, PATCH_JUMP);
 InjectHook(0x439410, &CTheScripts::IsPlayerOnAMission, PATCH_JUMP);
+//InjectHook(0x44FD10, &CTheScripts::UndoBuildingSwaps, PATCH_JUMP);
+//InjectHook(0x44FD60, &CTheScripts::UndoEntityVisibilitySettings, PATCH_JUMP);
 ENDPATCHES
diff --git a/src/control/Script.h b/src/control/Script.h
index fcbd8395..5533c417 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -269,10 +269,16 @@ public:
 	static CRunningScript* StartTestScript();
 	static bool IsPlayerOnAMission();
 	static void ClearSpaceForMissionEntity(const CVector&, CEntity*);
-	static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2);
+
 	static void UndoBuildingSwaps();
 	static void UndoEntityVisibilitySettings();
 
+	static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2);
+	static void RenderTheScriptDebugLines();
+
+	static void SaveAllScripts(uint8*, uint32*);
+	static void LoadAllScripts(uint8*, uint32);
+
 	static bool IsDebugOn() { return DbgFlag; };
 	static void InvertDebugFlag() { DbgFlag = !DbgFlag; }
 
@@ -303,9 +309,7 @@ private:
 	static void DrawDebugAngledSquare(float, float, float, float, float, float, float, float);
 	static void DrawDebugCube(float, float, float, float, float, float);
 	static void DrawDebugAngledCube(float, float, float, float, float, float, float, float, float, float);
-	static void RenderTheScriptDebugLines();
-	static void SaveAllScripts(uint8*, uint32*);
-	static void LoadAllScripts(uint8*, uint32);
+
 	static void AddToInvisibilitySwapArray(CEntity*, bool);
 	static void AddToBuildingSwapArray(CBuilding*, int32, int32);
 

From 0255f5d15fdbe569e6133b162c4da5e91ed7afa4 Mon Sep 17 00:00:00 2001
From: Nikolay Korolev <nickvnuk@gmail.com>
Date: Sun, 23 Feb 2020 14:06:12 +0300
Subject: [PATCH 4/8] more cosmetic stuff

---
 src/control/Script.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 1d2e011f..c6efaada 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -9995,4 +9995,9 @@ InjectHook(0x439400, &CTheScripts::StartTestScript, PATCH_JUMP);
 InjectHook(0x439410, &CTheScripts::IsPlayerOnAMission, PATCH_JUMP);
 //InjectHook(0x44FD10, &CTheScripts::UndoBuildingSwaps, PATCH_JUMP);
 //InjectHook(0x44FD60, &CTheScripts::UndoEntityVisibilitySettings, PATCH_JUMP);
+//InjectHook(0x4534E0, &CTheScripts::ScriptDebugLine3D, PATCH_JUMP);
+//InjectHook(0x453550, &CTheScripts::RenderTheScriptDebugLines, PATCH_JUMP);
+//InjectHook(0x4535E0, &CTheScripts::SaveAllScripts, PATCH_JUMP);
+//InjectHook(0x453B30, &CTheScripts::LoadAllScripts, PATCH_JUMP);
+//InjectHook(0x454060, &CTheScripts::ClearSpaceForMissionEntity, PATCH_JUMP);
 ENDPATCHES

From 7d78879c48aa9bebea5a38cac4a3ac58051dda99 Mon Sep 17 00:00:00 2001
From: Nikolay Korolev <nickvnuk@gmail.com>
Date: Mon, 24 Feb 2020 12:10:21 +0300
Subject: [PATCH 5/8] more stuff

---
 src/control/Script.cpp | 658 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 646 insertions(+), 12 deletions(-)

diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index c6efaada..8b765c8c 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -9787,8 +9787,26 @@ void CTheScripts::AddToInvisibilitySwapArray(CEntity* pEntity, bool remove)
 	}
 }
 
-WRAPPER void CTheScripts::UndoBuildingSwaps() { EAXJMP(0x44FD10); }
-WRAPPER void CTheScripts::UndoEntityVisibilitySettings() { EAXJMP(0x44FD60); }
+void CTheScripts::UndoBuildingSwaps()
+{
+	for (int i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) {
+		if (BuildingSwapArray[i].m_pBuilding) {
+			BuildingSwapArray[i].m_pBuilding->ReplaceWithNewModel(BuildingSwapArray[i].m_nOldModel);
+			BuildingSwapArray[i].m_pBuilding = nil;
+			BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1;
+		}
+	}
+}
+
+void CTheScripts::UndoEntityVisibilitySettings()
+{
+	for (int i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) {
+		if (InvisibilitySettingArray[i]) {
+			InvisibilitySettingArray[i]->bIsVisible = true;
+			InvisibilitySettingArray[i] = nil;
+		}
+	}
+}
 
 void CRunningScript::UpdateCompareFlag(bool flag)
 {
@@ -9919,14 +9937,630 @@ void CRunningScript::LocatePlayerCommand(int32 command, uint32* pIp)
 	}
 }
 
-WRAPPER void CRunningScript::LocatePlayerCharCommand(int32, uint32*) { EAXJMP(0x4501E0); }
-WRAPPER void CRunningScript::LocatePlayerCarCommand(int32, uint32*) { EAXJMP(0x450540); }
-WRAPPER void CRunningScript::LocateCharCommand(int32, uint32*) { EAXJMP(0x450870); }
-WRAPPER void CRunningScript::LocateCharCharCommand(int32, uint32*) { EAXJMP(0x450BF0); }
-WRAPPER void CRunningScript::LocateCharCarCommand(int32, uint32*) { EAXJMP(0x450F30); }
-WRAPPER void CRunningScript::LocateCharObjectCommand(int32, uint32*) { EAXJMP(0x451260); }
-WRAPPER void CRunningScript::LocateCarCommand(int32, uint32*) { EAXJMP(0x451590); }
-WRAPPER void CRunningScript::LocateSniperBulletCommand(int32, uint32*) { EAXJMP(0x4518A0); }
+void CRunningScript::LocatePlayerCharCommand(int32 command, uint32* pIp)
+{
+	bool b3D, result, debug;
+	float X, Y, Z, dX, dY, dZ;
+	switch (command) {
+	case COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_3D:
+	case COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_3D:
+	case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 6 : 5);
+	CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+	CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+	assert(pTarget);
+	CVector pos = pPlayerInfo->GetPos();
+	if (pTarget->bInVehicle) {
+		X = pTarget->m_pMyVehicle->GetPosition().x;
+		Y = pTarget->m_pMyVehicle->GetPosition().y;
+		Z = pTarget->m_pMyVehicle->GetPosition().z;
+	} else {
+		X = pTarget->GetPosition().x;
+		Y = pTarget->GetPosition().y;
+		Z = pTarget->GetPosition().z;
+	}
+	dX = *(float*)&ScriptParams[2];
+	dY = *(float*)&ScriptParams[3];
+	if (b3D) {
+		dZ = *(float*)&ScriptParams[4];
+		debug = ScriptParams[5];
+	}
+	else {
+		debug = ScriptParams[5];
+	}
+	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) {
+		switch (command) {
+		case COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_2D:
+		case COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_3D:
+			result = true;
+			break;
+		case COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_2D:
+		case COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_3D:
+			result = !pPlayerInfo->m_pPed->bInVehicle;
+			break;
+		case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_2D:
+		case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_3D:
+			result = pPlayerInfo->m_pPed->bInVehicle;
+			break;
+		default:
+			assert(false);
+			break;
+		}
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+#ifdef FIX_BUGS
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : -100.0f);
+#else
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : -100.0f);
+#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)
+{
+	bool b3D, result, debug;
+	float X, Y, Z, dX, dY, dZ;
+	switch (command) {
+	case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D:
+	case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D:
+	case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 6 : 5);
+	CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+	CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+	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];
+	if (b3D) {
+		dZ = *(float*)&ScriptParams[4];
+		debug = ScriptParams[5];
+	}
+	else {
+		debug = ScriptParams[4];
+	}
+	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) {
+		switch (command) {
+		case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_2D:
+		case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D:
+			result = true;
+			break;
+		case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_2D:
+		case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D:
+			result = !pPlayerInfo->m_pPed->bInVehicle;
+			break;
+		case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_2D:
+		case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_3D:
+			result = pPlayerInfo->m_pPed->bInVehicle;
+			break;
+		default:
+			assert(false);
+			break;
+		}
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : -100.0f);
+	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)
+{
+	bool b3D, result, debug, decided = false;
+	float X, Y, Z, dX, dY, dZ;
+	switch (command) {
+	case COMMAND_LOCATE_CHAR_ANY_MEANS_3D:
+	case COMMAND_LOCATE_CHAR_ON_FOOT_3D:
+	case COMMAND_LOCATE_CHAR_IN_CAR_3D:
+	case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_3D:
+	case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_3D:
+	case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 8 : 6);
+	CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+	assert(pPed);
+	CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
+	switch (command) {
+	case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_2D:
+	case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_3D:
+	case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_2D:
+	case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_3D:
+	case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_2D:
+	case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_3D:
+		if (!CTheScripts::IsPedStopped(pPed)) {
+			result = false;
+			decided = true;
+		}
+		break;
+	default:
+		break;
+	}
+	X = *(float*)&ScriptParams[1];
+	Y = *(float*)&ScriptParams[2];
+	if (b3D) {
+		Z = *(float*)&ScriptParams[3];
+		dX = *(float*)&ScriptParams[4];
+		dY = *(float*)&ScriptParams[5];
+		dZ = *(float*)&ScriptParams[6];
+		debug = ScriptParams[7];
+	}
+	else {
+		dX = *(float*)&ScriptParams[3];
+		dY = *(float*)&ScriptParams[4];
+		debug = ScriptParams[5];
+	}
+	if (!decided) {
+		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) {
+			switch (command) {
+			case COMMAND_LOCATE_CHAR_ANY_MEANS_2D:
+			case COMMAND_LOCATE_CHAR_ANY_MEANS_3D:
+			case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_2D:
+			case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_3D:
+				result = true;
+				break;
+			case COMMAND_LOCATE_CHAR_ON_FOOT_2D:
+			case COMMAND_LOCATE_CHAR_ON_FOOT_3D:
+			case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_2D:
+			case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_3D:
+				result = !pPed->bInVehicle;
+				break;
+			case COMMAND_LOCATE_CHAR_IN_CAR_2D:
+			case COMMAND_LOCATE_CHAR_IN_CAR_3D:
+			case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_2D:
+			case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_3D:
+				result = pPed->bInVehicle;
+				break;
+			default:
+				assert(false);
+				break;
+			}
+		}
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : -100.0f);
+	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)
+{
+	bool b3D, result, debug;
+	float X, Y, Z, dX, dY, dZ;
+	switch (command) {
+	case COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_3D:
+	case COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_3D:
+	case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 6 : 5);
+	CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+	assert(pPed);
+	CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+	assert(pTarget);
+	CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
+	if (pTarget->bInVehicle) {
+		X = pTarget->m_pMyVehicle->GetPosition().x;
+		Y = pTarget->m_pMyVehicle->GetPosition().y;
+		Z = pTarget->m_pMyVehicle->GetPosition().z;
+	}
+	else {
+		X = pTarget->GetPosition().x;
+		Y = pTarget->GetPosition().y;
+		Z = pTarget->GetPosition().z;
+	}
+	dX = *(float*)&ScriptParams[2];
+	dY = *(float*)&ScriptParams[3];
+	if (b3D) {
+		dZ = *(float*)&ScriptParams[4];
+		debug = ScriptParams[5];
+	}
+	else {
+		debug = ScriptParams[4];
+	}
+	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) {
+		switch (command) {
+		case COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_2D:
+		case COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_3D:
+			result = true;
+			break;
+		case COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_2D:
+		case COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_3D:
+			result = !pPed->bInVehicle;
+			break;
+		case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_2D:
+		case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D:
+			result = pPed->bInVehicle;
+			break;
+		default:
+			assert(false);
+			break;
+		}
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+#ifdef FIX_BUGS
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : -100.0f);
+#else
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : -100.0f);
+#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)
+{
+	bool b3D, result, debug;
+	float X, Y, Z, dX, dY, dZ;
+	switch (command) {
+	case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_3D:
+	case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D:
+	case COMMAND_LOCATE_CHAR_IN_CAR_CAR_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 6 : 5);
+	CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+	assert(pPed);
+	CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+	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];
+	if (b3D) {
+		dZ = *(float*)&ScriptParams[4];
+		debug = ScriptParams[5];
+	}
+	else {
+		debug = ScriptParams[4];
+	}
+	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) {
+		switch (command) {
+		case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_2D:
+		case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_3D:
+			result = true;
+			break;
+		case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_2D:
+		case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D:
+			result = !pPed->bInVehicle;
+			break;
+		case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_2D:
+		case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D:
+			result = pPed->bInVehicle;
+			break;
+		default:
+			assert(false);
+			break;
+		}
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : -100.0f);
+	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)
+{
+	bool b3D, result, debug;
+	float X, Y, Z, dX, dY, dZ;
+	switch (command) {
+	case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D:
+	case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D:
+	case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 6 : 5);
+	CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+	assert(pPed);
+	CObject* pTarget = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+	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];
+	if (b3D) {
+		dZ = *(float*)&ScriptParams[4];
+		debug = ScriptParams[5];
+	}
+	else {
+		debug = ScriptParams[4];
+	}
+	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) {
+		switch (command) {
+		case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_2D:
+		case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D:
+			result = true;
+			break;
+		case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_2D:
+		case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D:
+			result = !pPed->bInVehicle;
+			break;
+		case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_2D:
+		case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D:
+			result = pPed->bInVehicle;
+			break;
+		default:
+			assert(false);
+			break;
+		}
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : -100.0f);
+	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)
+{
+	bool b3D, result, debug, decided = false;
+	float X, Y, Z, dX, dY, dZ;
+	switch (command) {
+	case COMMAND_LOCATE_CAR_3D:
+	case COMMAND_LOCATE_STOPPED_CAR_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 8 : 6);
+	CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+	assert(pVehicle);
+	CVector pos = pVehicle->GetPosition();
+	switch (command) {
+	case COMMAND_LOCATE_STOPPED_CAR_2D:
+	case COMMAND_LOCATE_STOPPED_CAR_3D:
+		if (!CTheScripts::IsVehicleStopped(pVehicle)) {
+			result = false;
+			decided = true;
+		}
+		break;
+	default:
+		break;
+	}
+	X = *(float*)&ScriptParams[1];
+	Y = *(float*)&ScriptParams[2];
+	if (b3D) {
+		Z = *(float*)&ScriptParams[3];
+		dX = *(float*)&ScriptParams[4];
+		dY = *(float*)&ScriptParams[5];
+		dZ = *(float*)&ScriptParams[6];
+		debug = ScriptParams[7];
+	}
+	else {
+		dX = *(float*)&ScriptParams[3];
+		dY = *(float*)&ScriptParams[4];
+		debug = ScriptParams[5];
+	}
+	if (!decided) {
+		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;
+		}
+		result = in_area;
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : -100.0f);
+	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)
+{
+	bool b3D, result, debug;
+	float X, Y, Z, dX, dY, dZ;
+	switch (command) {
+	case COMMAND_LOCATE_SNIPER_BULLET_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 7 : 5);
+	X = *(float*)&ScriptParams[0];
+	Y = *(float*)&ScriptParams[1];
+	if (b3D) {
+		Z = *(float*)&ScriptParams[2];
+		dX = *(float*)&ScriptParams[3];
+		dY = *(float*)&ScriptParams[4];
+		dZ = *(float*)&ScriptParams[5];
+		debug = ScriptParams[6];
+	}
+	else {
+		dX = *(float*)&ScriptParams[2];
+		dY = *(float*)&ScriptParams[3];
+		debug = ScriptParams[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((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : -100.0f);
+	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);
+	}
+}
+
 WRAPPER void CRunningScript::PlayerInAreaCheckCommand(int32, uint32*) { EAXJMP(0x451A60); }
 WRAPPER void CRunningScript::PlayerInAngledAreaCheckCommand(int32, uint32*) { EAXJMP(0x451E50); }
 WRAPPER void CRunningScript::CharInAreaCheckCommand(int32, uint32*) { EAXJMP(0x4523B0); }
@@ -9993,8 +10627,8 @@ InjectHook(0x438790, &CTheScripts::Init, PATCH_JUMP);
 InjectHook(0x439040, &CTheScripts::Process, PATCH_JUMP);
 InjectHook(0x439400, &CTheScripts::StartTestScript, PATCH_JUMP);
 InjectHook(0x439410, &CTheScripts::IsPlayerOnAMission, PATCH_JUMP);
-//InjectHook(0x44FD10, &CTheScripts::UndoBuildingSwaps, PATCH_JUMP);
-//InjectHook(0x44FD60, &CTheScripts::UndoEntityVisibilitySettings, PATCH_JUMP);
+InjectHook(0x44FD10, &CTheScripts::UndoBuildingSwaps, PATCH_JUMP);
+InjectHook(0x44FD60, &CTheScripts::UndoEntityVisibilitySettings, PATCH_JUMP);
 //InjectHook(0x4534E0, &CTheScripts::ScriptDebugLine3D, PATCH_JUMP);
 //InjectHook(0x453550, &CTheScripts::RenderTheScriptDebugLines, PATCH_JUMP);
 //InjectHook(0x4535E0, &CTheScripts::SaveAllScripts, PATCH_JUMP);

From 56c83dfaaebffc1eabec01671c2da892661059af Mon Sep 17 00:00:00 2001
From: Nikolay Korolev <nickvnuk@gmail.com>
Date: Mon, 24 Feb 2020 21:17:15 +0300
Subject: [PATCH 6/8] more stuff + intro fix

---
 src/control/Script.cpp | 640 +++++++++++++++++++++++++++++++++++++++--
 src/control/Script.h   |  16 +-
 src/core/main.cpp      |   3 +-
 3 files changed, 635 insertions(+), 24 deletions(-)

diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 3e4c7e8f..b167ac54 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -29,6 +29,7 @@
 #include "HandlingMgr.h"
 #include "Heli.h"
 #include "Hud.h"
+#include "Lines.h"
 #include "main.h"
 #include "Messages.h"
 #include "ModelIndices.h"
@@ -95,6 +96,7 @@ tUsedObject(&CTheScripts::UsedObjectArray)[MAX_NUM_USED_OBJECTS] = *(tUsedObject
 int32(&CTheScripts::MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS] = *(int32(*)[MAX_NUM_MISSION_SCRIPTS])*(uintptr*)0x6F0558;
 tBuildingSwap(&CTheScripts::BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS] = *(tBuildingSwap(*)[MAX_NUM_BUILDING_SWAPS])*(uintptr*)0x880E30;
 CEntity*(&CTheScripts::InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS] = *(CEntity*(*)[MAX_NUM_INVISIBILITY_SETTINGS])*(uintptr*)0x8620F0;
+CStoredLine (&CTheScripts::aStoredLines)[MAX_NUM_STORED_LINES] = *(CStoredLine(*)[MAX_NUM_STORED_LINES])*(uintptr*)0x743018;
 bool &CTheScripts::DbgFlag = *(bool*)0x95CD87;
 uint32 &CTheScripts::OnAMissionFlag = *(uint32*)0x8F1B64;
 int32 &CTheScripts::StoreVehicleIndex = *(int32*)0x8F5F3C;
@@ -115,7 +117,7 @@ uint8 &CTheScripts::DelayMakingPlayerUnsafeThisTime = *(uint8*)0x95CD88;
 uint16 &CTheScripts::NumScriptDebugLines = *(uint16*)0x95CC42;
 uint16 &CTheScripts::NumberOfIntroRectanglesThisFrame = *(uint16*)0x95CC88;
 uint16 &CTheScripts::NumberOfIntroTextLinesThisFrame = *(uint16*)0x95CC32;
-bool &CTheScripts::UseTextCommands = *(bool*)0x95CD57;
+uint8 &CTheScripts::UseTextCommands = *(uint8*)0x95CD57;
 CMissionCleanup (&CTheScripts::MissionCleanup) = *(CMissionCleanup*)0x8F2A24;
 CUpsideDownCarCheck (&CTheScripts::UpsideDownCars) = *(CUpsideDownCarCheck*)0x6EE450;
 CStuckCarCheck (&CTheScripts::StuckCars) = *(CStuckCarCheck*)0x87C588;
@@ -561,7 +563,7 @@ void CTheScripts::Init()
 	ReadMultiScriptFileOffsetsFromScript();
 	FailCurrentMission = 0;
 	CountdownToMakePlayerUnsafe = 0;
-	DbgFlag = 0;
+	DbgFlag = false;
 	DelayMakingPlayerUnsafeThisTime = 1;
 	NumScriptDebugLines = 0;
 	for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++){
@@ -575,7 +577,7 @@ void CTheScripts::Init()
 		IntroTextLines[i].Reset();
 	}
 	NumberOfIntroTextLinesThisFrame = 0;
-	UseTextCommands = false;
+	UseTextCommands = 0;
 	for (int i = 0; i < MAX_NUM_INTRO_RECTANGLES; i++){
 		IntroRectangles[i].m_bIsUsed = false;
 		IntroRectangles[i].m_bBeforeFade = false;
@@ -702,6 +704,9 @@ int8 CRunningScript::ProcessOneCommand()
 	int32 command = Read2BytesFromScript(&m_nIp);
 	m_bNotFlag = (command & 0x8000);
 	command &= 0x7FFF;
+	if (command >= 1000)
+		debug("Time: %d, Script: %s, Command: %d\n", CTheScripts::CommandsExecuted, m_abScriptName, command);
+	debug("IntroSomething: %d\n", CTheScripts::NumberOfIntroTextLinesThisFrame);
 	if (command < 100)
 		return ProcessCommands0To99(command);
 	if (command < 200)
@@ -2454,9 +2459,9 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
 	{
 		CollectParameters(&m_nIp, 2);
 		bool value = GetPadState(ScriptParams[0], ScriptParams[1]) != 0;
-		if (CGame::playingIntro && ScriptParams[0] == 0 && ScriptParams[1] == 12){ /* pad1, start */
+		if (CGame::playingIntro && ScriptParams[0] == 0 && ScriptParams[1] == 12) {
 			if (CPad::GetPad(0)->GetLeftMouseJustDown() ||
-				CPad::GetPad(0)->GetPadEnterJustDown() ||
+				CPad::GetPad(0)->GetEnterJustDown() ||
 				CPad::GetPad(0)->GetCharJustDown(' '))
 				value = true;
 		}
@@ -8454,7 +8459,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
 	}
 	case COMMAND_USE_TEXT_COMMANDS:
 		CollectParameters(&m_nIp, 1);
-		CTheScripts::UseTextCommands = ScriptParams[0] != 0 ? 2 : 1;
+		CTheScripts::UseTextCommands = (ScriptParams[0] != 0) ? 2 : 1;
 		return 0;
 	case COMMAND_SET_THREAT_FOR_PED_TYPE:
 		CollectParameters(&m_nIp, 2);
@@ -9972,7 +9977,7 @@ void CRunningScript::LocatePlayerCharCommand(int32 command, uint32* pIp)
 		debug = ScriptParams[5];
 	}
 	else {
-		debug = ScriptParams[5];
+		debug = ScriptParams[4];
 	}
 	result = false;
 	bool in_area;
@@ -10561,11 +10566,503 @@ void CRunningScript::LocateSniperBulletCommand(int32 command, uint32* pIp)
 	}
 }
 
-WRAPPER void CRunningScript::PlayerInAreaCheckCommand(int32, uint32*) { EAXJMP(0x451A60); }
-WRAPPER void CRunningScript::PlayerInAngledAreaCheckCommand(int32, uint32*) { EAXJMP(0x451E50); }
-WRAPPER void CRunningScript::CharInAreaCheckCommand(int32, uint32*) { EAXJMP(0x4523B0); }
-WRAPPER void CRunningScript::CarInAreaCheckCommand(int32, uint32*) { EAXJMP(0x452750); }
-WRAPPER void CRunningScript::DoDeatharrestCheck() { EAXJMP(0x452A30); }
+void CRunningScript::PlayerInAreaCheckCommand(int32 command, uint32* pIp)
+{
+	bool b3D, result, debug, decided = false;
+	float infX, infY, infZ, supX, supY, supZ;
+	switch (command) {
+	case COMMAND_IS_PLAYER_IN_AREA_3D:
+	case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_3D:
+	case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 8 : 6);
+	CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+	switch (command) {
+	case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_AREA_2D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D:
+		if (!CTheScripts::IsPlayerStopped(pPlayerInfo)) {
+			result = false;
+			decided = true;
+		}
+		break;
+	default:
+		break;
+	}
+	infX = *(float*)&ScriptParams[1];
+	infY = *(float*)&ScriptParams[2];
+	if (b3D) {
+		infZ = *(float*)&ScriptParams[3];
+		supX = *(float*)&ScriptParams[4];
+		supY = *(float*)&ScriptParams[5];
+		supZ = *(float*)&ScriptParams[6];
+		if (infZ > supZ) {
+			infZ = *(float*)&ScriptParams[6];
+			supZ = *(float*)&ScriptParams[3];
+		}
+		debug = ScriptParams[7];
+	}
+	else {
+		supX = *(float*)&ScriptParams[3];
+		supY = *(float*)&ScriptParams[4];
+		debug = ScriptParams[5];
+	}
+	if (infX > supX) {
+		float tmp = infX;
+		infX = supX;
+		supX = tmp;
+	}
+	if (infY > supY) {
+		float tmp = infY;
+		infY = supY;
+		supY = tmp;
+	}
+	if (!decided) {
+		CVector pos = pPlayerInfo->GetPos();
+		result = false;
+		bool in_area;
+		if (b3D) {
+			in_area = infX <= pos.x &&
+				supX >= pos.x &&
+				infY <= pos.y &&
+				supY >= pos.y &&
+				infZ <= pos.z &&
+				supZ >= pos.z;
+		}
+		else {
+			in_area = infX <= pos.x &&
+				supX >= pos.x &&
+				infY <= pos.y &&
+				supY >= pos.y;
+		}
+		if (in_area) {
+			switch (command) {
+			case COMMAND_IS_PLAYER_IN_AREA_2D:
+			case COMMAND_IS_PLAYER_IN_AREA_3D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_AREA_2D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
+				result = true;
+				break;
+			case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_2D:
+			case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_3D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
+				result = !pPlayerInfo->m_pPed->bInVehicle;
+				break;
+			case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_2D:
+			case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_3D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D:
+				result = pPlayerInfo->m_pPed->bInVehicle;
+				break;
+			default:
+				assert(false);
+				break;
+			}
+		}
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : -100.0f);
+	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)
+{
+	bool b3D, result, debug, decided = false;
+	float infX, infY, infZ, supX, supY, supZ, side2length;
+	switch (command) {
+	case COMMAND_IS_PLAYER_IN_ANGLED_AREA_3D:
+	case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_3D:
+	case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 9 : 7);
+	CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+	switch (command) {
+	case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_2D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_2D:
+	case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_2D:
+		if (!CTheScripts::IsPlayerStopped(pPlayerInfo)) {
+			result = false;
+			decided = true;
+		}
+		break;
+	default:
+		break;
+	}
+	infX = *(float*)&ScriptParams[1];
+	infY = *(float*)&ScriptParams[2];
+	if (b3D) {
+		infZ = *(float*)&ScriptParams[3];
+		supX = *(float*)&ScriptParams[4];
+		supY = *(float*)&ScriptParams[5];
+		supZ = *(float*)&ScriptParams[6];
+		if (infZ > supZ) {
+			infZ = *(float*)&ScriptParams[6];
+			supZ = *(float*)&ScriptParams[3];
+		}
+		side2length = *(float*)&ScriptParams[7];
+		debug = ScriptParams[8];
+	}
+	else {
+		supX = *(float*)&ScriptParams[3];
+		supY = *(float*)&ScriptParams[4];
+		side2length = *(float*)&ScriptParams[5];
+		debug = ScriptParams[6];
+	}
+	float initAngle = CGeneral::GetRadianAngleBetweenPoints(infX, infY, supX, supY) + HALFPI;
+	while (initAngle < 0.0f)
+		initAngle += TWOPI;
+	while (initAngle > TWOPI)
+		initAngle -= TWOPI;
+	// it looks like the idea is to use a rectangle using the diagonal of the rectangle as
+	// the side of new rectangle, with "length" being the length of second side
+	float rotatedSupX = supX + side2length * sin(initAngle);
+	float rotatedSupY = supY - side2length * cos(initAngle);
+	float rotatedInfX = infX + side2length * sin(initAngle);
+	float rotatedInfY = infY - side2length * cos(initAngle);
+	float side1X = supX - infX;
+	float side1Y = supY - infY;
+	float side1Length = CVector2D(side1X, side1Y).Magnitude();
+	float side2X = rotatedInfX - infX;
+	float side2Y = rotatedInfY - infY;
+	float side2Length = CVector2D(side2X, side2Y).Magnitude(); // == side2length?
+	if (!decided) {
+		CVector pos = pPlayerInfo->GetPos();
+		result = false;
+		float X = pos.x - infX;
+		float Y = pos.y - infY;
+		float positionAlongSide1 = X * side1X / side1Length + Y * side1Y / side1Length;
+		bool in_area = false;
+		if (positionAlongSide1 >= 0.0f && positionAlongSide1 <= side1Length) {
+			float positionAlongSide2 = X * side2X / side2Length + Y * side2Y / side2Length;
+			if (positionAlongSide2 >= 0.0f && positionAlongSide2 <= side2Length) {
+				in_area = !b3D || pos.z >= infZ && pos.z <= supZ;
+			}
+		}
+
+		if (in_area) {
+			switch (command) {
+			case COMMAND_IS_PLAYER_IN_ANGLED_AREA_2D:
+			case COMMAND_IS_PLAYER_IN_ANGLED_AREA_3D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_2D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
+				result = true;
+				break;
+			case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_2D:
+			case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_3D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_2D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
+				result = !pPlayerInfo->m_pPed->bInVehicle;
+				break;
+			case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_2D:
+			case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_3D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_2D:
+			case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D:
+				result = pPlayerInfo->m_pPed->bInVehicle;
+				break;
+			default:
+				assert(false);
+				break;
+			}
+		}
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+		CTheScripts::HighlightImportantAngledArea((uint32)this + m_nIp, infX, infY, supX, supY,
+			rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY, b3D ? (infZ + supZ) / 2 : -100.0f);
+	if (CTheScripts::DbgFlag) {
+		if (b3D)
+			CTheScripts::DrawDebugAngledCube(infX, infY, infZ, supX, supY, supZ,
+				rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY);
+		else
+			CTheScripts::DrawDebugAngledSquare(infX, infY, supX, supY,
+				rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY);
+	}
+}
+
+void CRunningScript::CharInAreaCheckCommand(int32 command, uint32* pIp)
+{
+	bool b3D, result, debug, decided = false;
+	float infX, infY, infZ, supX, supY, supZ;
+	switch (command) {
+	case COMMAND_IS_CHAR_IN_AREA_3D:
+	case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_3D:
+	case COMMAND_IS_CHAR_IN_AREA_IN_CAR_3D:
+	case COMMAND_IS_CHAR_STOPPED_IN_AREA_3D:
+	case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D:
+	case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 8 : 6);
+	CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+	assert(pPed);
+	CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
+	switch (command) {
+	case COMMAND_IS_CHAR_STOPPED_IN_AREA_3D:
+	case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D:
+	case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D:
+	case COMMAND_IS_CHAR_STOPPED_IN_AREA_2D:
+	case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_2D:
+	case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D:
+		if (!CTheScripts::IsPedStopped(pPed)) {
+			result = false;
+			decided = true;
+		}
+		break;
+	default:
+		break;
+	}
+	infX = *(float*)&ScriptParams[1];
+	infY = *(float*)&ScriptParams[2];
+	if (b3D) {
+		infZ = *(float*)&ScriptParams[3];
+		supX = *(float*)&ScriptParams[4];
+		supY = *(float*)&ScriptParams[5];
+		supZ = *(float*)&ScriptParams[6];
+		if (infZ > supZ) {
+			infZ = *(float*)&ScriptParams[6];
+			supZ = *(float*)&ScriptParams[3];
+		}
+		debug = ScriptParams[7];
+	}
+	else {
+		supX = *(float*)&ScriptParams[3];
+		supY = *(float*)&ScriptParams[4];
+		debug = ScriptParams[5];
+	}
+	if (infX > supX) {
+		float tmp = infX;
+		infX = supX;
+		supX = tmp;
+	}
+	if (infY > supY) {
+		float tmp = infY;
+		infY = supY;
+		supY = tmp;
+	}
+	if (!decided) {
+		result = false;
+		bool in_area;
+		if (b3D) {
+			in_area = infX <= pos.x &&
+				supX >= pos.x &&
+				infY <= pos.y &&
+				supY >= pos.y &&
+				infZ <= pos.z &&
+				supZ >= pos.z;
+		}
+		else {
+			in_area = infX <= pos.x &&
+				supX >= pos.x &&
+				infY <= pos.y &&
+				supY >= pos.y;
+		}
+		if (in_area) {
+			switch (command) {
+			case COMMAND_IS_CHAR_IN_AREA_2D:
+			case COMMAND_IS_CHAR_IN_AREA_3D:
+			case COMMAND_IS_CHAR_STOPPED_IN_AREA_2D:
+			case COMMAND_IS_CHAR_STOPPED_IN_AREA_3D:
+				result = true;
+				break;
+			case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_2D:
+			case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_3D:
+			case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_2D:
+			case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D:
+				result = !pPed->bInVehicle;
+				break;
+			case COMMAND_IS_CHAR_IN_AREA_IN_CAR_2D:
+			case COMMAND_IS_CHAR_IN_AREA_IN_CAR_3D:
+			case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D:
+			case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D:
+				result = pPed->bInVehicle;
+				break;
+			default:
+				assert(false);
+				break;
+			}
+		}
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : -100.0f);
+	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)
+{
+	bool b3D, result, debug, decided = false;
+	float infX, infY, infZ, supX, supY, supZ;
+	switch (command) {
+	case COMMAND_IS_CAR_IN_AREA_3D:
+	case COMMAND_IS_CAR_STOPPED_IN_AREA_3D:
+		b3D = true;
+		break;
+	default:
+		b3D = false;
+		break;
+	}
+	CollectParameters(pIp, b3D ? 8 : 6);
+	CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+	assert(pVehicle);
+	CVector pos = pVehicle->GetPosition();
+	switch (command) {
+	case COMMAND_IS_CAR_STOPPED_IN_AREA_3D:
+	case COMMAND_IS_CAR_STOPPED_IN_AREA_2D:
+		if (!CTheScripts::IsVehicleStopped(pVehicle)) {
+			result = false;
+			decided = true;
+		}
+		break;
+	default:
+		break;
+	}
+	infX = *(float*)&ScriptParams[1];
+	infY = *(float*)&ScriptParams[2];
+	if (b3D) {
+		infZ = *(float*)&ScriptParams[3];
+		supX = *(float*)&ScriptParams[4];
+		supY = *(float*)&ScriptParams[5];
+		supZ = *(float*)&ScriptParams[6];
+		if (infZ > supZ) {
+			infZ = *(float*)&ScriptParams[6];
+			supZ = *(float*)&ScriptParams[3];
+		}
+		debug = ScriptParams[7];
+	}
+	else {
+		supX = *(float*)&ScriptParams[3];
+		supY = *(float*)&ScriptParams[4];
+		debug = ScriptParams[5];
+	}
+	if (infX > supX) {
+		float tmp = infX;
+		infX = supX;
+		supX = tmp;
+	}
+	if (infY > supY) {
+		float tmp = infY;
+		infY = supY;
+		supY = tmp;
+	}
+	if (!decided) {
+		result = false;
+		bool in_area;
+		if (b3D) {
+			in_area = infX <= pos.x &&
+				supX >= pos.x &&
+				infY <= pos.y &&
+				supY >= pos.y &&
+				infZ <= pos.z &&
+				supZ >= pos.z;
+		}
+		else {
+			in_area = infX <= pos.x &&
+				supX >= pos.x &&
+				infY <= pos.y &&
+				supY >= pos.y;
+		}
+		if (in_area) {
+			switch (command) {
+			case COMMAND_IS_CAR_IN_AREA_2D:
+			case COMMAND_IS_CAR_IN_AREA_3D:
+			case COMMAND_IS_CAR_STOPPED_IN_AREA_2D:
+			case COMMAND_IS_CAR_STOPPED_IN_AREA_3D:
+				result = true;
+				break;
+			default:
+				assert(false);
+				break;
+			}
+		}
+	}
+	UpdateCompareFlag(result);
+	if (debug)
+		CTheScripts::HighlightImportantArea((uint32)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : -100.0f);
+	if (CTheScripts::DbgFlag) {
+		if (b3D)
+			CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
+		else
+			CTheScripts::DrawDebugSquare(infX, infY, supX, supY);
+	}
+}
+
+void CRunningScript::DoDeatharrestCheck()
+{
+	if (!m_bDeatharrestEnabled)
+		return;
+	if (!CTheScripts::IsPlayerOnAMission())
+		return;
+	CPlayerInfo* pPlayer = &CWorld::Players[CWorld::PlayerInFocus];
+	if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest() && !CTheScripts::UpsideDownCars.AreAnyCarsUpsideDown())
+		return;
+	assert(m_nStackPointer > 0);
+	while (m_nStackPointer > 1)
+		--m_nStackPointer;
+	m_nIp = m_anStack[--m_nStackPointer];
+	int16 messageId;
+	if (pPlayer->IsRestartingAfterDeath())
+		messageId = 0;
+	else if (pPlayer->IsRestartingAfterArrest())
+		messageId = 5;
+	else
+		messageId = 10;
+	messageId += CGeneral::GetRandomNumberInRange(0, 5);
+	bool found = false;
+	for (int16 contact = 0; !found && contact < MAX_NUM_CONTACTS; contact++) {
+		int contactFlagOffset = CTheScripts::OnAMissionForContactFlag[contact];
+		if (contactFlagOffset && CTheScripts::ScriptSpace[contactFlagOffset] == 1) {
+			messageId += CTheScripts::BaseBriefIdForContact[contact];
+		}
+	}
+	if (!found)
+		messageId = 8001;
+	char tmp[16];
+	sprintf(tmp, "%d", messageId);
+	CMessages::ClearSmallMessagesOnly();
+	wchar* text = TheText.Get(tmp);
+	// ...and do nothing about it
+	*(int32*)&CTheScripts::ScriptSpace[CTheScripts::OnAMissionFlag] = 0;
+	m_bDeatharrestExecuted = true;
+	m_nWakeTime = 0;
+}
 
 int16 CRunningScript::GetPadState(uint16 pad, uint16 button)
 {
@@ -10596,12 +11093,115 @@ int16 CRunningScript::GetPadState(uint16 pad, uint16 button)
 	return 0;
 }
 
-WRAPPER void CTheScripts::DrawDebugSquare(float, float, float, float) { EAXJMP(0x452D00); }
-WRAPPER void CTheScripts::DrawDebugAngledSquare(float, float, float, float, float, float, float, float) { EAXJMP(0x452F00); }
-WRAPPER void CTheScripts::DrawDebugCube(float, float, float, float, float, float) { EAXJMP(0x453100); }
-WRAPPER void CTheScripts::DrawDebugAngledCube(float, float, float, float, float, float, float, float, float, float) { EAXJMP(0x4532F0); }
-WRAPPER void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2) { EAXJMP(0x4534E0); }
-WRAPPER void CTheScripts::RenderTheScriptDebugLines() { EAXJMP(0x453550); }
+uint32 DbgLineColour = 0x0000FFFF; // r = 0, g = 0, b = 255, a = 255
+
+void CTheScripts::DrawDebugSquare(float infX, float infY, float supX, float supY)
+{
+	CColPoint tmpCP;
+	CEntity* tmpEP;
+	CVector p1, p2, p3, p4;
+	p1 = CVector(infX, infY, -1000.0f);
+	CWorld::ProcessVerticalLine(p1, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+	p1.z = 2.0f + tmpCP.point.z;
+	p2 = CVector(supX, supY, -1000.0f);
+	CWorld::ProcessVerticalLine(p2, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+	p2.z = 2.0f + tmpCP.point.z;
+	p3 = CVector(infX, supY, -1000.0f);
+	CWorld::ProcessVerticalLine(p3, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+	p3.z = 2.0f + tmpCP.point.z;
+	p4 = CVector(supX, infY, -1000.0f);
+	CWorld::ProcessVerticalLine(p4, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+	p4.z = 2.0f + tmpCP.point.z;
+	CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(p2.x, p2.y, p2.z, p3.x, p3.y, p3.z, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(p3.x, p3.y, p3.z, p4.x, p4.y, p4.z, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(p4.x, p4.y, p4.z, p1.x, p1.y, p1.z, DbgLineColour, DbgLineColour);
+}
+
+void CTheScripts::DrawDebugAngledSquare(float infX, float infY, float supX, float supY, float rotSupX, float rotSupY, float rotInfX, float rotInfY)
+{
+	CColPoint tmpCP;
+	CEntity* tmpEP;
+	CVector p1, p2, p3, p4;
+	p1 = CVector(infX, infY, -1000.0f);
+	CWorld::ProcessVerticalLine(p1, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+	p1.z = 2.0f + tmpCP.point.z;
+	p2 = CVector(supX, supY, -1000.0f);
+	CWorld::ProcessVerticalLine(p2, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+	p2.z = 2.0f + tmpCP.point.z;
+	p3 = CVector(rotSupX, rotSupY, -1000.0f);
+	CWorld::ProcessVerticalLine(p3, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+	p3.z = 2.0f + tmpCP.point.z;
+	p4 = CVector(rotInfX, rotInfY, -1000.0f);
+	CWorld::ProcessVerticalLine(p4, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+	p4.z = 2.0f + tmpCP.point.z;
+	CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(p2.x, p2.y, p2.z, p3.x, p3.y, p3.z, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(p3.x, p3.y, p3.z, p4.x, p4.y, p4.z, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(p4.x, p4.y, p4.z, p1.x, p1.y, p1.z, DbgLineColour, DbgLineColour);
+}
+
+void CTheScripts::DrawDebugCube(float infX, float infY, float infZ, float supX, float supY, float supZ)
+{
+	CTheScripts::ScriptDebugLine3D(infX, infY, infZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(supX, infY, infZ, supX, supY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(supX, supY, infZ, infX, supY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(infX, supY, infZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(infX, infY, supZ, supX, infY, supZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(supX, infY, supZ, supX, supY, supZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(supX, supY, supZ, infX, supY, supZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(infX, supY, supZ, infX, infY, supZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(infX, infY, supZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(supX, infY, supZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(supX, supY, supZ, supX, supY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(infX, supY, supZ, infX, supY, infZ, DbgLineColour, DbgLineColour);
+}
+
+void CTheScripts::DrawDebugAngledCube(float infX, float infY, float infZ, float supX, float supY, float supZ, float rotSupX, float rotSupY, float rotInfX, float rotInfY)
+{
+	CTheScripts::ScriptDebugLine3D(infX, infY, infZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(supX, infY, infZ, rotSupX, rotSupY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(rotSupX, rotSupY, infZ, rotInfX, rotInfY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(rotInfX, rotInfY, infZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(infX, infY, supZ, supX, infY, supZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(supX, infY, supZ, rotSupX, rotSupY, supZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(rotSupX, rotSupY, rotInfX, rotInfY, supY, supZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(rotInfX, rotInfY, supZ, infX, infY, supZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(infX, infY, supZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(supX, infY, supZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(rotSupX, rotSupY, supZ, rotSupX, rotSupY, infZ, DbgLineColour, DbgLineColour);
+	CTheScripts::ScriptDebugLine3D(rotInfX, rotInfY, supZ, rotInfX, rotInfY, infZ, DbgLineColour, DbgLineColour);
+}
+
+void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, uint32 col, uint32 col2)
+{
+	if (NumScriptDebugLines >= MAX_NUM_STORED_LINES)
+		return;
+	aStoredLines[NumScriptDebugLines].vecInf = CVector(x1, y1, z1);
+	aStoredLines[NumScriptDebugLines].vecSup = CVector(x2, y2, z2);
+	aStoredLines[NumScriptDebugLines].color1 = col;
+	aStoredLines[NumScriptDebugLines++].color2 = col2;
+}
+
+void CTheScripts::RenderTheScriptDebugLines()
+{
+	RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1);
+	RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)1);
+	for (int i = 0; i < NumScriptDebugLines; i++) {
+		CLines::RenderLineWithClipping(
+			aStoredLines[i].vecInf.x,
+			aStoredLines[i].vecInf.y,
+			aStoredLines[i].vecInf.z,
+			aStoredLines[i].vecSup.x,
+			aStoredLines[i].vecSup.y,
+			aStoredLines[i].vecSup.z,
+			aStoredLines[i].color1,
+			aStoredLines[i].color2);
+	}
+	NumScriptDebugLines = 0;
+	RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)0);
+}
+
 WRAPPER void CTheScripts::SaveAllScripts(uint8*, uint32*) { EAXJMP(0x4535E0); }
 WRAPPER void CTheScripts::LoadAllScripts(uint8*, uint32) { EAXJMP(0x453B30); }
 WRAPPER void CTheScripts::ClearSpaceForMissionEntity(const CVector&, CEntity*) { EAXJMP(0x454060); }
@@ -10629,8 +11229,8 @@ InjectHook(0x439400, &CTheScripts::StartTestScript, PATCH_JUMP);
 InjectHook(0x439410, &CTheScripts::IsPlayerOnAMission, PATCH_JUMP);
 InjectHook(0x44FD10, &CTheScripts::UndoBuildingSwaps, PATCH_JUMP);
 InjectHook(0x44FD60, &CTheScripts::UndoEntityVisibilitySettings, PATCH_JUMP);
-//InjectHook(0x4534E0, &CTheScripts::ScriptDebugLine3D, PATCH_JUMP);
-//InjectHook(0x453550, &CTheScripts::RenderTheScriptDebugLines, PATCH_JUMP);
+InjectHook(0x4534E0, &CTheScripts::ScriptDebugLine3D, PATCH_JUMP);
+InjectHook(0x453550, &CTheScripts::RenderTheScriptDebugLines, PATCH_JUMP);
 //InjectHook(0x4535E0, &CTheScripts::SaveAllScripts, PATCH_JUMP);
 //InjectHook(0x453B30, &CTheScripts::LoadAllScripts, PATCH_JUMP);
 //InjectHook(0x454060, &CTheScripts::ClearSpaceForMissionEntity, PATCH_JUMP);
diff --git a/src/control/Script.h b/src/control/Script.h
index 5533c417..18d148bf 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -83,6 +83,14 @@ struct CScriptSphere
 	float m_fRadius;
 };
 
+struct CStoredLine
+{
+	CVector vecInf;
+	CVector vecSup;
+	uint32 color1;
+	uint32 color2;
+};
+
 enum {
 	CLEANUP_UNUSED = 0,
 	CLEANUP_CAR,
@@ -217,7 +225,8 @@ enum {
 	MAX_NUM_USED_OBJECTS = 200,
 	MAX_NUM_MISSION_SCRIPTS = 120,
 	MAX_NUM_BUILDING_SWAPS = 25,
-	MAX_NUM_INVISIBILITY_SETTINGS = 20
+	MAX_NUM_INVISIBILITY_SETTINGS = 20,
+	MAX_NUM_STORED_LINES = 1024
 };
 
 class CTheScripts
@@ -235,6 +244,7 @@ class CTheScripts
 	static int32(&MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS];
 	static tBuildingSwap(&BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS];
 	static CEntity*(&InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS];
+	static CStoredLine(&aStoredLines)[MAX_NUM_STORED_LINES];
 	static bool &DbgFlag;
 	static uint32 &OnAMissionFlag;
 	static CMissionCleanup &MissionCleanup;
@@ -258,7 +268,7 @@ class CTheScripts
 	static uint16 &NumScriptDebugLines;
 	static uint16 &NumberOfIntroRectanglesThisFrame;
 	static uint16 &NumberOfIntroTextLinesThisFrame;
-	static bool &UseTextCommands;
+	static uint8 &UseTextCommands;
 	static uint16 &CommandsExecuted;
 	static uint16 &ScriptsUpdated;
 
@@ -273,7 +283,7 @@ public:
 	static void UndoBuildingSwaps();
 	static void UndoEntityVisibilitySettings();
 
-	static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2);
+	static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, uint32 col, uint32 col2);
 	static void RenderTheScriptDebugLines();
 
 	static void SaveAllScripts(uint8*, uint32*);
diff --git a/src/core/main.cpp b/src/core/main.cpp
index 2f266a9e..90afff72 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -48,6 +48,7 @@
 #include "RpAnimBlend.h"
 #include "Frontend.h"
 #include "AnimViewer.h"
+#include "Script.h"
 
 #define DEFAULT_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f)))
 
@@ -356,7 +357,7 @@ RenderScene(void)
 void
 RenderDebugShit(void)
 {
-	// CTheScripts::RenderTheScriptDebugLines()
+	CTheScripts::RenderTheScriptDebugLines();
 	if(gbShowCollisionLines)
 		CRenderer::RenderCollisionLines();
 }

From 4d9853b0ce842dfa74e8ffa8ba652a90262bc2c1 Mon Sep 17 00:00:00 2001
From: Nikolay Korolev <nickvnuk@gmail.com>
Date: Mon, 24 Feb 2020 21:18:11 +0300
Subject: [PATCH 7/8] removed debug leftovers

---
 src/control/Script.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index b167ac54..dab68e5a 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -704,9 +704,6 @@ int8 CRunningScript::ProcessOneCommand()
 	int32 command = Read2BytesFromScript(&m_nIp);
 	m_bNotFlag = (command & 0x8000);
 	command &= 0x7FFF;
-	if (command >= 1000)
-		debug("Time: %d, Script: %s, Command: %d\n", CTheScripts::CommandsExecuted, m_abScriptName, command);
-	debug("IntroSomething: %d\n", CTheScripts::NumberOfIntroTextLinesThisFrame);
 	if (command < 100)
 		return ProcessCommands0To99(command);
 	if (command < 200)

From 5eccf44e7a4c7628beac2faaa87cbe9560133ff8 Mon Sep 17 00:00:00 2001
From: Nikolay Korolev <nickvnuk@gmail.com>
Date: Sun, 1 Mar 2020 17:42:47 +0300
Subject: [PATCH 8/8] review fixes

---
 src/control/Script.cpp | 267 +++++++++++++++++++++--------------------
 src/control/Script.h   |  67 +++++------
 2 files changed, 169 insertions(+), 165 deletions(-)

diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index acecc863..b8add76a 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -385,25 +385,30 @@ void CRunningScript::CollectParameters(uint32* pIp, int16 total)
 {
 	for (int16 i = 0; i < total; i++){
 		float tmp;
-		switch (Read1ByteFromScript(pIp))
+		uint16 varIndex;
+		switch (CTheScripts::Read1ByteFromScript(pIp))
 		{
 		case ARGUMENT_INT32:
-			ScriptParams[i] = Read4BytesFromScript(pIp);
+			ScriptParams[i] = CTheScripts::Read4BytesFromScript(pIp);
 			break;
 		case ARGUMENT_GLOBALVAR:
-			ScriptParams[i] = *((int32*)&CTheScripts::ScriptSpace[Read2BytesFromScript(pIp)]);
+			varIndex = CTheScripts::Read2BytesFromScript(pIp);
+			assert(varIndex >= 8 && varIndex < CTheScripts::GetSizeOfVariableSpace());
+			ScriptParams[i] = *((int32*)&CTheScripts::ScriptSpace[varIndex]);
 			break;
 		case ARGUMENT_LOCALVAR:
-			ScriptParams[i] = m_anLocalVariables[Read2BytesFromScript(pIp)];
+			varIndex = CTheScripts::Read2BytesFromScript(pIp);
+			assert(varIndex >= 0 && varIndex < ARRAY_SIZE(m_anLocalVariables));
+			ScriptParams[i] = m_anLocalVariables[varIndex];
 			break;
 		case ARGUMENT_INT8:
-			ScriptParams[i] = Read1ByteFromScript(pIp);
+			ScriptParams[i] = CTheScripts::Read1ByteFromScript(pIp);
 			break;
 		case ARGUMENT_INT16:
-			ScriptParams[i] = Read2BytesFromScript(pIp);
+			ScriptParams[i] = CTheScripts::Read2BytesFromScript(pIp);
 			break;
 		case ARGUMENT_FLOAT:
-			tmp = ReadFloatFromScript(pIp);
+			tmp = CTheScripts::ReadFloatFromScript(pIp);
 			ScriptParams[i] = *(int32*)&tmp;
 			break;
 		default:
@@ -417,20 +422,20 @@ int32 CRunningScript::CollectNextParameterWithoutIncreasingPC(uint32 ip)
 {
 	uint32* pIp = &ip;
 	float tmp;
-	switch (Read1ByteFromScript(pIp))
+	switch (CTheScripts::Read1ByteFromScript(pIp))
 	{
 	case ARGUMENT_INT32:
-		return Read4BytesFromScript(pIp);
+		return CTheScripts::Read4BytesFromScript(pIp);
 	case ARGUMENT_GLOBALVAR:
-		return *((int32*)&CTheScripts::ScriptSpace[Read2BytesFromScript(pIp)]);
+		return *((int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)]);
 	case ARGUMENT_LOCALVAR:
-		return m_anLocalVariables[Read2BytesFromScript(pIp)];
+		return m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)];
 	case ARGUMENT_INT8:
-		return Read1ByteFromScript(pIp);
+		return CTheScripts::Read1ByteFromScript(pIp);
 	case ARGUMENT_INT16:
-		return Read2BytesFromScript(pIp);
+		return CTheScripts::Read2BytesFromScript(pIp);
 	case ARGUMENT_FLOAT:
-		tmp = ReadFloatFromScript(pIp);
+		tmp = CTheScripts::ReadFloatFromScript(pIp);
 		return *(int32*)&tmp;
 	default:
 		assert(0);
@@ -441,12 +446,12 @@ int32 CRunningScript::CollectNextParameterWithoutIncreasingPC(uint32 ip)
 void CRunningScript::StoreParameters(uint32* pIp, int16 number)
 {
 	for (int16 i = 0; i < number; i++){
-		switch (Read1ByteFromScript(pIp)) {
+		switch (CTheScripts::Read1ByteFromScript(pIp)) {
 		case ARGUMENT_GLOBALVAR:
-			*(int32*)&CTheScripts::ScriptSpace[Read2BytesFromScript(pIp)] = ScriptParams[i];
+			*(int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)] = ScriptParams[i];
 			break;
 		case ARGUMENT_LOCALVAR:
-			m_anLocalVariables[Read2BytesFromScript(pIp)] = ScriptParams[i];
+			m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)] = ScriptParams[i];
 			break;
 		default:
 			assert(0);
@@ -456,14 +461,14 @@ void CRunningScript::StoreParameters(uint32* pIp, int16 number)
 
 int32 *CRunningScript::GetPointerToScriptVariable(uint32* pIp, int16 type)
 {
-	switch (Read1ByteFromScript(pIp))
+	switch (CTheScripts::Read1ByteFromScript(pIp))
 	{
 	case ARGUMENT_GLOBALVAR:
 		assert(type == VAR_GLOBAL);
-		return (int32*)&CTheScripts::ScriptSpace[Read2BytesFromScript(pIp)];
+		return (int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)];
 	case ARGUMENT_LOCALVAR:
 		assert(type == VAR_LOCAL);
-		return &m_anLocalVariables[Read2BytesFromScript(pIp)];
+		return &m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)];
 	default:
 		assert(0);
 	}
@@ -701,7 +706,7 @@ void CRunningScript::Process()
 int8 CRunningScript::ProcessOneCommand()
 {
 	++CTheScripts::CommandsExecuted;
-	int32 command = Read2BytesFromScript(&m_nIp);
+	int32 command = CTheScripts::Read2BytesFromScript(&m_nIp);
 	m_bNotFlag = (command & 0x8000);
 	command &= 0x7FFF;
 	if (command < 100)
@@ -1229,27 +1234,27 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
 		CollectParameters(&m_nIp, 1);
 		assert(ScriptParams[0] >= 0);
 		CRunningScript* pNew = CTheScripts::StartNewScript(ScriptParams[0]);
-		int8 type = Read1ByteFromScript(&m_nIp);
+		int8 type = CTheScripts::Read1ByteFromScript(&m_nIp);
 		float tmp;
-		for (int i = 0; type != ARGUMENT_END; type = Read1ByteFromScript(&m_nIp), i++) {
+		for (int i = 0; type != ARGUMENT_END; type = CTheScripts::Read1ByteFromScript(&m_nIp), i++) {
 			switch (type) {
 			case ARGUMENT_INT32:
-				pNew->m_anLocalVariables[i] = Read4BytesFromScript(&m_nIp);
+				pNew->m_anLocalVariables[i] = CTheScripts::Read4BytesFromScript(&m_nIp);
 				break;
 			case ARGUMENT_GLOBALVAR:
-				pNew->m_anLocalVariables[i] = *(int32*)&CTheScripts::ScriptSpace[Read2BytesFromScript(&m_nIp)];
+				pNew->m_anLocalVariables[i] = *(int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(&m_nIp)];
 				break;
 			case ARGUMENT_LOCALVAR:
-				pNew->m_anLocalVariables[i] = m_anLocalVariables[Read2BytesFromScript(&m_nIp)];
+				pNew->m_anLocalVariables[i] = m_anLocalVariables[CTheScripts::Read2BytesFromScript(&m_nIp)];
 				break;
 			case ARGUMENT_INT8:
-				pNew->m_anLocalVariables[i] = Read1ByteFromScript(&m_nIp);
+				pNew->m_anLocalVariables[i] = CTheScripts::Read1ByteFromScript(&m_nIp);
 				break;
 			case ARGUMENT_INT16:
-				pNew->m_anLocalVariables[i] = Read2BytesFromScript(&m_nIp);
+				pNew->m_anLocalVariables[i] = CTheScripts::Read2BytesFromScript(&m_nIp);
 				break;
 			case ARGUMENT_FLOAT:
-				tmp = ReadFloatFromScript(&m_nIp);
+				tmp = CTheScripts::ReadFloatFromScript(&m_nIp);
 				pNew->m_anLocalVariables[i] = *(int32*)&tmp;
 				break;
 			default:
@@ -2671,7 +2676,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
 		CollectParameters(&m_nIp, 1);
 		CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]];
 		char label[12];
-		ReadTextLabelFromScript(&m_nIp, label);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
 		int zoneToCheck = CTheZones::FindZoneByLabelAndReturnIndex(label);
 		if (zoneToCheck != -1)
 			m_nIp += KEY_LENGTH_IN_SCRIPT; /* why only if zone != 1? */
@@ -2966,7 +2971,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	}
 	case COMMAND_ADD_PAGER_MESSAGE:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 3);
 		CUserDisplay::Pager.AddMessage(text, ScriptParams[0], ScriptParams[1], ScriptParams[2]);
 		return 0;
@@ -2975,21 +2980,21 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
 		m_nIp++;
-		CUserDisplay::OnscnTimer.AddClock(Read2BytesFromScript(&m_nIp), nil);
+		CUserDisplay::OnscnTimer.AddClock(CTheScripts::Read2BytesFromScript(&m_nIp), nil);
 		return 0;
 	}
 	case COMMAND_CLEAR_ONSCREEN_TIMER:
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
 		m_nIp++;
-		CUserDisplay::OnscnTimer.ClearClock(Read2BytesFromScript(&m_nIp));
+		CUserDisplay::OnscnTimer.ClearClock(CTheScripts::Read2BytesFromScript(&m_nIp));
 		return 0;
 	}
 	case COMMAND_DISPLAY_ONSCREEN_COUNTER:
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
 		m_nIp++;
-		int32 counter = Read2BytesFromScript(&m_nIp);
+		int32 counter = CTheScripts::Read2BytesFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 1);
 		CUserDisplay::OnscnTimer.AddCounter(counter, ScriptParams[0], nil);
 		return 0;
@@ -2998,13 +3003,13 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
 		m_nIp++;
-		CUserDisplay::OnscnTimer.ClearCounter(Read2BytesFromScript(&m_nIp));
+		CUserDisplay::OnscnTimer.ClearCounter(CTheScripts::Read2BytesFromScript(&m_nIp));
 		return 0;
 	}
 	case COMMAND_SET_ZONE_CAR_INFO:
 	{
 		char label[12];
-		ReadTextLabelFromScript(&m_nIp, label);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
 		m_nIp += KEY_LENGTH_IN_SCRIPT;
 		CollectParameters(&m_nIp, 16);
 		int zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
@@ -3027,7 +3032,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 		CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
 		assert(pPed);
 		char label[12];
-		ReadTextLabelFromScript(&m_nIp, label);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
 		int zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
 		if (zone != -1)
 			m_nIp += KEY_LENGTH_IN_SCRIPT;
@@ -3038,7 +3043,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	case COMMAND_SET_CAR_DENSITY:
 	{
 		char label[12];
-		ReadTextLabelFromScript(&m_nIp, label);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
 		int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
 		m_nIp += 8;
 		CollectParameters(&m_nIp, 2);
@@ -3052,7 +3057,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	case COMMAND_SET_PED_DENSITY:
 	{
 		char label[12];
-		ReadTextLabelFromScript(&m_nIp, label);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
 		int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
 		m_nIp += KEY_LENGTH_IN_SCRIPT;
 		CollectParameters(&m_nIp, 2);
@@ -3095,7 +3100,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	case COMMAND_SET_ZONE_PED_INFO:
 	{
 		char label[12];
-		ReadTextLabelFromScript(&m_nIp, label);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
 		m_nIp += KEY_LENGTH_IN_SCRIPT;
 		CollectParameters(&m_nIp, 10);
 		int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
@@ -3387,11 +3392,11 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
 	case COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE:
 	*/
 	case COMMAND_DECLARE_MISSION_FLAG:
-		CTheScripts::OnAMissionFlag = Read2BytesFromScript(&++m_nIp);
+		CTheScripts::OnAMissionFlag = CTheScripts::Read2BytesFromScript(&++m_nIp);
 		return 0;
 	case COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT:
 		CollectParameters(&m_nIp, 1);
-		CTheScripts::OnAMissionForContactFlag[ScriptParams[0]] = Read2BytesFromScript(&++m_nIp);
+		CTheScripts::OnAMissionForContactFlag[ScriptParams[0]] = CTheScripts::Read2BytesFromScript(&++m_nIp);
 		return 0;
 	case COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT:
 		CollectParameters(&m_nIp, 2);
@@ -4201,21 +4206,21 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
 	}
 	case COMMAND_PRINT_WITH_NUMBER_BIG:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 3);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[1], ScriptParams[2] - 1, ScriptParams[0], -1, -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_NUMBER:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 3);
 		CMessages::AddMessageWithNumber(text, ScriptParams[1], ScriptParams[2], ScriptParams[0], -1, -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_NUMBER_NOW:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 3);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[1], ScriptParams[2], ScriptParams[0], -1, -1, -1, -1, -1);
 		return 0;
@@ -4405,7 +4410,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
 	}
 	case COMMAND_ADD_PAGER_MESSAGE_WITH_NUMBER:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 4);
 		CUserDisplay::Pager.AddMessageWithNumber(text, ScriptParams[0], -1, -1, -1, -1, -1,
 			ScriptParams[1], ScriptParams[2], ScriptParams[3]);
@@ -4413,7 +4418,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
 	}
 	case COMMAND_START_KILL_FRENZY:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CDarkel::StartFrenzy((eWeaponType)ScriptParams[0], ScriptParams[1], ScriptParams[2],
 			ScriptParams[3], text, ScriptParams[4], ScriptParams[5],
@@ -4590,14 +4595,14 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
 	}
 	case COMMAND_PRINT_BIG_Q:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 2);
 		CMessages::AddBigMessageQ(text, ScriptParams[0], ScriptParams[1] - 1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_NUMBER_BIG_Q:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 3);
 		CMessages::AddBigMessageWithNumberQ(text, ScriptParams[1], ScriptParams[2] - 1,
 			ScriptParams[0], -1, -1, -1, -1, -1);
@@ -5114,14 +5119,14 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
 	case COMMAND_SET_REPEATED_PHONE_MESSAGE:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text, nil, nil, nil, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_PHONE_MESSAGE:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text, nil, nil, nil, nil, nil);
 		return 0;
 	}
@@ -6191,105 +6196,105 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
 	}
 	case COMMAND_PRINT_WITH_2_NUMBERS:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 4);
 		CMessages::AddMessageWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_2_NUMBERS_NOW:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 4);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_2_NUMBERS_SOON:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 4);
 		CMessages::AddMessageSoonWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_3_NUMBERS:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 5);
 		CMessages::AddMessageWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_3_NUMBERS_NOW:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 5);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_3_NUMBERS_SOON:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 5);
 		CMessages::AddMessageSoonWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_4_NUMBERS:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 6);
 		CMessages::AddMessageWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_4_NUMBERS_NOW:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 6);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_4_NUMBERS_SOON:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 6);
 		CMessages::AddMessageSoonWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_5_NUMBERS:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 7);
 		CMessages::AddMessageWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_5_NUMBERS_NOW:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 7);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_5_NUMBERS_SOON:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 7);
 		CMessages::AddMessageSoonWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_6_NUMBERS:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CMessages::AddMessageWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_6_NUMBERS_NOW:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CMessages::AddMessageJumpQWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_6_NUMBERS_SOON:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CMessages::AddMessageSoonWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]);
 		return 0;
@@ -6485,7 +6490,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	case COMMAND_SET_ZONE_GROUP:
 	{
 		char zone[KEY_LENGTH_IN_SCRIPT];
-		ReadTextLabelFromScript(&m_nIp, zone);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
 		m_nIp += KEY_LENGTH_IN_SCRIPT;
 		CollectParameters(&m_nIp, 2);
 		int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone);
@@ -6547,7 +6552,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	case COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_ZONE:
 	{
 		char zone[KEY_LENGTH_IN_SCRIPT];
-		ReadTextLabelFromScript(&m_nIp, zone);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
 		int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone);
 		if (zone_id != -1)
 			m_nIp += KEY_LENGTH_IN_SCRIPT;
@@ -6746,7 +6751,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	case COMMAND_DISPLAY_TEXT:
 	{
 		CollectParameters(&m_nIp, 2);
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
 		uint16 len = CMessages::GetWideStringLength(text);
@@ -6991,7 +6996,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 		CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
 		assert(pPed);
 		char name[KEY_LENGTH_IN_SCRIPT];
-		ReadTextLabelFromScript(&m_nIp, name);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, name);
 		for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
 			name[i] = tolower(name[i]);
 		int mi = pPed->GetModelIndex();
@@ -7053,7 +7058,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	{
 		CollectParameters(&m_nIp, 1);
 		char zone[KEY_LENGTH_IN_SCRIPT];
-		ReadTextLabelFromScript(&m_nIp, zone);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
 		int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone);
 		if (zone_id != -1)
 			m_nIp += KEY_LENGTH_IN_SCRIPT;
@@ -7234,7 +7239,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	}
 	case COMMAND_START_KILL_FRENZY_HEADSHOT:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CDarkel::StartFrenzy((eWeaponType)ScriptParams[0], ScriptParams[1], ScriptParams[2],
 			ScriptParams[3], text, ScriptParams[4], ScriptParams[5],
@@ -7288,35 +7293,35 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	//case COMMAND_SET_AUDIO_STREAM:
 	case COMMAND_PRINT_WITH_2_NUMBERS_BIG:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 4);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[2], ScriptParams[3] - 1, ScriptParams[0], ScriptParams[1], -1, -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_3_NUMBERS_BIG:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 5);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[3], ScriptParams[4] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_4_NUMBERS_BIG:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 6);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[4], ScriptParams[5] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_5_NUMBERS_BIG:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 7);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[5], ScriptParams[6] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
 		return 0;
 	}
 	case COMMAND_PRINT_WITH_6_NUMBERS_BIG:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 8);
 		CMessages::AddBigMessageWithNumber(text, ScriptParams[6], ScriptParams[7] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]);
 		return 0;
@@ -7338,8 +7343,8 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 		return 0;
 	case COMMAND_PRINT_STRING_IN_STRING:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
-		wchar* string = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* string = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 2);
 		CMessages::AddMessageWithString(text, ScriptParams[0], ScriptParams[1], string);
 		return 0;
@@ -7394,54 +7399,54 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
 	case COMMAND_SET_2_REPEATED_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, nil, nil, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_2_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, nil, nil, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_3_REPEATED_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, nil, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_3_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, nil, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_4_REPEATED_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, nil, nil);
 		return 0;
 	}
 	case COMMAND_SET_4_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, nil, nil);
 		return 0;
 	}
@@ -7518,8 +7523,8 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 	switch (command) {
 	case COMMAND_PRINT_STRING_IN_STRING_NOW:
 	{
-		wchar* source = GetTextByKeyFromScript(&m_nIp);
-		wchar* pstr = GetTextByKeyFromScript(&m_nIp);
+		wchar* source = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* pstr = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 2);
 		CMessages::AddMessageJumpQWithString(source, ScriptParams[0], ScriptParams[1], pstr);
 		return 0;
@@ -7528,46 +7533,46 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 	case COMMAND_SET_5_REPEATED_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text5 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, text5, nil);
 		return 0;
 	}
 	case COMMAND_SET_5_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text5 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, text5, nil);
 		return 0;
 	}
 	case COMMAND_SET_6_REPEATED_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text5 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text6 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text6 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, text5, text6);
 		return 0;
 	}
 	case COMMAND_SET_6_PHONE_MESSAGES:
 	{
 		CollectParameters(&m_nIp, 1);
-		wchar* text1 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text2 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text3 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text4 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text5 = GetTextByKeyFromScript(&m_nIp);
-		wchar* text6 = GetTextByKeyFromScript(&m_nIp);
+		wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+		wchar* text6 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, text5, text6);
 		return 0;
 	}
@@ -8071,7 +8076,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 	case COMMAND_DISPLAY_ONSCREEN_TIMER_WITH_STRING:
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR);
-		int16 var = Read2BytesFromScript(&m_nIp);
+		int16 var = CTheScripts::Read2BytesFromScript(&m_nIp);
 		wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ???
 		strncpy(onscreen_str, (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
 		m_nIp += KEY_LENGTH_IN_SCRIPT;
@@ -8081,7 +8086,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 	case COMMAND_DISPLAY_ONSCREEN_COUNTER_WITH_STRING:
 	{
 		assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR);
-		int16 var = Read2BytesFromScript(&m_nIp);
+		int16 var = CTheScripts::Read2BytesFromScript(&m_nIp);
 		CollectParameters(&m_nIp, 1);
 		wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ???
 		strncpy(onscreen_str, (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
@@ -8297,13 +8302,13 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 	}
 	case COMMAND_CLEAR_THIS_PRINT:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CMessages::ClearThisPrint(text);
 		return 0;
 	}
 	case COMMAND_CLEAR_THIS_BIG_PRINT:
 	{
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CMessages::ClearThisBigPrint(text);
 		return 0;
 	}
@@ -8393,7 +8398,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
 			m_nIp += KEY_LENGTH_IN_SCRIPT;
 			return 0;
 		}
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CHud::SetHelpMessage(text, false);
 		return 0;
 	}
@@ -9134,7 +9139,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
 		CTimer::Update();
 		return 0;
 	case COMMAND_LOAD_SPLASH_SCREEN:
-		ReadTextLabelFromScript(&m_nIp, tmp);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp);
 		for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
 			tmp[i] = tolower(tmp[i]);
 		m_nIp += 8;
@@ -9236,7 +9241,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
 	}
 	case COMMAND_TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME:
 	{
-		ReadTextLabelFromScript(&m_nIp, tmp);
+		CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp);
 		for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
 			tmp[i] = tolower(tmp[i]);
 		m_nIp += 8;
@@ -9254,7 +9259,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
 	case COMMAND_DISPLAY_TEXT_WITH_NUMBER:
 	{
 		CollectParameters(&m_nIp, 2);
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
 		CollectParameters(&m_nIp, 1);
@@ -9265,7 +9270,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
 	case COMMAND_DISPLAY_TEXT_WITH_2_NUMBERS:
 	{
 		CollectParameters(&m_nIp, 2);
-		wchar* text = GetTextByKeyFromScript(&m_nIp);
+		wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
 		CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
 		CollectParameters(&m_nIp, 2);
@@ -9680,7 +9685,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
 
 int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index)
 {
-	if (ScriptSphereArray[index].m_Index >= 0xFFFE)
+	if (ScriptSphereArray[index].m_Index >= UINT16_MAX - 1)
 		ScriptSphereArray[index].m_Index = 1;
 	else
 		ScriptSphereArray[index].m_Index++;
diff --git a/src/control/Script.h b/src/control/Script.h
index 18d148bf..59054be3 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -292,11 +292,43 @@ public:
 	static bool IsDebugOn() { return DbgFlag; };
 	static void InvertDebugFlag() { DbgFlag = !DbgFlag; }
 
-	static int32* GetPointerToScriptVariable(int32 offset) { return (int32*)&ScriptSpace[offset]; }
+	static int32* GetPointerToScriptVariable(int32 offset) { assert(offset >= 8 && offset < CTheScripts::GetSizeOfVariableSpace()); return (int32*)&ScriptSpace[offset]; }
 
 	static void ResetCountdownToMakePlayerUnsafe() { CountdownToMakePlayerUnsafe = 0; }
 	static bool IsCountdownToMakePlayerUnsafeOn() { return CountdownToMakePlayerUnsafe != 0; }
 
+	static int32 Read4BytesFromScript(uint32* pIp) {
+		int32 retval = ScriptSpace[*pIp + 3] << 24 | ScriptSpace[*pIp + 2] << 16 | ScriptSpace[*pIp + 1] << 8 | ScriptSpace[*pIp];
+		*pIp += 4;
+		return retval;
+	}
+	static int16 Read2BytesFromScript(uint32* pIp) {
+		int16 retval = ScriptSpace[*pIp + 1] << 8 | ScriptSpace[*pIp];
+		*pIp += 2;
+		return retval;
+	}
+	static int8 Read1ByteFromScript(uint32* pIp) {
+		int8 retval = ScriptSpace[*pIp];
+		*pIp += 1;
+		return retval;
+	}
+	static float ReadFloatFromScript(uint32* pIp) {
+		return Read2BytesFromScript(pIp) / 16.0f;
+	}
+	static void ReadTextLabelFromScript(uint32* pIp, char* buf) {
+		strncpy(buf, (const char*)&CTheScripts::ScriptSpace[*pIp], KEY_LENGTH_IN_SCRIPT);
+	}
+	static wchar* GetTextByKeyFromScript(uint32* pIp) {
+		wchar* text = TheText.Get((const char*)&CTheScripts::ScriptSpace[*pIp]);
+		*pIp += KEY_LENGTH_IN_SCRIPT;
+		return text;
+	}
+	static int32 GetSizeOfVariableSpace()
+	{
+		uint32 tmp = 3;
+		return Read4BytesFromScript(&tmp);
+	}
+
 private:
 
 	static CRunningScript* StartNewScript(uint32);
@@ -387,39 +419,6 @@ public:
 		m_anLocalVariables[NUM_LOCAL_VARS + 1] += timeStep;
 	}
 
-	static int32 Read4BytesFromScript(uint32* pIp) {
-		int32 retval = 0;
-		for (int i = 0; i < 4; i++) {
-			retval |= CTheScripts::ScriptSpace[(*pIp)++] << (8 * i);
-		}
-		return retval;
-	}
-	static int16 Read2BytesFromScript(uint32* pIp) {
-		int16 retval = 0;
-		for (int i = 0; i < 2; i++) {
-			retval |= CTheScripts::ScriptSpace[(*pIp)++] << (8 * i);
-		}
-		return retval;
-	}
-	static int8 Read1ByteFromScript(uint32* pIp) {
-		int8 retval = 0;
-		for (int i = 0; i < 1; i++) {
-			retval |= CTheScripts::ScriptSpace[(*pIp)++] << (8 * i);
-		}
-		return retval;
-	}
-	static float ReadFloatFromScript(uint32* pIp) {
-		return Read2BytesFromScript(pIp) / 16.0f;
-	}
-	static void ReadTextLabelFromScript(uint32* pIp, char* buf) {
-		strncpy(buf, (const char*)&CTheScripts::ScriptSpace[*pIp], KEY_LENGTH_IN_SCRIPT);
-	}
-	static wchar* GetTextByKeyFromScript(uint32* pIp) {
-		wchar* text = TheText.Get((const char*)&CTheScripts::ScriptSpace[*pIp]);
-		*pIp += KEY_LENGTH_IN_SCRIPT;
-		return text;
-	}
-
 	void Init();
 	void Process();