/*****************************************************************************\

  Copyright (C) 2013, Solarix <solarix.one1 at gmail dot com>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software subject to the 
  terms and conditions stated in Car Spawner - License.txt, and the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation is required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

\*****************************************************************************/
#include "SpeedoThread.h"
#include "../ScriptHook/ScriptHookManager.h"

#include <Windows.h>
#include <math.h>
#include <tchar.h>
#include <fstream>
#include <stack>
#include <time.h>

using namespace Scripting;

const float PI = 3.1415926535897932384626433832795f;
float PIX = float(atan(1)*4)/180.0f;

ch ScreenMessage[512];
Vehicle spawnedCars[31];
u32 spawnedCarz[31];
u32 arrsize_M = 0;
i32 attemptcounter = 0;
u32 NumberOfVehicles = 8;
u32 SpawnType = 2;
u32 counter = 0;
b8 DisableMod = false;
b8 Intro = true;
b8 ToggleControl = false;
b8 D3DHookHaveRendered = false;
b8 ToggleMenu = true;
b8 NotInGame = false;
b8 bDeleteAllSpawnedCars = false;
b8 bDeleteLastSpawnedCar = false;
b8 Control = false;
b8 ControlVar = true;
b8 bSpawnCar = false;
b8 CarGodMode = false;
b8 SimpleCarGodMode = false;
b8 FrozenCars = false;
b8 bFixCars = false;
b8 bFlipCars = false;
b8 bFreezeCars = false;
b8 bUnfreezeCars = false;
b8 bAddGodMode = false;
b8 bAddSimpleGodMode = false;
b8 bRemoveGodMode = false;
b8 bTeleportCars = false;
b8 bNewColors = false;
b8 bLockUnlockAllCarDoors = false;
b8 bAddBlips = false;
b8 bDestroyEngines = false;
b8 WaypointSpawning = false;
b8 Color = false;
b8 state = false, state3 = false;
u32 color1 = 0, color2 = 0, extra1 = 0, extra2 = 0;
eModel CarToSpawn;

SpeedoThread::SpeedoThread()
{
	SetName("Car Spawner");
}

Player SpeedoThread::GetPlayer()
{
	Player playerIndex = ConvertIntToPlayerIndex(GetPlayerId());
	return playerIndex;
}

Ped SpeedoThread::GetPlayerPed()
{
	Ped ped;
	GetPlayerChar(GetPlayer(), &ped);
	return ped;
}

Vehicle SpeedoThread::GetPlayerVehicle()
{
	Vehicle myveh;
	if (IsCharInAnyCar(GetPlayerPed()))
	{
		GetCarCharIsUsing(GetPlayerPed(),&myveh);
	}
	return myveh;
}

LPCWSTR *SpeedoThread::GetLiveUsername()
{
	LPCWSTR *LiveName = UNICODEGetPlayerName(GetPlayer());
	return LiveName;
}

void SpeedoThread::Print(const char* text, i32 time = 4000)
{
	ClearPrints();
	PrintStringWithLiteralStringNow("STRING",text,time,true);
	return;
}

b8 SpeedoThread::OwnRequestControlOfNetworkId(u32 netid)
{				
	if (!IsNetworkSession()) 
		return true;
	if (HasControlOfNetworkId(netid))
		return true;
	attemptcounter = 0;	
	while (!HasControlOfNetworkId(netid) &&  attemptcounter<1000) 
	{
		RequestControlOfNetworkId(netid);
		attemptcounter++;
		Wait(0);
	}	
	return HasControlOfNetworkId(netid);
}

void SpeedoThread::GetOffsetFromBlipInWorldCoords(Scripting::Blip blip, f32 x, f32 y, f32 z, f32 *pOffX, f32 *pOffY, f32 *pOffZ) //Not finished
{
	i32 attemptcounter1 = 0;
	GetBlipCoords(blip, pOffX,pOffY,pOffZ);
	*pOffX+=x;
	*pOffY+=y;
	*pOffZ+=z;
}

void SpeedoThread::ScriptedCarspawn(eModel model)
{
	u32 type, episode = GetCurrentEpisode(), tempsize = arrsize_M,maxsize = arrsize_M+NumberOfVehicles,rnd1,rnd2,rnd3,rnd4;
	Vehicle pveh;
	Ped ped = GetPlayerPed();
	f32 x,y,z,h;
	b8 max = false, alert = false;
	Blip b = GetFirstBlipInfoId(BLIP_WAYPOINT);
	i32 attemptcounter1 = 0;
	GetCharHeading(ped,&h);

	switch (SpawnType)
	{
		case 1:
			{
				type=1;
				break;
			}
		case 2:
			{
				type=2;
				break;
			}
		case 3:
			{
				type=3;
				break;
			}
		case 4:
			{
				type=4;
				break;
			}
	}
	if (IsModelInCDIMAGE(model))
	{
		if (type == 1)
		{
			if (arrsize_M < 32)
			{
				RequestModel(model);
				while(!HasModelLoaded(model))
					Wait(0);
				f32 a=4;
				if(WaypointSpawning && b.IsValid())
				{
					GetBlipCoords(b, &x,&y,&z);
					while(z == 0.0f)
					{
						GetGroundZFor3DCoord(x, y, 1000, &z);
						Wait(0);						
						if (++attemptcounter1 > 200) 
							break;
					}
				}
				else
					GetCharCoordinates(ped, &x, &y, &z);
				if (maxsize<=32)
				{
					for (u32 n=tempsize; arrsize_M<maxsize; ++n)
						if (!DoesVehicleExist(spawnedCars[n]))
						{
							if (model == MODEL_TUGA || model == MODEL_SKYLIFT || model == MODEL_ANNIHILATOR || model == MODEL_MAVERICK 
								|| model == MODEL_POLMAV || model == MODEL_TOURMAV || model == MODEL_BUZZARD || model == MODEL_SWIFT
								 || model == MODEL_MARQUIS || model == MODEL_PREDATOR || model == MODEL_PSTOCKADE || model == MODEL_NSTOCKADE
								  || model == MODEL_STOCKADE || model == MODEL_BUS || model == MODEL_TRASH || model == MODEL_AMBULANCE)
								++counter;
							if (counter>5)
							{
								counter = 5;
								alert = true;
								break;
							}
							CreateCar(model, x+(a*Sin((-1*h))), y+(a*Cos((-1*h))), z, &spawnedCars[n], true);
							if (!Color)
							{
								if (episode == 2)
								{
									GenerateRandomIntInRange(0,136,&rnd1);
									GenerateRandomIntInRange(0,136,&rnd2);
									GenerateRandomIntInRange(0,136,&rnd3);
									GenerateRandomIntInRange(0,136,&rnd4);
								}
								else
								{
									GenerateRandomIntInRange(0,133,&rnd1);
									GenerateRandomIntInRange(0,133,&rnd2);
									GenerateRandomIntInRange(0,133,&rnd3);
									GenerateRandomIntInRange(0,133,&rnd4);
								}
								ChangeCarColour(spawnedCars[n],rnd1,rnd2);
								SetExtraCarColours(spawnedCars[n],rnd3,rnd4);
							}
							else
							{
								ChangeCarColour(spawnedCars[n],color1,color2);
								SetExtraCarColours(spawnedCars[n],extra1,extra2);
							}
							if (CarGodMode)
							{
								SetCanBurstCarTyres(spawnedCars[n],false);
								SetCarStrong(spawnedCars[n],true);
								SetCarCanBeDamaged(spawnedCars[n],0);
								SetCarCanBeVisiblyDamaged(spawnedCars[n],0);
								SetCarProofs(spawnedCars[n],1,1,1,1,1);
								if (IsThisModelAHeli(model))
								{
									SetHeliBladesFullSpeed(spawnedCars[n]);
									SetHeliStabiliser(spawnedCars[n],1);
								}
							}
							if (SimpleCarGodMode)
							{
								SetCarCanBeDamaged(spawnedCars[n],0);
								SetCarCanBeVisiblyDamaged(spawnedCars[n],1);
							}
							if (FrozenCars)
								FreezeCarPosition(spawnedCars[n], 1);
							SetCarEngineOn(spawnedCars[n],true,true);
							SetCarHeading(spawnedCars[n],h);
							SetCarCoordinates(spawnedCars[n], x+(a*Sin((-1*h))), y+(a*Cos((-1*h))), z);
							if (!IsBigVehicle(spawnedCars[n]))
								a+=6.5f;
							else
								a+=13;
							GetNetworkIdFromVehicle(spawnedCars[n],&spawnedCarz[n]);
							++arrsize_M;
						}
				}
				else
				{
					sprintf_s(ScreenMessage,512,"~r~You can spawn only %u vehicles now or delete and spawn it again", 32-arrsize_M);
					Print(ScreenMessage, 2000);
					max = true;
				}
			}
			else
			{
				Print("~r~Max(32) vehicles have been created!");
				max = true;
			}
		}
		else if (type == 2)
		{
			if (arrsize_M < 32)
			{
				RequestModel(model);
				while(!HasModelLoaded(model))
					Wait(0);
				f32 p=0,radius=5;
				if(WaypointSpawning && b.IsValid())
				{
					GetBlipCoords(b, &x,&y,&z);
					while(z == 0.0f)
					{
						GetGroundZFor3DCoord(x, y, 1000, &z);
						Wait(0);						
						if (++attemptcounter1 > 200) 
							break;
					}
				}
				else
					GetCharCoordinates(ped, &x, &y, &z);
				if (maxsize<=32)
				{
					for (u32 n=tempsize; arrsize_M<maxsize; ++n)
					{
						if (p<360)
							p+=45;
						else
						{
							p=0;
							if (DoesVehicleExist(spawnedCars[n-1]))
							{
								if(IsBigVehicle(spawnedCars[n-1]))
									radius+=10;
								else
									radius+=7;
							}
							else
								radius+=7;
						}

						if (h<360)
							h+=40;
						else
							h-=360;

						if (!DoesVehicleExist(spawnedCars[n]))
						{
							if (model == MODEL_TUGA || model == MODEL_SKYLIFT || model == MODEL_ANNIHILATOR || model == MODEL_MAVERICK 
								|| model == MODEL_POLMAV || model == MODEL_TOURMAV || model == MODEL_BUZZARD || model == MODEL_SWIFT
								 || model == MODEL_MARQUIS || model == MODEL_PREDATOR || model == MODEL_PSTOCKADE || model == MODEL_NSTOCKADE
								  || model == MODEL_STOCKADE || model == MODEL_BUS || model == MODEL_TRASH || model == MODEL_AMBULANCE)
								++counter;
							if (counter>5)
							{
								counter = 5;
								alert = true;
								break;
							}
							CreateCar(model, x+cos(p*PI/180)*radius, y+sin(p*PI/180)*radius, z, &spawnedCars[n], true);
							if (!Color)
							{
								if (episode == 2)
								{
									GenerateRandomIntInRange(0,136,&rnd1);
									GenerateRandomIntInRange(0,136,&rnd2);
									GenerateRandomIntInRange(0,136,&rnd3);
									GenerateRandomIntInRange(0,136,&rnd4);
								}
								else
								{
									GenerateRandomIntInRange(0,133,&rnd1);
									GenerateRandomIntInRange(0,133,&rnd2);
									GenerateRandomIntInRange(0,133,&rnd3);
									GenerateRandomIntInRange(0,133,&rnd4);
								}
								ChangeCarColour(spawnedCars[n],rnd1,rnd2);
								SetExtraCarColours(spawnedCars[n],rnd3,rnd4);
							}
							else
							{
								ChangeCarColour(spawnedCars[n],color1,color2);
								SetExtraCarColours(spawnedCars[n],extra1,extra2);
							}
							if (CarGodMode)
							{
								SetCanBurstCarTyres(spawnedCars[n],false);
								SetCarStrong(spawnedCars[n],true);
								SetCarCanBeDamaged(spawnedCars[n],0);
								SetCarCanBeVisiblyDamaged(spawnedCars[n],0);
								SetCarProofs(spawnedCars[n],1,1,1,1,1);
								if (IsThisModelAHeli(model))
								{
									SetHeliBladesFullSpeed(spawnedCars[n]);
									SetHeliStabiliser(spawnedCars[n],1);
								}
							}
							if (SimpleCarGodMode)
							{
								SetCarCanBeDamaged(spawnedCars[n],0);
								SetCarCanBeVisiblyDamaged(spawnedCars[n],1);
							}
							if (FrozenCars)
								FreezeCarPosition(spawnedCars[n], 1);
							SetCarEngineOn(spawnedCars[n],true,true);
							SetCarHeading(spawnedCars[n],h);
							SetCarCoordinates(spawnedCars[n],x+cos(p*PI/180)*radius, y+sin(p*PI/180)*radius, z);
							GetNetworkIdFromVehicle(spawnedCars[n],&spawnedCarz[n]);
							++arrsize_M;
						}
					}
				}
				else
				{
					sprintf_s(ScreenMessage,512,"~r~You can spawn only %u vehicles now or delete and spawn it again", 32-arrsize_M);
					Print(ScreenMessage, 2000);
					max = true;
				}
			}
			else
			{
				Print("~r~Max(32) vehicles have been created!");
				max = true;
			}
		}
		else if (type == 3)
		{
			if (arrsize_M < 32)
			{
				RequestModel(model);
				while(!HasModelLoaded(model))
					Wait(0);
				if(WaypointSpawning && b.IsValid())
				{
					GetBlipCoords(b, &x,&y,&z);
					while(z == 0.0f)
					{
						GetGroundZFor3DCoord(x, y, 1000, &z);
						Wait(0);						
						if (++attemptcounter1 > 200) 
							break;
					}
					z+=2;
				}
				else
					GetOffsetFromCharInWorldCoords(ped, 0, 0, 2, &x, &y, &z);
				if (maxsize<=32)
				{
					for (u32 n=tempsize; arrsize_M<maxsize; ++n)
						if (!DoesVehicleExist(spawnedCars[n]))
						{
							if (model == MODEL_TUGA || model == MODEL_SKYLIFT || model == MODEL_ANNIHILATOR || model == MODEL_MAVERICK 
								|| model == MODEL_POLMAV || model == MODEL_TOURMAV || model == MODEL_BUZZARD || model == MODEL_SWIFT
								 || model == MODEL_MARQUIS || model == MODEL_PREDATOR || model == MODEL_PSTOCKADE || model == MODEL_NSTOCKADE
								  || model == MODEL_STOCKADE || model == MODEL_BUS || model == MODEL_TRASH || model == MODEL_AMBULANCE)
								++counter;
							if (counter>5)
							{
								counter = 5;
								alert = true;
								break;
							}
							z+=3;
							CreateCar(model, x, y, z, &spawnedCars[n], true);
							if (!Color)
							{
								if (episode == 2)
								{
									GenerateRandomIntInRange(0,136,&rnd1);
									GenerateRandomIntInRange(0,136,&rnd2);
									GenerateRandomIntInRange(0,136,&rnd3);
									GenerateRandomIntInRange(0,136,&rnd4);
								}
								else
								{
									GenerateRandomIntInRange(0,133,&rnd1);
									GenerateRandomIntInRange(0,133,&rnd2);
									GenerateRandomIntInRange(0,133,&rnd3);
									GenerateRandomIntInRange(0,133,&rnd4);
								}
								ChangeCarColour(spawnedCars[n],rnd1,rnd2);
								SetExtraCarColours(spawnedCars[n],rnd3,rnd4);
							}
							else
							{
								ChangeCarColour(spawnedCars[n],color1,color2);
								SetExtraCarColours(spawnedCars[n],extra1,extra2);
							}
							if (CarGodMode)
							{
								SetCanBurstCarTyres(spawnedCars[n],false);
								SetCarStrong(spawnedCars[n],true);
								SetCarCanBeDamaged(spawnedCars[n],0);
								SetCarCanBeVisiblyDamaged(spawnedCars[n],0);
								SetCarProofs(spawnedCars[n],1,1,1,1,1);
								if (IsThisModelAHeli(model))
								{
									SetHeliBladesFullSpeed(spawnedCars[n]);
									SetHeliStabiliser(spawnedCars[n],1);
								}
							}
							if (SimpleCarGodMode)
							{
								SetCarCanBeDamaged(spawnedCars[n],0);
								SetCarCanBeVisiblyDamaged(spawnedCars[n],1);
							}
							if (FrozenCars)
								FreezeCarPosition(spawnedCars[n], 1);
							SetCarEngineOn(spawnedCars[n],true,true);
							SetCarHeading(spawnedCars[n],h);
							SetCarCoordinates(spawnedCars[n], x, y, z);
							GetNetworkIdFromVehicle(spawnedCars[n],&spawnedCarz[n]);
							++arrsize_M;
						}
				}
				else
				{
					sprintf_s(ScreenMessage,512,"~r~You can spawn only %u vehicles now or delete and spawn it again", 32-arrsize_M);
					Print(ScreenMessage, 2000);
					max = true;
				}
			}
			else
			{
				Print("~r~Max(32) vehicles have been created!");
				max = true;
			}
		}
		else if (type == 4)
		{
			if (arrsize_M < 32)
			{
				RequestModel(model);
				while(!HasModelLoaded(model))
					Wait(0);
				f32 cX=0,cY=3,fZ;
				b8 ground = false;
				if (maxsize<=32)
				{
					for (u32 n=tempsize; arrsize_M<maxsize; ++n)
					{
						if (n==5 || n==10 || n==15 || n==20 || n==25 || n==30)
						{
							if(DoesVehicleExist(spawnedCars[n-1]))
								if(!IsBigVehicle(spawnedCars[n-1]))
								{
									cX=0;
									cY+=7;
								}
								else
								{
									cX=0;
									cY+=14;
								}
						}
						if (!DoesVehicleExist(spawnedCars[n]))
						{
							if (model == MODEL_TUGA || model == MODEL_SKYLIFT || model == MODEL_ANNIHILATOR || model == MODEL_MAVERICK 
								|| model == MODEL_POLMAV || model == MODEL_TOURMAV || model == MODEL_BUZZARD || model == MODEL_SWIFT
								 || model == MODEL_MARQUIS || model == MODEL_PREDATOR || model == MODEL_PSTOCKADE || model == MODEL_NSTOCKADE
								  || model == MODEL_STOCKADE || model == MODEL_BUS || model == MODEL_TRASH || model == MODEL_AMBULANCE)
								++counter;
							if (counter>5)
							{
								counter = 5;
								alert = true;
								break;
							}
							if(WaypointSpawning && b.IsValid())
							{
								if (!ground)
								{
									GetOffsetFromBlipInWorldCoords(b, cX, cY, 0, &x, &y, &z);
									while(z == 0.0f)
									{
										GetGroundZFor3DCoord(x, y, 1000, &z);
										Wait(0);						
										if (++attemptcounter1 > 200) 
											break;
									}
									ground = true;
								}
								GetOffsetFromBlipInWorldCoords(b, cX, cY, 0, &x, &y, &fZ);
							}
							else
								GetOffsetFromCharInWorldCoords(ped, cX, cY, 0, &x, &y, &z);
							cX+=4;
							CreateCar(model, x, y, z, &spawnedCars[n], true);
							if (!Color)
							{
								if (episode == 2)
								{
									GenerateRandomIntInRange(0,136,&rnd1);
									GenerateRandomIntInRange(0,136,&rnd2);
									GenerateRandomIntInRange(0,136,&rnd3);
									GenerateRandomIntInRange(0,136,&rnd4);
								}
								else
								{
									GenerateRandomIntInRange(0,133,&rnd1);
									GenerateRandomIntInRange(0,133,&rnd2);
									GenerateRandomIntInRange(0,133,&rnd3);
									GenerateRandomIntInRange(0,133,&rnd4);
								}
								ChangeCarColour(spawnedCars[n],rnd1,rnd2);
								SetExtraCarColours(spawnedCars[n],rnd3,rnd4);
							}
							else
							{
								ChangeCarColour(spawnedCars[n],color1,color2);
								SetExtraCarColours(spawnedCars[n],extra1,extra2);
							}
							if (CarGodMode)
							{
								SetCanBurstCarTyres(spawnedCars[n],false);
								SetCarStrong(spawnedCars[n],true);
								SetCarCanBeDamaged(spawnedCars[n],0);
								SetCarCanBeVisiblyDamaged(spawnedCars[n],0);
								SetCarProofs(spawnedCars[n],1,1,1,1,1);
								if (IsThisModelAHeli(model))
								{
									SetHeliBladesFullSpeed(spawnedCars[n]);
									SetHeliStabiliser(spawnedCars[n],1);
								}
							}
							if (SimpleCarGodMode)
							{
								SetCarCanBeDamaged(spawnedCars[n],0);
								SetCarCanBeVisiblyDamaged(spawnedCars[n],1);
							}
							if (FrozenCars)
								FreezeCarPosition(spawnedCars[n], 1);
							SetCarEngineOn(spawnedCars[n],true,true);
							SetCarHeading(spawnedCars[n],h);
							SetCarCoordinates(spawnedCars[n], x, y, z);
							GetNetworkIdFromVehicle(spawnedCars[n],&spawnedCarz[n]);
							++arrsize_M;
						}
					}
				}
				else
				{
					sprintf_s(ScreenMessage,512,"~r~You can spawn only %u vehicles now or delete and spawn it again", 32-arrsize_M);
					Print(ScreenMessage, 2000);
					max = true;
				}
			}
			else
			{
				Print("~r~Max(32) vehicles have been created!");
				max = true;
			}
		}
	}
	else
	{
		Print("Vehicle model not in your vehicle.img",2000);
		max = true;
	}
	if (alert)
	{
		Print ("~r~You cannot spawn more than 5 heavy vehicles");
		max = true;
	}
	if (arrsize_M <= 32 && !max)
		if (NumberOfVehicles>1)
			Print("~g~Vehicles spawned");
		else
			Print("~g~Vehicle spawned");
}

void SpeedoThread::FixAllSpawnedCars()
{
	u32 vehnetid, arrsize=0;
	b8 wrong = false, right = false;

	while (arrsize<=31) 
	{
		if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
			{
				GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
				FixCar(veh);
				for (u32 i=0; i<=10; ++i)
					if(IsCarTyreBurst(veh,i))
						FixCarTyre(veh,i);
				SetVehHazardLights(veh, 0);
				SetVehAlarm(veh,0);
				right = true;
			}
			else
				wrong = true;
		}
		else if(DoesVehicleExist(spawnedCars[arrsize]))
		{
			GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
			if (OwnRequestControlOfNetworkId(vehnetid)) 
			{
				FixCar(spawnedCars[arrsize]);
				for (u32 i=0; i<=10; ++i)
					if(IsCarTyreBurst(spawnedCars[arrsize],i))
						FixCarTyre(spawnedCars[arrsize],i);
				SetVehHazardLights(spawnedCars[arrsize],0);
				SetVehAlarm(spawnedCars[arrsize],0);
				right = true;
			}
			else
				wrong = true;
		}
		++arrsize;
	}
	if (!right && !wrong)
		Print("~r~No vehicles exist or available");
	else if (!wrong)
		Print("~g~All spawned vehicles have been fixed");
	else
		Print("~b~Not all spawned vehicles have been fixed (something went wrong)");
}

void SpeedoThread::FlipAllSpawnedCars()
{
	u32 vehnetid, arrsize=0;
	f32 head;
	b8 wrong = false, right = false;

	while (arrsize<=31) 
	{
		if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
			{
				GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
				GetCarHeading(veh, &head);
				SetCarHeading(veh, head);
				SetCarOnGroundProperly(veh);
				right = true;
			}
			else
				wrong = true;
		}
		else if(DoesVehicleExist(spawnedCars[arrsize]))
		{
			GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
			if (OwnRequestControlOfNetworkId(vehnetid)) 
			{
				GetCarHeading(spawnedCars[arrsize], &head);
				SetCarHeading(spawnedCars[arrsize], head);
				SetCarOnGroundProperly(spawnedCars[arrsize]);
				right = true;
			}
			else
				wrong = true;
		}
		++arrsize;
	}
	if (!right && !wrong)
		Print("~r~No vehicles exist or available");
	else if (!wrong)
		Print("~g~All the cars were located on the ground properly");
	else
		Print("~b~Not all the cars were located on the ground properly (something went wrong)");
}

void SpeedoThread::FreezeAllSpawnedCars()
{
	u32 vehnetid, arrsize=0;
	b8 wrong = false, right = false;

	while (arrsize<=31) 
	{
		if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
			{
				GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
				FreezeCarPosition(veh,1);
				right = true;
			}
			else
				wrong = true;
		}
		else if(DoesVehicleExist(spawnedCars[arrsize]))
		{
			GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
			if (OwnRequestControlOfNetworkId(vehnetid)) 
			{
				FreezeCarPosition(spawnedCars[arrsize],1);
				right = true;
			}
			else
				wrong = true;
		}
		++arrsize;
	}
	if (!right && !wrong)
		Print("~r~No vehicles exist or available");
	else if (!wrong)
		Print("~g~All spawned vehicles have been frozen");
	else
		Print("~b~Not all spawned vehicles have been frozen (something went wrong)");
}

void SpeedoThread::UnfreezeAllSpawnedCars()
{
	u32 vehnetid, arrsize=0;
	b8 wrong = false, right = false;

	while (arrsize<=31) 
	{
		if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
			{
				GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
				FreezeCarPosition(veh,0);
				right = true;
			}
			else
				wrong = true;
		}
		else if(DoesVehicleExist(spawnedCars[arrsize]))
		{
			GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
			if (OwnRequestControlOfNetworkId(vehnetid))
			{
				FreezeCarPosition(spawnedCars[arrsize],0);
				right = true;
			}
			else
				wrong = true;
		}
		++arrsize;
	}
	if (!right && !wrong)
		Print("~r~No vehicles exist or available");
	else if (!wrong)
		Print("~g~All spawned vehicles have been unfrozen");
	else
		Print("~b~Not all spawned vehicles have been unfrozen (something went wrong)");
}

void SpeedoThread::LockUnlockAllCarDoors()
{
	u32 vehnetid, arrsize=0;
	b8 wrong = false, right = false;

	if (!state && !state3)
	{
		while (arrsize<=31) 
		{
			if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
			{
				if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
				{
					GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
					LockCarDoors(spawnedCars[arrsize],VEHICLE_DOOR_LOCKED);
					right = true;
				}
				else
					wrong = true;
			}
			else if(DoesVehicleExist(spawnedCars[arrsize]))
			{
				GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
				if (OwnRequestControlOfNetworkId(vehnetid))
				{
					LockCarDoors(spawnedCars[arrsize],VEHICLE_DOOR_LOCKED);
					right = true;
				}
				else
					wrong = true;
			}
			++arrsize;
		}
		if (!right && !wrong)
			Print("~r~No vehicles exist or available");
		else if (!wrong)
		{
			Print("~g~All spawned vehicles have been locked");
			state = true;
		}
		else
		{
			Print("~b~Not all spawned vehicles have been locked");
			state = true;
		}
	}
	else if (state && !state3)
	{
		while (arrsize<=31) 
		{
			if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
			{
				if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
				{
					GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
					LockCarDoors(spawnedCars[arrsize],VEHICLE_DOOR_LOCKED_BOTH_SIDES);
					right = true;
				}
				else
					wrong = true;
			}
			else if(DoesVehicleExist(spawnedCars[arrsize]))
			{
				GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
				if (OwnRequestControlOfNetworkId(vehnetid))
				{
					LockCarDoors(spawnedCars[arrsize],VEHICLE_DOOR_LOCKED_BOTH_SIDES);
					right = true;
				}
				else
					wrong = true;
			}
			++arrsize;
		}
		if (!right && !wrong)
			Print("~r~No vehicles exist or available");
		else if (!wrong)
		{
			Print("~g~All spawned vehicles have been locked both sides");
			state3=true;
		}
		else
		{
			Print("~b~Not all spawned vehicles have been locked both sides");
			state3=true;
		}
	}
	else if (state && state3)
	{
		while (arrsize<=31) 
		{
			if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
			{
				if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
				{
					GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
					LockCarDoors(spawnedCars[arrsize],VEHICLE_DOOR_UNLOCKED);
					right = true;
				}
				else
					wrong = true;
			}
			else if(DoesVehicleExist(spawnedCars[arrsize]))
			{
				GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
				if (OwnRequestControlOfNetworkId(vehnetid))
				{
					LockCarDoors(spawnedCars[arrsize],VEHICLE_DOOR_UNLOCKED);
					right = true;
				}
				else
					wrong = true;
			}
			++arrsize;
		}
		if (!right && !wrong)
			Print("~r~No vehicles exist or available");
		else if (!wrong)
		{
			Print("~g~All spawned vehicles have been unlocked");
			state=false;
			state3=false;
		}
		else
		{
			Print("~b~Not all spawned vehicles have been unlocked");
			state=false;
			state3=false;
		}
	}
}

void SpeedoThread::AddBlips()
{
	u32 arrsize=0;
	b8 right = false;
	Blip blip;

	while (arrsize<=31) 
	{
		if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			AddBlipForCar(veh,&blip);
			ChangeBlipSprite(blip,BLIP_STATION_C);
			ChangeBlipScale(blip,0.5f);
			ChangeBlipAlpha(blip,128);
			right = true;
		}
		else if(DoesVehicleExist(spawnedCars[arrsize]))
		{
			AddBlipForCar(spawnedCars[arrsize],&blip);
			ChangeBlipSprite(blip,BLIP_STATION_C);
			ChangeBlipScale(blip,0.5f);
			ChangeBlipAlpha(blip,128);
			right = true;
		}
		++arrsize;
	}
	if (!right)
		Print("~r~No vehicles exist or available");
	else if (right)
		Print("~g~All spawned vehicles have a blip");
}

void SpeedoThread::DestroyEngines()
{
	u32 vehnetid, arrsize=0;
	b8 wrong = false, right = false;

	while (arrsize<=31) 
	{
		if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
			{
				GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
				SetCarEngineOn(veh,false,false);
				SetEngineHealth(veh,0);
				SetVehHazardLights(veh, 1);
				SetVehAlarm(veh,1);
				SetVehAlarmDuration(veh,30000);
				TriggerVehAlarm(veh);
				right = true;
			}
			else
				wrong = true;
		}
		else if(DoesVehicleExist(spawnedCars[arrsize]))
		{
			GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
			if (OwnRequestControlOfNetworkId(vehnetid)) 
			{
				SetCarEngineOn(spawnedCars[arrsize],false,false);
				SetEngineHealth(spawnedCars[arrsize],0);
				SetVehHazardLights(spawnedCars[arrsize], 1);
				SetVehAlarm(spawnedCars[arrsize],1);
				SetVehAlarmDuration(spawnedCars[arrsize],30000);
				TriggerVehAlarm(spawnedCars[arrsize]);
				right = true;
			}
			else
				wrong = true;
		}
		++arrsize;
	}
	if (!right && !wrong)
		Print("~r~No vehicles exist or available");
	else if (!wrong)
		Print("~g~Engines destroyed");
	else
		Print("~b~Not all engines destroyed (something went wrong)");
}

void SpeedoThread::AddGodMode()
{
	u32 vehnetid, arrsize=0;
	b8 wrong = false, right = false;
	eModel model;

	while (arrsize<=31) 
	{
		if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
			{
				GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
				GetCarModel(veh,&model);
				SetCanBurstCarTyres(veh,false);
				SetCarStrong(veh,true);
				SetCarCanBeDamaged(veh,false);
				SetCarCanBeVisiblyDamaged(veh,false);
				SetCarProofs(veh,true,true,true,true,true);
				if (IsThisModelAHeli(model))
				{
					SetHeliBladesFullSpeed(veh);
					SetHeliStabiliser(veh,true);
				}
				right = true;
			}
			else
				wrong = true;
		}
		else if(DoesVehicleExist(spawnedCars[arrsize]))
		{
			GetCarModel(spawnedCars[arrsize],&model);
			GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
			if (OwnRequestControlOfNetworkId(vehnetid))
			{
				SetCanBurstCarTyres(spawnedCars[arrsize],false);
				SetCarStrong(spawnedCars[arrsize],true);
				SetCarCanBeDamaged(spawnedCars[arrsize],false);
				SetCarCanBeVisiblyDamaged(spawnedCars[arrsize],false);
				SetCarProofs(spawnedCars[arrsize],true,true,true,true,true);
				if (IsThisModelAHeli(model))
				{
					SetHeliBladesFullSpeed(spawnedCars[arrsize]);
					SetHeliStabiliser(spawnedCars[arrsize],true);
				}
				right = true;
			}
			else
				wrong = true;
		}
		++arrsize;
	}
	if (!right && !wrong)
		Print("~r~No vehicles exist or available");
	else if (!wrong)
		Print("~g~All spawned vehicles is invincible now");
	else
		Print("~b~Not all spawned vehicles is invincible (something went wrong)");
}

void SpeedoThread::AddSimpleGodMode()
{
	u32 vehnetid, arrsize=0;
	b8 wrong = false, right = false;

	while (arrsize<=31) 
	{
		if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
			{
				GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
				SetCarCanBeDamaged(veh,false);
				SetCarCanBeVisiblyDamaged(veh,true);
				right = true;
			}
			else
				wrong = true;
		}
		else if(DoesVehicleExist(spawnedCars[arrsize]))
		{
			GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
			if (OwnRequestControlOfNetworkId(vehnetid))
			{
				SetCarCanBeDamaged(spawnedCars[arrsize],false);
				SetCarCanBeVisiblyDamaged(spawnedCars[arrsize],true);
				right = true;
			}
			else
				wrong = true;
		}
		++arrsize;
	}
	if (!right && !wrong)
		Print("~r~No vehicles exist or available");
	else if (!wrong)
		Print("~g~All spawned vehicles is invincible with visual damage");
	else
		Print("~b~Not all spawned vehicles is invincible&visual damage (something went wrong)");
}

void SpeedoThread::RemoveGodMode()
{
	u32 vehnetid, arrsize=0;
	b8 wrong = false, right = false;

	while (arrsize<=31) 
	{
		if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
			{
				GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
				SetCanBurstCarTyres(veh,true);
				SetCarStrong(veh,false);
				SetCarCanBeDamaged(veh,true);
				SetCarCanBeVisiblyDamaged(veh,true);
				SetCarProofs(veh,false,false,false,false,false);
				right = true;
			}
			else
				wrong = true;
		}
		else if(DoesVehicleExist(spawnedCars[arrsize]))
		{
			GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
			if (OwnRequestControlOfNetworkId(vehnetid))
			{
				SetCanBurstCarTyres(spawnedCars[arrsize],true);
				SetCarStrong(spawnedCars[arrsize],false);
				SetCarCanBeDamaged(spawnedCars[arrsize],true);
				SetCarCanBeVisiblyDamaged(spawnedCars[arrsize],true);
				SetCarProofs(spawnedCars[arrsize],false,false,false,false,false);
				right = true;
			}
			else
				wrong = true;
		}
		++arrsize;
	}
	if (!right && !wrong)
		Print("~r~No vehicles exist or available");
	else if (!wrong)
		Print("~g~All spawned vehicles isn't invincible now");
	else
		Print("~b~Not all spawned vehicles isn't invincible (something went wrong)");
}

void SpeedoThread::DeleteAllSpawnedCars()
{
	u32 vehnetid,arrsize=0;	
	eModel vehmodel;
	b8 wrong = false, right = false;
	
	while (arrsize<=31) 
	{
		if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
			{
				GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
				GetCarModel(veh, &vehmodel);
				DeleteCar(&veh);
				if (vehmodel == MODEL_TUGA || vehmodel == MODEL_SKYLIFT || vehmodel == MODEL_ANNIHILATOR || vehmodel == MODEL_MAVERICK 
					|| vehmodel == MODEL_POLMAV || vehmodel == MODEL_TOURMAV || vehmodel == MODEL_BUZZARD || vehmodel == MODEL_SWIFT
					 || vehmodel == MODEL_MARQUIS || vehmodel == MODEL_PREDATOR || vehmodel == MODEL_PSTOCKADE || vehmodel == MODEL_NSTOCKADE
					  || vehmodel == MODEL_STOCKADE || vehmodel == MODEL_BUS || vehmodel == MODEL_TRASH || vehmodel == MODEL_AMBULANCE)
					--counter;
				MarkModelAsNoLongerNeeded(vehmodel);
				right = true;
			}
			else
				wrong = true;
		}
		else if (DoesVehicleExist(spawnedCars[arrsize]))
		{
			GetCarModel(spawnedCars[arrsize], &vehmodel);
			GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
			if (OwnRequestControlOfNetworkId(vehnetid)) 
			{
				DeleteCar(&spawnedCars[arrsize]);
				if (vehmodel == MODEL_TUGA || vehmodel == MODEL_SKYLIFT || vehmodel == MODEL_ANNIHILATOR || vehmodel == MODEL_MAVERICK 
					|| vehmodel == MODEL_POLMAV || vehmodel == MODEL_TOURMAV || vehmodel == MODEL_BUZZARD || vehmodel == MODEL_SWIFT
					 || vehmodel == MODEL_MARQUIS || vehmodel == MODEL_PREDATOR || vehmodel == MODEL_PSTOCKADE || vehmodel == MODEL_NSTOCKADE
					  || vehmodel == MODEL_STOCKADE || vehmodel == MODEL_BUS || vehmodel == MODEL_TRASH || vehmodel == MODEL_AMBULANCE)
					--counter;
				MarkModelAsNoLongerNeeded(vehmodel);
				right = true;
			}
			else
				wrong = true;
		}
		++arrsize;
		if (arrsize == 32 && right && !wrong)
		{
			arrsize_M = 0;
			counter = 0;
		}
	}
	if (!right && !wrong)
		Print("~r~No vehicles exist or available");
	else if (!wrong)
		Print("~g~All spawned vehicles have been deleted");
	else
		Print("~b~Not all spawned vehicles have been deleted (something went wrong)");
}

void SpeedoThread::DeleteLastSpawnedCar() // Not finished!
{
	u32 vehnetid, arrsize=31;	
	eModel vehmodel;
	b8 right = false;

	while (arrsize>0) 
	{
		if(DoesVehicleExist(spawnedCars[arrsize]))
		{
			GetCarModel(spawnedCars[arrsize], &vehmodel);
			GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
			if (OwnRequestControlOfNetworkId(vehnetid)) 
			{
				DeleteCar(&spawnedCars[arrsize]);
				if (vehmodel == MODEL_TUGA || vehmodel == MODEL_SKYLIFT || vehmodel == MODEL_ANNIHILATOR || vehmodel == MODEL_MAVERICK 
					|| vehmodel == MODEL_POLMAV || vehmodel == MODEL_TOURMAV || vehmodel == MODEL_BUZZARD || vehmodel == MODEL_SWIFT
					 || vehmodel == MODEL_MARQUIS || vehmodel == MODEL_PREDATOR || vehmodel == MODEL_PSTOCKADE || vehmodel == MODEL_NSTOCKADE
					  || vehmodel == MODEL_STOCKADE || vehmodel == MODEL_BUS || vehmodel == MODEL_TRASH || vehmodel == MODEL_AMBULANCE)
					--counter;
				MarkModelAsNoLongerNeeded(vehmodel);
				--arrsize_M;
				Print("~g~Last spawned vehicle have been deleted");
				right = true;
				break;
			}
			else
			{
				Print("~r~Something went wrong :(");
				right = true;
				break;
			}
		}
		else if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
			{
				GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
				GetCarModel(veh, &vehmodel);
				DeleteCar(&veh);
				if (vehmodel == MODEL_TUGA || vehmodel == MODEL_SKYLIFT || vehmodel == MODEL_ANNIHILATOR || vehmodel == MODEL_MAVERICK 
					|| vehmodel == MODEL_POLMAV || vehmodel == MODEL_TOURMAV || vehmodel == MODEL_BUZZARD || vehmodel == MODEL_SWIFT
					 || vehmodel == MODEL_MARQUIS || vehmodel == MODEL_PREDATOR || vehmodel == MODEL_PSTOCKADE || vehmodel == MODEL_NSTOCKADE
					  || vehmodel == MODEL_STOCKADE || vehmodel == MODEL_BUS || vehmodel == MODEL_TRASH || vehmodel == MODEL_AMBULANCE)
					--counter;
				MarkModelAsNoLongerNeeded(vehmodel);
				--arrsize_M;
				Print("~g~Last spawned vehicle have been deleted");
				right = true;
				break;
			}
			else
			{
				Print("~r~Something went wrong :(");
				right = true;
				break;
			}
		}
		--arrsize;
	}
	if (!right)
		Print("~r~No vehicles exist or available");
}

void SpeedoThread::TeleportAllSpawnedVehicles()
{
	u32 type, vehnetid, arrsize=0, tempsize = arrsize_M, maxsize = arrsize_M+NumberOfVehicles;
	b8 wrong = false, right = false;
	Vehicle pveh,veh2;
	Ped ped = GetPlayerPed();
	Blip b = GetFirstBlipInfoId(BLIP_WAYPOINT);
	f32 x,y,z,h;
	i32 attemptcounter1 = 0;
	GetCharHeading(ped,&h);
	
	switch (SpawnType)
	{
		case 1:
			{
				type=1;
				break;
			}
		case 2:
			{
				type=2;
				break;
			}
		case 3:
			{
				type=3;
				break;
			}
		case 4:
			{
				type=4;
				break;
			}
	}
	if (type == 1)
	{
		f32 a=4;
		if(WaypointSpawning && b.IsValid())
		{
			GetBlipCoords(b, &x,&y,&z);
			while(z == 0.0f)
			{
				GetGroundZFor3DCoord(x, y, 1000, &z);
				Wait(0);						
				if (++attemptcounter1 > 200) 
					break;
			}
		}
		else
			GetCharCoordinates(ped, &x, &y, &z);
		while (arrsize<=31) 
		{
			if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
			{
				if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
				{
					GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
					SetCarHeading(veh,h);
					SetCarCoordinates(veh, x+(a*Sin((-1*h))), y+(a*Cos((-1*h))), z);
					if (!IsBigVehicle(veh))
						a+=6.5f;
					else
						a+=13;
					right = true;
				}
				else
					wrong = true;
			}
			else if(DoesVehicleExist(spawnedCars[arrsize]))
			{
				GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
				if (OwnRequestControlOfNetworkId(vehnetid)) 
				{
					SetCarHeading(spawnedCars[arrsize],h);
					SetCarCoordinates(spawnedCars[arrsize], x+(a*Sin((-1*h))), y+(a*Cos((-1*h))), z);
					if (!IsBigVehicle(spawnedCars[arrsize]))
						a+=6.5f;
					else
						a+=13;
					right = true;
				}
				else
					wrong = true;
			}
			++arrsize;
		}
	}
	else if (type == 2)
	{
		f32 p=0,radius=5;
		if(WaypointSpawning && b.IsValid())
		{
			GetBlipCoords(b, &x,&y,&z);
			while(z == 0.0f)
			{
				GetGroundZFor3DCoord(x, y, 1000, &z);
				Wait(0);						
				if (++attemptcounter1 > 200) 
					break;
			}
		}
		else
			GetCharCoordinates(ped, &x, &y, &z);
		while (arrsize<=31) 
		{
			if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
			{
				if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
				{
					GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
					if (p<360)
						p+=45;
					else
					{
						p=0;
						if (DoesVehicleExistWithNetworkId(spawnedCarz[arrsize-1]))
						{
							GetVehicleFromNetworkId(spawnedCarz[arrsize-1],&veh2);
							if(IsBigVehicle(veh2))
								radius+=10;
							else
								radius+=7;
						}
						else
							radius+=7;
					}

					if (h<360)
						h+=40;
					else
						h-=360;

					SetCarHeading(veh,h);
					SetCarCoordinates(veh,x+cos(p*PI/180)*radius, y+sin(p*PI/180)*radius, z);
					right = true;
				}
				else
					wrong = true;
			}
			else if(DoesVehicleExist(spawnedCars[arrsize]))
			{
				GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
				if (OwnRequestControlOfNetworkId(vehnetid)) 
				{
					if (p<360)
						p+=45;
					else
					{
						p=0;
						if (DoesVehicleExist(spawnedCars[arrsize-1]))
							if(IsBigVehicle(spawnedCars[arrsize-1]))
								radius+=10;
							else
								radius+=7;
						else
							radius+=7;
					}

					if (h<360)
						h+=40;
					else
						h-=360;

					SetCarHeading(spawnedCars[arrsize],h);
					SetCarCoordinates(spawnedCars[arrsize],x+cos(p*PI/180)*radius, y+sin(p*PI/180)*radius, z);
					right = true;
				}
				else
					wrong = true;
			}
			++arrsize;
		}
	}
	else if (type == 3)
	{
		if(WaypointSpawning && b.IsValid())
		{
			GetBlipCoords(b, &x,&y,&z);
			while(z == 0.0f)
			{
				GetGroundZFor3DCoord(x, y, 1000, &z);
				Wait(0);						
				if (++attemptcounter1 > 200) 
					break;
			}
			z+=2;
		}
		else
			GetOffsetFromCharInWorldCoords(ped, 0, 0, 2, &x, &y, &z);
		while (arrsize<=31) 
		{
			if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
			{
				if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
				{
					GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
					z+=3;
					SetCarHeading(veh,h);
					SetCarCoordinates(veh, x, y, z);
					right = true;
				}
				else
					wrong = true;
			}
			else if(DoesVehicleExist(spawnedCars[arrsize]))
			{
				GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
				if (OwnRequestControlOfNetworkId(vehnetid)) 
				{
					z+=3;
					SetCarHeading(spawnedCars[arrsize],h);
					SetCarCoordinates(spawnedCars[arrsize], x, y, z);
					right = true;
				}
				else
					wrong = true;
			}
			++arrsize;
		}
	}
	else if (type == 4)
	{
		f32 cX=0,cY=3,fZ;
		b8 ground = false;
		while (arrsize<=31) 
		{
			if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
			{
				if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
				{
					GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
					if (arrsize==5 || arrsize==10 || arrsize==15 || arrsize==20 || arrsize==25 || arrsize==30)
					{
						if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize-1]))
						{
							GetVehicleFromNetworkId(spawnedCarz[arrsize-1],&veh2);
							if(!IsBigVehicle(veh2))
							{
								cX=0;
								cY+=7;
							}
							else
							{
								cX=0;
								cY+=14;
							}
						}
					}
					if(WaypointSpawning && b.IsValid())
					{
						if (!ground)
						{
							GetOffsetFromBlipInWorldCoords(b, cX, cY, 0, &x, &y, &z);
							while(z == 0.0f)
							{
								GetGroundZFor3DCoord(x, y, 1000, &z);
								Wait(0);						
								if (++attemptcounter1 > 200) 
									break;
							}
							ground = true;
						}
						GetOffsetFromBlipInWorldCoords(b, cX, cY, 0, &x, &y, &fZ);
					}
					else
						GetOffsetFromCharInWorldCoords(ped, cX, cY, 0, &x, &y, &z);
					cX+=4;
					SetCarHeading(veh,h);
					SetCarCoordinates(veh, x, y, z);
					right = true;
				}
				else
					wrong = true;
			}
			else if(DoesVehicleExist(spawnedCars[arrsize]))
			{
				GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
				if (OwnRequestControlOfNetworkId(vehnetid)) 
				{
					if (arrsize==5 || arrsize==10 || arrsize==15 || arrsize==20 || arrsize==25 || arrsize==30)
					{
						if(DoesVehicleExist(spawnedCars[arrsize-1]))
							if(!IsBigVehicle(spawnedCars[arrsize-1]))
							{
								cX=0;
								cY+=7;
							}
							else
							{
								cX=0;
								cY+=14;
							}
					}
					GetOffsetFromCharInWorldCoords(ped, cX, cY, 0, &x, &y, &z);
					cX+=4;
					SetCarHeading(spawnedCars[arrsize],h);
					SetCarCoordinates(spawnedCars[arrsize], x, y, z);
					right = true;
				}
				else
					wrong = true;
			}
			++arrsize;
		}
	}
	if (!right && !wrong)
		Print("~r~No vehicles exist or available");
	else if (!wrong)
		Print("~g~All spawned vehicles have been teleported");
	else
		Print("~b~Not all spawned vehicles have been teleported (something went wrong)");
}

void SpeedoThread::SetNewColors()
{
	u32 vehnetid, arrsize=0, episode=GetCurrentEpisode(), rnd1, rnd2, rnd3, rnd4;
	i32 color_case = rand()%5;
	b8 wrong = false, right = false;

	while (arrsize<=31) 
	{
		if(DoesVehicleExistWithNetworkId(spawnedCarz[arrsize]))
		{
			if (OwnRequestControlOfNetworkId(spawnedCarz[arrsize])) 
			{
				GetVehicleFromNetworkId(spawnedCarz[arrsize],&veh);
				if (!Color)
				{
					if (episode == 2)
					{
						GenerateRandomIntInRange(0,136,&rnd1);
						GenerateRandomIntInRange(0,136,&rnd2);
						GenerateRandomIntInRange(0,136,&rnd3);
						GenerateRandomIntInRange(0,136,&rnd4);
					}
					else
					{
						GenerateRandomIntInRange(0,133,&rnd1);
						GenerateRandomIntInRange(0,133,&rnd2);
						GenerateRandomIntInRange(0,133,&rnd3);
						GenerateRandomIntInRange(0,133,&rnd4);
					}
					ChangeCarColour(veh,rnd1,rnd2);
					SetExtraCarColours(veh,rnd3,rnd4);
				}
				else
				{
					ChangeCarColour(veh,color1,color2);
					SetExtraCarColours(veh,extra1,extra2);
				}
				right = true;
			}
			else
				wrong = true;
		}
		else if(DoesVehicleExist(spawnedCars[arrsize]))
		{
			GetNetworkIdFromVehicle(spawnedCars[arrsize], &vehnetid);
			if (OwnRequestControlOfNetworkId(vehnetid)) 
			{
				if (!Color)
				{
					if (episode == 2)
					{
						GenerateRandomIntInRange(0,136,&rnd1);
						GenerateRandomIntInRange(0,136,&rnd2);
						GenerateRandomIntInRange(0,136,&rnd3);
						GenerateRandomIntInRange(0,136,&rnd4);
					}
					else
					{
						GenerateRandomIntInRange(0,133,&rnd1);
						GenerateRandomIntInRange(0,133,&rnd2);
						GenerateRandomIntInRange(0,133,&rnd3);
						GenerateRandomIntInRange(0,133,&rnd4);
					}
					ChangeCarColour(spawnedCars[arrsize],rnd1,rnd2);
					SetExtraCarColours(spawnedCars[arrsize],rnd3,rnd4);
				}
				else
				{
					ChangeCarColour(spawnedCars[arrsize],color1,color2);
					SetExtraCarColours(spawnedCars[arrsize],extra1,extra2);
				}
				right = true;
			}
			else
				wrong = true;
		}
		++arrsize;
	}
	if (!right && !wrong)
		Print("~r~No vehicles exist or available");
	else if (!wrong)
	{
		if (color_case == 0)
			Print("~g~New ~r~colors ~b~set~w~!");
		else if (color_case == 1)
			Print("~r~New ~g~colors ~b~set~w~!");
		else if (color_case == 2)
			Print("~g~New ~b~colors ~r~set~w~!");
		else if (color_case == 3)
			Print("~b~New ~g~colors ~r~set~w~!");
		else if (color_case == 4)
			Print("~r~New ~b~colors ~g~set~w~!");
		else if (color_case == 5)
			Print("~b~New ~r~colors ~g~set~w~!");
	}
	else
		Print("~b~Not all spawned vehicles have new colors (something went wrong)");
}

void SpeedoThread::OnKeyboardHookEvent( const IKeyboardHookHandler::KeyEventArgs &args )
{
	if (ToggleMenu)
		if ( !args.WasKeyDownBefore && args.VirtualKey == VK_F5 ) 
		{
			if (!D3DHookHaveRendered)
			{
				m_SpeedoRender.RemoveHook();
				m_SpeedoRender.InstallHook();
				D3DHookHaveRendered = true;
			}
			ToggleControl = !ToggleControl;
			m_SpeedoRender.SetMenuVisible( !m_SpeedoRender.GetMenuVisible() );
			PlayAudioEvent("FRONTEND_GAME_DROP_WEAPON");
			SetPlayerControlAdvanced(GetPlayer(),1,1,1);
		}
		else if (ToggleControl && (!Control))
			SetPlayerControlAdvanced(GetPlayer(),0,1,1);
}

b8 SpeedoThread::KeyPressed(int key)
{
  return (GetKeyState(key) & 0x80000000) != 0;
}

void SpeedoThread::RunScript()
{
	b8 msgstate=true;
	srand((unsigned)time(NULL));
    m_SpeedoRender.InstallHook();
    IKeyboardHookService *kbhService = ScriptHookManager::RequestService<IKeyboardHookService>( "KeyboardHook" );
    kbhService->AddHandler(this);

	while(IsThreadAlive())
	{
		if (!DisableMod)
		{
			ToggleMenu = true;
			if (Intro)
			{
				if(IsPlayerControlOn(GetPlayer()))
				{
					Print("~r~+~g~-~r~+~b~ Car Spawner ~g~by ~COL_NET_1~Solarix ~r~+~g~-~r~+",1500);
					Wait(1500);
					sprintf_s(ScreenMessage,512,"~BLIP_91~ ~g~Hello ~COL_NET_2~ %s~g~! ~BLIP_91~",GetPlayerName(GetPlayer())); 
					Print(ScreenMessage,2000);
					Intro = false;
				}
			}

			if(!Control)
				ControlVar=true;

			if(ControlVar)
				if(Control)
				{
					SetPlayerControlAdvanced(GetPlayer(),1,1,1);
					ControlVar = false;
				}

			if (bSpawnCar) 
			{
				ScriptedCarspawn(CarToSpawn);
				bSpawnCar = false;
			}

			if (bFixCars)
			{
				FixAllSpawnedCars();
				bFixCars = false;
			}

			if (bFlipCars)
			{
				FlipAllSpawnedCars();
				bFlipCars = false;
			}

			if (bFreezeCars)
			{
				FreezeAllSpawnedCars();
				bFreezeCars = false;
			}

			if (bUnfreezeCars)
			{
				UnfreezeAllSpawnedCars();
				bUnfreezeCars = false;
			}

			if (bAddGodMode)
			{
				AddGodMode();
				bAddGodMode = false;
			}

			if (bAddSimpleGodMode)
			{
				AddSimpleGodMode();
				bAddSimpleGodMode = false;
			}

			if (bRemoveGodMode)
			{
				RemoveGodMode();
				bRemoveGodMode = false;
			}

			if (bDeleteAllSpawnedCars) 
			{
				DeleteAllSpawnedCars();
				bDeleteAllSpawnedCars = false;
			}	

			if (bDeleteLastSpawnedCar) 
			{
				DeleteLastSpawnedCar();
				bDeleteLastSpawnedCar = false;
			}

			if (bTeleportCars)
			{
				TeleportAllSpawnedVehicles();
				bTeleportCars = false;
			}

			if (bNewColors)
			{
				SetNewColors();
				bNewColors = false;
			}

			if (bLockUnlockAllCarDoors)
			{
				LockUnlockAllCarDoors();
				bLockUnlockAllCarDoors = false;
			}

			if (bAddBlips)
			{
				AddBlips();
				bAddBlips = false;
			}

			if (bDestroyEngines)
			{
				DestroyEngines();
				bDestroyEngines = false;
			}

			m_SpeedoRender.SetMenuNrSpawnedCars(arrsize_M);
			m_SpeedoRender.SetMenuNrPlayers(GetNumberOfPlayers());

			if (IsPauseMenuActive() || IsScreenFadingOut() || IsScreenFadedOut() || !IsPlayerPlaying(GetPlayer()) || IsInPlayerSettingsMenu() || IsScreenFading() || IsScreenFadingIn() || IsFrontEndFading()) 
				NotInGame = true;
			else
				NotInGame = false;
			D3DHookHaveRendered = false;
		}
		else if (DisableMod)
		{
			if (msgstate)
			{
				Print("~r~Car Spawner disabled. Press LCtrl+F12 to enable",5000);
				m_SpeedoRender.SetMenuVisible( 0 );
				ToggleControl = !ToggleControl;
				SetPlayerControlAdvanced(GetPlayer(),1,1,1);
				attemptcounter = 0;
				D3DHookHaveRendered = false;
				ToggleMenu = false;
				Control = false;
				bSpawnCar = false;
				ControlVar = true;
				msgstate = false;
			}
			if (KeyPressed(VK_LCONTROL) && KeyPressed(VK_F12))
			{
				DisableMod = false;
				msgstate = true;
				Print("~g~Car Spawner enabled",5000); 
			}
		}
		// Call Wait() so we can process other scripts/game code
		// You must call Wait(...) in your loop code for a fiber thread!
		Wait(0);
	}
}

void SpeedoThread::OnKill()
{
    IKeyboardHookService *kbhService = ScriptHookManager::RequestService<IKeyboardHookService>( "KeyboardHook" );
    kbhService->RemoveHandler( this );
    m_SpeedoRender.RemoveHook();
    ScriptThread::OnKill();
}