All pastes #516127 Raw Edit

Someone

public text v1 · immutable
#516127 ·published 2007-05-28 15:23 UTC
rendered paste body
/*******************************************************************************************************

 SA~DMA+LG+PB+SR by Betamaster

 NO PORTION OF THIS SCRIPT IS TO BE REPRODUCED FOR COMMERCIAL USE. THIS INCLUDES USING SCRIPT SNIPPETS
 IN CUSTOM BUILT GAMEMODES FOR MONEY.

*******************************************************************************************************/

#define INVALID_PLAYER_ID             255
#define NO_TEAM                       255
#define MAX_CHATLINES                   9
#define MAX_PLAYER_NAME                24
#define MAX_WORLDBOUNDS           20000.0

#include <a_samp>  // <--- FILE HAS BEEN MODIFIED, SO USE MY VERSION OF A_SAMP
#include <core>
#include <float>
#include <bmdudb>
#include <dini>

new gWorldTime = 12;
new gOneSecondCount = 0;
new gOneMinuteCount = 0;

new gPlayerColours[100] = {
	0xFF8C13FF,0x3FE65CFF,0x20B2AAFF,0xDC143CFF,0x6495EDFF,0xf0e68cFF,0x778899FF,0xFF1493FF,0xF4A460FF,0xEE82EEFF,0xFFD720FF,
	0x8b4513FF,0x4949A0FF,0x148b8bFF,0x14ff7fFF,0x556b2fFF,0x0FD9FAFF,0x10DC29FF,0x534081FF,0x0495CDFF,0xEF6CE8FF,0xBD34DAFF,
	0x247C1BFF,0x0C8E5DFF,0x635B03FF,0xCB7ED3FF,0x65ADEBFF,0x5C1ACCFF,0xF2F853FF,0x11F891FF,0x7B39AAFF,0x53EB10FF,0x54137DFF,
	0x275222FF,0xF09F5BFF,0x3D0A4FFF,0x22F767FF,0xD63034FF,0x9A6980FF,0xDFB935FF,0x3793FAFF,0x90239DFF,0xE9AB2FFF,0xAF2FF3FF,
	0x057F94FF,0xB98519FF,0x388EEAFF,0x028151FF,0xA55043FF,0x0DE018FF,0x93AB1CFF,0x95BAF0FF,0x369976FF,0x18F71FFF,0x4B8987FF,
	0x491B9EFF,0x829DC7FF,0xBCE635FF,0xCEA6DFFF,0x20D4ADFF,0x2D74FDFF,0x3C1C0DFF,0x12D6D4FF,0x48C000FF,0x2A51E2FF,0xE3AC12FF,
	0xFC42A8FF,0x2FC827FF,0x1A30BFFF,0xB740C2FF,0x42ACF5FF,0x2FD9DEFF,0xFAFB71FF,0x05D1CDFF,0xC471BDFF,0x94436EFF,0xC1F7ECFF,
	0xCE79EEFF,0xBD1EF2FF,0x93B7E4FF,0x3214AAFF,0x184D3BFF,0xAE4B99FF,0x7E49D7FF,0x4C436EFF,0xFA24CCFF,0xCE76BEFF,0xA04E0AFF,
	0x9F945CFF,0xDCDE3DFF,0x10C9C5FF,0x70524DFF,0x0BE472FF,0x8A2CD7FF,0x6152C2FF,0xCF72A9FF,0xE59338FF,0xEEDC2DFF,0xD8C762FF,
	0xC715FFFF
};

#define COLOUR_GREY            0xAFAFAFAA
#define COLOUR_GREEN           0x33AA33AA
#define COLOUR_RED             0xAA3333AA
#define COLOUR_YELLOW          0xFFFF00AA
#define COLOUR_WHITE           0xFFFFFFAA
#define COLOUR_BLUE            0x0000BBAA
#define COLOUR_LIGHTBLUE       0x33CCFFAA
#define COLOUR_ORANGE          0xFF9900AA
#define COLOUR_TAXIYELLOW      0xF0E68CAA
#define COLOUR_POLICEBLUE      0x3F63CCAA

#define SOUND_MUSIC_CLASSSELECT      1187
#define SOUND_MUSIC_RACEFINISH       1183
#define SOUND_MUSIC_RACERECORD       1097
#define SOUND_MUSIC_MISSIONCOMPLETE  1185
#define SOUND_OFF                    1184
#define SOUND_BLIP1                  1056
#define SOUND_BLIP2                  1057
#define SOUND_EXPLOSION              1159
#define SOUND_PURCHASE               1149
#define SOUND_CHECKPOINT             1058

//------------------------------------------------------------------------------------------------------
// Weapons

#define MAX_WEAPONS                  48
#define WEAPON_FIST                   0
#define WEAPON_BRASSKNUCKLE           1
#define WEAPON_GOLFCLUB	              2
#define WEAPON_NIGHTSTICK             3
#define WEAPON_KNIFE                  4
#define WEAPON_BAT                    5
#define WEAPON_SHOVEL                 6
#define WEAPON_POOLSTICK              7
#define WEAPON_KATANA                 8
#define WEAPON_CHAINSAW               9
#define WEAPON_DILDO                 10
#define WEAPON_DILDO2                11
#define WEAPON_VIBRATOR              12
#define WEAPON_VIBRATOR2             13
#define WEAPON_FLOWER                14
#define WEAPON_CANE                  15
#define WEAPON_GRENADE               16
#define WEAPON_TEARGAS               17
#define WEAPON_MOLTOV                18
#define WEAPON_ROCKET                19
#define WEAPON_HSROCKET              20
#define WEAPON_HYDRAROCKET           21
#define WEAPON_PISTOL                22
#define WEAPON_SILENCEDPISTOL        23
#define WEAPON_DEAGLE                24
#define WEAPON_SHOTGUN               25
#define WEAPON_SHOTGUNSAWNOFF        26
#define WEAPON_SHOTGUNCOMBAT         27
#define WEAPON_UZI                   28
#define WEAPON_MP5                   29
#define WEAPON_AK47                  30
#define WEAPON_M4                    31
#define WEAPON_TEC9                  32
#define WEAPON_RIFLE                 33
#define WEAPON_SNIPERRIFLE           34
#define WEAPON_ROCKETLAUNCHER        35
#define WEAPON_HEATSEEKER            36
#define WEAPON_FLAMETHROWER          37
#define WEAPON_MINIGUN               38
#define WEAPON_SATCHEL               39
#define WEAPON_BOMB                  40
#define WEAPON_SPRAYCAN              41
#define WEAPON_FIREEXTINGUISHER      42
#define WEAPON_CAMERA                43
#define WEAPON_NIGHTVISION           44
#define WEAPON_THERMALVISION         45
#define WEAPON_PARACHUTE             46
#define WEAPON_FAKEPISTOL            47
#define WEAPON_VEHICLE               49
#define WEAPON_DROWN                 53
#define WEAPON_COLLISION             54
#define WEAPON_SELFKILL             255
#define WEAPON_TYPE_MELEE             0
#define WEAPON_TYPE_PROJECTIVE        1
#define WEAPON_TYPE_PISTOL            2
#define WEAPON_TYPE_SHOTGUN           3
#define WEAPON_TYPE_MACHINEGUN        4
#define WEAPON_TYPE_ASSAULT           5
#define WEAPON_TYPE_RIFLE             6
#define WEAPON_TYPE_HEAVYASSAULT      7
#define WEAPON_TYPE_SPECIAL           8
#define WEAPON_TYPE_DEATHREASON       9

enum WEAPON_MAIN {
	WEAPON_NAME[30],
	WEAPON_TYPE
};

new gWeapons[MAX_WEAPONS][WEAPON_MAIN] = {
	{"Unarmed", WEAPON_TYPE_MELEE},
	{"Brass Knuckles", WEAPON_TYPE_MELEE},  //crash game
	{"Golf Club", WEAPON_TYPE_MELEE},
	{"Night Stick", WEAPON_TYPE_MELEE},
	{"Knife", WEAPON_TYPE_MELEE},
	{"Baseball Bat", WEAPON_TYPE_MELEE},
	{"Shovel", WEAPON_TYPE_MELEE},
	{"Pool Cue", WEAPON_TYPE_MELEE},
	{"Katana", WEAPON_TYPE_MELEE},
	{"Chainsaw", WEAPON_TYPE_MELEE},
	{"Purple Dildo", WEAPON_TYPE_MELEE},
	{"White Dildo", WEAPON_TYPE_MELEE},
	{"Long White Dildo", WEAPON_TYPE_MELEE},
	{"White Dildo 2", WEAPON_TYPE_MELEE},
	{"Flowers", WEAPON_TYPE_MELEE},
	{"Cane", WEAPON_TYPE_MELEE},
	{"Grenades", WEAPON_TYPE_PROJECTIVE},  //crash game
	{"Tear Gas", WEAPON_TYPE_PROJECTIVE},  //crash game
	{"Molotovs", WEAPON_TYPE_PROJECTIVE},  //crash game
	{"Rockets", WEAPON_TYPE_PROJECTIVE},
	{"Heat-seeking Rocket", WEAPON_TYPE_PROJECTIVE},
	{"Hydra Rocket", WEAPON_TYPE_PROJECTIVE},
	{"Pistol (Colt 45)", WEAPON_TYPE_PISTOL},
	{"Silenced Pistol", WEAPON_TYPE_PISTOL},
	{"Desert Eagle", WEAPON_TYPE_PISTOL},
	{"Shotgun", WEAPON_TYPE_SHOTGUN},
	{"Sawn Off Shotgun", WEAPON_TYPE_SHOTGUN},
	{"Combat Shotgun", WEAPON_TYPE_SHOTGUN},
	{"Micro Uzi (Mac 10)", WEAPON_TYPE_MACHINEGUN},
	{"MP5", WEAPON_TYPE_ASSAULT},
	{"AK47", WEAPON_TYPE_ASSAULT},
	{"M4", WEAPON_TYPE_ASSAULT},
	{"Tec9", WEAPON_TYPE_MACHINEGUN},
	{"Rifle", WEAPON_TYPE_RIFLE},
	{"Sniper Rifle", WEAPON_TYPE_RIFLE},
	{"Rocket Launcher (RPG)", WEAPON_TYPE_HEAVYASSAULT},
	{"Heat-seeking Rocket Launcher", WEAPON_TYPE_HEAVYASSAULT},
	{"Flame Thrower", WEAPON_TYPE_HEAVYASSAULT},
	{"Minigun", WEAPON_TYPE_HEAVYASSAULT},
	{"Satchel Charges", WEAPON_TYPE_HEAVYASSAULT},  //crash game
	{"Detonator", WEAPON_TYPE_HEAVYASSAULT},  //crash game
	{"Spray Can", WEAPON_TYPE_SPECIAL},
	{"Fire Extinguisher", WEAPON_TYPE_SPECIAL},
	{"Camera", WEAPON_TYPE_SPECIAL},
	{"Nightvision Goggles", WEAPON_TYPE_SPECIAL},  //crash game
	{"Thermal Goggles", WEAPON_TYPE_SPECIAL},  //crash game
	{"Parachute", WEAPON_TYPE_SPECIAL},
	{"Fake Pistol", WEAPON_TYPE_SPECIAL}
};

//------------------------------------------------------------------------------------------------------
// Spawn weapons

#define MAX_SPAWNWEAPONS  9

enum SPAWNWEAPON_MAIN {
	SPAWNWEAPON_ID,
	SPAWNWEAPON_AMMO,
	SPAWNWEAPON_COST
};

new gSpawnWeapons[MAX_SPAWNWEAPONS][SPAWNWEAPON_MAIN] = {
//	ID                      AMMO  COST
	{WEAPON_KNIFE,          0,    500},
	{WEAPON_SHOTGUN,        15,   7000},
	{WEAPON_SHOTGUNCOMBAT,  20,   15000},
	{WEAPON_UZI,            120,  7000},
	{WEAPON_TEC9,           120,  5000},
	{WEAPON_MP5,            120,  15000},
	{WEAPON_AK47,           120,  25000},
	{WEAPON_M4,             120,  30000},
	{WEAPON_CHAINSAW,       0,    70000}
};

new gPlayerSpawnWeapons[MAX_PLAYERS][MAX_SPAWNWEAPONS];

//------------------------------------------------------------------------------------------------------
// Vehicles

#define MAX_VEHICLES             255
#define VEHICLE_TYPE_BIKE          0
#define VEHICLE_TYPE_BICYCLE       1
#define VEHICLE_TYPE_BOAT          2
#define VEHICLE_TYPE_CAR           3
#define VEHICLE_TYPE_HELICOPTER    4
#define VEHICLE_TYPE_MONSTER       5
#define VEHICLE_TYPE_PLANE         6
#define VEHICLE_TYPE_QUADBIKE      7
#define VEHICLE_TYPE_TRAILER       8
#define VEHICLE_TYPE_TRAIN         9
#define VEHICLE_TYPE_AMPHIBIOUS   10
#define VEHICLE_CLASS_LAND        11
#define VEHICLE_CLASS_WATER       12
#define VEHICLE_CLASS_AIR         13
#define VEHICLE_CLASS_FOOT        14
#define VEHICLE_MODEL_OFFSET     400
#define VEHICLE_TAXI             420
#define VEHICLE_CABBIE           438
#define VEHICLE_SECURICAR        428

enum VEHICLEINFO_MAIN {
	VEHICLEINFO_NAME[18],
	VEHICLEINFO_TYPE
};

new gVehicleInfo[][VEHICLEINFO_MAIN] = {
	{"Landstalker", VEHICLE_TYPE_CAR},
	{"Bravura", VEHICLE_TYPE_CAR},
	{"Buffalo", VEHICLE_TYPE_CAR},
	{"Linerunner", VEHICLE_TYPE_CAR},
	{"Pereniel", VEHICLE_TYPE_CAR},
	{"Sentinel", VEHICLE_TYPE_CAR},
	{"Dumper", VEHICLE_TYPE_MONSTER},
	{"Firetruck", VEHICLE_TYPE_CAR},
	{"Trashmaster", VEHICLE_TYPE_CAR},
	{"Stretch", VEHICLE_TYPE_CAR},
	{"Manana", VEHICLE_TYPE_CAR},
	{"Infernus", VEHICLE_TYPE_CAR},
	{"Voodoo", VEHICLE_TYPE_CAR},
	{"Pony", VEHICLE_TYPE_CAR},
	{"Mule", VEHICLE_TYPE_CAR},
	{"Cheetah", VEHICLE_TYPE_CAR},
	{"Ambulance", VEHICLE_TYPE_CAR},
	{"Leviathan", VEHICLE_TYPE_HELICOPTER},
	{"Moonbeam", VEHICLE_TYPE_CAR},
	{"Esperanto", VEHICLE_TYPE_CAR},
	{"Taxi", VEHICLE_TYPE_CAR},
	{"Washington", VEHICLE_TYPE_CAR},
	{"Bobcat", VEHICLE_TYPE_CAR},
	{"Mr Whoopee", VEHICLE_TYPE_CAR},
	{"BF Injection", VEHICLE_TYPE_CAR},
	{"Hunter", VEHICLE_TYPE_HELICOPTER},
	{"Premier", VEHICLE_TYPE_CAR},
	{"Enforcer", VEHICLE_TYPE_CAR},
	{"Securicar", VEHICLE_TYPE_CAR},
	{"Banshee", VEHICLE_TYPE_CAR},
	{"Predator", VEHICLE_TYPE_BOAT},
	{"Bus", VEHICLE_TYPE_CAR},
	{"Rhino", VEHICLE_TYPE_CAR},
	{"Barracks", VEHICLE_TYPE_CAR},
	{"Hotknife", VEHICLE_TYPE_CAR},
	{"Trailer", VEHICLE_TYPE_TRAILER},
	{"Previon", VEHICLE_TYPE_CAR},
	{"Coach", VEHICLE_TYPE_CAR},
	{"Cabbie", VEHICLE_TYPE_CAR},
	{"Stallion", VEHICLE_TYPE_CAR},
	{"Rumpo", VEHICLE_TYPE_CAR},
	{"RC Bandit", VEHICLE_TYPE_CAR},
	{"Romero", VEHICLE_TYPE_CAR},
	{"Packer", VEHICLE_TYPE_CAR},
	{"Monster", VEHICLE_TYPE_MONSTER},
	{"Admiral", VEHICLE_TYPE_CAR},
	{"Squalo", VEHICLE_TYPE_BOAT},
	{"Seasparrow", VEHICLE_TYPE_HELICOPTER},
	{"Pizzaboy", VEHICLE_TYPE_BIKE},
	{"Tram", VEHICLE_TYPE_TRAIN},
	{"Trailer", VEHICLE_TYPE_TRAILER},
	{"Turismo", VEHICLE_TYPE_CAR},
	{"Speeder", VEHICLE_TYPE_BOAT},
	{"Reefer", VEHICLE_TYPE_BOAT},
	{"Tropic", VEHICLE_TYPE_BOAT},
	{"Flatbed", VEHICLE_TYPE_CAR},
	{"Yankee", VEHICLE_TYPE_CAR},
	{"Caddy", VEHICLE_TYPE_CAR},
	{"Solair", VEHICLE_TYPE_CAR},
	{"Berkley's RC Van", VEHICLE_TYPE_CAR},
	{"Skimmer", VEHICLE_TYPE_PLANE},
	{"PCJ-600", VEHICLE_TYPE_BIKE},
	{"Faggio", VEHICLE_TYPE_BIKE},
	{"Freeway", VEHICLE_TYPE_BIKE},
	{"RC Baron", VEHICLE_TYPE_PLANE},
	{"RC Raider", VEHICLE_TYPE_HELICOPTER},
	{"Glendale", VEHICLE_TYPE_CAR},
	{"Oceanic", VEHICLE_TYPE_CAR},
	{"Sanchez", VEHICLE_TYPE_BIKE},
	{"Sparrow", VEHICLE_TYPE_HELICOPTER},
	{"Patriot", VEHICLE_TYPE_CAR},
	{"Quad", VEHICLE_TYPE_QUADBIKE},
	{"Coastguard", VEHICLE_TYPE_BOAT},
	{"Dinghy", VEHICLE_TYPE_BOAT},
	{"Hermes", VEHICLE_TYPE_CAR},
	{"Sabre", VEHICLE_TYPE_CAR},
	{"Rustler", VEHICLE_TYPE_PLANE},
	{"ZR3 50", VEHICLE_TYPE_CAR},
	{"Walton", VEHICLE_TYPE_CAR},
	{"Regina", VEHICLE_TYPE_CAR},
	{"Comet", VEHICLE_TYPE_CAR},
	{"BMX", VEHICLE_TYPE_BICYCLE},
	{"Burrito", VEHICLE_TYPE_CAR},
	{"Camper", VEHICLE_TYPE_CAR},
	{"Marquis", VEHICLE_TYPE_BOAT},
	{"Baggage", VEHICLE_TYPE_CAR},
	{"Dozer", VEHICLE_TYPE_CAR},
	{"Maverick", VEHICLE_TYPE_HELICOPTER},
	{"News Chopper", VEHICLE_TYPE_HELICOPTER},
	{"Rancher", VEHICLE_TYPE_CAR},
	{"FBI Rancher", VEHICLE_TYPE_CAR},
	{"Virgo", VEHICLE_TYPE_CAR},
	{"Greenwood", VEHICLE_TYPE_CAR},
	{"Jetmax", VEHICLE_TYPE_BOAT},
	{"Hotring", VEHICLE_TYPE_CAR},
	{"Sandking", VEHICLE_TYPE_CAR},
	{"Blista Compact", VEHICLE_TYPE_CAR},
	{"Police Maverick", VEHICLE_TYPE_HELICOPTER},
	{"Boxville", VEHICLE_TYPE_CAR},
	{"Benson", VEHICLE_TYPE_CAR},
	{"Mesa", VEHICLE_TYPE_CAR},
	{"RC Goblin", VEHICLE_TYPE_HELICOPTER},
	{"Hotring Racer", VEHICLE_TYPE_CAR},
	{"Hotring Racer", VEHICLE_TYPE_CAR},
	{"Bloodring Banger", VEHICLE_TYPE_CAR},
	{"Rancher", VEHICLE_TYPE_CAR},
	{"Super GT", VEHICLE_TYPE_CAR},
	{"Elegant", VEHICLE_TYPE_CAR},
	{"Journey", VEHICLE_TYPE_CAR},
	{"Bike", VEHICLE_TYPE_BICYCLE},
	{"Mountain Bike", VEHICLE_TYPE_BICYCLE},
	{"Beagle", VEHICLE_TYPE_PLANE},
	{"Cropdust", VEHICLE_TYPE_PLANE},
	{"Stunt", VEHICLE_TYPE_PLANE},
	{"Tanker", VEHICLE_TYPE_CAR},
	{"RoadTrain", VEHICLE_TYPE_CAR},
	{"Nebula", VEHICLE_TYPE_CAR},
	{"Majestic", VEHICLE_TYPE_CAR},
	{"Buccaneer", VEHICLE_TYPE_CAR},
	{"Shamal", VEHICLE_TYPE_PLANE},
	{"Hydra", VEHICLE_TYPE_PLANE},
	{"FCR-900", VEHICLE_TYPE_BIKE},
	{"NRG-500", VEHICLE_TYPE_BIKE},
	{"HPV1000", VEHICLE_TYPE_BIKE},
	{"Cement Truck", VEHICLE_TYPE_CAR},
	{"Tow Truck", VEHICLE_TYPE_CAR},
	{"Fortune", VEHICLE_TYPE_CAR},
	{"Cadrona", VEHICLE_TYPE_CAR},
	{"FBI Truck", VEHICLE_TYPE_CAR},
	{"Willard", VEHICLE_TYPE_CAR},
	{"Forklift", VEHICLE_TYPE_CAR},
	{"Tractor", VEHICLE_TYPE_CAR},
	{"Combine", VEHICLE_TYPE_CAR},
	{"Feltzer", VEHICLE_TYPE_CAR},
	{"Remington", VEHICLE_TYPE_CAR},
	{"Slamvan", VEHICLE_TYPE_CAR},
	{"Blade", VEHICLE_TYPE_CAR},
	{"Freight", VEHICLE_TYPE_TRAIN},
	{"Streak", VEHICLE_TYPE_TRAIN},
	{"Vortex", VEHICLE_TYPE_AMPHIBIOUS},
	{"Vincent", VEHICLE_TYPE_CAR},
	{"Bullet", VEHICLE_TYPE_CAR},
	{"Clover", VEHICLE_TYPE_CAR},
	{"Sadler", VEHICLE_TYPE_CAR},
	{"Firetruck", VEHICLE_TYPE_CAR},
	{"Hustler", VEHICLE_TYPE_CAR},
	{"Intruder", VEHICLE_TYPE_CAR},
	{"Primo", VEHICLE_TYPE_CAR},
	{"Cargobob", VEHICLE_TYPE_HELICOPTER},
	{"Tampa", VEHICLE_TYPE_CAR},
	{"Sunrise", VEHICLE_TYPE_CAR},
	{"Merit", VEHICLE_TYPE_CAR},
	{"Utility", VEHICLE_TYPE_CAR},
	{"Nevada", VEHICLE_TYPE_PLANE},
	{"Yosemite", VEHICLE_TYPE_CAR},
	{"Windsor", VEHICLE_TYPE_CAR},
	{"Monster", VEHICLE_TYPE_MONSTER},
	{"Monster", VEHICLE_TYPE_MONSTER},
	{"Uranus", VEHICLE_TYPE_CAR},
	{"Jester", VEHICLE_TYPE_CAR},
	{"Sultan", VEHICLE_TYPE_CAR},
	{"Stratum", VEHICLE_TYPE_CAR},
	{"Elegy", VEHICLE_TYPE_CAR},
	{"Raindance", VEHICLE_TYPE_HELICOPTER},
	{"RC Tiger", VEHICLE_TYPE_CAR},
	{"Flash", VEHICLE_TYPE_CAR},
	{"Tahoma", VEHICLE_TYPE_CAR},
	{"Savanna", VEHICLE_TYPE_CAR},
	{"Bandito", VEHICLE_TYPE_CAR},
	{"Freight", VEHICLE_TYPE_TRAIN},
	{"Trailer", VEHICLE_TYPE_TRAIN},
	{"Kart", VEHICLE_TYPE_CAR},
	{"Mower", VEHICLE_TYPE_CAR},
	{"Duneride", VEHICLE_TYPE_MONSTER},
	{"Sweeper", VEHICLE_TYPE_CAR},
	{"Broadway", VEHICLE_TYPE_CAR},
	{"Tornado", VEHICLE_TYPE_CAR},
	{"AT-400", VEHICLE_TYPE_PLANE},
	{"DFT-30", VEHICLE_TYPE_CAR},
	{"Huntley", VEHICLE_TYPE_CAR},
	{"Stafford", VEHICLE_TYPE_CAR},
	{"BF-400", VEHICLE_TYPE_BIKE},
	{"Newsvan", VEHICLE_TYPE_CAR},
	{"Tug", VEHICLE_TYPE_CAR},
	{"Trailer", VEHICLE_TYPE_TRAILER},
	{"Emperor", VEHICLE_TYPE_CAR},
	{"Wayfarer", VEHICLE_TYPE_BIKE},
	{"Euros", VEHICLE_TYPE_CAR},
	{"Hotdog", VEHICLE_TYPE_CAR},
	{"Club", VEHICLE_TYPE_CAR},
	{"Trailer", VEHICLE_TYPE_TRAIN},
	{"Trailer", VEHICLE_TYPE_TRAILER},
	{"Andromada", VEHICLE_TYPE_PLANE},
	{"Dodo", VEHICLE_TYPE_PLANE},
	{"RC Cam", VEHICLE_TYPE_CAR},
	{"Launch", VEHICLE_TYPE_BOAT},
	{"Police Car (LSPD)", VEHICLE_TYPE_CAR},
	{"Police Car (SFPD)", VEHICLE_TYPE_CAR},
	{"Police Car (LVPD)", VEHICLE_TYPE_CAR},
	{"Police Ranger", VEHICLE_TYPE_CAR},
	{"Picador", VEHICLE_TYPE_CAR},
	{"S.W.A.T. Van", VEHICLE_TYPE_CAR},
	{"Alpha", VEHICLE_TYPE_CAR},
	{"Phoenix", VEHICLE_TYPE_CAR},
	{"Glendale", VEHICLE_TYPE_CAR},
	{"Sadler", VEHICLE_TYPE_CAR},
	{"Luggage Trailer", VEHICLE_TYPE_TRAILER},
	{"Luggage Trailer", VEHICLE_TYPE_TRAILER},
	{"Stair Trailer", VEHICLE_TYPE_TRAILER},
	{"Boxville", VEHICLE_TYPE_CAR},
	{"Farm Plow", VEHICLE_TYPE_TRAILER},
	{"Utility Trailer", VEHICLE_TYPE_TRAILER}
};

enum VEHICLE_MAIN {
	VEHICLE_MODEL,
	Float:VEHICLE_SPAWN[4],
	VEHICLE_COLOUR[2]
}

new gVehicles[MAX_VEHICLES][VEHICLE_MAIN] = {
//	MODEL   SPAWN (X,Y,Z,angle)                        COLOUR
	// Special Spawns
	{428,   {1920.6417,964.2783,10.9440,89.7711},      {4,75}},       // Four Dragons Casino Securica
	{409,   {2038.9760,1004.2764,10.4725,180.5512},    {0,0}},        // Four Dragons Casino Limo (left)
	{409,   {2038.9464,1014.8927,10.4723,180.5512},    {0,0}},        // Four Dragons Casino Limo (right)
	{409,   {976.0334,-669.4716,120.9437,301.6110},    {0,0}},        // Four Dragons Casino Red County Limo
	{428,   {2298.7476,1566.9519,10.9462,180.8493},    {4,75}},       // Caligula's Casino Securica
	{409,   {2168.4163,1683.0472,10.6207,7.5586},      {1,1}},        // Caligula's Casino Limo (left)
	{409,   {2167.8572,1672.6106,10.6220,342.3914},    {1,1}},        // Caligula's Casino Limo (right)
	{409,   {304.1468,-1163.1853,80.7106,223.9524},    {1,1}},        // Caligula's Casino Richman Limo
	{451,   {2263.9753,2430.4702,-7.8282,358.1498},    {53,53}},      // Cop Turismo
	{451,   {2272.7852,2430.7451,-7.8280,358.1498},    {53,53}},      // Cop Turismo
	// AT-400 Spawns (reference for skydiving points)
	{577,   {1838.0181,-2423.8049,13.4708,142.8575},   {8,90}},       // LS AT-400
	{577,   {1585.5986,1190.2456,10.7286,180.1558},    {8,90}},       // LV AT-400
	{577,   {-1253.9702,-20.5812,14.0642,93.9676},     {8,90}},       // SF AT-400
	// Yellow Bell Golf Course
	{411,   {1464.9119,2773.7285,10.3990,359.8992},    {64,1}},       // Infernus
	// Prickle Pine
	{561,   {1977.9839,2657.6638,10.6410,180.8320},    {8,17}},       // Stratum
	{480,   {1960.3917,2755.6880,10.5932,181.9201},    {12,12}},      // Comet
	{541,   {2059.0203,2730.9084,10.4454,180.7771},    {68,8}},       // Bullet
	{421,   {1595.2922,2808.1826,10.7028,0.1646},      {13,1}},       // Wellington
	{429,   {1657.5507,2835.3894,10.5000,181.2647},    {13,13}},      // Banshee
	{434,   {1650.6552,2746.9497,10.7958,179.0845},    {12,12}},      // Hotknife
	{522,   {1638.1962,2575.7852,10.3993,28.6115},     {7,79}},       // NRG-500
	{405,   {1282.1233,2573.3083,10.6953,269.7541},    {24,1}},       // Sentinel
	// Whitewood Estates
	{405,   {984.3504,1744.3928,8.5276,270.9907},      {24,1}},       // Sentinel
	{560,   {984.3094,1738.1862,8.3573,269.5801},      {9,39}},       // Sultan
	{522,   {1032.5294,1839.8151,11.0306,268.0209},    {3,8}},        // NRG-500
	{545,   {992.3167,1886.1399,11.0168,267.7288},     {47,1}},       // Hustler
	{434,   {1165.6533,2096.0063,10.7879,180.9686},    {12,12}},      // Hotknife
	{521,   {1133.3789,1896.3176,10.3919,83.3056},     {75,13}},      // FCR-900
	{475,   {1132.4401,1926.0272,10.6224,89.3929},     {9,39}},       // Sabre
	// Redsands West
	{561,   {1372.2944,1937.6747,11.0311,268.6575},    {8,17}},       // Stratum
	{463,   {1472.7196,1927.5532,10.7455,83.2741},     {7,7}},        // Freeway
	{565,   {1521.0657,1998.7345,10.4426,178.4989},    {42,42}},      // Flash
	{567,   {1543.4987,2131.8120,11.2308,91.0327},     {88,64}},      // Savanna
	{443,   {1594.9929,2186.3948,11.4548,269.8246},    {20,1}},       // Packer
	{522,   {1613.3162,2207.1333,10.3896,268.6485},    {7,79}},       // NRG-500
	{415,   {1602.5441,2086.8467,10.9680,268.0530},    {25,1}},       // Cheetah
	{562,   {1685.3331,2191.4941,10.4791,269.8310},    {35,1}},       // Elegy
	// Red Sands East
	{558,   {1912.6658,2120.4172,10.4505,91.4711},     {116,1}},      // Uranus
	{429,   {1907.0883,2080.6199,10.5016,268.9371},    {13,13}},      // Bandshee
	{522,   {1907.9320,2075.9072,10.3841,267.9874},    {8,82}},       // NRG-500
	// The Emerald Isle
	{560,   {2009.0155,2475.7112,10.5256,269.9114},    {17,1}},       // Sultan
	{497,   {2092.6572,2415.2773,74.7654,268.4450},    {53,1}},       // Police Maverick
	// Roca Escalante
	{598,   {2251.7966,2477.4321,10.5663,180.5474},    {53,1}},       // Police Car (LVPD)
	{523,   {2269.2354,2477.0608,10.3882,176.8812},    {53,1}},       // HPV1000
	{523,   {2273.4016,2477.1033,10.3891,179.6992},    {53,1}},       // HPV1000
	{598,   {2290.9233,2477.4590,10.5668,179.1531},    {53,1}},       // Police Car (LVPD)
	{598,   {2277.9456,2459.9312,10.5691,181.9467},    {53,1}},       // Police Car (LVPD)
	{598,   {2269.2759,2443.1265,10.5689,0.2058},      {53,1}},       // Police Car (LVPD)
	{523,   {2290.8513,2442.7229,10.3900,0.4380},      {53,1}},       // HPV1000
	{523,   {2263.9290,2431.2693,2.8442,1.9574},       {53,1}},       // HPV1000
	{598,   {2272.7869,2431.1406,3.0197,359.5931},     {53,1}},       // Police Car (LVPD)
	{405,   {2511.9158,2374.5215,10.6953,271.0741},    {24,1}},       // Sentinel
	{421,   {2582.4771,2267.8779,10.7028,271.1774},    {13,1}},       // Washington
	{434,   {2592.4980,2275.2625,10.7849,89.9366},     {12,12}},      // Hotknife
	// The Old Strip
	{541,   {2360.4941,2196.8013,10.3090,359.5612},    {58,8}},       // Bullet
	{451,   {2496.8530,2131.4006,10.4503,88.8332},     {125,125}},    // Turismo
	{565,   {2603.9468,2139.6470,10.4436,270.3661},    {42,42}},      // Flash
	{545,   {2613.4038,2099.7717,10.6273,359.9260},    {47,1}},       // Hustler
	{415,   {2587.6123,1967.0841,10.5914,179.2745},    {25,1}},       // Cheetah
	// The Strip
	{411,   {2103.4971,2056.3457,10.5474,270.2649},    {64,1}},       // Infernus
	{567,   {2103.1704,2039.7742,10.6854,270.0377},    {90,96}},      // Savanna
	{535,   {2171.1963,2000.6390,10.5834,90.7606},     {123,1}},      // Slamvan
	{541,   {2186.5881,1979.1786,10.4465,270.7768},    {75,1}},       // Bullet
	{451,   {2127.8879,2356.8418,10.3785,271.2029},    {125,125}},    // Turismo
	{522,   {2154.8831,2187.0728,10.7642,178.4291},    {6,1}},        // NRG-500
	{437,   {2119.9902,1912.0364,10.8052,180.2860},    {79,7}},       // Coach
	{421,   {2034.7388,1922.8392,12.0606,178.7710},    {13,1}},       // Washington
	{506,   {2163.6624,1800.2600,10.5247,358.6726},    {6,6}},        // Super GT
	{451,   {2211.2493,1838.7480,10.5283,180.7583},    {36,36}},      // Turismo
	{400,   {2184.9307,1855.6844,10.9141,180.8331},    {113,1}},      // Landstalker
	{475,   {2039.8293,1598.9681,10.4769,179.9520},    {37,0}},       // Sabre
	{541,   {2039.7831,1515.1478,10.2969,180.2525},    {60,1}},       // Bullet
	{480,   {2136.0557,1397.9711,10.5946,0.0808},      {2,2}},        // Comet
	{522,   {2139.0811,1408.8306,10.3870,184.2194},    {36,105}},     // NRG-500
	{405,   {2103.9412,1408.7858,10.6965,179.2218},    {36,1}},       // Sentinel
	{429,   {2075.2915,1488.0377,10.3523,358.7982},    {1,2}},        // Banshee
	{421,   {2040.0330,1330.2434,10.5544,180.1878},    {25,1}},       // Washington
	{561,   {2039.8688,1128.7844,10.4853,179.8637},    {43,21}},      // Stratum
	{480,   {2074.8240,1008.6550,10.4442,358.3198},    {6,6}},        // Comet
	{522,   {2132.1016,986.9740,10.3865,176.3696},     {39,106}},     // NRG-500
	{522,   {2129.0042,987.0283,10.3807,178.9287},     {51,118}},     // NRG-500
	{567,   {2132.4739,1013.0201,10.6923,268.8758},    {115,0}},      // Savanna
	{411,   {2142.2119,1019.3263,10.5483,90.4899},     {123,1}},      // Infernus
	{506,   {2162.9055,1025.7577,10.5262,89.8965},     {7,7}},        // Super GT
	{475,   {2115.4761,911.5577,10.6215,91.5913},      {41,29}},      // Sabre
	{451,   {2039.9551,937.4134,9.3428,179.7310},      {16,16}},      // Turismo
	{481,   {2005.5536,1239.7672,10.3302,308.1699},    {65,9}},       // BMX
	// Pilgrim
	{482,   {2609.7375,1433.9945,10.9398,181.9168},    {10,10}},      // Burrito
	{434,   {2405.2878,1667.6499,10.7916,180.9429},    {2,2}},        // Hotknife
	{560,   {2395.7649,1658.8044,10.5270,0.8503},      {17,1}},       // Sultan
	{451,   {2479.2456,1658.7715,10.5281,0.7615},      {18,18}},      // Turismo
	{567,   {2603.9336,1795.6671,10.6910,89.5675},     {99,81}},      // Savanna
	// Royal Casino
	{411,   {2351.7439,1433.5945,10.5505,271.1658},    {112,1}},      // Infernus
	{559,   {2351.6943,1476.6534,10.4780,269.2504},    {68,8}},       // Jester
	{535,   {2292.2148,1472.9073,15.0519,271.2990},    {66,1}},       // Slamvan
	{470,   {2353.3252,1430.1967,21.8992,269.1465},    {43,0}},       // Patriot
	{522,   {2352.7593,1469.4891,10.3872,268.3273},    {3,8}},        // NRG-500
	{421,   {2182.4644,1285.1157,10.6239,179.3253},    {30,1}},       // Washington
	{480,   {2373.6279,1708.2518,10.5147,88.9637},     {46,46}},      // Comet
	// The Camel's Toe
	{415,   {2444.6428,1266.9944,10.5922,358.9572},    {36,1}},       // Cheetah
	{565,   {2458.5305,1357.7480,10.4438,358.9357},    {53,53}},      // Flash
	{567,   {2442.2456,1335.6665,10.6932,90.6199},     {97,96}},      // Savanna
	// Come-A-Lot
	{561,   {2640.1897,1114.3599,10.6342,87.6814},     {67,8}},       // Stratum
	{480,   {2501.2612,1208.6758,10.5939,359.9539},    {4,4}},        // Comet
	{429,   {2392.9595,993.7718,10.5000,91.7214},      {1,3}},        // Banshee
	{522,   {2485.3403,936.8294,10.3920,352.4774},     {3,3}},        // NRG-500
	{558,   {2460.3552,921.9429,10.4508,90.3145},      {24,1}},       // Uranus
	{463,   {2569.5938,1038.9706,10.3544,349.6521},    {22,22}},      // Freeway
	// Linden Station
	{521,   {2804.7852,1326.0862,10.3239,90.6217},     {87,118}},     // FCR-900
	{545,   {2804.7751,1339.0635,10.5617,90.0819},     {40,96}},      // Hustler
	{400,   {2853.3447,1354.8958,10.9059,269.8884},    {75,1}},       // Landstalker
	{475,   {2765.0881,1278.2692,10.5558,90.1357},     {56,29}},      // Sabre
	// Rockshore East
	{535,   {2626.0701,746.7289,9.5852,1.5000},        {55,1}},       // Slamvan
	{562,   {2568.9976,746.3758,10.4799,0.8673},       {17,1}},       // Elegy
	// Rockshore West
	{545,   {2049.0408,738.6982,11.0745,358.2963},     {44,96}},      // Hustler
	{405,   {2087.4722,767.8669,11.1356,180.1878},     {40,1}},       // Sentinel
	{468,   {2130.5808,648.7647,10.1301,9.0000},       {46,46}},      // Sanchez
	{429,   {2263.3459,647.7778,10.8922,180.4328},     {2,1}},        // Banshee
	{463,   {2360.5015,687.6550,11.0005,358.8569},     {19,19}},      // Freeway
	{470,   {2442.6875,709.1329,11.2290,89.8740},      {43,0}},       // Patriot
	// Last Dime Motel
	{559,   {1932.4072,697.9367,10.9135,1.2176},       {101,1}},      // Jester
	// Randolph Industrial Estate
	{482,   {1647.0278,746.2268,10.9379,359.5999},     {52,52}},      // Burrito
	// Blackfield Chapel
	{475,   {1451.8677,787.4940,10.9351,358.3996},     {48,48}},      // Sabre
	// LVA Freight Depot
	{400,   {1655.3875,1028.5929,10.9127,0.5995},      {123,1}},      // Landstalker
	{470,   {1553.6073,1019.8732,10.8130,91.1245},     {43,0}},       // Patriot
	{482,   {1425.0251,1066.7305,10.4366,91.4605},     {71,71}},      // Burrito
	// Las Venturas Airport
	{487,   {1601.6499,1627.3640,10.9989,203.7898},    {54,29}},      // Maverick
	{487,   {1630.7175,1536.9312,10.9760,0.0009},      {26,57}},      // Maverick
	{487,   {1666.0521,1632.2396,11.0244,226.1210},    {29,42}},      // Maverick
	{593,   {1556.7837,1469.9139,11.2863,89.6119},     {58,8}},       // Dodo
	{593,   {1556.7404,1490.5135,11.2914,90.7337},     {60,1}},       // Dodo
	{476,   {1283.0006,1324.8849,9.5332,275.0468},     {7,6}},        // Rustler
	{476,   {1283.5107,1361.3171,9.5382,271.1684},     {1,6}},        // Rustler
	{476,   {1283.6847,1386.5137,11.5300,272.1003},    {89,91}},      // Rustler
	{476,   {1288.0499,1403.6605,11.5295,243.5028},    {119,117}},    // Rustler
	{438,   {1692.2118,1316.2404,10.8254,0.1318},      {6,76}},       // Cabbie
	{438,   {1669.8727,1287.0087,10.8264,179.1879},    {6,76}},       // Cabbie
	{438,   {1669.7830,1306.4453,10.8257,180.5129},    {6,76}},       // Cabbie
	{420,   {1685.7094,1297.7819,10.5971,359.5703},    {6,1}},        // Taxi
	{420,   {1656.9625,1316.4486,10.6011,359.8242},    {6,1}},        // Taxi
	{420,   {1641.1725,1299.1936,10.5988,90.4988},     {6,1}},        // Taxi
	// Hunter Quarry
	{468,   {618.5558,884.0322,-43.1185,60.7366},      {89,90}},      // Sanchez
	// Red County
	{446,   {1618.6696,592.3465,-0.6024,179.0423},     {1,44}},       // Squalo
	{446,   {1637.7090,593.5861,-0.5096,180.0643},     {1,57}},       // Squalo
	{447,   {-350.5415,-413.3116,6.8884,257.0475},     {75,2}},       // Seasparrow
	{446,   {2344.8386,540.2310,-0.5675,181.2978},     {1,57}},       // Squalo
	{446,   {2303.6235,539.7185,-0.6380,181.2930},     {0,0}},        // Squalo
	{446,   {2284.5420,539.3775,-0.5683,180.4290},     {1,44}},       // Squalo
	{568,   {1544.4640,16.1206,24.0035,280.6194},      {9,39}},       // Bandito
	// Bayside
	{571,   {-2440.6904,2243.1841,4.8438,180.2010},    {8,3}},        // Kart
	{571,   {-2443.6787,2243.1536,4.8438,180.2010},    {8,3}},        // Kart
	{571,   {-2446.6096,2243.1050,4.7758,180.2010},    {8,3}},        // Kart
	{571,   {-2449.8267,2243.0588,4.7759,180.2010},    {8,3}},        // Kart
	{571,   {-2452.8452,2243.1338,4.0594,180.2010},    {8,3}},        // Kart
	// Whetstone (Petrol Station)
	{470,   {-1609.6151,-2718.1558,48.5342,231.5696},  {43,0}},       // Patriot
	{468,   {-1557.7052,-2741.2961,48.2089,337.5810},  {53,53}},      // Sanchez
	{463,   {-1555.4904,-2743.1360,48.0808,334.7023},  {11,11}},      // Freeway
	{443,   {-1540.2059,-2747.8230,49.1720,170.2765},  {20,1}},       // Packer
	// Whetstone (Mt Chilliad)
	{495,   {-2639.7834,-2259.0686,8.3627,122.0132},   {119,122}},    // Sandking
	{495,   {-2636.7153,-2263.3516,8.3947,126.0105},   {118,117}},    // Sandking
	{495,   {-2633.5925,-2267.8315,8.4314,124.7480},   {116,115}},    // Sandking
	// San Fierro (near Easter Tunnel)
	{593,   {-1419.1864,-951.2513,201.5534,0.2721},    {60,1}},       // Dodo
	// Missionary Hill
	{522,   {-2531.8560,-601.8262,132.1287,348.3372},  {39,106}},     // NRG-500
	{415,   {-2528.1165,-602.0258,132.3341,0.0547},    {36,1}},       // Cheetah
	{451,   {-2524.3589,-602.0073,132.2706,0.8348},    {125,125}},    // Turismo
	{429,   {-2520.5442,-601.9775,132.2428,1.1523},    {13,13}},      // Banshee
	{480,   {-2516.8877,-602.1099,132.3371,359.9960},  {12,12}},      // Comet
	{506,   {-2513.2051,-602.1282,132.2678,359.7968},  {6,6}},        // Super GT
	{411,   {-2509.4502,-602.6887,132.2896,359.6024},  {64,1}},       // Infernus
	{541,   {-2505.7559,-602.3135,132.1875,0.7726},    {3,1}},        // Bullet
	// Doherty
	{407,   {-2021.5985,75.4813,28.3148,271.9645},     {3,1}},        // Fire Truck
	{407,   {-2021.9418,84.2080,28.2642,269.8905},     {3,1}},        // Fire Truck
	{407,   {-2021.7910,92.5963,28.2868,270.9370},     {3,1}},        // Fire Truck
	{561,   {-1948.0776,270.3802,35.2893,111.1722},    {51,51}},      // Stratum
	{562,   {-1947.8015,263.5302,35.1296,83.8350},     {35,1}},       // Elegy
	{560,   {-1949.2981,258.2466,35.1757,68.8976},     {101,0}},      // Sultan
	{565,   {-1950.7279,259.1814,40.6710,74.6375},     {42,42}},      // Flash
	{558,   {-1949.8453,264.9350,40.6795,79.3161},     {116,1}},      // Uranus
	{559,   {-1988.6575,269.1683,34.8322,85.7853},     {58,8}},       // Jester
	{522,   {-1988.8091,273.6254,34.7360,76.3037},     {51,118}},     // NRG-500
	{506,   {-1986.8201,301.7560,34.8773,89.0623},     {7,7}},        // Super GT
	// Easter Bay Airport
	{593,   {-1357.7231,-225.5625,14.6049,314.2192},   {60,1}},       // Dodo
	{593,   {-1340.9133,-242.4454,14.6084,314.2594},   {58,8}},       // Dodo
	// Palisades
	{437,   {-2899.4502,497.6130,4.9219,267.0314},     {79,7}},       // Coach
	// El Quebrados
	{495,   {-1567.1733,2639.1189,56.1110,267.1029},   {118,117}},    // Sandking
	// Tierra Robada
	{522,   {-1256.1470,2717.0349,49.6315,10.8651},    {8,82}},       // NRG-500
	{522,   {-1258.8401,2715.5261,49.6300,10.4651},    {6,25}},       // NRG-500
	{522,   {-1261.9171,2713.9377,49.6229,14.3367},    {3,3}},        // NRG-500
	{447,   {-651.9423,951.1985,12.1222,268.3986},     {75,2}},       // Seasparrow
	{495,   {-684.3563,966.1020,12.4833,91.3615},      {119,122}},    // Sandking
	// Valle Ocultado
	{539,   {-901.5374,2709.6006,41.7272,190.4259},    {79,1}},       // Vortex
	{539,   {-904.4120,2709.1414,41.7272,190.4259},    {44,1}},       // Vortex
	{539,   {-907.2866,2708.6822,41.7272,190.4259},    {6,1}},        // Vortex
	{539,   {-910.1612,2708.2230,41.7272,190.4259},    {126,1}},      // Vortex
	{539,   {-913.0358,2707.7638,41.7272,190.4259},    {40,1}},       // Vortex
	// Las Payasadas
	{495,   {-231.7425,2594.3213,63.0511,178.7868},    {119,122}},    // Sandking
	// Las Barancas
	{437,   {-859.8746,1556.4474,24.1177,1.1274},      {79,7}},       // Coach
	// Fort Carson
	{400,   {-178.1895,1217.1228,19.8345,89.1810},     {113,1}},      // Landstalker
	{482,   {-177.9118,1225.3112,19.8652,90.8458},     {48,48}},      // Burrito
	{515,   {-306.4295,1115.7853,20.7603,178.5838},    {24,77}},      // Road Train
	// Bone County
	{515,   {647.3869,1250.5055,12.5907,298.4191},     {63,78}},      // Road Train
	{515,   {641.4462,1263.1208,12.6676,268.5403},     {54,77}},      // Road Train
	{521,   {657.0055,1718.8425,6.5577,218.7423},      {75,13}},      // FCR-900
	{522,   {654.7646,1717.0760,6.5618,209.9446},      {3,3}},        // NRG-500
	{400,   {618.9962,1685.2792,7.0846,304.6690},      {101,1}},      // Landstalker
	{451,   {612.5034,1695.1780,6.7000,304.9998},      {36,36}},      // Turismo
	{443,   {598.6343,1653.1960,7.6265,64.2697},       {36,1}},       // Packer
	{562,   {706.5347,1948.6503,5.1993,1.6575},        {35,1}},       // Elegy
	{521,   {701.0619,1948.9867,5.1081,355.1096},      {75,13}},      // FCR-900
	{437,   {683.4955,1945.8807,5.6754,256.9583},      {79,7}},       // Coach
	// Verdant Meadows Air Strip
	{468,   {432.9102,2537.1130,15.7590,142.1203},     {103,111}},    // Sanchez
	{593,   {347.9816,2538.6733,17.2088,178.9511},     {58,8}},       // Dodo
	{476,   {290.8257,2540.9556,17.5273,181.2132},     {1,6}},        // Rustler
	{476,   {325.8478,2541.2153,17.5251,180.5804},     {1,6}},        // Rustler
	// Restricted Area
	{470,   {278.8795,1949.0851,17.6328,297.8679},     {43,0}},       // Patriot
	{470,   {277.7540,1958.3246,17.6353,270.1597},     {43,0}},       // Patriot
	{568,   {276.5266,1982.7072,17.5037,295.7315},     {17,1}},       // Bandito
	{568,   {275.4705,1989.2720,17.5073,271.0313},     {21,1}},       // Bandito
	{568,   {276.6294,1995.8981,17.5063,262.8208},     {9,39}},       // Bandito
	// Hilltop Farm
	{482,   {1110.1783,-306.5116,74.1180,87.9642},     {48,48}},      // Burito
	// Dillimore
	{400,   {652.9937,-569.9136,16.4283,0.3351},       {123,1}},      // Landstalker
	{522,   {668.2988,-461.4507,15.8993,270.4431},     {3,8}},        // NRG-500
	{463,   {668.2633,-464.5114,15.8747,267.3629},     {84,84}},      // Freeway
	{468,   {668.3364,-467.6673,16.0030,269.4489},     {46,46}},      // Sanchez
	// Blueberry
	{515,   {62.5290,-265.0077,2.5905,36.2068},        {24,77}},      // Road Train
	{515,   {49.6592,-242.8187,2.6026,305.9583},       {63,78}},      // Road Train
	// Hampton Barns
	{495,   {751.7941,276.5259,27.6877,194.4415},      {119,122}},    // Sandking
	{468,   {765.0355,377.6133,22.8654,345.1718},      {53,53}},      // Sanchez
	// Montgomery
	{463,   {1289.9039,339.7356,19.0948,244.9244},     {11,11}},      // Freeway
	{463,   {1290.8905,341.7259,19.0938,244.8395},     {7,7}},        // Freeway
	// Flint County
	{515,   {-56.8040,-1136.4802,2.1147,69.7494},      {42,76}},      // Road Train
	// Red County
	{541,   {1011.9688,-660.9052,120.7653,32.1414},    {58,8}},       // Bullet
	{411,   {1007.0956,-663.6238,120.8738,32.5321},    {0,0}},        // Infernus
	{522,   {1001.7659,-677.0204,120.7175,330.7499},   {6,0}},        // NRG-500
	// Richman
	{429,   {298.5416,-1182.5927,80.5951,357.4430},    {6,0}},        // Banshee
	{522,   {294.0222,-1179.8579,80.4783,352.6656},    {3,8}},        // NRG-500
	{421,   {283.2916,-1160.5918,80.7961,224.3582},    {0,0}},        // Washington
	{451,   {287.3322,-1156.2987,80.6187,224.2682},    {125,125}},    // Turismo
	// Jefferson (Coutt and Schutz)
	{463,   {2135.8816,-1129.0271,25.1558,103.9032},   {7,7}},        // Freeway
	{545,   {2135.4683,-1133.3173,25.5013,53.9124},    {47,1}},       // Hustler
	{400,   {2135.4797,-1140.2880,25.4055,59.5536},    {123,1}},      // Landstalker
	{475,   {2118.9385,-1145.9985,24.3498,306.6122},   {9,39}},       // Sabre
	{535,   {2119.6768,-1138.6453,24.8455,300.4818},   {31,1}},       // Slamvan
	{567,   {2120.3372,-1131.3032,25.2190,316.5004},   {93,64}},      // Savanna
	// East Beach (stadium)
	{567,   {2767.9006,-1876.0645,9.6145,0.0},         {62,1}},       // Savanna
	{567,   {2772.7715,-1876.0645,9.6334,0.0},         {114,1}},      // Savanna
	{567,   {2777.8286,-1876.0645,9.6599,0.0},         {99,81}},      // Savanna
	{567,   {2782.9099,-1876.0645,9.6810,0.0},         {97,96}},      // Savanna
	// Verona Beach
	{446,   {926.6152,-1905.3445,-0.5741,359.4543},    {1,85}},       // Squalo
	{446,   {914.3162,-1905.6047,-0.5741,359.4543},    {109,109}},    // Squalo
	{446,   {902.0172,-1905.8649,-0.5741,359.4543},    {1,6}},        // Squalo
	{446,   {889.7182,-1906.1251,-0.5741,359.4543},    {3,3}},        // Squalo
	// Los Santos Inlet
	{468,   {-261.8891,-2216.8667,28.3333,134.0421},   {46,46}},      // Sanchez
	{568,   {-284.9293,-2169.6260,28.5094,189.5060},   {9,39}},       // Bandito
	{495,   {-258.9196,-2182.2327,29.3668,24.2143},    {119,122}}     // Sandking
};

//------------------------------------------------------------------------------------------------------
// INI customisation

enum GMC_MAIN {
	GMC_AC_PROTECTADMINS,
	GMC_AC_MONEY,
	GMC_AC_WEAPON,
	GMC_AC_SPOOFKILL,
	GMC_AC_SPAWNKILL,
	GMC_AC_SPAWNKILL_KILLS,
	Float:GMC_AC_SPAWNKILL_DIST,
	GMC_REG_KICK,
	GMC_STAT_SAVEINT,
	GMC_STAT_MAXRESTORE,
	GMC_PB_TEXT,
	GMC_WE_TEXT,
	GMC_VEHICLELOCK,
	GMC_VEHICLELOCK_AUTOUNLOCK,
	GMC_DM_ZONEWARNINGS,
	GMC_DM_TEXT,
	GMC_DM_BANK,
	GMC_DM_GROUPGANGS,
	GMC_DM_STEALTH,
	GMC_TAX,
	GMC_MAXBANK,
	GMC_POCKETMONEY,
	GMC_SPEEDO
};

new gGMConfig[GMC_MAIN];

//------------------------------------------------------------------------------------------------------
// Anti cheat

#define KICK_CHEAT_MONEY            0
#define KICK_CHEAT_MONEY_GAMBLING   1
#define KICK_CHEAT_WEAPON_FREEROAM  2
#define KICK_CHEAT_WEAPON_DM        3
#define KICK_CHEAT_SPOOFKILL        4
#define KICK_SPAWNKILL              5
#define KICK_SIGNINERROR            6
#define MAX_FREEROAMWEAPONS        13
#define MAX_AC_MONEYWARNINGS        3

new gFreeroamWeapons[MAX_FREEROAMWEAPONS] = {
	WEAPON_FIST,
	WEAPON_NIGHTSTICK,
	WEAPON_PISTOL,
	WEAPON_SILENCEDPISTOL,
	WEAPON_DEAGLE,
	WEAPON_SHOTGUN,
	WEAPON_SHOTGUNSAWNOFF,
	WEAPON_SHOTGUNCOMBAT,
	WEAPON_MP5,
	WEAPON_AK47,
	WEAPON_M4,
	WEAPON_TEC9,
	WEAPON_FLAMETHROWER  // needed because SA-MP incorrectly detects this weapon
};

enum AC_MAIN {
	AC_KICK,
	AC_KICK_MSG[MAX_STRING],
	AC_KICK_TIME,
	AC_MONEY[2],
	AC_MONEY_GAMBLE[2]
};

new gPlayerAC[MAX_PLAYERS][AC_MAIN];

//------------------------------------------------------------------------------------------------------
// Gangs

#define MAX_GANGS         13
#define MAX_GANG_NAME     16
#define MAX_GANG_MEMBERS   8

enum GANG_MAIN {
	GANG_NAME[MAX_GANG_NAME],
	GANG_COLOUR,
	GANG_MEMBERS[MAX_GANG_MEMBERS],
	GANG_TOTALMEMBERS,
	GANG_BANK
};

new gGangs[MAX_GANGS][GANG_MAIN];

enum PGANG_MAIN {
	PGANG_ID,
	PGANG_INVITE
};

new gPlayerGang[MAX_PLAYERS][PGANG_MAIN];

//------------------------------------------------------------------------------------------------------
// Taxman

#define MAX_TAXRANGES  5

enum TAX_MAIN {
	TAX_LOWER_RANGE,
	TAX_UPPER_RANGE,
	Float:TAX_RATE
};

new gTaxes[MAX_TAXRANGES][TAX_MAIN] = {
	{100000,149999,0.10},
	{150000,199999,0.20},
	{200000,249999,0.30},
	{250000,299999,0.40},
	{350000,99999999,0.50}
};

//------------------------------------------------------------------------------------------------------
// Officer patrol

#define MAX_PATROL_WARNINGS      3
#define MAX_PATROL_PROXIMITY  35.0
#define MAX_PATROL_VEHICLES      2
#define BUST_RACER               0
#define BUST_PITBOSS             1

enum PATROL_MAIN {
	PATROL_ONDUTY,
	PATROL_SUSPECT,
	PATROL_WARNINGS,
	PATROL_WARNINGREASON
}

new gPlayerPatrol[MAX_PLAYERS][PATROL_MAIN];
new gPatrolVehicles[MAX_PATROL_VEHICLES];

//------------------------------------------------------------------------------------------------------
// Taxi Driver

#define TAXI_REGFEE                 11500
#define TAXI_PICKUPFEE                 10
#define TAXI_DRIVER                     0
#define TAXI_PASSENGER                  1
#define MAX_TAXI_METER_FEE            500
#define MIN_TAXI_METER_FEE             20
#define TAXI_BONUS_PASSENGER_COUNT      5
#define TAXI_BONUS_CASH              5000

enum TAXI_MAIN {
	TAXI_STATUS,
	TAXI_VEHICLE,
	Float:TAXI_POS[3],
	TAXI_METER,
	TAXI_METER_FEE,
	TAXI_PASSENGERS
};

new gPlayerTaxi[MAX_PLAYERS][TAXI_MAIN];

//------------------------------------------------------------------------------------------------------
// Pit Boss

#define MAX_CASINO                2
#define MAX_GFEE              10000
#define MIN_GFEE                  1
#define PB_MAXTRANSPORTTIME       4  // 4mins
#define PB_DRAGON                 0
#define PB_CALIGULA               1

enum PITBOSS_MAIN {
	PB_OWNER,
	PB_GFEE,
	PB_CASH,
	Float:PB_GAMBLINGAREA[6],
	PB_TRANSPORTING,
	PB_TRANSPORT_COUNT,
	PB_VEHICLE_SECURICAR,
	PB_VEHICLE_1,
	PB_VEHICLE_2,
	PB_VEHICLE_3
};

new gPitBoss[MAX_CASINO][PITBOSS_MAIN] = {
//	OWNER                GFEE       CASH  GAMBLING AREA (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax)                   TRANSPORTING
	{INVALID_PLAYER_ID,  MIN_GFEE,  0,    {2171.3618,1584.2649,1005.1797,2279.4915,1628.6199,1015.1797},  0, ...},
	{INVALID_PLAYER_ID,  MIN_GFEE,  0,    {1928.1771,987.5739,991.4688,1970.5675,1042.8369,1001.4688},    0, ...}
};

//------------------------------------------------------------------------------------------------------
// Wang exports

#define MAX_WANGEXPORT_VEHICLES     22
#define MAX_WANGEXPORT_CASH      30000
#define MIN_WANGEXPORT_CASH      10000

new gWantedWangExportVehicle;

new gWantedWangExportVehicles[MAX_WANGEXPORT_VEHICLES] = {
	400,405,411,415,420,421,429,434,451,463,468,470,475,480,482,495,521,535,541,545,567,568
};

//------------------------------------------------------------------------------------------------------
// Deathmatch Arena

#define MAX_DMARENAS  14
#define DM_WEAPON      0
#define DM_AMMO        1

enum DM_MAIN {
	DM_NAME[30],
	Float:DM_SPAWN1[4],
	DM_SPAWN1_COUNT,
	Float:DM_SPAWN2[4],
	DM_SPAWN2_COUNT,
	Float:DM_AREA[4],
	DM_WEAPON1[2],
	DM_WEAPON2[2]
};

new gDMArenas[MAX_DMARENAS][DM_MAIN] = {
//	NAME                               SPAWN1 (X,Y,Z,angle)                        SPAWN1_COUNT  SPAWN2 (X,Y,Z,angle)                        SPAWN2_COUNT  AREA (Xmin,Ymin,Xmax,Ymax)                      WEAPON1 (weapon,ammo)         WEAPON2 (weapon,ammo)
	{"Hunter Quarry",                  {434.5465,896.3121,1.8641,185.1584},        0,            {690.6714,845.3350,-39.0077,117.7910},      0,            {399.2510,788.0517,736.5633,1050.3473},         {WEAPON_M4,1500},             {WEAPON_FIST,0}},
	{"Back O' Beyond Swamp",           {-600.5984,-1989.0066,43.4250,8.4601},      0,            {-623.1288,-1779.0776,100.2193,200.8486},   0,            {-634.0051,-2001.1038,-440.6504,-1722.3127},    {WEAPON_DEAGLE,120},          {WEAPON_M4,1500}},
	{"Montgomery",                     {1447.7856,362.7201,18.9239,160.1148},      0,            {1247.3853,204.2742,23.0547,12.2201},       0,            {1153.1282,197.6021,1531.6736,435.2268},        {WEAPON_AK47,1500},           {WEAPON_FIST,0}},
	{"K.A.C.C. Military Fuels",        {2593.3096,2638.1885,114.0313,347.1531},    0,            {2632.5679,2832.2026,127.5781,168.8648},    0,            {2494.8147,2615.9419,2750.4375,2859.4443},      {WEAPON_MINIGUN,5000},        {WEAPON_PARACHUTE,0}},
	{"Las Barrancas",                  {-938.8171,1427.7638,30.4340,333.6797},     0,            {-734.1335,1546.4265,39.0080,264.4323},     0,            {-939.4901,1384.7155,-707.3583,1636.4291},      {WEAPON_DEAGLE,120},          {WEAPON_FIST,0}},
	{"Ocean Docks",                    {2790.4875,-2378.6331,16.2244,149.7982},    0,            {2414.8733,-2651.1584,17.9107,89.6377},     0,            {2374.1794,-2696.3215,2810.3977,-2330.2258},    {WEAPON_SHOTGUNCOMBAT,120},   {WEAPON_PISTOL,0}},
	{"Ocean Docks Container Storage",  {2453.8127,-2208.9075,26.6328,249.4158},    0,            {2753.7483,-2231.1760,18.8828,83.9977},     0,            {2435.5593,-2259.0547,2763.6199,-2182.2756},    {WEAPON_RIFLE,240},           {WEAPON_TEC9,1500}},
	{"Ocean Docks Loading Bay",        {2449.8110,-2129.0605,39.4219,195.5454},    0,            {2668.4905,-2073.3923,26.5938,116.8980},    0,            {2425.2222,-2143.8071,2702.7571,-2066.7720},    {WEAPON_MP5,1500},            {WEAPON_FIST,0}},
	{"El Quebrados",                   {-1308.0055,2544.7805,87.7422,173.9252},    0,            {-1665.8292,2551.0815,88.3455,295.4996},    0,            {-1679.7235,2459.0403,-1274.9779,2756.8276},    {WEAPON_PISTOL,240},          {WEAPON_TEC9,1500}},
	{"Green Palms Refinery",           {247.9906,1468.6728,60.1355,145.1216},      0,            {199.8452,1404.6445,60.1355,52.4466},       0,            {110.8816,1336.2959,288.1432,1484.3304},        {WEAPON_AK47,1500},           {WEAPON_PARACHUTE,0}},
	{"Easter Basin Aircraft Carrier",  {-1462.5336,489.2468,3.0414,271.7095},      0,            {-1358.9319,497.6422,24.2969,354.7437},     0,            {-1470.3805,486.9461,-1243.6833,520.1677},      {WEAPON_SILENCEDPISTOL,170},  {WEAPON_KNIFE,0}},
	{"San Fierro Bay Container Ship",  {-2336.1484,1542.9773,17.3281,271.4835},    0,            {-2477.6333,1550.5587,33.2344,243.8866},    0,            {-2527.0298,1525.5637,-2283.4482,1576.6284},    {WEAPON_PISTOL,240},          {WEAPON_FLAMETHROWER,5000}},
	{"Mount Chiliad",                  {-2798.1133,-1360.4624,132.4197,185.4717},  0,            {-2816.5259,-1652.0499,141.5092,8.7500},    0,            {-2851.9526,-1818.3044,-2642.0146,-1270.1024},  {WEAPON_DEAGLE,120},          {WEAPON_KNIFE,0}},
	{"Area51 Research Facility",       {275.6678,1856.1140,8.7578,8.7500},         0,            {215.7180,1822.9941,6.4141,268.4823},       0,            {185.9494,1797.4834,314.8864,1893.0876},        {WEAPON_UZI,5000},            {WEAPON_FLAMETHROWER,5000}}
};

enum DMP_MAIN {
	DM_ZONE,
	DM_SPAWN
};

new gPlayerDM[MAX_PLAYERS][DMP_MAIN];

//------------------------------------------------------------------------------------------------------
// Street racing

#define MAX_RACES           23
#define RACE_SPONSOR_WANG    0
#define RACE_SPONSOR_OTTO    1
#define RACE_SPONSOR_CANDA   2
#define RACE_TYPE_CIRCUIT    0
#define RACE_TYPE_SPRINT     1

enum RACE_PS_MAIN {
	PRACE_ID,
	PRACE_CP,
	PRACE_STARTTIME,
	PRACE_LAPCOUNT
};

new gPlayerRace[MAX_PLAYERS][RACE_PS_MAIN];

enum RACE_MAIN {
	RACE_NAME[24],
	RACE_CPSTART,
	RACE_CPEND,
	RACE_STARTTIME,
	RACE_COUNTDOWN,
	RACE_TOTALRACERS,
	RACE_COMPLETEDRACERS,
	RACE_TIMEOUT,  // in seconds
	RACE_SPLITDISPLAY,
	RACE_TYPE,
	RACE_REQLAPS,
	RACE_REQTIME,
	RACE_REQVEHICLETYPE,
	RACE_REQVEHICLE,
	RACE_REQCASH,
	RACE_REQPOINTS,
	RACE_CASH,
	RACE_POINTS,
	RACE_RECORD,
	RACE_FORMATTEDRECORD[MAX_STRING]
};

new gRaces[MAX_RACES][RACE_MAIN] = {
//	NAME                        CPSTART  CPEND  COUNTDOWN  STARTTIME  TOTALRACERS  COMPLETEDRACERS  TIMEOUT  SPLITDISPLAY  TYPE                REQLAPS  REQTIME  REQVEHICLETYPE           REQVEHICLE  REQCASH  REQPOINTS  CASH    POINTS  RECORD  FORMATTEDRECORD
	{"Dust Devil",              0,       11,    -1,        -1,        0,           0,               300,     1,            RACE_TYPE_CIRCUIT,  1,       -1,      VEHICLE_CLASS_LAND,      -1,         600,     0,         800,    2,      0,      "None"},
	{"Fastlane",                12,      26,    -1,        -1,        0,           0,               240,     1,            RACE_TYPE_SPRINT,   -1,      -1,      VEHICLE_CLASS_LAND,      -1,         750,     0,         1000,   2,      0,      "None"},
	{"Bayside Tour",            27,      36,    -1,        -1,        0,           0,               240,     4,            RACE_TYPE_CIRCUIT,  1,       -1,      VEHICLE_CLASS_LAND,      571,        800,     10,        1000,   2,      0,      "None"},
	{"Water Under The Bridge",  37,      54,    -1,        -1,        0,           0,               360,     1,            RACE_TYPE_CIRCUIT,  2,       -1,      VEHICLE_CLASS_WATER,     -1,         15000,   200,       38000,  16,     0,      "None"},
	{"Right Turn",              55,      72,    -1,        -1,        0,           0,               300,     4,            RACE_TYPE_CIRCUIT,  2,       -1,      VEHICLE_CLASS_LAND,      -1,         2000,    50,        7000,   6,      0,      "None"},
	{"Three Sands",             73,      82,    -1,        -1,        0,           0,               240,     1,            RACE_TYPE_SPRINT,   -1,      -1,      VEHICLE_TYPE_AMPHIBIOUS, -1,         3000,    10,        8000,   5,      0,      "None"},
	{"Eightball Confusion",     83,      90,    -1,        -1,        0,           0,               300,     4,            RACE_TYPE_CIRCUIT,  5,       -1,      VEHICLE_CLASS_LAND,      571,        5000,    20,        6050,   4,      0,      "None"},
	{"Aircaville",              91,      102,   -1,        -1,        0,           0,               300,     1,            RACE_TYPE_CIRCUIT,  2,       -1,      VEHICLE_TYPE_AMPHIBIOUS, -1,         700,     0,         950,    1,      0,      "None"},
	{"Going Up?",               103,     110,   -1,        -1,        0,           0,               240,     1,            RACE_TYPE_SPRINT,   -1,      -1,      VEHICLE_CLASS_LAND,      -1,         3000,    15,        4250,   3,      0,      "None"},
	{"Luv'n",                   111,     127,   -1,        -1,        0,           0,               300,     1,            RACE_TYPE_SPRINT,   -1,      -1,      VEHICLE_CLASS_LAND,      -1,         2000,    10,        1500,   4,      0,      "None"},
	{"No Where",                128,     136,   -1,        -1,        0,           0,               300,     1,            RACE_TYPE_CIRCUIT,  2,       -1,      VEHICLE_CLASS_LAND,      -1,         500,     0,         900,    0,      0,      "None"},
	{"Back Roads",              137,     158,   -1,        -1,        0,           0,               360,     4,            RACE_TYPE_SPRINT,   -1,      -1,      VEHICLE_CLASS_LAND,      -1,         2000,    20,        1800,   6,      0,      "None"},
	{"Pace",                    159,     177,   -1,        -1,        0,           0,               300,     4,            RACE_TYPE_SPRINT,   -1,      -1,      VEHICLE_CLASS_LAND,      -1,         1000,    20,        3000,   3,      0,      "None"},
	{"Marina Dash",             178,     191,   -1,        -1,        0,           0,               300,     1,            RACE_TYPE_SPRINT,   -1,      -1,      VEHICLE_CLASS_WATER,     -1,         2000,    40,        5900,   6,      0,      "None"},
	{"Bullitt",                 192,     210,   -1,        -1,        0,           0,               300,     4,            RACE_TYPE_CIRCUIT,  2,       -1,      VEHICLE_CLASS_LAND,      -1,         6000,    70,        9000,   2,      0,      "None"},
	{"Jerry",                   211,     225,   -1,        -1,        0,           0,               300,     1,            RACE_TYPE_CIRCUIT,  1,       -1,      VEHICLE_CLASS_LAND,      -1,         6000,    30,        9000,   6,      0,      "None"},
	{"Dune",                    226,     235,   -1,        -1,        0,           0,               240,     1,            RACE_TYPE_CIRCUIT,  3,       -1,      VEHICLE_CLASS_LAND,      -1,         5000,    60,        8700,   7,      0,      "None"},
	{"Treacherous Sarasvati",   236,     252,   -1,        -1,        0,           0,               300,     1,            RACE_TYPE_SPRINT,   -1,      -1,      VEHICLE_CLASS_WATER,     -1,         10000,   100,       30000,  12,     0,      "None"},
	{"Tolsma Beginning",        253,     277,   -1,        -1,        0,           0,               300,     4,            RACE_TYPE_CIRCUIT,  1,       -1,      VEHICLE_CLASS_LAND,      571,        11000,   120,       27000,  10,     0,      "None"},
	{"Jack 'n Jill",            278,     299,   -1,        -1,        0,           0,               300,     1,            RACE_TYPE_CIRCUIT,  1,       -1,      VEHICLE_CLASS_LAND,      -1,         3000,    5,         5500,   2,      0,      "None"},
	{"Hilltop Mill",            300,     310,   -1,        -1,        0,           0,               240,     1,            RACE_TYPE_SPRINT,   -1,      -1,      VEHICLE_CLASS_LAND,      -1,         8000,    60,        10500,  4,      0,      "None"},
	{"Dusty Roads",             311,     322,   -1,        -1,        0,           0,               300,     1,            RACE_TYPE_CIRCUIT,  1,       -1,      VEHICLE_CLASS_LAND,      -1,         10000,   80,        30500,  10,     0,      "None"},
	{"Old School",              323,     335,   -1,        -1,        0,           0,               300,     1,            RACE_TYPE_CIRCUIT,  1,       -1,      VEHICLE_CLASS_LAND,      567,        10000,   55,        27000,  4,      0,      "None"}
};

new Float:gRaceCheckpoints[][4] = {
	{-768.8769,2730.1309,45.4151,15.0},  // Dust Devil
	{-994.3484,2714.3503,45.8672,10.0},
	{-1202.7035,2631.5608,52.1334,10.0},
	{-1109.4838,2419.6350,81.4255,10.0},
	{-1150.9731,2102.6924,84.8138,10.0},
	{-1211.9895,1864.1584,40.3733,10.0},
	{-971.7077,1832.3748,61.6141,10.0},
	{-756.6122,2056.0596,59.9461,10.0},
	{-436.6937,2120.0767,46.5704,10.0},
	{-371.6131,2351.1440,29.2572,10.0},
	{-588.2740,2514.8264,75.5239,10.0},
	{-768.8769,2730.1309,45.4151,10.0},
	{960.4440,733.6182,10.4246,17.0},  // Fastlane
	{702.5709,657.0952,9.2782,10.0},
	{381.6338,755.2902,5.8612,10.0},
	{-73.7830,584.2697,13.7547,10.0},
	{-569.7733,616.8351,16.3647,10.0},
	{-888.3674,846.1666,19.1802,10.0},
	{-1125.6389,1517.3347,22.2438,10.0},
	{-1612.1970,1782.3490,9.9386,10.0},
	{-1743.8693,2172.2529,16.6304,10.0},
	{-2007.6545,2572.9683,54.8235,10.0},
	{-2695.5010,2552.4841,76.3446,10.0},
	{-2714.0632,2360.6011,71.1038,10.0},
	{-2628.7134,2506.1189,27.8944,10.0},
	{-2488.9316,2428.6089,16.0156,10.0},
	{-2276.6877,2354.9668,4.6336,10.0},
	{-2227.9651,2326.5593,7.5469,10.0},  // Bayside Tour
	{-2287.2295,2279.4375,4.2537,9.0},
	{-2431.0364,2301.7419,4.2659,9.0},
	{-2497.8606,2214.2861,4.2680,9.0},
	{-2615.0693,2304.8044,7.4872,9.0},
	{-2594.2239,2458.5981,19.6351,9.0},
	{-2468.9353,2554.7456,22.8853,9.0},
	{-2272.0784,2552.6316,3.2372,9.0},
	{-2287.2439,2419.6404,4.1978,9.0},
	{-2227.9651,2326.5593,7.5469,10.0},
	{2263.9019,482.2055,-0.4068,20.0},  // Water Under The Bridge
	{1867.4991,510.2875,-0.6732,16.0},
	{1377.3889,586.8354,-0.4513,16.0},
	{957.0933,594.8831,-0.4821,16.0},
	{386.1639,317.6354,-0.5569,16.0},
	{96.7395,192.6710,-0.5354,16.0},
	{-184.8372,302.7436,-0.3960,16.0},
	{-620.5742,310.7862,-0.5682,16.0},
	{-956.9727,43.1476,-0.6076,16.0},
	{-921.6808,-312.9729,-0.6370,16.0},
	{-421.1471,-334.2631,-0.5480,16.0},
	{-55.1399,-590.4675,-0.6147,16.0},
	{295.6742,-349.9172,-0.6093,16.0},
	{763.8837,-181.1484,-0.5527,16.0},
	{1258.2032,-184.4532,-0.4742,16.0},
	{1707.8536,-17.8053,-0.5373,16.0},
	{2104.1912,50.6238,-0.5744,16.0},
	{2263.9019,482.2055,-0.4068,16.0},
	{-2685.1467,468.3502,5.5702,20.0},  // Right Turn
	{-2791.9600,467.1815,5.0058,16.0},
	{-2849.7869,484.8507,3.8342,16.0},
	{-2837.5994,700.3406,24.2679,16.0},
	{-2831.9951,961.6788,43.4732,16.0},
	{-2881.3501,1137.4923,19.0032,16.0},
	{-2659.4231,1289.7703,6.6061,16.0},
	{-2455.4395,1356.0621,6.6092,16.0},
	{-2469.7180,1219.1582,34.6492,16.0},
	{-2628.2292,1182.1476,34.5848,16.0},
	{-2734.6614,1104.1705,46.1033,16.0},
	{-2677.3391,1204.4344,54.9935,16.0},
	{-2611.9473,1127.1266,54.9887,16.0},
	{-2524.6282,1069.5999,58.2918,16.0},
	{-2526.9170,895.7682,64.2199,16.0},
	{-2526.9065,625.8153,27.6348,16.0},
	{-2539.2737,475.8054,14.0279,16.0},
	{-2685.1467,468.3502,5.5702,16.0},
	{-504.2885,2182.6306,41.0580,15.0},  // Three Sands
	{-692.8309,2127.0205,41.0244,11.0},
	{-914.2137,2133.1821,40.9737,11.0},
	{-1167.4318,2157.2402,41.0862,11.0},
	{-1389.0740,2060.6262,51.2332,11.0},
	{-1513.8218,1963.2596,47.7213,11.0},
	{-1775.0813,1907.7542,15.0911,11.0},
	{-1915.9333,2147.6194,0.4159,11.0},
	{-2119.4614,2368.1711,0.3900,11.0},
	{-2327.6504,2503.0754,0.5339,11.0},
	{-2486.5261,2517.1675,17.3465,7.0},  // Eightball Confusion
	{-2484.3745,2478.5518,17.3416,6.0},
	{-2398.9312,2477.3701,9.5726,6.0},
	{-2397.0784,2497.9700,10.9230,6.0},
	{-2466.1738,2501.4751,15.9659,6.0},
	{-2517.6445,2502.9915,18.1821,6.0},
	{-2517.8882,2523.1638,18.0713,6.0},
	{-2486.5261,2517.1675,17.3465,6.0},
	{-966.4324,2643.5464,40.9758,15.0},  //Aircaville
	{-943.1414,2488.3088,41.0333,11.0},
	{-881.2023,2264.4373,41.0525,11.0},
	{-784.0468,2123.1272,41.0265,11.0},
	{-616.9702,2081.8928,41.0671,11.0},
	{-506.6332,2209.8677,41.0333,11.0},
	{-669.3363,2200.6438,40.9644,11.0},
	{-854.7924,2096.0615,40.9928,11.0},
	{-970.5964,2324.7385,40.9756,11.0},
	{-1077.3926,2563.6973,41.0222,11.0},
	{-1174.2169,2755.6677,40.9409,11.0},
	{-966.4324,2643.5464,40.9758,11.0},
	{-2390.3538,-2203.0872,33.2891,17.0},  // Going Up?
	{-2132.3562,-1917.4426,116.5317,12.0},
	{-2344.9683,-2095.3113,114.5274,12.0},
	{-2627.4224,-1835.1287,218.7748,12.0},
	{-2527.4897,-1855.2715,306.5247,12.0},
	{-2586.2493,-1681.8401,352.7166,12.0},
	{-2435.1367,-1804.9152,411.1393,12.0},
	{-2324.2275,-1623.8970,484.0653,12.0},
	{2543.0781,1012.0637,10.4225,18.0},  // Luv'n
	{2527.4045,1317.5782,10.5784,16.0},
	{2539.3042,1525.8682,10.2969,16.0},
	{2507.5164,1731.9197,10.2967,16.0},
	{2527.4229,2085.1824,10.2968,16.0},
	{2228.0361,2136.5815,10.2961,16.0},
	{1999.2305,2113.1025,10.2968,16.0},
	{1776.0942,2173.1541,10.4530,16.0},
	{1527.2020,2106.8359,10.2968,16.0},
	{1547.9091,1973.6052,10.2969,16.0},
	{1567.4656,1781.5397,10.3115,16.0},
	{1767.4790,1816.9302,6.4002,16.0},
	{1787.6453,2231.3127,4.3869,16.0},
	{1490.7322,2452.8860,6.3593,16.0},
	{1031.3876,2545.0059,10.2401,16.0},
	{640.7631,2460.0029,30.6051,16.0},
	{663.2757,1962.3256,5.8510,16.0},
	{1042.7639,-2019.8535,12.5588,18.0},  // No Where
	{1104.2753,-2375.0413,11.4097,16.0},
	{1336.3232,-2600.8538,12.9998,16.0},
	{2128.7466,-2662.5674,12.9999,16.0},
	{2128.6660,-2326.4580,12.9813,16.0},
	{1903.9204,-2166.6145,13.0077,16.0},
	{1529.8291,-1986.6089,23.4409,16.0},
	{1266.4916,-1852.2683,13.0077,16.0},
	{1042.7639,-2019.8535,12.5588,16.0},
	{-110.4382,-97.4268,2.7422,20.0},  // Back Roads
	{-35.6646,-202.7928,1.2197,17.0},
	{240.9247,-212.8593,1.0580,17.0},
	{352.0965,-94.3385,0.9557,17.0},
	{434.7423,12.2750,7.1566,17.0},
	{525.5955,80.8106,21.0914,17.0},
	{555.4393,165.9326,24.8435,17.0},
	{807.4002,214.9393,37.1730,17.0},
	{1015.1445,174.8448,30.0085,17.0},
	{1166.1698,302.5778,17.9060,17.0},
	{1314.3752,235.9252,19.0304,17.0},
	{1425.5968,207.6501,18.1238,17.0},
	{1816.6566,192.7651,29.6226,17.0},
	{2073.2700,104.1172,27.1506,17.0},
	{2394.0955,67.1737,25.9608,17.0},
	{2638.5061,28.4389,26.3405,17.0},
	{2689.5637,-163.7186,34.8071,17.0},
	{2683.5525,-413.7129,53.2850,17.0},
	{2758.5767,-736.6437,56.7092,17.0},
	{2663.5098,-926.9838,73.8974,17.0},
	{2459.0234,-970.7441,79.7118,17.0},
	{2339.6152,-1047.1232,52.2521,17.0},
	{435.0856,-529.4698,42.5854,18.0},  // Pace
	{478.6890,-371.6828,28.8377,15.0},
	{528.2913,-122.0558,37.1176,15.0},
	{525.0408,245.8118,14.1129,15.0},
	{649.2278,310.5838,19.4539,15.0},
	{933.0985,373.4023,19.4416,15.0},
	{1102.7587,576.3670,19.4540,15.0},
	{1388.8677,439.8092,19.4410,15.0},
	{1745.0463,386.3632,19.2303,15.0},
	{1997.3301,348.0247,27.3102,15.0},
	{2147.7876,240.4559,14.0727,15.0},
	{2344.0476,228.7420,25.8998,15.0},
	{2315.3071,283.9052,26.8515,15.0},
	{1932.1979,286.6570,31.4463,15.0},
	{1711.5120,306.9321,20.2171,15.0},
	{1768.0015,580.3362,23.3722,15.0},
	{1764.0168,835.8906,9.7988,15.0},
	{1426.9980,835.3503,6.3840,15.0},
	{1063.9213,782.1961,10.2507,15.0},
	{1605.3835,537.2941,-0.4996,20.0},  // Marina Dash
	{1856.2898,508.7566,-0.4909,16.0},
	{2177.9133,290.8115,-0.5147,16.0},
	{2005.4084,-84.8071,-0.5983,16.0},
	{1593.8789,-126.2781,-0.4949,16.0},
	{1229.3861,-152.1033,-0.5574,16.0},
	{723.8047,-209.1560,-0.5187,16.0},
	{294.7455,-354.4502,-0.5888,16.0},
	{-52.6780,-610.8663,-0.5423,16.0},
	{14.9497,-912.9983,-0.5903,16.0},
	{90.9849,-1148.8900,-0.4832,16.0},
	{43.3004,-1607.7220,-0.6484,16.0},
	{263.8876,-2011.0693,-0.3202,16.0},
	{899.0437,-1962.6243,-0.4830,16.0},
	{-2255.3508,-9.0412,34.7392,20.0},  // Bullitt
	{-2251.5623,222.1380,34.7310,16.0},
	{-2298.5608,408.8454,34.5772,16.0},
	{-2386.5610,606.7647,29.1675,16.0},
	{-2387.0933,938.8635,44.8636,16.0},
	{-2400.5325,1085.9475,55.1451,16.0},
	{-2603.2244,1122.9561,55.0181,16.0},
	{-2634.6245,1211.5518,54.1889,16.0},
	{-2459.3269,1199.3387,34.6738,16.0},
	{-2278.6982,1176.0835,55.1090,16.0},
	{-2141.6023,1133.1025,67.4458,16.0},
	{-2143.4910,883.4421,79.4120,16.0},
	{-2143.1716,704.8212,68.9809,16.0},
	{-2143.6868,477.9875,34.5826,16.0},
	{-2146.5952,170.4455,34.7388,16.0},
	{-2166.8662,21.9151,34.7385,16.0},
	{-2197.9082,-69.9361,34.7389,16.0},
	{-2255.7212,-52.7203,34.7389,16.0},
	{-2255.3508,-9.0412,34.7392,16.0},
	{-238.4895,2634.2556,63.0216,20.0},  // Jerry
	{265.7311,2738.7544,60.1957,17.0},
	{766.6691,2704.5486,48.0370,17.0},
	{783.9382,2240.9661,9.6757,17.0},
	{857.0721,1579.2692,17.3996,17.0},
	{734.7920,1110.5352,28.7389,17.0},
	{214.3634,1000.6898,27.6433,17.0},
	{373.0702,1493.9045,9.6383,17.0},
	{585.2939,1826.9283,14.3447,17.0},
	{561.2527,2276.3386,34.5613,17.0},
	{161.7783,2283.7639,22.0623,17.0},
	{-197.6888,2503.0015,25.7737,17.0},
	{-639.0822,2473.5417,75.6246,17.0},
	{-668.1237,2740.3530,58.7980,17.0},
	{-238.4895,2634.2556,63.0216,17.0},
	{-2668.3191,-2246.4521,5.4405,17.0},  // Dune
	{-2771.3958,-2530.3469,3.3513,12.0},
	{-2615.7175,-2775.1965,3.5570,12.0},
	{-2394.3357,-2854.2898,3.9257,12.0},
	{-2152.4116,-2829.8967,1.6272,12.0},
	{-1879.6536,-2751.2068,9.1258,12.0},
	{-2188.7422,-2806.9724,5.9882,12.0},
	{-2470.8572,-2735.6555,8.3306,12.0},
	{-2646.4084,-2464.7451,6.1860,12.0},
	{-2668.3191,-2246.4521,5.4405,12.0},
	{900.9455,-1993.5244,-0.6398,20.0},  // Treacherous Sarasvati
	{563.0526,-1985.7623,-0.4228,16.0},
	{297.5530,-2105.4958,-0.3344,16.0},
	{104.7726,-2623.2646,-0.6955,16.0},
	{-164.9999,-2939.4036,-0.9317,16.0},
	{-583.9410,-2954.3740,0.0783,16.0},
	{-1001.8202,-2923.7803,-0.2472,16.0},
	{-1185.4100,-2611.4873,-0.5829,16.0},
	{-1207.2715,-2315.3098,-0.5005,16.0},
	{-1358.7010,-1765.7704,-0.5170,16.0},
	{-1695.6187,-1591.4415,-0.4977,16.0},
	{-2070.7090,-1225.3699,-0.5728,16.0},
	{-2448.2678,-898.4624,-0.5409,16.0},
	{-2819.0938,-1020.7505,-0.5891,16.0},
	{-2993.8794,-1386.1599,-0.1949,16.0},
	{-3000.0728,-1744.1499,-0.7221,16.0},
	{-2738.9871,-2158.1477,-0.5212,16.0},
	{-2466.1228,2233.4314,4.0904,12.0},  // Tolsma Beginning
	{-2495.3354,2292.5574,4.2680,10.0},
	{-2602.4617,2278.0642,7.6430,10.0},
	{-2582.6208,2331.2820,4.8021,10.0},
	{-2482.8782,2383.3501,12.4832,10.0},
	{-2599.0508,2493.9336,22.7826,10.0},
	{-2677.7957,2423.3071,51.8139,10.0},
	{-2699.0256,2359.2585,70.2152,10.0},
	{-2786.9138,2333.5564,79.2322,10.0},
	{-2823.5393,2378.8794,102.5622,10.0},
	{-2826.7163,2423.3049,111.9351,10.0},
	{-2806.9763,2479.7598,108.9405,10.0},
	{-2796.4172,2594.0601,113.5658,10.0},
	{-2747.6057,2649.0413,100.7013,10.0},
	{-2721.0574,2696.8987,106.3175,10.0},
	{-2635.0566,2714.0505,92.3162,10.0},
	{-2552.2458,2726.1377,91.9948,10.0},
	{-2403.2334,2720.0105,84.2616,10.0},
	{-2250.0698,2676.1355,79.2267,10.0},
	{-2283.0044,2547.1575,4.3349,10.0},
	{-2348.4207,2498.5837,0.6907,10.0},
	{-2359.2656,2436.9182,7.2499,10.0},
	{-2353.9934,2359.6650,4.2907,10.0},
	{-2443.0078,2333.2876,4.1197,10.0},
	{-2466.1228,2233.4314,4.0904,12.0},
	{-2417.2146,-616.6351,132.2990,15.0},  // Jack 'n Jill
	{-2344.8030,-691.3068,113.5059,13.0},
	{-2308.4121,-779.5612,89.8587,13.0},
	{-2194.5645,-815.1674,59.4245,13.0},
	{-2150.2561,-1032.3330,32.1006,13.0},
	{-1999.9912,-1284.9677,37.0161,13.0},
	{-1907.9111,-1339.7021,40.0807,13.0},
	{-1928.7911,-1242.6444,39.1921,13.0},
	{-1989.8210,-1064.0470,31.7305,13.0},
	{-1991.4684,-696.2742,31.8311,13.0},
	{-2138.8821,-510.1121,38.0495,13.0},
	{-2256.0435,-188.9420,34.8789,13.0},
	{-2277.7207,-70.2467,34.8720,13.0},
	{-2507.6499,-69.9490,25.2537,13.0},
	{-2808.8350,-81.9251,6.7406,13.0},
	{-2816.1040,-344.8020,6.7383,13.0},
	{-2751.1506,-512.1845,7.1566,13.0},
	{-2561.2983,-368.3450,50.8852,13.0},
	{-2354.3955,-406.4320,78.9473,13.0},
	{-2479.4126,-438.1902,79.4592,13.0},
	{-2571.2759,-492.5153,76.8335,13.0},
	{-2417.2146,-616.6351,132.2990,13.0},
	{1025.0171,-349.3963,73.6907,16.0},  // Hilltop Mill
	{1102.0238,-435.9999,42.8676,13.0},
	{1386.4983,-327.1533,2.8209,13.0},
	{1737.1354,-341.0624,44.1749,13.0},
	{1878.6470,-59.5119,34.5593,13.0},
	{1632.0280,132.8818,29.8557,13.0},
	{1232.5723,-132.7461,38.9031,13.0},
	{828.2620,-169.5046,18.4596,13.0},
	{481.8470,-257.1970,10.5587,13.0},
	{773.8123,-281.7836,13.4629,13.0},
	{1000.5244,-402.9030,67.5005,13.0},
	{365.8413,-93.4504,1.0828,16.0},  // Dusty Roads
	{232.6801,-239.7997,1.1363,13.0},
	{329.6740,-347.6389,8.5008,13.0},
	{545.7914,-206.3070,16.5101,13.0},
	{896.6926,-90.9153,22.3725,13.0},
	{1258.5741,-149.8508,38.1793,13.0},
	{1559.5702,-48.2781,20.7874,13.0},
	{1328.3936,231.9874,19.1134,13.0},
	{1253.1971,341.6346,19.1137,13.0},
	{1049.5676,188.8388,32.4139,13.0},
	{584.2161,189.0732,20.1444,13.0},
	{365.8413,-93.4504,1.0828,13.0},
	{2780.3391,-1854.2334,9.6620,16.0},  // Old School
	{2821.6328,-1913.3925,10.8022,15.0},
	{2754.8606,-2148.6377,10.7986,15.0},
	{2347.2690,-2208.0137,13.2454,15.0},
	{2262.0869,-2196.5430,10.3588,15.0},
	{2041.5787,-1929.7871,7.8537,15.0},
	{1746.9832,-1790.1371,3.8521,15.0},
	{1618.0137,-1630.2446,13.4177,15.0},
	{1897.1365,-1612.3605,13.2532,15.0},
	{2214.6819,-1647.6506,15.1649,15.0},
	{2481.7512,-1694.6499,13.3900,15.0},
	{2642.4231,-1699.0020,10.6031,15.0},
	{2780.3391,-1854.2334,9.6620,15.0}
};

//------------------------------------------------------------------------------------------------------
// Player preferences

enum PREF_MAIN {
	PREF_SPEEDO,
	PREF_SPEEDO_DELAY,
	PREF_RACEMARKERS,
	PREF_METRIC,
	PREF_ZONE
}

new gPlayerPref[MAX_PLAYERS][PREF_MAIN];

//------------------------------------------------------------------------------------------------------
// Player stats

enum STATS_MAIN {
	STATS_AUTHENTICATED,
	STATS_FIRSTSPAWN,
	STATS_NAME[MAX_PLAYER_NAME],
	STATS_MONEY_POCKET,
	STATS_MONEY_BANK,
	STATS_BOUNTY,
	STATS_WARNINGS_SPAWNKILLS,
	STATS_WARNINGS_DMZONE,
	Float:STATS_POSITION[3],
	STATS_AREA_PRIMARY,
	STATS_AREA_SECONDARY,
	STATS_MUSIC_COUNT,
	STATS_KILLS_FREEROAM,
	STATS_KILLS_DM,
	STATS_KILLS_COPS,
	STATS_DEATHS_SELF,
	STATS_DEATHS_NONSELF,
	STATS_EXPORTS,
	STATS_SKYDIVES,
	STATS_TAXI_PASSENGERS,
	STATS_TAXI_RIDES,
	STATS_BUSTS_SELF,
	STATS_BUSTS_OTHERS,
	STATS_BUSTS_EVADED,
	STATS_RACE_STARTS,
	STATS_RACE_DNF,
	STATS_RACE_WINS,
	STATS_RACE_KNOCKOUTWINS,
	STATS_RACE_POINTS,
	STATS_RACE_SPONSOR
};

new gPlayerStats[MAX_PLAYERS][STATS_MAIN];

//---> saved stats...

#define MAX_SAVES  50

enum STATS_SAVED_MAIN {
	STATS_SAVED_NAME[MAX_PLAYER_NAME],
	STATS_SAVED_LASTACTIVETIME,
	STATS_SAVED_MONEY_POCKET,
	STATS_SAVED_MONEY_BANK,
	STATS_SAVED_BOUNTY,
	STATS_SAVED_SPAWNWEAPONS[MAX_STRING],
	STATS_SAVED_WARNINGS_SPAWNKILLS,
	STATS_SAVED_WARNINGS_DMZONE,
	STATS_SAVED_KILLS_FREEROAM,
	STATS_SAVED_KILLS_DM,
	STATS_SAVED_KILLS_COPS,
	STATS_SAVED_DEATHS_SELF,
	STATS_SAVED_DEATHS_NONSELF,
	STATS_SAVED_EXPORTS,
	STATS_SAVED_SKYDIVES,
	STATS_SAVED_TAXI_PASSENGERS,
	STATS_SAVED_TAXI_RIDES,
	STATS_SAVED_BUSTS_SELF,
	STATS_SAVED_BUSTS_OTHERS,
	STATS_SAVED_BUSTS_EVADED,
	STATS_SAVED_RACE_STARTS,
	STATS_SAVED_RACE_DNF,
	STATS_SAVED_RACE_WINS,
	STATS_SAVED_RACE_KNOCKOUTWINS,
	STATS_SAVED_RACE_POINTS,
	STATS_SAVED_RACE_SPONSOR
};

new gPlayerStatSaves[MAX_SAVES][STATS_SAVED_MAIN];
new gSavePos = 0;

//------------------------------------------------------------------------------------------------------
// Player spawn

#define MAX_SPAWNS         23
#define MAX_SPAWN_SCREENS  15
#define SPAWN_COP           0
#define SPAWN_FREEROAM      1
#define SPAWN_PROPERTY      0
#define SPAWN_DM            1
#define SPAWN_RANDOM       -1
#define SPAWN_COP_OFFSET   20

enum SPAWN_MAIN {
	SPAWN_SCREEN,
	SPAWN_CLASS,    // COP | FREEROAM
	SPAWN_TYPE,     // PROPERTY | DM | RANDOM
	SPAWN_POSITION  // POSITION
};

new gPlayerSpawn[MAX_PLAYERS][SPAWN_MAIN];

new Float:gSpawns[MAX_SPAWNS][4] = {
	{1647.3457,1614.7863,14.8222,248.7199},  // Las Venturas Airport
	{1364.2782,1928.2811,16.6928,264.1317},  // Redsands West
	{1657.4419,2190.6682,20.2413,150.9660},  // Redsands West #2
	{1050.0034,1843.1744,13.8222,183.0843},  // Whitewood Estates
	{1491.1084,2773.6748,15.9938,275.2484},  // Yellow Bell Golf Course
	{1969.3591,2726.5967,10.8203,2.2940},    // Prickle Pine
	{2002.1711,1914.0096,40.3453,271.3445},  // The Strip
	{1996.1078,1659.1333,22.1406,223.3500},  // Pirates In Men's Pants
	{2021.4436,1076.8898,15.4093,268.5197},  // The Four Dragons Casino
	{2068.5278,730.0189,16.6928,0.6403},     // Rockshore West
	{2597.6316,753.2578,17.3547,3.7428},     // Rockshore East
	{2840.3926,1324.1161,11.3906,270.1858},  // Linden Station
	{2517.0908,1568.1057,11.5560,270.3835},  // Pilgrim
	{2610.0334,2132.9473,14.1161,274.2806},  // Old Venturas Strip
	{2165.9536,2055.4607,32.8346,96.9973},   // Old Venturas Strip #2
	{2634.9653,2321.2444,17.8203,151.8564},  // Roca Escalante
	{2315.4890,2353.0066,17.7403,90.5683},   // Roca Escalante #2
	{2179.5457,1285.7235,42.5992,88.8118},   // The Camel's Toe
	{2097.0459,1159.4720,24.5625,60.0838},   // Come-A-Lot
	{2498.9956,1149.8524,22.0232,355.6338},  // Come-A-Lot #2
	{2296.9187,2451.5854,10.8203,266.0854},  // Roca Escalante (Police Station Upper Level)
	{2296.6892,2468.7627,10.8203,267.0253},  // Roca Escalante (Police Station Upper Level)
	{2268.0334,2448.9536,3.5313,358.9524}    // Roca Escalante (Police Station Lower Level)
};

//------------------------------------------------------------------------------------------------------
// Player area capture

#define AREA_BANK        0
#define AREA_AMMUNATION  1
#define AREA_BUSINESS    2
#define AREA_PROPERTY    3
#define AREA_AIRPORT     4
#define AREA_SKYDIVE     5
#define AREA_RACE        6
#define AREA_CASINO      7
#define AREA_OTHER       8

enum SAZONE_MAIN {
	SAZONE_NAME[28],
	Float:SAZONE_AREA[6]
};

new gSAZones[][SAZONE_MAIN] = {  // Majority of names and area coordinates adopted from Mabako's 'Zones Script' v0.2
//	NAME                            AREA (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax)
	{"The Big Ear",	                {-410.00,1403.30,-3.00,-137.90,1681.20,200.00}},
	{"Aldea Malvada",               {-1372.10,2498.50,0.00,-1277.50,2615.30,200.00}},
	{"Angel Pine",                  {-2324.90,-2584.20,-6.10,-1964.20,-2212.10,200.00}},
	{"Arco del Oeste",              {-901.10,2221.80,0.00,-592.00,2571.90,200.00}},
	{"Avispa Country Club",         {-2646.40,-355.40,0.00,-2270.00,-222.50,200.00}},
	{"Avispa Country Club",         {-2831.80,-430.20,-6.10,-2646.40,-222.50,200.00}},
	{"Avispa Country Club",         {-2361.50,-417.10,0.00,-2270.00,-355.40,200.00}},
	{"Avispa Country Club",         {-2667.80,-302.10,-28.80,-2646.40,-262.30,71.10}},
	{"Avispa Country Club",         {-2470.00,-355.40,0.00,-2270.00,-318.40,46.10}},
	{"Avispa Country Club",         {-2550.00,-355.40,0.00,-2470.00,-318.40,39.70}},
	{"Back o Beyond",               {-1166.90,-2641.10,0.00,-321.70,-1856.00,200.00}},
	{"Battery Point",               {-2741.00,1268.40,-4.50,-2533.00,1490.40,200.00}},
	{"Bayside",                     {-2741.00,2175.10,0.00,-2353.10,2722.70,200.00}},
	{"Bayside Marina",              {-2353.10,2275.70,0.00,-2153.10,2475.70,200.00}},
	{"Beacon Hill",                 {-399.60,-1075.50,-1.40,-319.00,-977.50,198.50}},
	{"Blackfield",                  {964.30,1203.20,-89.00,1197.30,1403.20,110.90}},
	{"Blackfield",                  {964.30,1403.20,-89.00,1197.30,1726.20,110.90}},
	{"Blackfield Chapel",           {1375.60,596.30,-89.00,1558.00,823.20,110.90}},
	{"Blackfield Chapel",           {1325.60,596.30,-89.00,1375.60,795.00,110.90}},
	{"Blackfield Intersection",     {1197.30,1044.60,-89.00,1277.00,1163.30,110.90}},
	{"Blackfield Intersection",     {1166.50,795.00,-89.00,1375.60,1044.60,110.90}},
	{"Blackfield Intersection",     {1277.00,1044.60,-89.00,1315.30,1087.60,110.90}},
	{"Blackfield Intersection",     {1375.60,823.20,-89.00,1457.30,919.40,110.90}},
	{"Blueberry",                   {104.50,-220.10,2.30,349.60,152.20,200.00}},
	{"Blueberry",                   {19.60,-404.10,3.80,349.60,-220.10,200.00}},
	{"Blueberry Acres",             {-319.60,-220.10,0.00,104.50,293.30,200.00}},
	{"Caligula's Palace",           {2087.30,1543.20,-89.00,2437.30,1703.20,110.90}},
	{"Caligula's Palace",           {2137.40,1703.20,-89.00,2437.30,1783.20,110.90}},
	{"Calton Heights",              {-2274.10,744.10,-6.10,-1982.30,1358.90,200.00}},
	{"Chinatown",                   {-2274.10,578.30,-7.60,-2078.60,744.10,200.00}},
	{"City Hall",                   {-2867.80,277.40,-9.10,-2593.40,458.40,200.00}},
	{"Come-A-Lot",                  {2087.30,943.20,-89.00,2623.10,1203.20,110.90}},
	{"Commerce",                    {1323.90,-1842.20,-89.00,1701.90,-1722.20,110.90}},
	{"Commerce",                    {1323.90,-1722.20,-89.00,1440.90,-1577.50,110.90}},
	{"Commerce",                    {1370.80,-1577.50,-89.00,1463.90,-1384.90,110.90}},
	{"Commerce",                    {1463.90,-1577.50,-89.00,1667.90,-1430.80,110.90}},
	{"Commerce",                    {1583.50,-1722.20,-89.00,1758.90,-1577.50,110.90}},
	{"Commerce",                    {1667.90,-1577.50,-89.00,1812.60,-1430.80,110.90}},
	{"Conference Center",           {1046.10,-1804.20,-89.00,1323.90,-1722.20,110.90}},
	{"Conference Center",           {1073.20,-1842.20,-89.00,1323.90,-1804.20,110.90}},
	{"Cranberry Station",           {-2007.80,56.30,0.00,-1922.00,224.70,100.00}},
	{"Creek",                       {2749.90,1937.20,-89.00,2921.60,2669.70,110.90}},
	{"Dillimore",                   {580.70,-674.80,-9.50,861.00,-404.70,200.00}},
	{"Doherty",                     {-2270.00,-324.10,-0.00,-1794.90,-222.50,200.00}},
	{"Doherty",                     {-2173.00,-222.50,-0.00,-1794.90,265.20,200.00}},
	{"Downtown",                    {-1982.30,744.10,-6.10,-1871.70,1274.20,200.00}},
	{"Downtown",                    {-1871.70,1176.40,-4.50,-1620.30,1274.20,200.00}},
	{"Downtown",                    {-1700.00,744.20,-6.10,-1580.00,1176.50,200.00}},
	{"Downtown",                    {-1580.00,744.20,-6.10,-1499.80,1025.90,200.00}},
	{"Downtown",                    {-2078.60,578.30,-7.60,-1499.80,744.20,200.00}},
	{"Downtown",                    {-1993.20,265.20,-9.10,-1794.90,578.30,200.00}},
	{"Downtown Los Santos",         {1463.90,-1430.80,-89.00,1724.70,-1290.80,110.90}},
	{"Downtown Los Santos",         {1724.70,-1430.80,-89.00,1812.60,-1250.90,110.90}},
	{"Downtown Los Santos",         {1463.90,-1290.80,-89.00,1724.70,-1150.80,110.90}},
	{"Downtown Los Santos",         {1370.80,-1384.90,-89.00,1463.90,-1170.80,110.90}},
	{"Downtown Los Santos",         {1724.70,-1250.90,-89.00,1812.60,-1150.80,110.90}},
	{"Downtown Los Santos",         {1370.80,-1170.80,-89.00,1463.90,-1130.80,110.90}},
	{"Downtown Los Santos",         {1378.30,-1130.80,-89.00,1463.90,-1026.30,110.90}},
	{"Downtown Los Santos",         {1391.00,-1026.30,-89.00,1463.90,-926.90,110.90}},
	{"Downtown Los Santos",         {1507.50,-1385.20,110.90,1582.50,-1325.30,335.90}},
	{"East Beach",                  {2632.80,-1852.80,-89.00,2959.30,-1668.10,110.90}},
	{"East Beach",                  {2632.80,-1668.10,-89.00,2747.70,-1393.40,110.90}},
	{"East Beach",                  {2747.70,-1668.10,-89.00,2959.30,-1498.60,110.90}},
	{"East Beach",                  {2747.70,-1498.60,-89.00,2959.30,-1120.00,110.90}},
	{"East Los Santos",             {2421.00,-1628.50,-89.00,2632.80,-1454.30,110.90}},
	{"East Los Santos",             {2222.50,-1628.50,-89.00,2421.00,-1494.00,110.90}},
	{"East Los Santos",             {2266.20,-1494.00,-89.00,2381.60,-1372.00,110.90}},
	{"East Los Santos",             {2381.60,-1494.00,-89.00,2421.00,-1454.30,110.90}},
	{"East Los Santos",             {2281.40,-1372.00,-89.00,2381.60,-1135.00,110.90}},
	{"East Los Santos",             {2381.60,-1454.30,-89.00,2462.10,-1135.00,110.90}},
	{"East Los Santos",             {2462.10,-1454.30,-89.00,2581.70,-1135.00,110.90}},
	{"Easter Basin",                {-1794.90,249.90,-9.10,-1242.90,578.30,200.00}},
	{"Easter Basin",                {-1794.90,-50.00,-0.00,-1499.80,249.90,200.00}},
	{"Easter Bay Airport",          {-1499.80,-50.00,-0.00,-1242.90,249.90,200.00}},
	{"Easter Bay Airport",          {-1794.90,-730.10,-3.00,-1213.90,-50.00,200.00}},
	{"Easter Bay Airport",          {-1213.90,-730.10,0.00,-1132.80,-50.00,200.00}},
	{"Easter Bay Airport",          {-1242.90,-50.00,0.00,-1213.90,578.30,200.00}},
	{"Easter Bay Airport",          {-1213.90,-50.00,-4.50,-947.90,578.30,200.00}},
	{"Easter Bay Airport",          {-1315.40,-405.30,15.40,-1264.40,-209.50,25.40}},
	{"Easter Bay Airport",          {-1354.30,-287.30,15.40,-1315.40,-209.50,25.40}},
	{"Easter Bay Airport",          {-1490.30,-209.50,15.40,-1264.40,-148.30,25.40}},
	{"Easter Bay Chemicals",        {-1132.80,-768.00,0.00,-956.40,-578.10,200.00}},
	{"Easter Bay Chemicals",        {-1132.80,-787.30,0.00,-956.40,-768.00,200.00}},
	{"El Castillo del Diablo",      {-464.50,2217.60,0.00,-208.50,2580.30,200.00}},
	{"El Castillo del Diablo",      {-208.50,2123.00,-7.60,114.00,2337.10,200.00}},
	{"El Castillo del Diablo",      {-208.50,2337.10,0.00,8.40,2487.10,200.00}},
	{"El Corona",                   {1812.60,-2179.20,-89.00,1970.60,-1852.80,110.90}},
	{"El Corona",                   {1692.60,-2179.20,-89.00,1812.60,-1842.20,110.90}},
	{"El Quebrados",                {-1645.20,2498.50,0.00,-1372.10,2777.80,200.00}},
	{"Esplanade East",              {-1620.30,1176.50,-4.50,-1580.00,1274.20,200.00}},
	{"Esplanade East",              {-1580.00,1025.90,-6.10,-1499.80,1274.20,200.00}},
	{"Esplanade East",              {-1499.80,578.30,-79.60,-1339.80,1274.20,20.30}},
	{"Esplanade North",             {-2533.00,1358.90,-4.50,-1996.60,1501.20,200.00}},
	{"Esplanade North",             {-1996.60,1358.90,-4.50,-1524.20,1592.50,200.00}},
	{"Esplanade North",             {-1982.30,1274.20,-4.50,-1524.20,1358.90,200.00}},
	{"Fallen Tree",                 {-792.20,-698.50,-5.30,-452.40,-380.00,200.00}},
	{"Fallow Bridge",               {434.30,366.50,0.00,603.00,555.60,200.00}},
	{"Fern Ridge",                  {508.10,-139.20,0.00,1306.60,119.50,200.00}},
	{"Financial",                   {-1871.70,744.10,-6.10,-1701.30,1176.40,300.00}},
	{"Fisher's Lagoon",             {1916.90,-233.30,-100.00,2131.70,13.80,200.00}},
	{"Flint Intersection",          {-187.70,-1596.70,-89.00,17.00,-1276.60,110.90}},
	{"Flint Range",                 {-594.10,-1648.50,0.00,-187.70,-1276.60,200.00}},
	{"Fort Carson",                 {-376.20,826.30,-3.00,123.70,1220.40,200.00}},
	{"Foster Valley",               {-2270.00,-430.20,-0.00,-2178.60,-324.10,200.00}},
	{"Foster Valley",               {-2178.60,-599.80,-0.00,-1794.90,-324.10,200.00}},
	{"Foster Valley",               {-2178.60,-1115.50,0.00,-1794.90,-599.80,200.00}},
	{"Foster Valley",               {-2178.60,-1250.90,0.00,-1794.90,-1115.50,200.00}},
	{"Frederick Bridge",            {2759.20,296.50,0.00,2774.20,594.70,200.00}},
	{"Gant Bridge",                 {-2741.40,1659.60,-6.10,-2616.40,2175.10,200.00}},
	{"Gant Bridge",                 {-2741.00,1490.40,-6.10,-2616.40,1659.60,200.00}},
	{"Ganton",                      {2222.50,-1852.80,-89.00,2632.80,-1722.30,110.90}},
	{"Ganton",                      {2222.50,-1722.30,-89.00,2632.80,-1628.50,110.90}},
	{"Garcia",                      {-2411.20,-222.50,-0.00,-2173.00,265.20,200.00}},
	{"Garcia",                      {-2395.10,-222.50,-5.30,-2354.00,-204.70,200.00}},
	{"Garver Bridge",               {-1339.80,828.10,-89.00,-1213.90,1057.00,110.90}},
	{"Garver Bridge",               {-1213.90,950.00,-89.00,-1087.90,1178.90,110.90}},
	{"Garver Bridge",               {-1499.80,696.40,-179.60,-1339.80,925.30,20.30}},
	{"Glen Park",                   {1812.60,-1449.60,-89.00,1996.90,-1350.70,110.90}},
	{"Glen Park",                   {1812.60,-1100.80,-89.00,1994.30,-973.30,110.90}},
	{"Glen Park",                   {1812.60,-1350.70,-89.00,2056.80,-1100.80,110.90}},
	{"Green Palms",                 {176.50,1305.40,-3.00,338.60,1520.70,200.00}},
	{"Greenglass College",          {964.30,1044.60,-89.00,1197.30,1203.20,110.90}},
	{"Greenglass College",          {964.30,930.80,-89.00,1166.50,1044.60,110.90}},
	{"Hampton Barns",               {603.00,264.30,0.00,761.90,366.50,200.00}},
	{"Hankypanky Point",            {2576.90,62.10,0.00,2759.20,385.50,200.00}},
	{"Harry Gold Parkway",          {1777.30,863.20,-89.00,1817.30,2342.80,110.90}},
	{"Hashbury",                    {-2593.40,-222.50,-0.00,-2411.20,54.70,200.00}},
	{"Hilltop Farm",                {967.30,-450.30,-3.00,1176.70,-217.90,200.00}},
	{"Hunter Quarry",               {337.20,710.80,-115.20,860.50,1031.70,203.70}},
	{"Idlewood",                    {1812.60,-1852.80,-89.00,1971.60,-1742.30,110.90}},
	{"Idlewood",                    {1812.60,-1742.30,-89.00,1951.60,-1602.30,110.90}},
	{"Idlewood",                    {1951.60,-1742.30,-89.00,2124.60,-1602.30,110.90}},
	{"Idlewood",                    {1812.60,-1602.30,-89.00,2124.60,-1449.60,110.90}},
	{"Idlewood",                    {2124.60,-1742.30,-89.00,2222.50,-1494.00,110.90}},
	{"Idlewood",                    {1971.60,-1852.80,-89.00,2222.50,-1742.30,110.90}},
	{"Jefferson",                   {1996.90,-1449.60,-89.00,2056.80,-1350.70,110.90}},
	{"Jefferson",                   {2124.60,-1494.00,-89.00,2266.20,-1449.60,110.90}},
	{"Jefferson",                   {2056.80,-1372.00,-89.00,2281.40,-1210.70,110.90}},
	{"Jefferson",                   {2056.80,-1210.70,-89.00,2185.30,-1126.30,110.90}},
	{"Jefferson",                   {2185.30,-1210.70,-89.00,2281.40,-1154.50,110.90}},
	{"Jefferson",                   {2056.80,-1449.60,-89.00,2266.20,-1372.00,110.90}},
	{"Julius Thruway East",         {2623.10,943.20,-89.00,2749.90,1055.90,110.90}},
	{"Julius Thruway East",         {2685.10,1055.90,-89.00,2749.90,2626.50,110.90}},
	{"Julius Thruway East",         {2536.40,2442.50,-89.00,2685.10,2542.50,110.90}},
	{"Julius Thruway East",         {2625.10,2202.70,-89.00,2685.10,2442.50,110.90}},
	{"Julius Thruway North",        {2498.20,2542.50,-89.00,2685.10,2626.50,110.90}},
	{"Julius Thruway North",        {2237.40,2542.50,-89.00,2498.20,2663.10,110.90}},
	{"Julius Thruway North",        {2121.40,2508.20,-89.00,2237.40,2663.10,110.90}},
	{"Julius Thruway North",        {1938.80,2508.20,-89.00,2121.40,2624.20,110.90}},
	{"Julius Thruway North",        {1534.50,2433.20,-89.00,1848.40,2583.20,110.90}},
	{"Julius Thruway North",        {1848.40,2478.40,-89.00,1938.80,2553.40,110.90}},
	{"Julius Thruway North",        {1704.50,2342.80,-89.00,1848.40,2433.20,110.90}},
	{"Julius Thruway North",        {1377.30,2433.20,-89.00,1534.50,2507.20,110.90}},
	{"Julius Thruway South",        {1457.30,823.20,-89.00,2377.30,863.20,110.90}},
	{"Julius Thruway South",        {2377.30,788.80,-89.00,2537.30,897.90,110.90}},
	{"Julius Thruway West",         {1197.30,1163.30,-89.00,1236.60,2243.20,110.90}},
	{"Julius Thruway West",         {1236.60,2142.80,-89.00,1297.40,2243.20,110.90}},
	{"Juniper Hill",                {-2533.00,578.30,-7.60,-2274.10,968.30,200.00}},
	{"Juniper Hollow",              {-2533.00,968.30,-6.10,-2274.10,1358.90,200.00}},
	{"K.A.C.C. Military Fuels",     {2498.20,2626.50,-89.00,2749.90,2861.50,110.90}},
	{"Kincaid Bridge",              {-1339.80,599.20,-89.00,-1213.90,828.10,110.90}},
	{"Kincaid Bridge",              {-1213.90,721.10,-89.00,-1087.90,950.00,110.90}},
	{"Kincaid Bridge",              {-1087.90,855.30,-89.00,-961.90,986.20,110.90}},
	{"King's",                      {-2329.30,458.40,-7.60,-1993.20,578.30,200.00}},
	{"King's",                      {-2411.20,265.20,-9.10,-1993.20,373.50,200.00}},
	{"King's",                      {-2253.50,373.50,-9.10,-1993.20,458.40,200.00}},
	{"LVA Freight Depot",           {1457.30,863.20,-89.00,1777.40,1143.20,110.90}},
	{"LVA Freight Depot",           {1375.60,919.40,-89.00,1457.30,1203.20,110.90}},
	{"LVA Freight Depot",           {1277.00,1087.60,-89.00,1375.60,1203.20,110.90}},
	{"LVA Freight Depot",           {1315.30,1044.60,-89.00,1375.60,1087.60,110.90}},
	{"LVA Freight Depot",           {1236.60,1163.40,-89.00,1277.00,1203.20,110.90}},
	{"Las Barrancas",               {-926.10,1398.70,-3.00,-719.20,1634.60,200.00}},
	{"Las Brujas",                  {-365.10,2123.00,-3.00,-208.50,2217.60,200.00}},
	{"Las Colinas",                 {1994.30,-1100.80,-89.00,2056.80,-920.80,110.90}},
	{"Las Colinas",                 {2056.80,-1126.30,-89.00,2126.80,-920.80,110.90}},
	{"Las Colinas",                 {2185.30,-1154.50,-89.00,2281.40,-934.40,110.90}},
	{"Las Colinas",                 {2126.80,-1126.30,-89.00,2185.30,-934.40,110.90}},
	{"Las Colinas",                 {2747.70,-1120.00,-89.00,2959.30,-945.00,110.90}},
	{"Las Colinas",                 {2632.70,-1135.00,-89.00,2747.70,-945.00,110.90}},
	{"Las Colinas",                 {2281.40,-1135.00,-89.00,2632.70,-945.00,110.90}},
	{"Las Payasadas",               {-354.30,2580.30,2.00,-133.60,2816.80,200.00}},
	{"Las Venturas Airport",        {1236.60,1203.20,-89.00,1457.30,1883.10,110.90}},
	{"Las Venturas Airport",        {1457.30,1203.20,-89.00,1777.30,1883.10,110.90}},
	{"Las Venturas Airport",        {1457.30,1143.20,-89.00,1777.40,1203.20,110.90}},
	{"Las Venturas Airport",        {1515.80,1586.40,-12.50,1729.90,1714.50,87.50}},
	{"Last Dime Motel",             {1823.00,596.30,-89.00,1997.20,823.20,110.90}},
	{"Leafy Hollow",                {-1166.90,-1856.00,0.00,-815.60,-1602.00,200.00}},
	{"Liberty City",                {-1000.00,400.00,1300.00,-700.00,600.00,1400.00}},
	{"Lil' Probe Inn",              {-90.20,1286.80,-3.00,153.80,1554.10,200.00}},
	{"Linden Side",                 {2749.90,943.20,-89.00,2923.30,1198.90,110.90}},
	{"Linden Station",              {2749.90,1198.90,-89.00,2923.30,1548.90,110.90}},
	{"Linden Station",              {2811.20,1229.50,-39.50,2861.20,1407.50,60.40}},
	{"Little Mexico",               {1701.90,-1842.20,-89.00,1812.60,-1722.20,110.90}},
	{"Little Mexico",               {1758.90,-1722.20,-89.00,1812.60,-1577.50,110.90}},
	{"Los Flores",                  {2581.70,-1454.30,-89.00,2632.80,-1393.40,110.90}},
	{"Los Flores",                  {2581.70,-1393.40,-89.00,2747.70,-1135.00,110.90}},
	{"Los Santos International",    {1249.60,-2394.30,-89.00,1852.00,-2179.20,110.90}},
	{"Los Santos International",    {1852.00,-2394.30,-89.00,2089.00,-2179.20,110.90}},
	{"Los Santos International",    {1382.70,-2730.80,-89.00,2201.80,-2394.30,110.90}},
	{"Los Santos International",    {1974.60,-2394.30,-39.00,2089.00,-2256.50,60.90}},
	{"Los Santos International",    {1400.90,-2669.20,-39.00,2189.80,-2597.20,60.90}},
	{"Los Santos International",    {2051.60,-2597.20,-39.00,2152.40,-2394.30,60.90}},
	{"Marina",                      {647.70,-1804.20,-89.00,851.40,-1577.50,110.90}},
	{"Marina",                      {647.70,-1577.50,-89.00,807.90,-1416.20,110.90}},
	{"Marina",                      {807.90,-1577.50,-89.00,926.90,-1416.20,110.90}},
	{"Market",                      {787.40,-1416.20,-89.00,1072.60,-1310.20,110.90}},
	{"Market",                      {952.60,-1310.20,-89.00,1072.60,-1130.80,110.90}},
	{"Market",                      {1072.60,-1416.20,-89.00,1370.80,-1130.80,110.90}},
	{"Market",                      {926.90,-1577.50,-89.00,1370.80,-1416.20,110.90}},
	{"Market Station",              {787.40,-1410.90,-34.10,866.00,-1310.20,65.80}},
	{"Martin Bridge",               {-222.10,293.30,0.00,-122.10,476.40,200.00}},
	{"Missionary Hill",             {-2994.40,-811.20,0.00,-2178.60,-430.20,200.00}},
	{"Montgomery",                  {1119.50,119.50,-3.00,1451.40,493.30,200.00}},
	{"Montgomery",                  {1451.40,347.40,-6.10,1582.40,420.80,200.00}},
	{"Montgomery Intersection",     {1546.60,208.10,0.00,1745.80,347.40,200.00}},
	{"Montgomery Intersection",     {1582.40,347.40,0.00,1664.60,401.70,200.00}},
	{"Mulholland",                  {1414.00,-768.00,-89.00,1667.60,-452.40,110.90}},
	{"Mulholland",                  {1281.10,-452.40,-89.00,1641.10,-290.90,110.90}},
	{"Mulholland",                  {1269.10,-768.00,-89.00,1414.00,-452.40,110.90}},
	{"Mulholland",                  {1357.00,-926.90,-89.00,1463.90,-768.00,110.90}},
	{"Mulholland",                  {1318.10,-910.10,-89.00,1357.00,-768.00,110.90}},
	{"Mulholland",                  {1169.10,-910.10,-89.00,1318.10,-768.00,110.90}},
	{"Mulholland",                  {768.60,-954.60,-89.00,952.60,-860.60,110.90}},
	{"Mulholland",                  {687.80,-860.60,-89.00,911.80,-768.00,110.90}},
	{"Mulholland",                  {737.50,-768.00,-89.00,1142.20,-674.80,110.90}},
	{"Mulholland",                  {1096.40,-910.10,-89.00,1169.10,-768.00,110.90}},
	{"Mulholland",                  {952.60,-937.10,-89.00,1096.40,-860.60,110.90}},
	{"Mulholland",                  {911.80,-860.60,-89.00,1096.40,-768.00,110.90}},
	{"Mulholland",                  {861.00,-674.80,-89.00,1156.50,-600.80,110.90}},
	{"Mulholland Intersection",     {1463.90,-1150.80,-89.00,1812.60,-768.00,110.90}},
	{"North Rock",                  {2285.30,-768.00,0.00,2770.50,-269.70,200.00}},
	{"Ocean Docks",                 {2373.70,-2697.00,-89.00,2809.20,-2330.40,110.90}},
	{"Ocean Docks",                 {2201.80,-2418.30,-89.00,2324.00,-2095.00,110.90}},
	{"Ocean Docks",                 {2324.00,-2302.30,-89.00,2703.50,-2145.10,110.90}},
	{"Ocean Docks",                 {2089.00,-2394.30,-89.00,2201.80,-2235.80,110.90}},
	{"Ocean Docks",                 {2201.80,-2730.80,-89.00,2324.00,-2418.30,110.90}},
	{"Ocean Docks",                 {2703.50,-2302.30,-89.00,2959.30,-2126.90,110.90}},
	{"Ocean Docks",                 {2324.00,-2145.10,-89.00,2703.50,-2059.20,110.90}},
	{"Ocean Flats",                 {-2994.40,277.40,-9.10,-2867.80,458.40,200.00}},
	{"Ocean Flats",                 {-2994.40,-222.50,-0.00,-2593.40,277.40,200.00}},
	{"Ocean Flats",                 {-2994.40,-430.20,-0.00,-2831.80,-222.50,200.00}},
	{"Octane Springs",              {338.60,1228.50,0.00,664.30,1655.00,200.00}},
	{"Old Venturas Strip",          {2162.30,2012.10,-89.00,2685.10,2202.70,110.90}},
	{"Palisades",                   {-2994.40,458.40,-6.10,-2741.00,1339.60,200.00}},
	{"Palomino Creek",              {2160.20,-149.00,0.00,2576.90,228.30,200.00}},
	{"Paradiso",                    {-2741.00,793.40,-6.10,-2533.00,1268.40,200.00}},
	{"Pershing Square",             {1440.90,-1722.20,-89.00,1583.50,-1577.50,110.90}},
	{"Pilgrim",                     {2437.30,1383.20,-89.00,2624.40,1783.20,110.90}},
	{"Pilgrim",                     {2624.40,1383.20,-89.00,2685.10,1783.20,110.90}},
	{"Pilson Intersection",         {1098.30,2243.20,-89.00,1377.30,2507.20,110.90}},
	{"Pirates in Men's Pants",      {1817.30,1469.20,-89.00,2027.40,1703.20,110.90}},
	{"Playa del Seville",           {2703.50,-2126.90,-89.00,2959.30,-1852.80,110.90}},
	{"Prickle Pine",                {1534.50,2583.20,-89.00,1848.40,2863.20,110.90}},
	{"Prickle Pine",                {1117.40,2507.20,-89.00,1534.50,2723.20,110.90}},
	{"Prickle Pine",                {1848.40,2553.40,-89.00,1938.80,2863.20,110.90}},
	{"Prickle Pine",                {1938.80,2624.20,-89.00,2121.40,2861.50,110.90}},
	{"Queens",                      {-2533.00,458.40,0.00,-2329.30,578.30,200.00}},
	{"Queens",                      {-2593.40,54.70,0.00,-2411.20,458.40,200.00}},
	{"Queens",                      {-2411.20,373.50,0.00,-2253.50,458.40,200.00}},
	{"Randolph Industrial Estate",  {1558.00,596.30,-89.00,1823.00,823.20,110.90}},
	{"Redsands East",               {1817.30,2011.80,-89.00,2106.70,2202.70,110.90}},
	{"Redsands East",               {1817.30,2202.70,-89.00,2011.90,2342.80,110.90}},
	{"Redsands East",               {1848.40,2342.80,-89.00,2011.90,2478.40,110.90}},
	{"Redsands West",               {1236.60,1883.10,-89.00,1777.30,2142.80,110.90}},
	{"Redsands West",               {1297.40,2142.80,-89.00,1777.30,2243.20,110.90}},
	{"Redsands West",               {1377.30,2243.20,-89.00,1704.50,2433.20,110.90}},
	{"Redsands West",               {1704.50,2243.20,-89.00,1777.30,2342.80,110.90}},
	{"Regular Tom",                 {-405.70,1712.80,-3.00,-276.70,1892.70,200.00}},
	{"Richman",                     {647.50,-1118.20,-89.00,787.40,-954.60,110.90}},
	{"Richman",                     {647.50,-954.60,-89.00,768.60,-860.60,110.90}},
	{"Richman",                     {225.10,-1369.60,-89.00,334.50,-1292.00,110.90}},
	{"Richman",                     {225.10,-1292.00,-89.00,466.20,-1235.00,110.90}},
	{"Richman",                     {72.60,-1404.90,-89.00,225.10,-1235.00,110.90}},
	{"Richman",                     {72.60,-1235.00,-89.00,321.30,-1008.10,110.90}},
	{"Richman",                     {321.30,-1235.00,-89.00,647.50,-1044.00,110.90}},
	{"Richman",                     {321.30,-1044.00,-89.00,647.50,-860.60,110.90}},
	{"Richman",                     {321.30,-860.60,-89.00,687.80,-768.00,110.90}},
	{"Richman",                     {321.30,-768.00,-89.00,700.70,-674.80,110.90}},
	{"Robada Intersection",         {-1119.00,1178.90,-89.00,-862.00,1351.40,110.90}},
	{"Roca Escalante",              {2237.40,2202.70,-89.00,2536.40,2542.50,110.90}},
	{"Roca Escalante",              {2536.40,2202.70,-89.00,2625.10,2442.50,110.90}},
	{"Rockshore East",              {2537.30,676.50,-89.00,2902.30,943.20,110.90}},
	{"Rockshore West",              {1997.20,596.30,-89.00,2377.30,823.20,110.90}},
	{"Rockshore West",              {2377.30,596.30,-89.00,2537.30,788.80,110.90}},
	{"Rodeo",                       {72.60,-1684.60,-89.00,225.10,-1544.10,110.90}},
	{"Rodeo",                       {72.60,-1544.10,-89.00,225.10,-1404.90,110.90}},
	{"Rodeo",                       {225.10,-1684.60,-89.00,312.80,-1501.90,110.90}},
	{"Rodeo",                       {225.10,-1501.90,-89.00,334.50,-1369.60,110.90}},
	{"Rodeo",                       {334.50,-1501.90,-89.00,422.60,-1406.00,110.90}},
	{"Rodeo",                       {312.80,-1684.60,-89.00,422.60,-1501.90,110.90}},
	{"Rodeo",                       {422.60,-1684.60,-89.00,558.00,-1570.20,110.90}},
	{"Rodeo",                       {558.00,-1684.60,-89.00,647.50,-1384.90,110.90}},
	{"Rodeo",                       {466.20,-1570.20,-89.00,558.00,-1385.00,110.90}},
	{"Rodeo",                       {422.60,-1570.20,-89.00,466.20,-1406.00,110.90}},
	{"Rodeo",                       {466.20,-1385.00,-89.00,647.50,-1235.00,110.90}},
	{"Rodeo",                       {334.50,-1406.00,-89.00,466.20,-1292.00,110.90}},
	{"Royal Casino",                {2087.30,1383.20,-89.00,2437.30,1543.20,110.90}},
	{"San Andreas Sound",           {2450.30,385.50,-100.00,2759.20,562.30,200.00}},
	{"Santa Flora",                 {-2741.00,458.40,-7.60,-2533.00,793.40,200.00}},
	{"Santa Maria Beach",           {342.60,-2173.20,-89.00,647.70,-1684.60,110.90}},
	{"Santa Maria Beach",           {72.60,-2173.20,-89.00,342.60,-1684.60,110.90}},
	{"Shady Cabin",                 {-1632.80,-2263.40,-3.00,-1601.30,-2231.70,200.00}},
	{"Shady Creeks",                {-1820.60,-2643.60,-8.00,-1226.70,-1771.60,200.00}},
	{"Shady Creeks",                {-2030.10,-2174.80,-6.10,-1820.60,-1771.60,200.00}},
	{"Sobell Rail Yards",           {2749.90,1548.90,-89.00,2923.30,1937.20,110.90}},
	{"Spinybed",                    {2121.40,2663.10,-89.00,2498.20,2861.50,110.90}},
	{"Starfish Casino",             {2437.30,1783.20,-89.00,2685.10,2012.10,110.90}},
	{"Starfish Casino",             {2437.30,1858.10,-39.00,2495.00,1970.80,60.90}},
	{"Starfish Casino",             {2162.30,1883.20,-89.00,2437.30,2012.10,110.90}},
	{"Temple",                      {1252.30,-1130.80,-89.00,1378.30,-1026.30,110.90}},
	{"Temple",                      {1252.30,-1026.30,-89.00,1391.00,-926.90,110.90}},
	{"Temple",                      {1252.30,-926.90,-89.00,1357.00,-910.10,110.90}},
	{"Temple",                      {952.60,-1130.80,-89.00,1096.40,-937.10,110.90}},
	{"Temple",                      {1096.40,-1130.80,-89.00,1252.30,-1026.30,110.90}},
	{"Temple",                      {1096.40,-1026.30,-89.00,1252.30,-910.10,110.90}},
	{"The Camel's Toe",             {2087.30,1203.20,-89.00,2640.40,1383.20,110.90}},
	{"The Clown's Pocket",          {2162.30,1783.20,-89.00,2437.30,1883.20,110.90}},
	{"The Emerald Isle",            {2011.90,2202.70,-89.00,2237.40,2508.20,110.90}},
	{"The Farm",                    {-1209.60,-1317.10,114.90,-908.10,-787.30,251.90}},
	{"The Four Dragons Casino",     {1817.30,863.20,-89.00,2027.30,1083.20,110.90}},
	{"The High Roller",             {1817.30,1283.20,-89.00,2027.30,1469.20,110.90}},
	{"The Mako Span",               {1664.60,401.70,0.00,1785.10,567.20,200.00}},
	{"The Panopticon",              {-947.90,-304.30,-1.10,-319.60,327.00,200.00}},
	{"The Pink Swan",               {1817.30,1083.20,-89.00,2027.30,1283.20,110.90}},
	{"The Sherman Dam",             {-968.70,1929.40,-3.00,-481.10,2155.20,200.00}},
	{"The Strip",                   {2027.40,863.20,-89.00,2087.30,1703.20,110.90}},
	{"The Strip",                   {2106.70,1863.20,-89.00,2162.30,2202.70,110.90}},
	{"The Strip",                   {2027.40,1783.20,-89.00,2162.30,1863.20,110.90}},
	{"The Strip",                   {2027.40,1703.20,-89.00,2137.40,1783.20,110.90}},
	{"The Visage",                  {1817.30,1863.20,-89.00,2106.70,2011.80,110.90}},
	{"The Visage",                  {1817.30,1703.20,-89.00,2027.40,1863.20,110.90}},
	{"Unity Station",               {1692.60,-1971.80,-20.40,1812.60,-1932.80,79.50}},
	{"Valle Ocultado",              {-936.60,2611.40,2.00,-715.90,2847.90,200.00}},
	{"Verdant Bluffs",              {930.20,-2488.40,-89.00,1249.60,-2006.70,110.90}},
	{"Verdant Bluffs",              {1073.20,-2006.70,-89.00,1249.60,-1842.20,110.90}},
	{"Verdant Bluffs",              {1249.60,-2179.20,-89.00,1692.60,-1842.20,110.90}},
	{"Verdant Meadows",             {37.00,2337.10,-3.00,435.90,2677.90,200.00}},
	{"Verona Beach",                {647.70,-2173.20,-89.00,930.20,-1804.20,110.90}},
	{"Verona Beach",                {930.20,-2006.70,-89.00,1073.20,-1804.20,110.90}},
	{"Verona Beach",                {851.40,-1804.20,-89.00,1046.10,-1577.50,110.90}},
	{"Verona Beach",                {1161.50,-1722.20,-89.00,1323.90,-1577.50,110.90}},
	{"Verona Beach",                {1046.10,-1722.20,-89.00,1161.50,-1577.50,110.90}},
	{"Vinewood",                    {787.40,-1310.20,-89.00,952.60,-1130.80,110.90}},
	{"Vinewood",                    {787.40,-1130.80,-89.00,952.60,-954.60,110.90}},
	{"Vinewood",                    {647.50,-1227.20,-89.00,787.40,-1118.20,110.90}},
	{"Vinewood",                    {647.70,-1416.20,-89.00,787.40,-1227.20,110.90}},
	{"Whitewood Estates",           {883.30,1726.20,-89.00,1098.30,2507.20,110.90}},
	{"Whitewood Estates",           {1098.30,1726.20,-89.00,1197.30,2243.20,110.90}},
	{"Willowfield",                 {1970.60,-2179.20,-89.00,2089.00,-1852.80,110.90}},
	{"Willowfield",                 {2089.00,-2235.80,-89.00,2201.80,-1989.90,110.90}},
	{"Willowfield",                 {2089.00,-1989.90,-89.00,2324.00,-1852.80,110.90}},
	{"Willowfield",                 {2201.80,-2095.00,-89.00,2324.00,-1989.90,110.90}},
	{"Willowfield",                 {2541.70,-1941.40,-89.00,2703.50,-1852.80,110.90}},
	{"Willowfield",                 {2324.00,-2059.20,-89.00,2541.70,-1852.80,110.90}},
	{"Willowfield",                 {2541.70,-2059.20,-89.00,2703.50,-1941.40,110.90}},
	{"Yellow Bell Station",         {1377.40,2600.40,-21.90,1492.40,2687.30,78.00}},
	// Main Zones
	{"Los Santos",                  {44.60,-2892.90,-242.90,2997.00,-768.00,900.00}},
	{"Las Venturas",                {869.40,596.30,-242.90,2997.00,2993.80,900.00}},
	{"Bone County",                 {-480.50,596.30,-242.90,869.40,2993.80,900.00}},
	{"Tierra Robada",               {-2997.40,1659.60,-242.90,-480.50,2993.80,900.00}},
	{"Tierra Robada",               {-1213.90,596.30,-242.90,-480.50,1659.60,900.00}},
	{"San Fierro",                  {-2997.40,-1115.50,-242.90,-1213.90,1659.60,900.00}},
	{"Red County",                  {-1213.90,-768.00,-242.90,2997.00,596.30,900.00}},
	{"Flint County",                {-1213.90,-2892.90,-242.90,44.60,-768.00,900.00}},
	{"Whetstone",                   {-2997.40,-2892.90,-242.90,-1213.90,-1115.50,900.00}}
};

//------------------------------------------------------------------------------------------------------
// Banks

#define MAX_BANKS  6

enum BANK_MAIN {
	Float:BANK_MARKER[4],
	Float:BANK_AREA[6]
};

new gBanks[MAX_BANKS][BANK_MAIN] = {
//      MARKER (X,Y,Z,size)                   AREA (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax)
	{{-29.0024,-184.5411,1003.5468,2.0},  {-34.2454,-186.9409,1002.5500,-3.1593,-169.7346,1012.5500}},
	{{2.0753,-28.1609,1003.5494,2.0},     {-10.8753,-31.3464,1002.5500,9.4595,-2.8128,1012.5500}},
	{{-28.0260,-89.2416,1003.5468,2.0},   {-38.2325,-91.9075,1002.5500,-14.8211,-74.6289,1012.5500}},
	{{-22.1975,-137.8901,1003.5468,2.0},  {-38.1968,-140.4389,1002.5500,-14.8772,-123.2906,1012.5500}},
	{{-30.7577,-28.4008,1003.5572,2.0},   {-35.9806,-31.3470,1002.5500,-26.6673,-2.6750,1012.5500}},
	{{-22.2549,-55.6575,1003.5469,2.0},   {-36.5483,-57.9948,1002.5500,-17.2655,-49.2967,1012.5500}}
};

//------------------------------------------------------------------------------------------------------
// Ammunations

#define MAX_AMMUNATIONS  5

enum AMMUNATION_MAIN {
	Float:AMMUNATION_MARKER[4],
	Float:AMMUNATION_AREA[6]
};

new gAmmunations[MAX_AMMUNATIONS][AMMUNATION_MAIN] = {
//      MARKER (X,Y,Z,size)                   AREA (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax)
	{{291.0965,-39.3390,1001.5156,2.0},   {284.2408,-41.8134,1000.5700,300.0405,-31.2181,1010.5700}},
	{{290.4729,-83.1950,1001.5156,2.0},   {284.6208,-86.3999,1000.5700,303.0274,-56.6638,1010.5700}},
	{{286.6993,-108.0543,1001.5156,2.0},  {284.5086,-112.3020,1000.5700,298.1575,-103.1596,1010.5700}},
	{{313.5173,-134.1832,999.6015,2.0},   {302.9599,-144.3313,998.6620,317.0632,-126.0514,1008.6620}},
	{{307.9458,-166.7047,999.5937,2.0},   {306.3992,-169.9078,998.6620,319.1140,-158.7571,1008.6620}}
};	

//------------------------------------------------------------------------------------------------------
// Businesses

#define MAX_BUSINESSES        31
#define B_DRAGON              30
#define B_CALIGULA            29
#define B_CITYPLANNING        22
#define B_CITYPLANNING_CUT  0.01

enum B_MAIN {
	BUSINESS_NAME[26],
	Float:BUSINESS_MARKER[4],
	Float:BUSINESS_AREA[6],
	BUSINESS_COST,
	BUSINESS_VALUE,
	BUSINESS_OWNER
};

new gBusinesses[MAX_BUSINESSES][B_MAIN] = {
//	NAME                           MARKER (X,Y,Z,size)                   AREA (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax)                            COST     VALUE  OWNER
	{"Botique",                    {418.5547,-80.1667,1001.8047,2.0},    {416.7485,-84.4242,1000.8047,422.6890,-74.0611,1010.8047},      10000,   6000,   INVALID_PLAYER_ID},
	{"Shithole Bar",               {501.4927,-75.4323,998.7578,2.0},     {487.6558,-88.5900,997.7578,512.0635,-67.7503,1007.7578},       25000,   13500,  INVALID_PLAYER_ID},
	{"Tattoo Parlor",              {-203.4864,-41.2045,1002.2734,2.0},   {-204.7623,-44.0326,1001.2734,-200.2330,-39.8128,1011.2734},    10000,   7000,   INVALID_PLAYER_ID},
	{"Binco Clothing",             {207.5640,-97.8188,1005.2578,2.0},    {201.4462,-112.4556,1004.1328,218.5237,-95.1238,1014.1328},     15000,   10000,   INVALID_PLAYER_ID},
	{"Train Hard Clothing",        {210.1111,-129.1273,1003.5152,2.0},   {197.4132,-139.7514,1001.8672,216.3092,-126.4872,1011.8672},    15000,   10000,   INVALID_PLAYER_ID},
	{"Urban Clothing",             {203.8557,-40.4717,1001.8047,2.0},    {196.5104,-50.5463,1000.8047,210.6805,-32.8884,1010.8047},      15000,   10000,   INVALID_PLAYER_ID},
	{"Victim Clothing",            {210.3724,-8.1825,1005.2109,2.0},     {199.7022,-12.8217,1000.2109,227.5434,-3.5228,1010.2109},       15000,   10000,   INVALID_PLAYER_ID},
	{"Zip Clothing",               {161.1875,-79.9915,1001.8047,2.0},    {144.9131,-96.0927,1000.8047,177.4128,-70.7923,1010.8047},      15000,   10000,   INVALID_PLAYER_ID},
	{"DidierSachs (DS) Clothing",  {204.2810,-157.2614,1000.5234,2.0},   {197.8987,-168.0074,999.5234,216.9775,-154.7798,1009.5234},     20000,   13000,   INVALID_PLAYER_ID},
	{"Gym",                        {773.6138,-72.1616,1000.6484,2.0},    {757.0806,-78.0856,999.5853,776.2919,-57.9732,1009.5853},       20000,   13000,  INVALID_PLAYER_ID},
	{"Zero RC",                    {-2231.2478,131.9623,1035.4141,2.0},  {-2242.3579,127.6580,1034.4141,-2219.3308,136.9540,1044.4141},  10000,   7000,   INVALID_PLAYER_ID},
	{"Zombotech",                  {-1951.5938,704.3567,46.5625,2.0},    {-1992.0277,618.2405,44.2969,-1911.2921,718.9108,54.2969},      35000,   29000,  INVALID_PLAYER_ID},
	{"Verdant Meadows Air Strip",  {418.1210,2536.8762,10.0000,2.0},     {413.4203,2534.9907,9.0000,421.4078,2542.7031,19.0000},         20000,   13000,  INVALID_PLAYER_ID},
	{"Blueberry Liquor Store",     {252.4851,-57.3515,1.5703,2.0},       {241.2532,-66.1770,0.4333,258.5785,-50.5863,10.4333},           15000,   10000,   INVALID_PLAYER_ID},
	{"Club/Disco",                 {500.7049,-13.3777,1000.6797,2.0},    {473.7363,-26.5902,999.6719,507.0171,-1.2407,1009.6719},        30000,   23000,  INVALID_PLAYER_ID},
	{"Lil' Probe-Inn",             {-225.7790,1403.9459,27.7734,2.0},    {-229.1012,1393.8146,26.7734,-222.3756,1412.1490,36.7734},      17000,   9000,  INVALID_PLAYER_ID},
	{"Sex Shop",                   {-103.5525,-22.4661,1000.7188,2.0},   {-115.9544,-24.2706,999.7188,-99.1631,-7.1391,1009.7188},       20000,   1015,   INVALID_PLAYER_ID},
	{"Strip Club",                 {1212.3918,-10.9459,1000.9219,2.0},   {1201.1422,-16.6343,999.9219,1223.4420,12.6656,1009.9219},      30000,   19992,  INVALID_PLAYER_ID},
	{"The Big Spread Ranch",       {1208.5027,-32.6044,1000.9531,2.0},   {1205.7026,-41.1453,999.9531,1216.8755,-23.9896,1009.9531},     28000,   24000,  INVALID_PLAYER_ID},
	{"Jizzy's",                    {-2650.0667,1409.2106,906.2734,2.0},  {-2689.9922,1389.1339,905.2734,-2631.0840,1431.7927,925.2734},  38000,   36000,  INVALID_PLAYER_ID},
	{"The Sherman Dam",            {-955.5327,1948.5414,9.0000,2.0},     {-955.8810,1846.5143,4.0051,-937.9516,1953.8832,14.0051},       48000,   45000,  INVALID_PLAYER_ID},
	{"Cobra Marital Arts",         {768.2014,-36.9461,1000.6865,2.0},    {754.8499,-50.4424,999.5859,778.0082,-18.5262,1009.5859},       15000,   10000,   INVALID_PLAYER_ID},
	{"City Planning Department",   {357.0584,173.5787,1008.3820,2.0},    {354.1739,158.7280,1007.3801,390.2873,188.4325,1017.3801},      35000,   290000,     INVALID_PLAYER_ID},
	{"Inside Track",               {823.1819,3.2361,1004.1797,2.0},      {820.5568,-0.8004,1001.1870,834.1219,11.6339,1011.1870},        20000,   22300,  INVALID_PLAYER_ID},
	{"Coutt and Schutz Auto",      {2131.6455,-1148.2836,24.3898,2.0},   {2093.0315,-1164.0535,22.8238,2152.8079,-1094.6797,32.8238},    25000,   22300,  INVALID_PLAYER_ID},
	{"Otto's Auto",                {-1657.8334,1207.3041,7.2500,2.0},    {-1684.3929,1201.0292,6.0391,-1636.1268,1210.3168,26.0391},     25000,   22300,  INVALID_PLAYER_ID},
	{"Wang Cars",                  {-1957.5327,300.2131,35.4688,2.0},    {-1996.0801,253.4684,25.4688,-1942.0564,310.0717,55.4688},      25000,   22300,  INVALID_PLAYER_ID},
	{"Emerald Isle",               {2127.5940,2370.4255,10.8203,2.0},    {2099.1985,2328.5200,9.6719,2179.1382,2405.8721,19.6719},       160000,  150000,  INVALID_PLAYER_ID},
	{"The Visage",                 {2022.5179,1916.6848,12.3397,2.0},    {1998.3783,1875.9679,11.1771,2066.3425,1957.0034,21.1771},      145000,  130000,  INVALID_PLAYER_ID},
	{"Caligula's",                 {2235.5408,1679.0402,1008.3594,2.0},  {2216.7971,1638.0493,1005.1771,2255.2097,1714.0806,1015.1771},  220000,  215000,  INVALID_PLAYER_ID},
	{"Four Dragons",               {1993.9758,1017.8945,994.8906,2.0},   {1970.0497,1005.8727,991.4688,2019.0717,1032.8519,1001.4688},   195000,  180000,  INVALID_PLAYER_ID}
};

//------------------------------------------------------------------------------------------------------
// Properties

#define MAX_PROPERTIES  31

enum P_MAIN {
	PROPERTY_NAME[40],
	Float:PROPERTY_MARKER[3],
	PROPERTY_VEHICLE,
	Float:PROPERTY_VEHICLE_SPAWN[4],
	PROPERTY_COST,
	PROPERTY_UPKEEP,
	PROPERTY_OWNER
};

new gProperties[MAX_PROPERTIES][P_MAIN] = {
//      NAME                                         MARKER (X,Y,Z)                     VEHICLE  VEHICLESPAWN (X,Y,Z,angle)                 COST     UPKEEP  OWNER
	{"Four Dragons Mansion",                     {991.8711,-668.1383,121.9763},     -1,      {0.0,0.0,0.0,0.0},                         -1,      -1,     INVALID_PLAYER_ID},
	{"Caligula Mansion",                         {300.2951,-1154.5029,81.3909},     -1,      {0.0,0.0,0.0,0.0},                         -1,      -1,     INVALID_PLAYER_ID},
	{"Safe House (LS: Willowfield)",             {2486.8389,-1997.4480,13.8343},    -1,      {2494.5283,-1994.1805,13.1300,181.3349},    10000,   10,    INVALID_PLAYER_ID},
	{"Safe House (LS: Verdant Bluffs)",          {1687.8954,-2100.4861,13.8343},    -1,      {1698.8572,-2083.7195,13.1728,179.3985},    10000,   10,    INVALID_PLAYER_ID},
	{"Safe House (LS: Jefferson)",               {2108.2073,-1280.1827,25.6875},    -1,      {2103.4307,-1275.3805,25.1159,179.5528},    10000,   10,    INVALID_PLAYER_ID},
	{"Safe House (LS: Mulholland)",              {1325.8687,-633.3270,109.1349},    -1,      {1354.6711,-631.1613,108.7579,17.0284},    120000,  120,    INVALID_PLAYER_ID},
	{"Safe House (LS: Verona Beach)",            {890.5464,-1638.7795,14.9616},     -1,      {894.5661,-1644.0613,13.2128,195.1457},     10000,   10,    INVALID_PLAYER_ID},
	{"Safe House (LS: Santa Maria Beach)",       {312.6361,-1772.2003,4.6282},      -1,      {322.2773,-1764.7043,4.1956,180.3049},      30000,   30,    INVALID_PLAYER_ID},
	{"Safe House (LS: Palomino Creek)",          {2238.4756,166.0871,28.1535},      -1,      {2231.2734,172.3486,27.1053,178.0615},      35000,   35,    INVALID_PLAYER_ID},
	{"Safe House (LS: Blueberry)",               {206.6301,-109.8167,4.8965},       -1,      {201.2664,-114.5452,1.2165,112.4739},       10000,   10,    INVALID_PLAYER_ID},
	{"Safe House (LS: Dillimore)",               {791.9865,-507.5847,18.0129},      -1,      {786.0810,-489.1288,16.9612,178.9169},      40000,   40,    INVALID_PLAYER_ID},
	{"Safe House (SF: Angel Pine)",              {-2080.1499,-2312.3855,30.6250},   -1,      {-2082.9905,-2322.4644,30.2500,51.0459},    20000,   20,    INVALID_PLAYER_ID},
	{"Safe House (SF: Whetstone)",               {-1442.8309,-1541.9430,101.7578},  -1,      {-1435.0696,-1538.2642,101.3843,88.4039},  100000,  100,    INVALID_PLAYER_ID},
	{"Safe House (SF: Hashbury)",                {-2456.8408,-131.7211,26.0440},    -1,      {-2448.9182,-123.1912,25.7608,89.7528},     40000,   40,    INVALID_PLAYER_ID},
	{"Safe House (SF: Doherty)",                 {-2027.6254,-44.5550,38.4414},     -1,      {-2022.9924,-45.6301,34.9851,177.5642},     20000,   20,    INVALID_PLAYER_ID},
	{"Safe House (SF: Queens)",                  {-2421.6580,335.3531,35.7626},     -1,      {-2411.0249,328.4082,34.5936,331.4149},     50000,   50,    INVALID_PLAYER_ID},
	{"Safe House (SF: Chinatown)",               {-2210.9714,723.4057,49.4141},     -1,      {-2206.8999,717.1359,49.1197,0.3468},       20000,   20,    INVALID_PLAYER_ID},
	{"Safe House (SF: Paradiso)",                {-2703.1348,818.3945,49.9844},     -1,      {-2695.9668,825.1044,49.6114,179.1829},     20000,   20,    INVALID_PLAYER_ID},
	{"Safe House (SF: Calton Heights)",          {-2103.9272,900.6589,76.7109},     -1,      {-2105.3892,893.0870,76.3292,0.8677},      100000,  100,    INVALID_PLAYER_ID},
	{"Safe House (LV: El Quebradas)",            {-1534.4202,2649.6294,55.8359},    -1,      {-1529.5422,2644.5068,55.4614,87.9083},     20000,   20,    INVALID_PLAYER_ID},
	{"Safe House (LV: Tierra Robada)",           {-1045.4006,1552.8932,33.3112},    -1,      {-1058.0560,1547.7667,32.9439,221.8480},    20000,   20,    INVALID_PLAYER_ID},
	{"Safe House (LV: Fort Carson)",             {-364.1446,1168.8844,19.7422},     -1,      {-360.6525,1198.4445,19.3517,179.9464},     30000,   30,    INVALID_PLAYER_ID},
	{"Safe House (LV: Whitewood Estates)",       {926.3783,2010.8345,11.4609},      -1,      {934.0626,2011.9355,11.0862,88.8243},       30000,   30,    INVALID_PLAYER_ID},
	{"Safe House (LV: Prickle Pine)",            {1282.0720,2525.0994,10.8203},     -1,      {1274.5979,2529.6389,10.4464,269.8529},     50000,   50,    INVALID_PLAYER_ID},
	{"Safe House (LV: Redsands West)",           {1405.6171,1900.5596,11.4609},     -1,      {1413.1158,1902.3392,11.0866,88.7683},      30000,   30,    INVALID_PLAYER_ID},
	{"Safe House (LV: Pirates In Men's Pants)",  {1969.4005,1623.1444,12.8625},     -1,      {1966.9027,1626.7555,12.3551,310.5855},      6000,    6,    INVALID_PLAYER_ID},
	{"Safe House (LV: The Camel's Toe)",         {2233.6375,1288.4495,10.8203},     -1,      {2232.2229,1280.0878,10.3704,180.3086},      6000,    6,    INVALID_PLAYER_ID},
	{"Safe House (LV: Rockshore West)",          {2446.2251,695.2101,11.4609},      -1,      {2452.8860,697.4849,11.0852,89.0021},       20000,   20,    INVALID_PLAYER_ID},
	{"Safe House (LV: The Clown's Pocket)",      {2223.1616,1840.9108,10.8203},     -1,      {2216.6589,1838.7125,10.4467,181.4032},      6000,    6,    INVALID_PLAYER_ID},
	{"Safe House (LV: Old Venturas Strip)",      {2371.1787,2169.1052,10.8257},     -1,      {2363.0129,2174.3489,10.4139,1.0025},        6000,    6,    INVALID_PLAYER_ID},
	{"Safe House (LV: Creek)",                   {2820.9004,2140.8269,14.6615},     -1,      {2823.2332,2152.8130,10.4451,92.3374},      10000,   10,    INVALID_PLAYER_ID}
};

//------------------------------------------------------------------------------------------------------
// Airports

#define MAX_AIRPORTS                        3
#define AIRPORT_FLIGHT_FEE                500
#define AIRPORT_FLIGHT_VEHICLEMULTIPLIER    3
#define AIRPORT_LV                          0
#define AIRPORT_LS                          1
#define AIRPORT_SF                          2

enum AIRPORT_MAIN {
	AIRPORT_NAME[35],
	Float:AIRPORT_MARKER[4],
	Float:AIRPORT_AREA[6]
};

new gAirports[MAX_AIRPORTS][AIRPORT_MAIN] = {
//      NAME                                    MARKER (X,Y,Z,size)                  AREA (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax)
	{"Las Venturas International Airport",  {1676.9878,1448.0142,10.7829,4.0},   {1591.1667,1330.5260,9.3845,1747.6305,1557.2911,49.3845}},
	{"Los Santos International Airport",    {1685.7150,-2242.6440,13.5469,4.0},  {1578.8071,-2263.3557,-3.6824,1768.0049,-2210.9470,37.6824}},
	{"San Fierro International Airport",    {-1424.4857,-290.6034,14.1484,4.0},  {-1467.9697,-356.2959,5.0000,-1381.7617,-264.2767,45.0000}}
};

//------------------------------------------------------------------------------------------------------
// Skydives

#define MAX_SKYDIVES           3
#define MAX_SKYDIVEJUMPS      15
#define SKYDIVE_FEE          500

enum SKYDIVE_MAIN {
	SKYDIVE_NAME[23],
	Float:SKYDIVE_MARKER[4],
	Float:SKYDIVE_AREA[6]
};

new gSkydives[MAX_SKYDIVES][SKYDIVE_MAIN] = {
//      NAME                        MARKER (X,Y,Z,size)                  AREA (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax)
	{"Las Venturas Skydiving",  {1603.6815,1178.3738,14.2241,4.0},   {1533.5276,1148.0375,9.8125,1632.5746,1240.2479,29.8125}},
	{"Los Santos Skydiving",    {1812.6095,-2429.0881,13.5547,4.0},  {1748.0222,-2462.7825,12.5391,1861.7125,-2400.1621,52.5391}},
	{"San Fierro Skydiving",    {-1257.8129,14.0936,14.1484,4.0},    {-1295.9435,-15.2781,4.1484,-1226.7222,69.8264,54.1484}}
};

enum SKYDIVE_JUMP_MAIN {
	SKYDIVE_JUMP_NAME[24],
	Float:SKYDIVE_JUMP_MARKER[3]
};

new gSkydiveJumps[MAX_SKYDIVEJUMPS][SKYDIVE_JUMP_MAIN] = {
	{"Los Santos Inlet",         {-276.4088,-2191.1550,1500.0000}},
	{"Angel Pine",               {-2146.2078,-2410.8572,1500.0000}},
	{"Missionary Hill",          {-2510.8315,-613.2032,1500.0000}},
	{"Calton Heights",           {-2128.7444,918.7960,1500.0000}},
	{"Battery Heights",          {-2631.1018,1365.6899,1500.0000}},
	{"Esplanade North",          {-1630.2244,1419.0817,1500.0000}},
	{"Fishers Lagoon",           {2104.1182,-103.4581,1500.0000}},
	{"Commerce (LS CBD)",        {1660.0391,-1709.4559,1500.0000}},
	{"Fern Ridge",               {872.0431,-21.3734,1500.0000}},
	{"Verdant Maria Beach",      {1199.3325,-2037.3644,1500.0000}},
	{"Santa Maria Beach",        {370.4959,-2032.2311,1500.0000}},
	{"Yellow Bell Golf Course",  {1395.8832,2952.9963,1500.0000}},
	{"The Sherman Dam",          {-713.1229,1883.3695,1500.0000}},
	{"Bayside",                  {-2501.6062,2420.4026,1500.0000}},
	{"Fort Carson",              {-67.6139,1099.7059,1500.0000}}
};

new gPlayerSkydive[MAX_PLAYERS] = {-1, ...};

//------------------------------------------------------------------------------------------------------
// Misc areas

#define MAX_OTHERAREAS          18
#define OA_PIRATESHIP            0
#define OA_WANGEXPORTS           1
#define OA_HEAVEN                2
#define OA_HELL                  3
#define OA_LVTOLCWARP            4
#define OA_LIBERTYCITY           5
#define OA_TAXIINFO              6
#define OA_PATROLINFO            7
#define OA_SKYDIVEPLANE          8
#define OA_CASINOFLOOR           9
#define OA_PBDRAGONIN           10
#define OA_PBDRAGONOUT          11
#define OA_PBDRAGONMONEY        12
#define OA_PBDRAGONSAFEHOUSE    13
#define OA_PBDRAGONTRANSCP      14
#define OA_PBCALIGULAMONEY      15
#define OA_PBCALIGULASAFEHOUSE  16
#define OA_PBCALIGULATRANSCP    17

new Float:gOtherAreas[MAX_OTHERAREAS][6] = {
	{1894.6128,1445.3431,0.6719,2084.9739,1637.8186,40.6719},         // Pirate Ship
	{-1924.2008,245.8384,31.0469,-1897.0090,310.0460,51.0469},        // Wang Exports
	{2301.1162,1260.2860,67.4688,2346.1741,1305.4763,117.4535},       // Heaven fall
	{-2549.7979,-1660.4034,483.6910,-2339.2673,-1589.3324,536.7890},  // Hell fall
	{1700.0000,2100.0000,-100.0000,1800.0000,2200.0000,-55.0000},     // LV (Randsands East) -> Liberty City warp
	{-1000.0000,400.0000,1150.0000,-700.0000,600.0000,1400.0000},     // Liberty City -> LV (Randsands East) warp
	{1684.4969,1291.2892,9.6304,1701.5283,1311.0322,15.6304},         // Taxi Information
	{2259.5747,2424.8020,-8.4531,2277.0645,2439.1260,2.2734},         // Police patrol information
	{250.0000,960.0000,1752.8896,370.0000,1100.0000,2000.0000},       // Skydive AT-400 Interior
	{1117.5068,-11.2747,999.6797,1142.4843,12.5986,1009.6797},        // Casino Floor
	{1925.1505,968.2361,991.4688,1981.3546,1000.9938,999.4688},       // PitBoss - Four Dragons CP IN
	{-2171.3599,637.9680,1056.6960,-2157.6924,646.5863,1063.5413},    // PitBoss - Four Dragons CP OUT
	{-2171.3137,640.3600,1052.3750,-2164.8662,646.5512,1054.9687},    // PitBoss - Four Dragons Money Area
	{893.3315,-872.7241,120.1472,1234.1179,-577.8191,130.1472},       // PitBoss - Four Dragons Safehouse
	{-2171.3135,635.3906,1051.3750,-2157.8484,646.5513,1061.3750},    // PitBoss - Four Dragons Trans CP Area
	{2141.2017,1627.7067,992.5761,2147.1655,1642.7124,999.5761},      // PitBoss - Caligula Money Area
	{246.7787,-1359.3147,79.9141,450.6779,-983.2086,89.9141},         // PitBoss - Caligula Safehouse
	{2142.4827,1573.4395,998.9745,2210.3237,1632.1488,1008.9745}      // PitBoss - Caligula Trans CP Area
};

#define dcmd(%1,%2,%3) if ((strcmp(cmdtext, "/%1", true, %2 + 1) == 0) && (((cmdtext[%2 + 1] == 0) && (%3(playerid, ""))) || ((cmdtext[%2 + 1] == 32) && (%3(playerid, cmdtext[%2 + 2]))))) return 1  // Based on code by DracoBlue
#define dcmd2(%1,%2,%3) if ((strcmp(text, "%1", true, %2) == 0) && (((text[%2] == 0) && (%3(playerid, ""))) || ((text[%2] == 32) && (%3(playerid, text[%2 + 1]))))) return 1                          // Based on code by DracoBlue

forward Float:GetDistanceBetweenPoints(Float:pos1[3], Float:pos2[3]);
forward Float:GetDistanceBetweenPlayers(player1, player2);
forward Float:GetDistanceToPoint(playerid, Float:data[3]);

/*
)IIIIi,,........................,,,,,,;,........................,,=IIIIIIIII)i:,,,,,................................,,iIIII+.................
I,,,,I,,........................,,,,;)I,........................,,I,,,,,,,,,,;)),,,,................................,,I,,,,I.................
I,,,,I,,........................,,,=i,I,........................,,I,,,,,,,,,,,,:),,,................................,,I,,,,I.................
I,,,,I,,........................,,)+,,I,........................,,I,,,,,,,,,,,,,i;,,................................,,I,,,,I.................
I,..,I,.............,,,,,,,,,,,,,I:,,,I,,,,,,,,,,,,,,,,,........,,I,,,,,,,,,,,,,,),,....,,,,,,,,........,,,,,,,,,,,.,,I,,,,I,,,,,,,,,,,,,,,,.
I,..,I,.............,,,,,,,,,,,,,I,,.,I,,,,,,,,,,,,,,,,,........,,I,,.,,:::,,,,,,I,,....,,.,,.,,........,.,,,,,,,,,,,,LIIIII,,,,,.,,,,,,,,,,.
I,..,I,.............,,,,,,,,,,,,,I,,,,I,,,,,,,,,,,,,,,,,........,,I,,,,+Ii)I;,,,,I,,....,,,,,,,,........,,,,,,,,,,,,,,.,,,,,,,,,,,.,,,,,,,,,.
I,..,I,.............+III);.,,.,;=I,,,.L++,,,,,=IIIIi:,,,........,,I,,.,++,,,I,,,,):,....,+IIIi;,........:)II;,:++++:,,;=+++:,,;++++,,;II):,,.
I,..,I,.........,,;I=,,,:iI:,,,I+;,,,,=+I+,,;I+,,,,;)=,,........,,I,,,,++,,,I,,,,I,,,,,;I=,,,:iI,,,,,,,+i:,,i=I++++I,,T++++I,.T+++T:ii,,:);,.
I,..,I,.........,;),,,,,,,,),,,I,,,,,,,,=+,:),,,,,,,,=+,........,,I,,,,++,,,I,,,,I,,,,;i,,,,,,,,I,,,,,;i,.,,,+H,,,,I,,I,,,,I,,I,,,)i+,,,,,I,.
I,..,I,.........,I,,,,,,,,,,),,I,,.,,,,,=+,I,,,,,,,,,,I,........,,I,,,,+i:;i=.,,,),,,,I,,,,,,,,,,),,,,I,,,,,,,H,,,,I,,I,,.,I.,I,,,)),,,,,,;=.
I,..,I,.........i;,,,,;;,,,,i;,I,.,,,,,,=+:),,,+II:,,,++........,,I,,,,:iii;,,,,):,,,i;,,,,;;,,,,i;,,:),,,,,,,,,,,,I,,I,,,,I,,I,,,:,,,,,,,,I.
I,..,I,.....,,,,I,,,,)iii,,,,I,I,,,,,,,,=++=,,,I,,I,:+)I........,,I,,,..,,,,,,,i+,,,,I,,,,)i==,,,,I,,i;,,,,:+,,,,,,I.,I,,,.I,.I,,,,,,,,,,,,I.
I,..,I,.....,,,:i,,,+=,,):,,,I,iI),,,,LIT:=+,,,I,,=I)+:,........,,I,,...,,,,,,:I=,,,;i,,,+=,,):,,,I,,I,.,,;)+),,,,,I.,I,,,.I,.I,,,,,II;,,,,I.
I,..,I,.....,,.i;,,,I,,,;i,,,i:,,I,,,,I,,,++,,,;IIi;,,,,........,,I,...,,,,,,,,,=+,,i;,,,I,,,;=,,,):,I,,,,I,,+=,,,,I.,I,,,.I,.I,,,,),,I,,,,I.
I,..,I,.....,,,I,,,,Tiii)),,,+=,,I.,,,I,,,:),,,,,,:iI=,,........,,I,..,,:::,,,,,,):,I,,,,Tiii)),,,++,I,,,,I,,,I,,,,I.,I,,,.I,.I,,,,I,,I,,,.I.
I,..,I,.....,,,I..,,:::::,..,;=,,I,...I,,,,I,,,,,,,,,+i,........,,I,,,,+IiiI),,,,;i,I,,,,:::::,,,,+=,I,,,,I,,,I,,,,I.,I,,,.I,.I,,,,I,,),,,,I.
I,..,I,.....,,,I...,,,,,,,,,,:i,,I,...I,,,,;),,,,,,.,,=;........,,I,,,,++,,,+=,,,,I,I,,,,.,,,..,,,;i,I,,,,I,,,I,,,,I.,I,,,.I,.I,,.:),,),,,,I.
I,..,I,.....,.,I,...,,,,,,,,,,),,I,...I,,,,,+I;,,,,,,.,I........,,I,,,,++,,,,I,,,,I,I,,,,,,,,.,,,,:),I,,,,I,,,I,,,,I.,I,,,.I,.I,,,,),,),,,,I.
I,..,I,.....,,,I,,..IIIIIIIIII+,,I,...I,,,,,,,=II+,,,,,I........,,I,,,,++,,,:),,,,I,I,,,,IIIIIIIIII+,I,,,,I,,:i,,,,I.,I,,,.I,.I,,,,),,),,,,I.
I,..,IIIIIIIII;):,,,I,,,,,,,,,,,,I,,,,I,,,,,,,,,,+I:,,,I,.,,....,,I,,,,++,,,):,,,,I,):.,,I,,,,,,,,,,,),,,,=+,):,,,,I.,I,,,.I,.I,,,:),,),,,,I.
I,..,,,,,,,,,+=;i,,,=+,,:TI)=;,,,I,.,,I,;,iIII)I,,,I,,,I,,,,....,,I,.,,;IIII;,,,,.I,;=,,,=;,,;TI)=;,,++,,,,=I;,,,,,I.,I,,,.I,.I,,,:),,),,,,I.
I,..,,,,....,+=,I,,,,);:I,,:+L:,,I,,,,+IL,I,,,,):,;i.,,I.,,,....,,I,,,,,,,,,,,,,,,),,I,,,,I;;I,,:+L,,,I,,,,,,,,,,,,I.,I,,,.I,.I,,,:),,),,,,I.
I,..,,,,....,+=,):,,,,ii,,,,,I,,,I,,,,,,i;i:,,,,)I),,,,I,,,,....,,I,.,,,.,,,,,,,,i;,,):,,,,ii,,,,,I,,,i:,,,,,,i,,,,I.,I,,,.I,.I,,,:),,),,,,I.
I,,,,,,,,,,,,+=,,).,,,,,,,,,):,,,),,,,,,=+:i,,,,,,,,,,i;........,,I,,,,,,,,,,,,,,I,,,:),,,,,,,,,,):.,,,I,,,,,iL,,,.I,,I,,,,I,,I,,,,),,),,,,I.
I,,,........,;=,,+=,,,,,,,,+=,,,,:i,,,,,+=,=+,,,,,,,,:i,........,,I,........,,,,I:,,,,=+,,,,,,,,+=,,,,,:I;,:)+I,,,.I,,I,,,,I,,I,,,:),,):,,,I.
T:;:::::::::;==,,,=I:,,,,:I=,,,,,,i+,,,,=i,,ii,,,,,,i),,........,,I:::::::::+iII:.,,,,,=):,,,,;I=,,,,,,,,iI):.I,,,.I,,T;::;I,,T:::+),,)+:;:T.
=iiiiiiiiiiiii:,,,,,)IIIIi,,,,,,,,,=IIIIi,,,,:)IIII):,,,........,,+iiiiiiiii+:,,,,,,,,,,,)IIIIi,,,,,,=I)+:,,,,I,,,.I,,=iiii;,,=iiii;,,;iiii=.
....................................................................................................,I,:+)I,,:),,,,).........................
....................................................................................................,i;,,.==,):,,,+=.........................
....................................................................................................,+=,,,,+);,,,,),.........................
....................................................................................................,,I,,,,,,,,,,,I,.........................
....................................................................................................,,i;,.,,,,,,,):,.........................
....................................................................................................,,,)+,,,,,,,i+,,.........................
....................................................................................................,,,,=IIIIII):,,,.........................
*/

main() {
	print("\n========================================");
	print("  Running SA~DMA+LG+PB+SR by Betamaster");
	print("========================================\n");
}

//******************************************************************************************************
// Callbacks...
//******************************************************************************************************

//------------------------------------------------------------------------------------------------------

public OnGameModeInit() {
	print("\n\n==== Initialising gamemode ====");
	SetGameModeText("SA~DMA+LG+PB+SR");
	ShowPlayerMarkers(1);
	ShowNameTags(1);

	gWantedWangExportVehicle = gWantedWangExportVehicles[random(MAX_WANGEXPORT_VEHICLES)];

	Config_SetupGamemode();
	Config_SetupRaces();

	//---> Add police/security classes
	for(new i=280; i<=288; i++) {
		AddPlayerClass(i,0.0,0.0,0.0,0.0,0,0,WEAPON_DEAGLE,300,-1,-1);
	}
	//---> Add all other classes
	for(new i=1; i<=279; i++) {
		switch(i) {
			case 3, 4, 5, 6, 7, 8, 42, 65, 74, 86, 119, 149, 208, 265, 266, 267, 268, 269, 270, 271, 272, 273, 289: {} //do nothing, these peds crash game
			default: AddPlayerClass(i,0.0,0.0,0.0,0.0,0,0,WEAPON_DEAGLE,300,-1,-1);
		}
	}

	for(new i=0; i<MAX_GANGS; i++) Gang_Initialise(i);
	for(new i=0; i<MAX_PLAYERS; i++) {
		Stats_Reset(i);
		Taxi_Initialise(i);
		Gang_Reset(i);
		SpawnWeapons_Reset(i);
		DMA_Reset(i);
		Race_ResetProgress(i);
		Pref_Reset(i);
	}
	for(new i=0; i<MAX_CASINO; i++) {
		PitBoss_Initialise(i);
		gPitBoss[i][PB_OWNER] = INVALID_PLAYER_ID;
		gPitBoss[i][PB_GFEE] = MIN_GFEE;
	}

	// Car Spawns
	for(new i=0; i<MAX_VEHICLES; i++) {
		AddStaticVehicle(gVehicles[i][VEHICLE_MODEL], gVehicles[i][VEHICLE_SPAWN][0], gVehicles[i][VEHICLE_SPAWN][1], gVehicles[i][VEHICLE_SPAWN][2], gVehicles[i][VEHICLE_SPAWN][3], gVehicles[i][VEHICLE_COLOUR][0], gVehicles[i][VEHICLE_COLOUR][1]);
	}

	//---> START RESERVED VEHICLES
	gPitBoss[PB_DRAGON][PB_VEHICLE_SECURICAR] = 1;
	gPitBoss[PB_DRAGON][PB_VEHICLE_1] = 2;
	gPitBoss[PB_DRAGON][PB_VEHICLE_2] = 3;
	gPitBoss[PB_DRAGON][PB_VEHICLE_3] = 4;
	gPitBoss[PB_CALIGULA][PB_VEHICLE_SECURICAR] = 5;
	gPitBoss[PB_CALIGULA][PB_VEHICLE_1] = 6;
	gPitBoss[PB_CALIGULA][PB_VEHICLE_2] = 7;
	gPitBoss[PB_CALIGULA][PB_VEHICLE_3] = 8;
	gPatrolVehicles[0] = 9;
	gPatrolVehicles[1] = 10;
	//---> END RESERVED VEHICLES

	//---> Property Objects...
	for(new i=0; i<MAX_PROPERTIES; i++) {
		if(i<2) AddStaticPickup(1272,49,gProperties[i][PROPERTY_MARKER][0],gProperties[i][PROPERTY_MARKER][1],gProperties[i][PROPERTY_MARKER][2]);
		else AddStaticPickup(1273,49,gProperties[i][PROPERTY_MARKER][0],gProperties[i][PROPERTY_MARKER][1],gProperties[i][PROPERTY_MARKER][2]);
	}

	//---> Information objects...
	AddStaticPickup(1239,49,1694.5439,1302.0090,10.9922);   // Taxi
	AddStaticPickup(1239,49,2268.3777,2432.4988,-7.4531);   // Patrol

	//---> Game collectables...
	AddStaticPickup(371,15,1710.3359,1614.3585,10.1191);    // Parachute
	AddStaticPickup(371,15,1964.4523,1917.0341,130.9375);   // Parachute
	AddStaticPickup(371,15,2055.7258,2395.8589,150.4766);   // Parachute
	AddStaticPickup(371,15,2265.0120,1672.3837,94.9219);    // Parachute
	AddStaticPickup(371,15,2265.9739,1623.4060,94.9219);    // Parachute
	AddStaticPickup(371,15,2301.8430,1298.3070,67.4688);    // Parachute
	AddStaticPickup(321,22,1212.4238,-34.9983,1000.9531);   // Purple Dildo
	AddStaticPickup(321,22,1202.5164,11.0296,1000.9219);    // Purple Dildo
	AddStaticPickup(367,15,2097.9463,1160.1179,11.6484);    // Camera (lv)
	AddStaticPickup(367,15,-1954.8512,303.8038,41.0471);    // Camera (sf)
	AddStaticPickup(367,15,2830.9158,-1875.0287,11.1049);   // Camera (ls)
	AddStaticPickup(334,15,2250.9468,2489.5918,10.9908);    // Night Stick (lv police station)

	//---> Casino Cash objects...
	AddStaticPickup(1274,49,2142.8774,1629.4050,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2145.0217,1629.9515,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2145.8274,1632.7113,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2143.5422,1632.1873,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2141.2727,1632.3309,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2141.2019,1634.4384,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2141.8711,1635.8187,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2143.7397,1636.6322,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2145.2847,1639.2794,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2143.2800,1639.4965,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2141.2034,1638.1798,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2141.2036,1641.3331,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2143.2864,1642.2670,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2147.0281,1638.0121,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2146.2151,1633.6978,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2146.4807,1628.0156,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2141.7200,1628.7190,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2142.2476,1632.6307,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2141.8596,1637.8435,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2145.8916,1635.9810,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2144.7556,1632.9858,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2144.6377,1640.0598,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2146.4829,1630.7902,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2143.6855,1634.5087,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,2147.1646,1642.7123,993.5761);  // Caligula Money
	AddStaticPickup(1274,49,-2170.6072,640.9490,1052.3817); // Four Dragon Money
	AddStaticPickup(1274,49,-2170.0869,642.9522,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2170.4109,644.4947,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2167.9299,644.5926,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2166.5989,643.5547,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2165.5229,641.4185,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2166.5225,640.3839,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2168.3147,641.0391,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2168.0889,642.1072,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2166.8818,643.7977,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2169.4197,644.8042,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2169.4143,642.9215,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2169.2891,641.2472,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2170.0986,641.9453,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2169.4265,645.2766,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2166.6482,646.5524,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2166.5137,642.8809,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2167.3950,641.2070,1052.3750); // Four Dragon Money
	AddStaticPickup(1274,49,-2171.3137,645.4094,1052.3817); // Four Dragon Money

	//Timers...
	SetTimer("Timer_GM_OneSecond", 1000, 1);
	SetTimer("Timer_GM_Speedo", gGMConfig[GMC_SPEEDO], 1);

	print("==== Initialision complete ====");
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnGameModeExit() {
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerRequestClass(playerid, classid) {
	ShowGameTextForPlayer(playerid, "~w~SA-MP Freeroam~y~ ~n~ ~n~ ~n~ ~n~ ~n~ ~n~ ~n~ ..Deathmatch.PitBoss.Racing..~n~~g~..And.More..", 600000, 6);
	if(classid>=0 && classid<=8) gPlayerSpawn[playerid][SPAWN_CLASS] = SPAWN_COP;
	else gPlayerSpawn[playerid][SPAWN_CLASS] = SPAWN_FREEROAM;
	Spawn_SetupClassSelection(playerid);
	PlaySoundForPlayer(playerid, SOUND_MUSIC_CLASSSELECT);
	SetPlayerColor(playerid, gPlayerColours[playerid]);
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerRequestSpawn(playerid) {
	ShowGameTextForPlayer(playerid, " ", 1, 2);
	gPlayerSpawn[playerid][SPAWN_SCREEN] = random(MAX_SPAWN_SCREENS);
	PlaySoundForPlayer(playerid, SOUND_OFF);
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerConnect(playerid) {
	SendClientMessage(playerid, COLOUR_GREEN, "Welcome to San Andreas DMA+LG+PB+SR.");
	GetPlayerName(playerid, gPlayerStats[playerid][STATS_NAME], MAX_PLAYER_NAME);
	new string[MAX_STRING];
	format(string, MAX_STRING, "Hi %s, welcome!", gPlayerStats[playerid][STATS_NAME]);
	if(udb_Exists(udb_encode(gPlayerStats[playerid][STATS_NAME]))) {
		format(string, MAX_STRING, "%s Your username is registered on this server.", string);
		SendClientMessage(playerid, COLOUR_WHITE, string);
		SendClientMessage(playerid, COLOUR_YELLOW, "Please '/signin' before continuing or reconnect with an alternate username.");
	} else {
		format(string, MAX_STRING, "%s Please '/signup' to have your game progress saved after you leave.", string);
		SendClientMessage(playerid, COLOUR_WHITE, string);
	}
	SendClientMessage(playerid, COLOUR_YELLOW, "Type '/help' to get started.");
	SetPlayerPocketMoney(playerid, 0);
	gPlayerStats[playerid][STATS_FIRSTSPAWN] = 1;
	gPlayerSpawn[playerid][SPAWN_SCREEN] = random(MAX_SPAWN_SCREENS);
	gPlayerSpawn[playerid][SPAWN_TYPE] = SPAWN_RANDOM;
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerDisconnect(playerid) {
	for(new i=2; i<MAX_PROPERTIES; i++) {
		if(gProperties[i][PROPERTY_OWNER]==playerid) {
			GivePlayerPocketMoney(playerid, gProperties[i][PROPERTY_COST]);
			gProperties[i][PROPERTY_OWNER] = INVALID_PLAYER_ID;
		}
	}
	for(new i=0; i<MAX_BUSINESSES; i++) {
		if(gBusinesses[i][BUSINESS_OWNER]==playerid) {
			GivePlayerPocketMoney(playerid, gBusinesses[i][BUSINESS_COST]);
			gBusinesses[i][BUSINESS_OWNER] = INVALID_PLAYER_ID;
		}
	}
	AC_Reset(playerid);
	if(gPlayerTaxi[playerid][TAXI_STATUS]!=-1)  Taxi_Leave(playerid);
	if(gPlayerRace[playerid][PRACE_ID]!=-1)     Race_Leave(playerid);
	if(gPlayerGang[playerid][PGANG_ID]!=-1)     Gang_Leave(playerid, "");
	if(gPlayerDM[playerid][DM_ZONE]!=-1)        DMA_Leave(playerid);
	if(gPlayerPatrol[playerid][PATROL_ONDUTY])  Patrol_Reset(playerid);

	if(gPlayerStats[playerid][STATS_AUTHENTICATED]) {
		Registration_Signout(playerid, "");
	} else {
		Stats_Save(playerid);
	}
	Stats_Reset(playerid);
	Pref_Reset(playerid);

	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerSpawn(playerid) {
	if(gPlayerStats[playerid][STATS_FIRSTSPAWN]) {
		if(udb_Exists(gPlayerStats[playerid][STATS_NAME]) && !gPlayerStats[playerid][STATS_AUTHENTICATED]) {
			if(gGMConfig[GMC_REG_KICK]) {
				KickPlayer(playerid, KICK_SIGNINERROR);
				return 1;  // Player will spawn in a cold, dark world
			}
			SendClientMessage(playerid, COLOUR_RED, "You have NOT logged in. Please '/signin' to have your game progress saved after you leave.");
		} else if(!gPlayerStats[playerid][STATS_AUTHENTICATED]) {
			Stats_Restore(playerid);
		}
		gPlayerStats[playerid][STATS_FIRSTSPAWN] = 0;
	}
	SetPlayerColor(playerid, GetPlayerColor(playerid));  // <-- work around for SA-MP bug
	//---> Spawn player at deathmatch zone if they have not quit the zone
	SetPlayerInterior(playerid, 0);
	if(gPlayerDM[playerid][DM_ZONE]!=-1) {
		DMA_Enter(playerid, gPlayerDM[playerid][DM_ZONE]);
	} else {
		new money = GetPlayerMoney(playerid);
		if(money>=0 && money<gGMConfig[GMC_POCKETMONEY]) SetPlayerPocketMoney(playerid, gGMConfig[GMC_POCKETMONEY]);
		Spawn_Set(playerid);
		SpawnWeapons_Issue(playerid);
		SetPlayerWorldBounds(playerid, MAX_WORLDBOUNDS, -MAX_WORLDBOUNDS, MAX_WORLDBOUNDS, -MAX_WORLDBOUNDS);
	}

	if(gPlayerPatrol[playerid][PATROL_ONDUTY]) {
		for(new i=0; i<MAX_PATROL_VEHICLES; i++) SetVehicleParamsForPlayer(gPatrolVehicles[i], playerid, 0, 0);
	} else {
		for(new i=0; i<MAX_PATROL_VEHICLES; i++) SetVehicleParamsForPlayer(gPatrolVehicles[i], playerid, 0, 1);
	}

	Taxi_Reset(playerid);
	Race_ResetProgress(playerid);
	AC_Reset(playerid);

	if(gBusinesses[B_DRAGON][BUSINESS_OWNER]==playerid && gPitBoss[PB_DRAGON][PB_TRANSPORTING]) gPitBoss[PB_DRAGON][PB_TRANSPORTING] = 0;
	if(gBusinesses[B_CALIGULA][BUSINESS_OWNER]==playerid && gPitBoss[PB_CALIGULA][PB_TRANSPORTING]) gPitBoss[PB_CALIGULA][PB_TRANSPORTING] = 0;
	PitBoss_AutoLockVehicles(playerid);

	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerDeath(playerid, killerid, reason) {
	new string[MAX_STRING], money = GetPlayerMoney(playerid);

	SendDeathMessage(killerid, playerid, reason);
	if(killerid==INVALID_PLAYER_ID) {
		gPlayerStats[playerid][STATS_DEATHS_SELF]++;
	} else {
		new cash = 0, moneyearnt = 0;

		// Collect bounty
		if(gPlayerStats[playerid][STATS_BOUNTY]>0 && (gPlayerGang[killerid][PGANG_ID]==-1 || gPlayerGang[playerid][PGANG_ID]!=gPlayerGang[killerid][PGANG_ID])) {
			format(string, MAX_STRING, "You earned a bounty of $%d for killing %s.", gPlayerStats[playerid][STATS_BOUNTY], gPlayerStats[playerid][STATS_NAME]);
			SendClientMessage(killerid, COLOUR_GREEN, string);
			moneyearnt += gPlayerStats[playerid][STATS_BOUNTY];
			format(string, MAX_STRING, "%s has claimed your $%d bounty.", gPlayerStats[killerid][STATS_NAME], gPlayerStats[playerid][STATS_BOUNTY]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			gPlayerStats[playerid][STATS_BOUNTY] = 0;
		}

		// Collect pocket money
		if(money>0) {
			moneyearnt += money;
		}

		// Collect Pit Boss cash
		for(new i=0; i<MAX_CASINO; i++) {
			if(gPitBoss[i][PB_OWNER]==playerid && gPitBoss[i][PB_TRANSPORTING]) {
				cash = floatround(gPitBoss[i][PB_CASH]*0.5);
				format(string, MAX_STRING, "You have stolen $%d from Pit Boss %s!", cash, gPlayerStats[playerid][STATS_NAME]);
				SendClientMessage(killerid, COLOUR_GREEN, string);
				format(string, MAX_STRING, "%s has stolen $%d of your casino funds!", gPlayerStats[killerid][STATS_NAME], cash);
				gPitBoss[i][PB_CASH] -= cash;
				moneyearnt += cash;
				break;
			}
		}

		// Pay the killer
		if(moneyearnt>0) {
			if(gPlayerDM[killerid][DM_ZONE]!=-1) {
				gPlayerStats[killerid][STATS_MONEY_BANK] += moneyearnt;
				if(gPlayerStats[killerid][STATS_MONEY_BANK]>gGMConfig[GMC_MAXBANK]) gPlayerStats[killerid][STATS_MONEY_BANK] = gGMConfig[GMC_MAXBANK];
			} else {
				GivePlayerPocketMoney(killerid, moneyearnt);
			}
		}

		// Update stats
		gPlayerStats[playerid][STATS_DEATHS_NONSELF]++;
		if(gPlayerDM[playerid][DM_ZONE]!=-1) {
			if(gPlayerDM[killerid][DM_ZONE]!=-1) {
				gPlayerStats[killerid][STATS_KILLS_DM]++;
				PlaySoundForPlayer(killerid, SOUND_BLIP1);
			} else {
				gPlayerStats[killerid][STATS_KILLS_DM]--;
				SendClientMessage(killerid, COLOUR_YELLOW, "You idiot, you killed a deathmatch player when your not in a deathmatch!");
				SetPlayerHealth(killerid, 0.0);
			}
		}
		else if(gPlayerPatrol[playerid][PATROL_ONDUTY]) gPlayerStats[killerid][STATS_KILLS_COPS]++;
		else gPlayerStats[killerid][STATS_KILLS_FREEROAM]++;

		// Was kill legit?
		AC_OnPlayerDeath(playerid, killerid, reason);
	}
	if(money>0) SetPlayerPocketMoney(playerid, 0);
	if(gPlayerRace[playerid][PRACE_ID]!=-1) {
		format(string, MAX_STRING, "You have quit race \"%s\" (id: %d).", gRaces[gPlayerRace[playerid][PRACE_ID]][RACE_NAME], gPlayerRace[playerid][PRACE_ID]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		Race_Leave(playerid);
	}
	if(gPlayerTaxi[playerid][TAXI_STATUS]!=-1) {
		Taxi_Leave(playerid);
	}
	if(gPlayerDM[playerid][DM_ZONE]!=-1) {
		if(gPlayerDM[playerid][DM_SPAWN]==1) gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN1_COUNT]--;
		else gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN2_COUNT]--;
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnVehicleSpawn(vehicleid) {
	if(gGMConfig[GMC_VEHICLELOCK]) {
		for(new i=0; i<MAX_CASINO; i++) if(vehicleid==gPitBoss[i][PB_VEHICLE_SECURICAR] || vehicleid==gPitBoss[i][PB_VEHICLE_1] || vehicleid==gPitBoss[i][PB_VEHICLE_2] || vehicleid==gPitBoss[i][PB_VEHICLE_3]) return 1;
		for(new i=0; i<MAX_PATROL_VEHICLES; i++) if(vehicleid==gPatrolVehicles[i]) return 1;
		for(new i=0; i<MAX_PLAYERS; i++) if(IsPlayerConnected(i)) SetVehicleParamsForPlayer(vehicleid, i, 0, 0);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnVehicleDeath(vehicleid, killerid) {
 	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerText(playerid, text[]) {
	new string[MAX_STRING];
	if(text[0]=='!') {
		if(gPlayerGang[playerid][PGANG_ID]!=-1) {
			format(string, MAX_STRING, "%s: %s", gPlayerStats[playerid][STATS_NAME], text[1]);
			for(new i=0; i<gGangs[gPlayerGang[playerid][PGANG_ID]][GANG_TOTALMEMBERS]; i++) {
				if(IsPlayerConnected(gGangs[gPlayerGang[playerid][PGANG_ID]][GANG_MEMBERS][i])) {
					SendClientMessage(gGangs[gPlayerGang[playerid][PGANG_ID]][GANG_MEMBERS][i], COLOUR_LIGHTBLUE, string);
				}
			}
		}
		return 0;
	}
	if(text[0]=='@') {
		if(gPlayerPatrol[playerid][PATROL_ONDUTY]) {
			format(string, MAX_STRING,"%s: %s", gPlayerStats[playerid][STATS_NAME], text[1]);
			for(new i=0; i<MAX_PLAYERS; i++) {
				if(gPlayerPatrol[i][PATROL_ONDUTY] && IsPlayerConnected(i)) {
					SendClientMessage(i, COLOUR_POLICEBLUE, string);
				}
			}
		} else if(gPlayerTaxi[playerid][TAXI_STATUS]==TAXI_DRIVER) {
			format(string, MAX_STRING,"%s: %s", gPlayerStats[playerid][STATS_NAME], text[1]);
			for(new i=0; i<MAX_PLAYERS; i++) {
				if(gPlayerTaxi[i][TAXI_STATUS]==TAXI_DRIVER && IsPlayerConnected(i)) {
					SendClientMessage(i, COLOUR_TAXIYELLOW, string);
				}
			}
		}
		return 0;
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerPrivmsg(playerid, senderid, text[]) {
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerCommandText(playerid, cmdtext[]) {
	dcmd(help, 4, Help_Gamemode);
	dcmd(signup, 6, Registration_Signup);
	dcmd(signin, 6, Registration_Signin);
	dcmd(signout, 7, Registration_Signout);
	dcmd(password, 8, Registration_PwdChange);
	dcmd(admin, 5, Admin_Action);
	dcmd(pref, 4, Pref_Action);
	dcmd(stats, 5, Stats_Show);
	dcmd(whereami, 8, Freeroam_ZoneLookup);
	dcmd(speedo, 6, Freeroam_Speedo);
	dcmd(givecash, 8, Freeroam_Money_Transfer);
	dcmd(bank, 4, Bank_Deposit);
	dcmd(gbank, 5, Bank_Gang_Deposit);
	dcmd(withdraw, 8, Bank_Withdraw);
	dcmd(gwithdraw, 9, Bank_Gang_Withdraw);
	dcmd(transfer, 8, Bank_Transfer);
	dcmd(gtransfer, 9, Bank_Gang_Transfer);
	dcmd(balance, 7, Bank_Balance);
	dcmd(gbalance, 8, Bank_Gang_Balance);
	dcmd(hitman, 6, Freeroam_Bounty_SetHit);
	dcmd(bounty, 6, Freeroam_Bounty_Show);
	dcmd(bounties, 8, Freeroam_Bounty_ShowList);
	if(gGMConfig[GMC_VEHICLELOCK]) dcmd(lock, 4, Vehicle_Lock);
	if(gGMConfig[GMC_VEHICLELOCK]) dcmd(unlock, 6, Vehicle_UnLock);
	dcmd(weaponlist, 10, SpawnWeapons_ShowList);
	dcmd(gang, 4, Gang_Action);
	dcmd(gangs, 5, Gang_ShowList);
	dcmd(exports, 7, WangExport_ShowExportVehicle);
	dcmd(skydive, 7, SkyDive_Enter);
	dcmd(jump, 4, SkyDive_SetJump);
	dcmd(jumplist, 8, SkyDive_ShowJumps);
	dcmd(patrol, 6, Patrol_OnDuty);
	dcmd(pbcash, 6, PitBoss_ShowCash);
	dcmd(pbfee, 5, PitBoss_SetFee);
	dcmd(pbrun, 5, PitBoss_Transport);
	dcmd(taxi, 4, Taxi_Driver);
	dcmd(taxifee, 7, Taxi_SetFee);
	dcmd(dm, 2, DMA_Action);
	dcmd(dmlist, 6, DMA_ShowList);
	dcmd(race, 4, Race_Action);
	dcmd(rescue, 6, Race_Rescue);
	dcmd(racelist, 8, Race_ShowList);
	dcmd(fly, 3, Fly_Action);
	dcmd(flysf, 5, Fly_SF);
	dcmd(flyls, 5, Fly_LS);
	dcmd(flylv, 5, Fly_LV);
	dcmd(buy, 3, Freeroam_Buy_Action);
	dcmd(sell, 3, Freeroam_Sell_Action);
	dcmd(businesses, 10, Business_ShowList);
	dcmd(properties, 10, Property_ShowList);
	dcmd(home, 4, Spawn_SetHome);
	dcmd(cls, 3, ClearScreen);
	SendClientMessage(playerid, COLOUR_RED, "Command not recognised on this server!");
	Help_Gamemode(playerid, "");
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerInfoChange(playerid) {
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger) {
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerExitVehicle(playerid, vehicleid) {
	if(gPlayerTaxi[playerid][TAXI_STATUS]!=-1) Taxi_Leave(playerid);
	if(gPlayerRace[playerid][PRACE_ID]!=-1 && gPlayerRace[playerid][PRACE_STARTTIME]>0) Race_Quit(playerid, "");
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerStateChange(playerid, newstate, oldstate) {
	if(newstate==PLAYER_STATE_PASSENGER) {
		new vehicle = GetPlayerVehicleID(playerid);
		for(new i=0; i<MAX_PLAYERS; i++) {
			if(gPlayerTaxi[i][TAXI_VEHICLE]==vehicle) {
				Taxi_Enter(playerid, i);
				break;
			}
		}
	} else {
		new vehicleid = GetPlayerVehicleID(playerid);
		if(vehicleid>0) {
			if(gVehicles[vehicleid-1][VEHICLE_MODEL]==VEHICLE_TAXI || gVehicles[vehicleid-1][VEHICLE_MODEL]==VEHICLE_CABBIE) {
				gPlayerStats[playerid][STATS_MONEY_POCKET] += 12;
			} else if(gVehicles[vehicleid-1][VEHICLE_MODEL]==VEHICLE_SECURICAR) {
				gPlayerStats[playerid][STATS_MONEY_POCKET] += 299;
			}
		}
	}
}

//------------------------------------------------------------------------------------------------------

public OnPlayerEnterCheckpoint(playerid) {
	if(gPlayerRace[playerid][PRACE_ID]!=-1 || gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_RACE) Race_EnterCheckpoint(playerid);
	else Freeroam_EnterCheckpoint(playerid);
	return 1;
}

//------------------------------------------------------------------------------------------------------

public OnPlayerLeaveCheckpoint(playerid) {
	return 1;
}

//******************************************************************************************************
// Supporting gamemode functions...
//******************************************************************************************************

//------------------------------------------------------------------------------------------------------
// Help...
//------------------------------------------------------------------------------------------------------

Help_Gamemode(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_GREEN, "SA~DMA+LG+PB+SR version 1.03");
		SendClientMessage(playerid, COLOUR_WHITE, "This is a freeroam gamemode where you choose to lead the life you want. Buy businesses, ");
		SendClientMessage(playerid, COLOUR_WHITE, "properties, weapons, kill players, or perhaps go skydiving, racing, steal, mod or sell a");
		SendClientMessage(playerid, COLOUR_WHITE, "few cars... the choice is yours!");
		SendClientMessage(playerid, COLOUR_YELLOW, "Type '/help topics' to view specific gamemode feature help.");
	} else {
		if(equal(text,"topics",false)) {
			SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /help [topic]");
			SendClientMessage(playerid, COLOUR_GREEN, "Available Topics:");
			SendClientMessage(playerid, COLOUR_YELLOW, "commands admincommands preferences landgrab deathmatch pitboss patrol taxi skydive race");
		} else if(equal(text, "commands",false)) {
			SendClientMessage(playerid, COLOUR_GREEN, "Available commands...");
			SendClientMessage(playerid, COLOUR_WHITE, "Registration: /signup /signin /signout /password  Freeroam: /buy /sell /properties");
			SendClientMessage(playerid, COLOUR_WHITE, "/businesses /home /givecash /hitman /bounty /bounties /lock /unlock /exports /fly /stats");
			SendClientMessage(playerid, COLOUR_WHITE, "/whereami /speedo  ATM: /bank /withdraw /transfer /balance  Spawn Weapons: /weaponlist");
			SendClientMessage(playerid, COLOUR_WHITE, "Gangs: /gang /gangs /gbank /gwithdraw /gtransfer /gbalance  Skydive: /skydive /jump /jumplist");
			SendClientMessage(playerid, COLOUR_WHITE, "Officer Patrol: /patrol  Taxi Driver: /taxi /taxifee  Pit Boss: /pbcash /pbfee /pbrun");
			SendClientMessage(playerid, COLOUR_WHITE, "Deathmatch: /dm /dmlist  Racing: /race /racelist /rescue  Preferences: /pref  Other: /help");
			SendClientMessage(playerid, COLOUR_WHITE, "/cls.");
		} else if(equal(text, "admincommands",false)) {
			SendClientMessage(playerid, COLOUR_GREEN, "Available admin commands...");
			SendClientMessage(playerid, COLOUR_WHITE, "/admin");
		} else if(equal(text, "preferences",false)) {
			SendClientMessage(playerid, COLOUR_WHITE, "You can configure certain game preferences by using the command '/pref'. Preferences are saved")
			SendClientMessage(playerid, COLOUR_WHITE, "if you are registered.")
		} else if(equal(text, "landgrab",false)) {
			SendClientMessage(playerid, COLOUR_WHITE, "You can buy and sell businesses and properties by using the '/buy' and '/sell' commands.");
			SendClientMessage(playerid, COLOUR_WHITE, "Businesses will earn you money regularly, whereas properties require an upkeep fee paid");
			SendClientMessage(playerid, COLOUR_WHITE, "daily. Properties can be located by looking for green house icons. If you own a property you");
			SendClientMessage(playerid, COLOUR_WHITE, "can set this location has your home starting (spawn) position by using the command '/home'.");
			SendClientMessage(playerid, COLOUR_WHITE, "To view a list of the available businesses and properties and their owners, use the comamnds");
			SendClientMessage(playerid, COLOUR_WHITE, "'/businesses' and '/properties' respectively.");
		} else if(equal(text, "deathmatch",false)) {
			SendClientMessage(playerid, COLOUR_WHITE, "To join a deathmatch arena use the command '/dm'. If you leave a deathmatch arena a notice");
			SendClientMessage(playerid, COLOUR_WHITE, "will be sent to all remaining deathmatch players. To view a list of all deathmatch arenas and");
			SendClientMessage(playerid, COLOUR_WHITE, "the number of players in each, use the command '/dmlist'.");
		} else if(equal(text, "pitboss",false)) {
			SendClientMessage(playerid, COLOUR_WHITE, "Pit Bosses (casino owners) and any gang members have exclusive access to limousines. Owners");
			SendClientMessage(playerid, COLOUR_WHITE, "inherit a Pit Boss mansion in Los Santos which can be used as a home starting point with the");
			SendClientMessage(playerid, COLOUR_WHITE, "command '/home'. Funds cannot be directly earned from casinos. This is because the");
			SendClientMessage(playerid, COLOUR_WHITE, "Las Venturas gambling board recently declared it illegal to profit from local citizens");
			SendClientMessage(playerid, COLOUR_WHITE, "bad gambling habits. To earn money from casinos Pit Bosses will need to smuggle funds");
			SendClientMessage(playerid, COLOUR_WHITE, "from the casino safe out of Las Venturas and transport it to their safehouses in Los Santos.");
			SendClientMessage(playerid, COLOUR_WHITE, "Once there, money can be pocketed undetected from the authorities. To view the contents of a");
			SendClientMessage(playerid, COLOUR_WHITE, "casino safe use the command '/pbcash'. To change the gambling fee use the command '/pbfee',");
			SendClientMessage(playerid, COLOUR_WHITE, "and to transport the safe cash use the command '/pbrun'.");
		} else if(equal(text, "patrol",false)) {
			SendClientMessage(playerid, COLOUR_WHITE, "After numerous complaints from San Andreas citizens the local law enforcement has been");
			SendClientMessage(playerid, COLOUR_WHITE, "empowered to begin patrolling the streets and busting suspicious illegal activities. To");
			SendClientMessage(playerid, COLOUR_WHITE, "start patrolling the streets, use the command '/patrol'. Racers and Pit Bosses can be");
			SendClientMessage(playerid, COLOUR_WHITE, "busted.");
		} else if(equal(text, "taxi",false)) {
			SendClientMessage(playerid, COLOUR_WHITE, "Taxi drivers are welcomed by the San Andreas community. To start offering taxi services,");
			SendClientMessage(playerid, COLOUR_WHITE, "use the command '/taxi'.");
		} else if(equal(text, "skydive",false)) {
			SendClientMessage(playerid, COLOUR_WHITE, "Skydiving popularity in San Andreas is booming. To go skydiving, local a skydive plane at");
			SendClientMessage(playerid, COLOUR_WHITE, "a local San Andreas airport and then use the command '/skydive'. Skydive locations are");
			SendClientMessage(playerid, COLOUR_WHITE, "availabel right across San Andreas.");
		} else if(equal(text, "race",false)) {
			SendClientMessage(playerid, COLOUR_WHITE, "The racing scene has finally hit the streets and countryside of San Andreas. To view a list");
			SendClientMessage(playerid, COLOUR_WHITE, "of available races, use the command '/racelist'. Once at a race start line, use the command");
			SendClientMessage(playerid, COLOUR_WHITE, "'/race' for further instructions.");
		} else {
			new string[MAX_STRING];
			format(string, MAX_STRING, "I'm sorry, no help topic for '%s' was found.", text);
			SendClientMessage(playerid, COLOUR_RED, string);
			Help_Gamemode(playerid, "topics");
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------
// Config
//------------------------------------------------------------------------------------------------------

Config_SetupGamemode() {
	print("Loading gamemode config...");
	gGMConfig[GMC_AC_PROTECTADMINS] = 0;
	gGMConfig[GMC_AC_MONEY] = 1;
	gGMConfig[GMC_AC_WEAPON] = 1;
	gGMConfig[GMC_AC_SPOOFKILL] = 1;
	gGMConfig[GMC_AC_SPAWNKILL] = 1;
	gGMConfig[GMC_AC_SPAWNKILL_KILLS] = 3;
	gGMConfig[GMC_AC_SPAWNKILL_DIST] = 20.0;
	gGMConfig[GMC_REG_KICK] = 0;
	gGMConfig[GMC_STAT_SAVEINT] = 5;
	gGMConfig[GMC_STAT_MAXRESTORE] = 30;
	gGMConfig[GMC_PB_TEXT] = 1;
	gGMConfig[GMC_WE_TEXT] = 1;
	gGMConfig[GMC_VEHICLELOCK] = 1;
	gGMConfig[GMC_VEHICLELOCK_AUTOUNLOCK] = 2;
	gGMConfig[GMC_DM_ZONEWARNINGS] = 3;
	gGMConfig[GMC_DM_TEXT] = 1;
	gGMConfig[GMC_DM_BANK] = 1;
	gGMConfig[GMC_DM_GROUPGANGS] = 1;
	gGMConfig[GMC_DM_STEALTH] = 1;
	gGMConfig[GMC_TAX] = 1;
	gGMConfig[GMC_MAXBANK] = 10000000;
	gGMConfig[GMC_POCKETMONEY] = 500;

	new ini[] = "SAMP_DMA+LG+PB+SR.ini";
	if(!dini_Exists(ini)) {  // If ini config exists, overwrite the defaults...
		print("...config set to defaults");
		return;
	}
	if(dini_Isset(ini,"AntiCheat_ProtectAdmins")) gGMConfig[GMC_AC_PROTECTADMINS] = dini_Int(ini, "AntiCheat_ProtectAdmins");
	if(dini_Isset(ini,"AntiCheat_MoneyCheck")) gGMConfig[GMC_AC_MONEY] = dini_Int(ini, "AntiCheat_MoneyCheck");
	if(dini_Isset(ini,"AntiCheat_WeaponCheck")) gGMConfig[GMC_AC_WEAPON] = dini_Int(ini, "AntiCheat_WeaponCheck");
	if(dini_Isset(ini,"AntiCheat_SpoofKillCheck")) gGMConfig[GMC_AC_SPOOFKILL] = dini_Int(ini, "AntiCheat_SpoofKillCheck");
	if(dini_Isset(ini,"AntiCheat_SpawnKillCheck")) gGMConfig[GMC_AC_SPAWNKILL] = dini_Int(ini, "AntiCheat_SpawnKillCheck");
	if(dini_Isset(ini,"AntiCheat_SpawnKillCheck_MaxKills")) gGMConfig[GMC_AC_SPAWNKILL_KILLS] = dini_Int(ini, "AntiCheat_SpawnKillCheck_MaxKills");
	if(dini_Isset(ini,"AntiCheat_SpawnKillCheck_MaxKillDistance")) gGMConfig[GMC_AC_SPAWNKILL_DIST] = dini_Int(ini, "AntiCheat_SpawnKillCheck_MaxKillDistance");
	if(dini_Isset(ini,"KickOnSigninFailure")) gGMConfig[GMC_REG_KICK] = dini_Int(ini, "KickOnSiginFailure");
	if(dini_Isset(ini,"Stats_SaveInterval")) gGMConfig[GMC_STAT_SAVEINT] = dini_Int(ini, "Stats_SaveInterval");
	if(dini_Isset(ini,"Stats_MaxMoneyWeaponRestoreTime")) gGMConfig[GMC_STAT_MAXRESTORE] = dini_Int(ini, "Stats_MaxMoneyWeaponRestoreTime");
	if(dini_Isset(ini,"PitBoss_ShowGameText")) gGMConfig[GMC_PB_TEXT] = dini_Int(ini, "PitBoss_ShowGameText");
	if(dini_Isset(ini,"WangExport_ShowChatText")) gGMConfig[GMC_WE_TEXT] = dini_Int(ini, "WangExport_ShowChatText");
	if(dini_Isset(ini,"VehicleLocks")) gGMConfig[GMC_VEHICLELOCK] = dini_Int(ini, "VehicleLocks");
	if(dini_Isset(ini,"VehicleLocks_AutoUnlock")) gGMConfig[GMC_VEHICLELOCK_AUTOUNLOCK] = dini_Int(ini, "VehicleLocks_AutoUnlock");
	if(dini_Isset(ini,"Deathmatch_Zone_Warnings")) gGMConfig[GMC_DM_ZONEWARNINGS] = dini_Int(ini, "Deathmatch_Zone_Warnings");
	if(dini_Isset(ini,"Deathmatch_ShowPlayerEnterChatText")) gGMConfig[GMC_DM_TEXT] = dini_Int(ini, "Deathmatch_ShowPlayerEnterChatText");
	if(dini_Isset(ini,"Deathmatch_BankCashOnEnter")) gGMConfig[GMC_DM_BANK] = dini_Int(ini, "Deathmatch_BankCashOnEnter");
	if(dini_Isset(ini,"Deathmatch_SpawnGangMembersTogether")) gGMConfig[GMC_DM_GROUPGANGS] = dini_Int(ini, "Deathmatch_SpawnGangMembersTogether");
	if(dini_Isset(ini,"Deathmatch_StealthPlayers")) gGMConfig[GMC_DM_STEALTH] = dini_Int(ini, "Deathmatch_StealthPlayers");
	if(dini_Isset(ini,"Tax")) gGMConfig[GMC_TAX] = dini_Int(ini, "Tax");
	if(dini_Isset(ini,"MaxBank")) gGMConfig[GMC_MAXBANK] = dini_Int(ini, "MaxBank");
	if(dini_Isset(ini,"PocketMoney")) gGMConfig[GMC_POCKETMONEY] = dini_Int(ini, "PocketMoney");
	print("...config set to defaults/ini values");
}

//------------------------------------------------------------------------------------------------------

Config_SetupRaces() {
	print("Loading race records...");
	new playername[MAX_PLAYER_NAME], record, formattedrecord[MAX_STRING], vehicle;
	for(new i=0; i<MAX_RACES; i++) {
		if(udb_RaceExists(gRaces[i][RACE_NAME])) {
			format(playername, MAX_PLAYER_NAME, "%s", udb_getRacePlayer(gRaces[i][RACE_NAME]));
			record = udb_getRaceRecord(gRaces[i][RACE_NAME]);
			format(formattedrecord, MAX_STRING, "%s", udb_getRaceFormattedRecord(gRaces[i][RACE_NAME]));
			vehicle = udb_getRaceVehicle(gRaces[i][RACE_NAME]);
			if(strcmp(playername, "Empty", true)!=0 && record!=0 && strcmp(formattedrecord, "Empty", true)!=0) {
				gRaces[i][RACE_RECORD] = record;
				format(gRaces[i][RACE_FORMATTEDRECORD], MAX_STRING, "%s by %s (%s)", formattedrecord, playername, gVehicleInfo[vehicle-VEHICLE_MODEL_OFFSET][VEHICLEINFO_NAME]);
				printf("Race '%s' record loaded.", gRaces[i][RACE_NAME]);
			} else {
				printf("Race '%s' loaded. No record set.", gRaces[i][RACE_NAME]);
			}
		} else {
			if(udb_RaceCreate(gRaces[i][RACE_NAME])) {
				printf("Race '%s' not found. Empty record created.", gRaces[i][RACE_NAME]);
			} else {
				printf("Race '%s' not found. **Error creating record.**", gRaces[i][RACE_NAME]);
			}
		}
	}
	print("...race records loaded");
}

//------------------------------------------------------------------------------------------------------
// Stats
//------------------------------------------------------------------------------------------------------

Stats_Save(playerid) {
	new spawnweapons[MAX_STRING];
	format(spawnweapons, MAX_STRING, "%s", SpawnWeapons_ConvertToString(playerid));
	if(gPlayerStats[playerid][STATS_AUTHENTICATED]) {
		if(!udb_Exists(gPlayerStats[playerid][STATS_NAME]) || udb_getAccState(gPlayerStats[playerid][STATS_NAME])!=1) return;
		udb_setLastActiveTime(gPlayerStats[playerid][STATS_NAME],Time());
		if(gPlayerStats[playerid][STATS_MONEY_POCKET]<1) udb_setMoneyPocket(gPlayerStats[playerid][STATS_NAME],0);
		else udb_setMoneyPocket(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_MONEY_POCKET]);
		udb_setMoneyBank(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_MONEY_BANK]);
		udb_setBounty(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_BOUNTY]);
		udb_setSpawnWeapons(gPlayerStats[playerid][STATS_NAME],spawnweapons);
		udb_setKillsFreeroam(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_KILLS_FREEROAM]);
		udb_setKillsDM(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_KILLS_DM]);
		udb_setKillsCops(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_KILLS_COPS]);
		udb_setDeathsSelfInflicted(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_DEATHS_SELF]);
		udb_setDeathsNonSelfInflicted(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_DEATHS_NONSELF]);
		udb_setExports(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_EXPORTS]);
		udb_setSkyDives(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_SKYDIVES]);
		udb_setTaxiPassengers(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_TAXI_PASSENGERS]);
		udb_setTaxiRides(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_TAXI_RIDES]);
		udb_setBusts(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_BUSTS_SELF]);
		udb_setBustsOthers(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_BUSTS_OTHERS]);
		udb_setBustsEvaded(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_BUSTS_EVADED]);
		udb_setRaceStarts(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_RACE_STARTS]);
		udb_setRacesDNF(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_RACE_DNF]);
		udb_setRaceWins(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_RACE_WINS]);
		udb_setRaceKnockoutWins(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_RACE_KNOCKOUTWINS]);
		udb_setRacePoints(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_RACE_POINTS]);
		udb_setRaceSponsor(gPlayerStats[playerid][STATS_NAME],gPlayerStats[playerid][STATS_RACE_SPONSOR]);
	} else {
		format(gPlayerStatSaves[gSavePos][STATS_SAVED_NAME], MAX_PLAYER_NAME, "%s", gPlayerStats[playerid][STATS_NAME]);
		gPlayerStatSaves[gSavePos][STATS_SAVED_LASTACTIVETIME] = Time();
		gPlayerStatSaves[gSavePos][STATS_SAVED_MONEY_POCKET] = (gPlayerStats[playerid][STATS_MONEY_POCKET]>0) ? gPlayerStats[playerid][STATS_MONEY_POCKET] : 0;
		gPlayerStatSaves[gSavePos][STATS_SAVED_MONEY_BANK] = gPlayerStats[playerid][STATS_MONEY_BANK];
		gPlayerStatSaves[gSavePos][STATS_SAVED_BOUNTY] = gPlayerStats[playerid][STATS_BOUNTY];
		format(gPlayerStatSaves[gSavePos][STATS_SAVED_SPAWNWEAPONS], MAX_STRING, "%s", spawnweapons);
		gPlayerStatSaves[gSavePos][STATS_SAVED_KILLS_FREEROAM] = gPlayerStats[playerid][STATS_KILLS_FREEROAM];
		gPlayerStatSaves[gSavePos][STATS_SAVED_KILLS_DM] = gPlayerStats[playerid][STATS_KILLS_DM];
		gPlayerStatSaves[gSavePos][STATS_SAVED_KILLS_COPS] = gPlayerStats[playerid][STATS_KILLS_COPS];
		gPlayerStatSaves[gSavePos][STATS_SAVED_DEATHS_SELF] = gPlayerStats[playerid][STATS_DEATHS_SELF];
		gPlayerStatSaves[gSavePos][STATS_SAVED_DEATHS_NONSELF] = gPlayerStats[playerid][STATS_DEATHS_NONSELF];
		gPlayerStatSaves[gSavePos][STATS_SAVED_EXPORTS] = gPlayerStats[playerid][STATS_EXPORTS];
		gPlayerStatSaves[gSavePos][STATS_SAVED_SKYDIVES] = gPlayerStats[playerid][STATS_SKYDIVES];
		gPlayerStatSaves[gSavePos][STATS_SAVED_TAXI_PASSENGERS] = gPlayerStats[playerid][STATS_TAXI_PASSENGERS];
		gPlayerStatSaves[gSavePos][STATS_SAVED_TAXI_RIDES] = gPlayerStats[playerid][STATS_TAXI_RIDES];
		gPlayerStatSaves[gSavePos][STATS_SAVED_BUSTS_SELF] = gPlayerStats[playerid][STATS_BUSTS_SELF];
		gPlayerStatSaves[gSavePos][STATS_SAVED_BUSTS_OTHERS] = gPlayerStats[playerid][STATS_BUSTS_OTHERS];
		gPlayerStatSaves[gSavePos][STATS_SAVED_BUSTS_EVADED] = gPlayerStats[playerid][STATS_BUSTS_EVADED];
		gPlayerStatSaves[gSavePos][STATS_SAVED_RACE_STARTS] = gPlayerStats[playerid][STATS_RACE_STARTS];
		gPlayerStatSaves[gSavePos][STATS_SAVED_RACE_DNF] = gPlayerStats[playerid][STATS_RACE_DNF];
		gPlayerStatSaves[gSavePos][STATS_SAVED_RACE_WINS] = gPlayerStats[playerid][STATS_RACE_WINS];
		gPlayerStatSaves[gSavePos][STATS_SAVED_RACE_KNOCKOUTWINS] = gPlayerStats[playerid][STATS_RACE_KNOCKOUTWINS];
		gPlayerStatSaves[gSavePos][STATS_SAVED_RACE_POINTS] = gPlayerStats[playerid][STATS_RACE_POINTS];
		gPlayerStatSaves[gSavePos][STATS_SAVED_RACE_SPONSOR] = gPlayerStats[playerid][STATS_RACE_SPONSOR];
		gSavePos++;
		gSavePos %= MAX_SAVES;
	}
}

//------------------------------------------------------------------------------------------------------

Stats_Restore(playerid) {
	if(gPlayerStats[playerid][STATS_AUTHENTICATED]) {
		if(!udb_Exists(gPlayerStats[playerid][STATS_NAME]) || udb_getAccState(gPlayerStats[playerid][STATS_NAME])!=1) return;
		if(floatround((Time()-udb_getLastActiveTime(gPlayerStats[playerid][STATS_NAME]))/60.0)>=gGMConfig[GMC_STAT_MAXRESTORE]) {
			SetPlayerPocketMoney(playerid, 0);
			gPlayerStats[playerid][STATS_MONEY_BANK] = 0;
			gPlayerStats[playerid][STATS_BOUNTY] = 0;
			SpawnWeapons_Reset(playerid);
		} else {
			if(gPlayerDM[playerid][DM_ZONE]==-1) {
				SetPlayerPocketMoney(playerid, udb_getMoneyPocket(gPlayerStats[playerid][STATS_NAME]));
				gPlayerStats[playerid][STATS_MONEY_BANK] = udb_getMoneyBank(gPlayerStats[playerid][STATS_NAME]);
				gPlayerStats[playerid][STATS_BOUNTY] = udb_getBounty(gPlayerStats[playerid][STATS_NAME]);
				SpawnWeapons_RestoreFromString(playerid, udb_getSpawnWeapons(gPlayerStats[playerid][STATS_NAME]));
			}
		}
		gPlayerStats[playerid][STATS_KILLS_FREEROAM] = udb_getKillsFreeroam(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_KILLS_FREEROAM] = udb_getKillsFreeroam(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_KILLS_DM] = udb_getKillsDM(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_KILLS_COPS] = udb_getKillsCops(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_DEATHS_SELF] = udb_getDeathsSelfInflicted(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_DEATHS_NONSELF] = udb_getDeathsNonSelfInflicted(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_EXPORTS] = udb_getExports(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_SKYDIVES] = udb_getSkyDives(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_TAXI_PASSENGERS] = udb_getTaxiPassengers(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_TAXI_RIDES] = udb_getTaxiRides(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_BUSTS_SELF] = udb_getBusts(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_BUSTS_OTHERS] = udb_getBustsOthers(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_BUSTS_EVADED] = udb_getBustsEvaded(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_RACE_STARTS] = udb_getRaceStarts(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_RACE_DNF] = udb_getRacesDNF(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_RACE_WINS] = udb_getRaceWins(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_RACE_KNOCKOUTWINS] = udb_getRaceKnockoutWins(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_RACE_POINTS] = udb_getRacePoints(gPlayerStats[playerid][STATS_NAME]);
		gPlayerStats[playerid][STATS_RACE_SPONSOR] = udb_getRaceSponsor(gPlayerStats[playerid][STATS_NAME]);
		SendClientMessage(playerid, COLOUR_GREEN, "Your game progress has been restored.");
	} else {
		for(new i=0; i<MAX_SAVES; i++) {
			if(equal(gPlayerStatSaves[i][STATS_SAVED_NAME], gPlayerStats[playerid][STATS_NAME], true)) {
				if(floatround((Time()-gPlayerStatSaves[i][STATS_SAVED_LASTACTIVETIME])/60.0)<gGMConfig[GMC_STAT_MAXRESTORE]) {
					if(gPlayerDM[playerid][DM_ZONE]==-1) {
						SetPlayerPocketMoney(playerid, gPlayerStatSaves[i][STATS_SAVED_MONEY_POCKET]);
						gPlayerStats[playerid][STATS_MONEY_BANK] = gPlayerStatSaves[i][STATS_SAVED_MONEY_BANK];
						gPlayerStats[playerid][STATS_BOUNTY] = gPlayerStatSaves[i][STATS_SAVED_BOUNTY];
						SpawnWeapons_RestoreFromString(playerid, gPlayerStatSaves[i][STATS_SAVED_SPAWNWEAPONS]);
						gPlayerStats[playerid][STATS_KILLS_FREEROAM] = gPlayerStatSaves[i][STATS_SAVED_KILLS_FREEROAM];
						gPlayerStats[playerid][STATS_KILLS_DM] = gPlayerStatSaves[i][STATS_SAVED_KILLS_DM];
						gPlayerStats[playerid][STATS_KILLS_COPS] = gPlayerStatSaves[i][STATS_SAVED_KILLS_COPS];
						gPlayerStats[playerid][STATS_DEATHS_SELF] = gPlayerStatSaves[i][STATS_SAVED_DEATHS_SELF];
						gPlayerStats[playerid][STATS_DEATHS_NONSELF] = gPlayerStatSaves[i][STATS_SAVED_DEATHS_NONSELF];
						gPlayerStats[playerid][STATS_EXPORTS] = gPlayerStatSaves[i][STATS_SAVED_EXPORTS];
						gPlayerStats[playerid][STATS_SKYDIVES] = gPlayerStatSaves[i][STATS_SAVED_SKYDIVES];
						gPlayerStats[playerid][STATS_TAXI_PASSENGERS] = gPlayerStatSaves[i][STATS_SAVED_TAXI_PASSENGERS];
						gPlayerStats[playerid][STATS_TAXI_RIDES] = gPlayerStatSaves[i][STATS_SAVED_TAXI_RIDES];
						gPlayerStats[playerid][STATS_BUSTS_SELF] = gPlayerStatSaves[i][STATS_SAVED_BUSTS_SELF];
						gPlayerStats[playerid][STATS_BUSTS_OTHERS] = gPlayerStatSaves[i][STATS_SAVED_BUSTS_OTHERS];
						gPlayerStats[playerid][STATS_BUSTS_EVADED] = gPlayerStatSaves[i][STATS_SAVED_BUSTS_EVADED];
						gPlayerStats[playerid][STATS_RACE_STARTS] = gPlayerStatSaves[i][STATS_SAVED_RACE_STARTS];
						gPlayerStats[playerid][STATS_RACE_DNF] = gPlayerStatSaves[i][STATS_SAVED_RACE_DNF];
						gPlayerStats[playerid][STATS_RACE_WINS] = gPlayerStatSaves[i][STATS_SAVED_RACE_WINS];
						gPlayerStats[playerid][STATS_RACE_KNOCKOUTWINS] = gPlayerStatSaves[i][STATS_SAVED_RACE_KNOCKOUTWINS];
						gPlayerStats[playerid][STATS_RACE_POINTS] = gPlayerStatSaves[i][STATS_SAVED_RACE_POINTS];
						gPlayerStats[playerid][STATS_RACE_SPONSOR] = gPlayerStatSaves[i][STATS_SAVED_RACE_SPONSOR];
						SendClientMessage(playerid, COLOUR_GREEN, "Your game progress has been restored.");
					}
				}

				// Shift saves down 1
				for(new j=i; j<MAX_SAVES-1; j++) {
					format(gPlayerStatSaves[i][STATS_SAVED_NAME], MAX_PLAYER_NAME, "%s", gPlayerStatSaves[i+1][STATS_SAVED_NAME]);
					gPlayerStatSaves[i][STATS_SAVED_LASTACTIVETIME] = gPlayerStatSaves[i+1][STATS_SAVED_LASTACTIVETIME];
					gPlayerStatSaves[i][STATS_SAVED_MONEY_POCKET] = gPlayerStatSaves[i+1][STATS_SAVED_MONEY_POCKET];
					gPlayerStatSaves[i][STATS_SAVED_MONEY_BANK] = gPlayerStatSaves[i+1][STATS_SAVED_MONEY_BANK];
					gPlayerStatSaves[i][STATS_SAVED_BOUNTY] = gPlayerStatSaves[i+1][STATS_SAVED_BOUNTY];
					format(gPlayerStatSaves[i][STATS_SAVED_SPAWNWEAPONS], MAX_STRING, "%s", gPlayerStatSaves[i+1][STATS_SAVED_SPAWNWEAPONS]);
					gPlayerStatSaves[i][STATS_SAVED_KILLS_FREEROAM] = gPlayerStatSaves[i+1][STATS_SAVED_KILLS_FREEROAM];
					gPlayerStatSaves[i][STATS_SAVED_KILLS_DM] = gPlayerStatSaves[i+1][STATS_SAVED_KILLS_DM];
					gPlayerStatSaves[i][STATS_SAVED_KILLS_COPS] = gPlayerStatSaves[i+1][STATS_SAVED_KILLS_COPS];
					gPlayerStatSaves[i][STATS_SAVED_DEATHS_SELF] = gPlayerStatSaves[i+1][STATS_SAVED_DEATHS_SELF];
					gPlayerStatSaves[i][STATS_SAVED_DEATHS_NONSELF] = gPlayerStatSaves[i+1][STATS_SAVED_DEATHS_NONSELF];
					gPlayerStatSaves[i][STATS_SAVED_EXPORTS] = gPlayerStatSaves[i+1][STATS_SAVED_EXPORTS];
					gPlayerStatSaves[i][STATS_SAVED_SKYDIVES] = gPlayerStatSaves[i+1][STATS_SAVED_SKYDIVES];
					gPlayerStatSaves[i][STATS_SAVED_TAXI_PASSENGERS] = gPlayerStatSaves[i+1][STATS_SAVED_TAXI_PASSENGERS];
					gPlayerStatSaves[i][STATS_SAVED_TAXI_RIDES] = gPlayerStatSaves[i+1][STATS_SAVED_TAXI_RIDES];
					gPlayerStatSaves[i][STATS_SAVED_BUSTS_SELF] = gPlayerStatSaves[i+1][STATS_SAVED_BUSTS_SELF];
					gPlayerStatSaves[i][STATS_SAVED_BUSTS_OTHERS] = gPlayerStatSaves[i+1][STATS_SAVED_BUSTS_OTHERS];
					gPlayerStatSaves[i][STATS_SAVED_BUSTS_EVADED] = gPlayerStatSaves[i+1][STATS_SAVED_BUSTS_EVADED];
					gPlayerStatSaves[i][STATS_SAVED_RACE_STARTS] = gPlayerStatSaves[i+1][STATS_SAVED_RACE_STARTS];
					gPlayerStatSaves[i][STATS_SAVED_RACE_DNF] = gPlayerStatSaves[i+1][STATS_SAVED_RACE_DNF];
					gPlayerStatSaves[i][STATS_SAVED_RACE_WINS] = gPlayerStatSaves[i+1][STATS_SAVED_RACE_WINS];
					gPlayerStatSaves[i][STATS_SAVED_RACE_KNOCKOUTWINS] = gPlayerStatSaves[i+1][STATS_SAVED_RACE_KNOCKOUTWINS];
					gPlayerStatSaves[i][STATS_SAVED_RACE_POINTS] = gPlayerStatSaves[i+1][STATS_SAVED_RACE_POINTS];
					gPlayerStatSaves[i][STATS_SAVED_RACE_SPONSOR] = gPlayerStatSaves[i+1][STATS_SAVED_RACE_SPONSOR];
				}
				if(i<gSavePos) {
					gSavePos--;
					gSavePos %= MAX_SAVES;
				}
				Stats_ResetSave(MAX_SAVES-1);
				break;
			}
		}
	}
}

//------------------------------------------------------------------------------------------------------

Stats_ResetSave(pos) {
	gPlayerStatSaves[pos][STATS_SAVED_NAME][0] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_MONEY_POCKET] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_MONEY_BANK] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_BOUNTY] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_SPAWNWEAPONS][0] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_KILLS_FREEROAM] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_KILLS_DM] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_KILLS_COPS] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_DEATHS_SELF] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_DEATHS_NONSELF] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_EXPORTS] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_SKYDIVES] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_TAXI_PASSENGERS] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_TAXI_RIDES] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_BUSTS_SELF] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_BUSTS_OTHERS] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_BUSTS_EVADED] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_RACE_STARTS] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_RACE_DNF] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_RACE_WINS] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_RACE_KNOCKOUTWINS] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_RACE_POINTS] = 0;
	gPlayerStatSaves[pos][STATS_SAVED_RACE_SPONSOR] = -1;
}

//------------------------------------------------------------------------------------------------------

Stats_Reset(playerid) {
	gPlayerStats[playerid][STATS_AUTHENTICATED] = 0;
	gPlayerStats[playerid][STATS_FIRSTSPAWN] = 0;
	gPlayerStats[playerid][STATS_MONEY_POCKET] = 0;
	gPlayerStats[playerid][STATS_MONEY_BANK] = 0;
	gPlayerStats[playerid][STATS_BOUNTY] = 0;
	gPlayerStats[playerid][STATS_WARNINGS_SPAWNKILLS] = 0;
	gPlayerStats[playerid][STATS_WARNINGS_DMZONE] = 0;
	gPlayerStats[playerid][STATS_AREA_PRIMARY] = -1;
	gPlayerStats[playerid][STATS_AREA_SECONDARY] = -1;
	gPlayerStats[playerid][STATS_MUSIC_COUNT] = -1;
	gPlayerStats[playerid][STATS_KILLS_FREEROAM] = 0;
	gPlayerStats[playerid][STATS_KILLS_DM] = 0;
	gPlayerStats[playerid][STATS_KILLS_COPS] = 0;
	gPlayerStats[playerid][STATS_DEATHS_SELF] = 0;
	gPlayerStats[playerid][STATS_DEATHS_NONSELF] = 0;
	gPlayerStats[playerid][STATS_EXPORTS] = 0;
	gPlayerStats[playerid][STATS_SKYDIVES] = 0;
	gPlayerStats[playerid][STATS_TAXI_PASSENGERS] = 0;
	gPlayerStats[playerid][STATS_TAXI_RIDES] = 0;
	gPlayerStats[playerid][STATS_BUSTS_SELF] = 0;
	gPlayerStats[playerid][STATS_BUSTS_OTHERS] = 0;
	gPlayerStats[playerid][STATS_BUSTS_EVADED] = 0;
	gPlayerStats[playerid][STATS_RACE_STARTS] = 0;
	gPlayerStats[playerid][STATS_RACE_DNF] = 0;
	gPlayerStats[playerid][STATS_RACE_WINS] = 0;
	gPlayerStats[playerid][STATS_RACE_KNOCKOUTWINS] = 0;
	gPlayerStats[playerid][STATS_RACE_POINTS] = 0;
	gPlayerStats[playerid][STATS_RACE_SPONSOR] = -1;
}

//------------------------------------------------------------------------------------------------------

Stats_Show(playerid, text[]) {
	new player, string[MAX_STRING], Float:health, Float:pos[3], gang[MAX_GANG_NAME], vehicle[MAX_STRING];
	if(!text[0]) player = playerid;
	else player = GetPlayerID(text);
	if(player==INVALID_PLAYER_ID) {
		SendClientMessage(playerid, COLOUR_RED, "Player does not exist!");
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /stats [playerid/name]");
		return 1;
	}
	GetPlayerHealth(player, health);
	GetPlayerPos(player, pos[0], pos[1], pos[2]);

	if(gPlayerGang[player][PGANG_ID]!=-1) format(gang, MAX_GANG_NAME, "%s", gGangs[gPlayerGang[player][PGANG_ID]][GANG_NAME]);
	else gang = "Not in gang";

	new vehicleid = GetPlayerVehicleID(player);
	if(vehicleid>0) {
		new n_state = GetPlayerState(player), s_state[MAX_STRING];
		if(n_state==PLAYER_STATE_DRIVER) s_state = "Driver";
		else if(n_state==PLAYER_STATE_PASSENGER) s_state = "Passenger";
		else s_state = "Hitchhiker";
		format(vehicle, MAX_STRING, "Vehicle: %s, %s", s_state, gVehicleInfo[gVehicles[vehicleid-1][VEHICLE_MODEL]-VEHICLE_MODEL_OFFSET][VEHICLEINFO_NAME]);
	} else vehicle = "On foot";

	format(string, MAX_STRING, "Player '%s' (id: %d) Statistics...", gPlayerStats[player][STATS_NAME], player);
	SendClientMessage(playerid, COLOUR_GREEN, string);
	format(string, MAX_STRING, "General... Health: %.1f%%  Cash: $%d  Gang: %s", health, GetPlayerMoney(player), gang);
	SendClientMessage(playerid, COLOUR_WHITE, string);
	format(string, MAX_STRING, "Where am I?... Location: %s  %s", GetSAZone(pos), vehicle);
	SendClientMessage(playerid, COLOUR_WHITE, string);
	format(string, MAX_STRING, "Kills... Freeroam: %d  Deathmatch: %d  Police Officers: %d  Total: %d", gPlayerStats[player][STATS_KILLS_FREEROAM], gPlayerStats[player][STATS_KILLS_DM], gPlayerStats[player][STATS_KILLS_COPS], gPlayerStats[player][STATS_KILLS_FREEROAM]+gPlayerStats[player][STATS_KILLS_DM]+gPlayerStats[player][STATS_KILLS_COPS]);
	SendClientMessage(playerid, COLOUR_WHITE, string);
	format(string, MAX_STRING, "Deaths... Self-inflicted: %d  Non-self-inflicted: %d  Total: %d", gPlayerStats[player][STATS_DEATHS_SELF], gPlayerStats[player][STATS_DEATHS_NONSELF], gPlayerStats[player][STATS_DEATHS_SELF]+gPlayerStats[player][STATS_DEATHS_NONSELF]);
	SendClientMessage(playerid, COLOUR_WHITE, string);
	format(string, MAX_STRING, "Freeroam... Vehicle Exports: %d  Taxi (passengers collected): %d  (rides): %d  Skydives: %d", gPlayerStats[player][STATS_EXPORTS], gPlayerStats[player][STATS_TAXI_PASSENGERS], gPlayerStats[player][STATS_TAXI_RIDES], gPlayerStats[player][STATS_SKYDIVES]);
	SendClientMessage(playerid, COLOUR_WHITE, string);
	format(string, MAX_STRING, "Busts... Busted (self): %d  (others): %d  Evasions: %d ", gPlayerStats[player][STATS_BUSTS_SELF], gPlayerStats[player][STATS_BUSTS_OTHERS], gPlayerStats[player][STATS_BUSTS_EVADED]);
	SendClientMessage(playerid, COLOUR_WHITE, string);
	format(string, MAX_STRING, "Race... Starts: %d  DNF's: %d  Wins: %d  Knockout Wins: %d  Points: %d", gPlayerStats[player][STATS_RACE_STARTS], gPlayerStats[player][STATS_RACE_DNF], gPlayerStats[player][STATS_RACE_WINS], gPlayerStats[player][STATS_RACE_KNOCKOUTWINS], gPlayerStats[player][STATS_RACE_POINTS]);
	SendClientMessage(playerid, COLOUR_WHITE, string);
	return 1;
}

//------------------------------------------------------------------------------------------------------
// Preferences
//------------------------------------------------------------------------------------------------------

Pref_Reset(playerid) {
	gPlayerPref[playerid][PREF_SPEEDO] = false;
	gPlayerPref[playerid][PREF_SPEEDO_DELAY] = 0;
	gPlayerPref[playerid][PREF_RACEMARKERS] = true;
	gPlayerPref[playerid][PREF_METRIC] = 0;
	gPlayerPref[playerid][PREF_ZONE] = false;
}

//------------------------------------------------------------------------------------------------------

Pref_Save(playerid) {
	if(gPlayerStats[playerid][STATS_AUTHENTICATED]) {
		if(!udb_Exists(gPlayerStats[playerid][STATS_NAME]) || udb_getAccState(gPlayerStats[playerid][STATS_NAME])!=1) return;
		udb_setPrefSpeedo(gPlayerStats[playerid][STATS_NAME],gPlayerPref[playerid][PREF_SPEEDO]);
		udb_setPrefRaceMarkers(gPlayerStats[playerid][STATS_NAME],gPlayerPref[playerid][PREF_RACEMARKERS]);
		udb_setPrefMetric(gPlayerStats[playerid][STATS_NAME],gPlayerPref[playerid][PREF_METRIC]);
		udb_setPrefZone(gPlayerStats[playerid][STATS_NAME],gPlayerPref[playerid][PREF_ZONE]);
	}
}

//------------------------------------------------------------------------------------------------------

Pref_Restore(playerid) {
	if(gPlayerStats[playerid][STATS_AUTHENTICATED]) {
		if(!udb_Exists(gPlayerStats[playerid][STATS_NAME]) || udb_getAccState(gPlayerStats[playerid][STATS_NAME])!=1) return;
		gPlayerPref[playerid][PREF_SPEEDO] = udb_getPrefSpeedo(gPlayerStats[playerid][STATS_NAME]);
		gPlayerPref[playerid][PREF_RACEMARKERS] = udb_getPrefRaceMarkers(gPlayerStats[playerid][STATS_NAME]);
		gPlayerPref[playerid][PREF_METRIC] = udb_getPrefMetric(gPlayerStats[playerid][STATS_NAME]);
		gPlayerPref[playerid][PREF_ZONE] = udb_getPrefZone(gPlayerStats[playerid][STATS_NAME]);
	}
}

//------------------------------------------------------------------------------------------------------

Pref_Action(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /pref [action] where action is one of the following...");
		SendClientMessage(playerid, COLOUR_WHITE, "racemarkers zone metric");
		return 1;
	}
	dcmd2(racemarkers, 11, Pref_RaceMarkers);
	dcmd2(zone, 4, Pref_Zone);
	dcmd2(metric, 6, Pref_Metric);
	return 0;
}

//------------------------------------------------------------------------------------------------------

Pref_RaceMarkers(playerid, text[]) {
	#pragma unused text
	gPlayerPref[playerid][PREF_RACEMARKERS] = !gPlayerPref[playerid][PREF_RACEMARKERS];
	if(gPlayerPref[playerid][PREF_RACEMARKERS]) SendClientMessage(playerid, COLOUR_YELLOW, "Freeroam race start markers now visible.");
	else SendClientMessage(playerid, COLOUR_YELLOW, "Freeroam race start markers now hidden.");
	return 1;
}

//------------------------------------------------------------------------------------------------------

Pref_Zone(playerid, text[]) {
	#pragma unused text
	gPlayerPref[playerid][PREF_ZONE] = !gPlayerPref[playerid][PREF_ZONE];
	if(gPlayerPref[playerid][PREF_ZONE]) SendClientMessage(playerid, COLOUR_YELLOW, "Freeroam zone area updates now visible.");
	else SendClientMessage(playerid, COLOUR_YELLOW, "Freeroam zone area updates now hidden.");
	return 1;
}

//------------------------------------------------------------------------------------------------------

Pref_Metric(playerid, text[]) {
	#pragma unused text
	gPlayerPref[playerid][PREF_METRIC] = !gPlayerPref[playerid][PREF_METRIC];
	if(gPlayerPref[playerid][PREF_METRIC]) SendClientMessage(playerid, COLOUR_YELLOW, "Game metric updated (inches / feet / yards / miles).");
	else SendClientMessage(playerid, COLOUR_YELLOW, "Game metric updated (centimetres / metres / kilometres).");
	return 1;
}

//------------------------------------------------------------------------------------------------------
// Registration
//------------------------------------------------------------------------------------------------------

Registration_Signup(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /signup [password]");
	} else {
		new string[MAX_STRING];
		if(udb_Exists(gPlayerStats[playerid][STATS_NAME])) {
			format(string, MAX_STRING, "Username %s is already registered. Please reconnect and /signup with an alternate name.", gPlayerStats[playerid][STATS_NAME]);
			SendClientMessage(playerid, COLOUR_RED, string);
		} else {
			if(udb_Create(gPlayerStats[playerid][STATS_NAME],text)) {
				format(string, MAX_STRING, "Registration successful... Username: %s  Password: %s", gPlayerStats[playerid][STATS_NAME], text);
				SendClientMessage(playerid, COLOUR_GREEN, string);
				SendClientMessage(playerid, COLOUR_YELLOW, "Do not share your password! To change your password, type '/password'.");
				SendClientMessage(playerid, COLOUR_YELLOW, "If you forget your password, contact a server admin.");
				SendClientMessage(playerid, COLOUR_GREEN, "Signin successfull.");
				gPlayerStats[playerid][STATS_AUTHENTICATED] = 1;
			} else {
				SendClientMessage(playerid, COLOUR_RED, "Registration failed! Contact a server admin if problem reoccurs.");
			}
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Registration_Signin(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /signin [password]");
	} else {
		if(udb_CheckLogin(gPlayerStats[playerid][STATS_NAME], text)) {
			new ustate = udb_getAccState(gPlayerStats[playerid][STATS_NAME]);
			if(ustate==1) {
				gPlayerStats[playerid][STATS_AUTHENTICATED] = 1;
				Stats_Restore(playerid);
				Pref_Restore(playerid);
				SendClientMessage(playerid, COLOUR_GREEN, "Signin successfull.");
			} else if(ustate==0) {
				SendClientMessage(playerid, COLOUR_RED, "Your account has been locked by an administrator. Login failed.");
			} else {
				SendClientMessage(playerid, COLOUR_RED, "Signin failed! Connection with server error.");
			}
		} else {
			SendClientMessage(playerid, COLOUR_RED, "Signin failed! Check your username and password.");
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Registration_Signout(playerid, text[]) {
	#pragma unused text
	if(gPlayerStats[playerid][STATS_AUTHENTICATED]) {
		new ustate = udb_getAccState(gPlayerStats[playerid][STATS_NAME]);
		if(ustate==1) {
			Stats_Save(playerid);
			Pref_Save(playerid);
			SendClientMessage(playerid, COLOUR_GREEN, "Signout successfull.");
		} else if(ustate==0) {
			SendClientMessage(playerid, COLOUR_ORANGE, "Your account has been locked by an administrator. Stats not saved. Signout successful.");
		} else {
			SendClientMessage(playerid, COLOUR_RED, "Connection with server error. Stats not saved. Signout successful.");
		}
		gPlayerStats[playerid][STATS_AUTHENTICATED] = !gPlayerStats[playerid][STATS_AUTHENTICATED];
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You must '/signin' before you can '/signout'!");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Registration_PwdChange(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /password [previous password] [new password]");
	} else {
		new previous_pwd[MAX_STRING], new_pwd[MAX_STRING], idx, string[MAX_STRING], ustate;
		previous_pwd = strtok(text,idx);
		new_pwd = strtok(text,idx);
		if(!previous_pwd[0] || !new_pwd[0]) {
			SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /password [previous password] [new password]");
			return 1;
		}
		if(gPlayerStats[playerid][STATS_AUTHENTICATED]) {
			ustate = udb_getAccState(gPlayerStats[playerid][STATS_NAME]);
			if(ustate==1) {
				if(udb_hash(previous_pwd)==udb_getPwdHash(gPlayerStats[playerid][STATS_NAME]) && udb_hash(new_pwd)!=udb_hash(previous_pwd)) {
					if(udb_setPassword(gPlayerStats[playerid][STATS_NAME],new_pwd)) {
						format(string, MAX_STRING, "Password change successful. New password: %s", new_pwd);
						SendClientMessage(playerid, COLOUR_GREEN, string);
						SendClientMessage(playerid, COLOUR_YELLOW, "Do not share your password! To change your password, type '/password'.");
					} else {
						SendClientMessage(playerid, COLOUR_RED, "Connection with server error. Password not changed.");
					}
				} else {
					SendClientMessage(playerid, COLOUR_RED, "Invalid inputs!");
				}
			} else if(ustate==0) {
				SendClientMessage(playerid, COLOUR_RED, "Your account has been locked by an administrator. Password cannot be changed.");
			} else {
				SendClientMessage(playerid, COLOUR_RED, "Connection with server error. Password not changed.");
			}
		} else {
			SendClientMessage(playerid, COLOUR_RED, "You must /signin before you can change your /password!");
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------
// Freeroam
//------------------------------------------------------------------------------------------------------

Freeroam_ScoreUpdate(playerid) {
	SetPlayerScore(playerid, GetPlayerMoney(playerid));
}

//------------------------------------------------------------------------------------------------------

Freeroam_MoneyArea_PirateShip(playerid) {
	new Float:pirateShipCoords[4] = {1995.5,1518.0,2006.0,1569.0};
	if(IsPlayerIn2DArea(playerid, pirateShipCoords)) {
		GivePlayerPocketMoney(playerid, 100);
	}
}

//------------------------------------------------------------------------------------------------------

Freeroam_TaxUpdate(playerid) {
	new money = GetPlayerMoney(playerid), tax, string[MAX_STRING];
	if(money<gTaxes[0][TAX_LOWER_RANGE]) return;
	for(new i=0; i<MAX_TAXRANGES; i++) {
		if(money>=gTaxes[i][TAX_LOWER_RANGE] && money<=gTaxes[i][TAX_UPPER_RANGE]) {
			tax = floatround(money*gTaxes[i][TAX_RATE]);
			GivePlayerPocketMoney(playerid, -tax);
			format(string, MAX_STRING, "You have paid $%d in taxes. Have a nice day.", tax);
			SendClientMessage(playerid, COLOUR_GREEN, string);
			break;
		}
	}
}

//------------------------------------------------------------------------------------------------------

Freeroam_ZoneLookup(playerid, text[]) {
	#pragma unused text
	new Float:pos[3], string[MAX_STRING];
	GetPlayerPos(playerid, pos[0], pos[1], pos[2]);
	format(string, MAX_STRING, "~w~%s", GetSAZone(pos));
	ShowGameTextForPlayer(playerid, string, 4000, 1);
	return 1;
}

//------------------------------------------------------------------------------------------------------

Freeroam_Money_Transfer(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /givecash [playerid/name] [amount]");
		return 1;
	}
	new player, money, idx, string[MAX_STRING];
	player = GetPlayerID(strtok(text,idx));
	if(player==INVALID_PLAYER_ID) {
		SendClientMessage(playerid, COLOUR_RED, "No such player exists!");
	} else if(player==playerid) {
		SendClientMessage(playerid, COLOUR_RED, "Nice try, you cannot send cash to yourself!");
	} else if(gPlayerDM[player][DM_ZONE]!=-1) {
		SendClientMessage(playerid, COLOUR_RED, "You cannot send cash to a deathmatch player!");
	} else {
		money = strval(strtok(text,idx));
		if(money<1 || money>GetPlayerMoney(playerid)) {
			format(string, MAX_STRING, "Invalid transaction amount ($%d)!", money);
			SendClientMessage(playerid, COLOUR_RED, string);
			return 1;
		}
		GivePlayerPocketMoney(playerid, -money);
		GivePlayerPocketMoney(player, money);
		format(string, MAX_STRING, "You have sent $%d to %s (id: %d).", money, gPlayerStats[player][STATS_NAME], player);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		format(string, MAX_STRING, "You have received $%d from %s (id: %d).", money, gPlayerStats[playerid][STATS_NAME], playerid);
		SendClientMessage(player, COLOUR_GREEN, string);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Freeroam_Bounty_SetHit(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /hitman [playerid/name] [amount]");
		return 1;
	}
	new player, money, idx, string[MAX_STRING];
	player = GetPlayerID(strtok(text,idx));
	money = strval(strtok(text,idx));
	if(player==INVALID_PLAYER_ID) {
		SendClientMessage(playerid, COLOUR_RED, "No such player exists!");
	} else if(money<1 || money>GetPlayerMoney(playerid)) {
		format(string, MAX_STRING, "Invalid amount ($%d)!", money);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		gPlayerStats[player][STATS_BOUNTY] += money;
		GivePlayerPocketMoney(playerid, -money);
		format(string, MAX_STRING, "%s has had a $%d bounty put on there head from %s (total: $%d).", gPlayerStats[player][STATS_NAME], money, gPlayerStats[playerid][STATS_NAME], gPlayerStats[player][STATS_BOUNTY]);
		SendClientMessageToAll(COLOUR_ORANGE, string);
		format(string, MAX_STRING, "You have had a $%d bounty put on you from %s (id: %d).", money, gPlayerStats[playerid][STATS_NAME], playerid);
		SendClientMessage(player, COLOUR_RED, string);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Freeroam_Bounty_Show(playerid, text[]) {
	new player, string[MAX_STRING], idx;
	if(!text[0]) player = playerid;
	else player = GetPlayerID(strtok(text,idx));
	if(player==INVALID_PLAYER_ID) {
		SendClientMessage(playerid, COLOUR_RED, "No such player exists!");
	} else {
		format(string, MAX_STRING, "Player %s (id: %d) has a $%d bounty on his head.", gPlayerStats[player][STATS_NAME], player, gPlayerStats[player][STATS_BOUNTY]);
		SendClientMessage(playerid, COLOUR_ORANGE, string);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Freeroam_Bounty_ShowList(playerid, text[]) {
	#pragma unused text
	new string[MAX_STRING], x=0, bounties = 0;
	SendClientMessage(playerid, COLOUR_GREEN, "Bounties...");
	for(new i=0; i<MAX_PLAYERS; i++) {
		if(gPlayerStats[i][STATS_BOUNTY]>0) {
			bounties = 1;
			format(string, MAX_STRING, "%s%s(%d): $%d", string, gPlayerStats[i][STATS_NAME], i, gPlayerStats[i][STATS_BOUNTY]);
			x++;
			if(x>3) {
				SendClientMessage(playerid, COLOUR_YELLOW, string);
				x = 0;
				string = "";
			} else {
				format(string, MAX_STRING, "%s, ", string);
			}
		}
	}
	if(x>0 && x<=3) {
		string[strlen(string)-2] = '.';
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	}
	if(!bounties) SendClientMessage(playerid, COLOUR_YELLOW, "No bounties");
	return 1;	
}

//------------------------------------------------------------------------------------------------------

Freeroam_Buy_Action(playerid, text[]) {
	#pragma unused text
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_BUSINESS && IsPlayerInCheckpoint(playerid)) {
		Business_Buy(playerid);
	} else if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_PROPERTY) {
		Property_Buy(playerid);
	} else if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_AMMUNATION && IsPlayerInCheckpoint(playerid)) {
		SpawnWeapons_Buy(playerid, text);
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You cannot use this feature in your current location.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Freeroam_Sell_Action(playerid, text[]) {
	#pragma unused text
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_BUSINESS && IsPlayerInCheckpoint(playerid)) {
		Business_Sell(playerid);
	} else if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_PROPERTY) {
		Property_Sell(playerid);
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You cannot use this feature in your current location.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Freeroam_PlayerAreaUpdate(playerid) {
	new found=0, Float:pos[3], string[MAX_STRING], parea_primary = gPlayerStats[playerid][STATS_AREA_PRIMARY], parea_secondary = gPlayerStats[playerid][STATS_AREA_SECONDARY];
	GetPlayerPos(playerid, pos[0], pos[1], pos[2]);
	gPlayerStats[playerid][STATS_POSITION][0] = pos[0];
	gPlayerStats[playerid][STATS_POSITION][1] = pos[1];
	gPlayerStats[playerid][STATS_POSITION][2] = pos[2];
	if(gPlayerRace[playerid][PRACE_ID]!=-1 || (gPitBoss[PB_DRAGON][PB_OWNER]==playerid && gPitBoss[PB_DRAGON][PB_TRANSPORTING]) || (gPitBoss[PB_CALIGULA][PB_OWNER]==playerid && gPitBoss[PB_CALIGULA][PB_TRANSPORTING])) return;
	// Bank area...
	if(!found) {
		for(new i=0; i<MAX_BANKS; i++) {
			if(pos[0]>=gBanks[i][BANK_AREA][0] && pos[0]<=gBanks[i][BANK_AREA][3] && pos[1]>=gBanks[i][BANK_AREA][1] && pos[1]<=gBanks[i][BANK_AREA][4] && pos[2]>=gBanks[i][BANK_AREA][2] && pos[2]<=gBanks[i][BANK_AREA][5]) {
				gPlayerStats[playerid][STATS_AREA_PRIMARY] = AREA_BANK;
				if(gPlayerStats[playerid][STATS_AREA_SECONDARY]!=i) {
					gPlayerStats[playerid][STATS_AREA_SECONDARY] = i;
					DisablePlayerCheckpoint(playerid);
					SetPlayerCP(playerid, gBanks[i][BANK_MARKER][0], gBanks[i][BANK_MARKER][1], gBanks[i][BANK_MARKER][2], gBanks[i][BANK_MARKER][3]);
				}
				found = 1;
				break;
			}
		}
	}
	// Ammunation area...
	if(!found) {
		for(new i=0; i<MAX_AMMUNATIONS; i++) {
			if(pos[0]>=gAmmunations[i][AMMUNATION_AREA][0] && pos[0]<=gAmmunations[i][AMMUNATION_AREA][3] && pos[1]>=gAmmunations[i][AMMUNATION_AREA][1] && pos[1]<=gAmmunations[i][AMMUNATION_AREA][4] && pos[2]>=gAmmunations[i][AMMUNATION_AREA][2] && pos[2]<=gAmmunations[i][AMMUNATION_AREA][5]) {
				gPlayerStats[playerid][STATS_AREA_PRIMARY] = AREA_AMMUNATION;
				if(gPlayerStats[playerid][STATS_AREA_SECONDARY]!=i) {
					gPlayerStats[playerid][STATS_AREA_SECONDARY] = i;
					DisablePlayerCheckpoint(playerid);
					SetPlayerCP(playerid, gAmmunations[i][AMMUNATION_MARKER][0], gAmmunations[i][AMMUNATION_MARKER][1], gAmmunations[i][AMMUNATION_MARKER][2], gAmmunations[i][AMMUNATION_MARKER][3]);
				}
				found = 1;
				break;
			}
		}
	}
	// Business area...
	if(!found) {
		for(new i=0; i<MAX_BUSINESSES; i++) {
			if(pos[0]>=gBusinesses[i][BUSINESS_AREA][0] && pos[0]<=gBusinesses[i][BUSINESS_AREA][3] && pos[1]>=gBusinesses[i][BUSINESS_AREA][1] && pos[1]<=gBusinesses[i][BUSINESS_AREA][4] && pos[2]>=gBusinesses[i][BUSINESS_AREA][2] && pos[2]<=gBusinesses[i][BUSINESS_AREA][5]) {
				gPlayerStats[playerid][STATS_AREA_PRIMARY] = AREA_BUSINESS;
				if(gPlayerStats[playerid][STATS_AREA_SECONDARY]!=i) {
					gPlayerStats[playerid][STATS_AREA_SECONDARY] = i;
					DisablePlayerCheckpoint(playerid);
					SetPlayerCP(playerid, gBusinesses[i][BUSINESS_MARKER][0], gBusinesses[i][BUSINESS_MARKER][1], gBusinesses[i][BUSINESS_MARKER][2], gBusinesses[i][BUSINESS_MARKER][3]);
				}
				found = 1;
				break;
			}
		}
	}
	// Property area...
	if(!found) {
		new Float:p[3];
		for(new i=0; i<MAX_PROPERTIES; i++) {
			p[0] = gProperties[i][PROPERTY_MARKER][0];
			p[1] = gProperties[i][PROPERTY_MARKER][1];
			p[2] = gProperties[i][PROPERTY_MARKER][2];
			if(GetDistanceToPoint(playerid, p)<=5.0) {
				gPlayerStats[playerid][STATS_AREA_PRIMARY] = AREA_PROPERTY;
				if(gPlayerStats[playerid][STATS_AREA_SECONDARY]!=i) {
					gPlayerStats[playerid][STATS_AREA_SECONDARY] = i;
					if(gProperties[i][PROPERTY_OWNER]==playerid) {
						SendClientMessage(playerid, COLOUR_RED, "You already own this property!");
					} else {
						if(gProperties[i][PROPERTY_OWNER]!=INVALID_PLAYER_ID) {
							format(string, MAX_STRING, "This property is currently owned by %s (id: %d).", gPlayerStats[gProperties[i][PROPERTY_OWNER]][STATS_NAME], gProperties[i][PROPERTY_OWNER]);
							SendClientMessage(playerid, COLOUR_RED, string);
						}
						if(i>1) {
							format(string, MAX_STRING, "You can /buy %s for $%d or /sell it.", gProperties[i][PROPERTY_NAME], gProperties[i][PROPERTY_COST]);
							SendClientMessage(playerid, COLOUR_YELLOW, string);
							format(string, MAX_STRING, "This property has a $%d upkeep fee twice daily.", gProperties[i][PROPERTY_UPKEEP]);
							SendClientMessage(playerid, COLOUR_YELLOW, string);
						}
					}
				}
				found = 1;
				break;
			}
		}
	}
	// Skydive area...
	if(!found) {
		for(new i=0; i<MAX_SKYDIVES; i++) {
			if(pos[0]>=gSkydives[i][SKYDIVE_AREA][0] && pos[0]<=gSkydives[i][SKYDIVE_AREA][3] && pos[1]>=gSkydives[i][SKYDIVE_AREA][1] && pos[1]<=gSkydives[i][SKYDIVE_AREA][4] && pos[2]>=gSkydives[i][SKYDIVE_AREA][2] && pos[2]<=gSkydives[i][SKYDIVE_AREA][5]) {
				gPlayerStats[playerid][STATS_AREA_PRIMARY] = AREA_SKYDIVE;
				if(gPlayerStats[playerid][STATS_AREA_SECONDARY]!=i) {
					gPlayerStats[playerid][STATS_AREA_SECONDARY] = i;
					DisablePlayerCheckpoint(playerid);
					SetPlayerCP(playerid, gSkydives[i][SKYDIVE_MARKER][0], gSkydives[i][SKYDIVE_MARKER][1], gSkydives[i][SKYDIVE_MARKER][2], gSkydives[i][SKYDIVE_MARKER][3]);
				}
				found = 1;
				break;
			}
		}
	}
	// Airport area...
	if(!found) {
		for(new i=0; i<MAX_AIRPORTS; i++) {
			if(pos[0]>=gAirports[i][AIRPORT_AREA][0] && pos[0]<=gAirports[i][AIRPORT_AREA][3] && pos[1]>=gAirports[i][AIRPORT_AREA][1] && pos[1]<=gAirports[i][AIRPORT_AREA][4] && pos[2]>=gAirports[i][AIRPORT_AREA][2] && pos[2]<=gAirports[i][AIRPORT_AREA][5]) {
				gPlayerStats[playerid][STATS_AREA_PRIMARY] = AREA_AIRPORT;
				if(gPlayerStats[playerid][STATS_AREA_SECONDARY]!=i) {
					gPlayerStats[playerid][STATS_AREA_SECONDARY] = i;
					DisablePlayerCheckpoint(playerid);
					SetPlayerCP(playerid, gAirports[i][AIRPORT_MARKER][0], gAirports[i][AIRPORT_MARKER][1], gAirports[i][AIRPORT_MARKER][2], gAirports[i][AIRPORT_MARKER][3]);
				}
				found = 1;
				break;
			}
		}
	}
	// Race area...
	if(!found) {
		new Float:p[3];
		for(new i=0; i<MAX_RACES; i++) {
			p[0] = gRaceCheckpoints[gRaces[i][RACE_CPSTART]][0];
			p[1] = gRaceCheckpoints[gRaces[i][RACE_CPSTART]][1];
			p[2] = gRaceCheckpoints[gRaces[i][RACE_CPSTART]][2];
			if(GetDistanceToPoint(playerid, p)<=100.0) {
				gPlayerStats[playerid][STATS_AREA_PRIMARY] = AREA_RACE;
				if(gPlayerStats[playerid][STATS_AREA_SECONDARY]!=i && !gPlayerPatrol[playerid][PATROL_ONDUTY]) {
					gPlayerStats[playerid][STATS_AREA_SECONDARY] = i;
					if(gPlayerPref[playerid][PREF_RACEMARKERS]) {
						DisablePlayerCheckpoint(playerid);
						SetPlayerCP(playerid, gRaceCheckpoints[gRaces[i][RACE_CPSTART]][0], gRaceCheckpoints[gRaces[i][RACE_CPSTART]][1], gRaceCheckpoints[gRaces[i][RACE_CPSTART]][2], gRaceCheckpoints[gRaces[i][RACE_CPSTART]][3]);
					}
				}
				found = 1;
				break;
			}
		}
	}
	// Gambling area...
	if(!found) {
		for(new i=0; i<MAX_CASINO; i++) {
			if(pos[0]>=gPitBoss[i][PB_GAMBLINGAREA][0] && pos[0]>=gPitBoss[i][PB_GAMBLINGAREA][3] && pos[1]>=gPitBoss[i][PB_GAMBLINGAREA][1] && pos[1]>=gPitBoss[i][PB_GAMBLINGAREA][4] && pos[2]>=gPitBoss[i][PB_GAMBLINGAREA][2] && pos[2]>=gPitBoss[i][PB_GAMBLINGAREA][5]) {
				gPlayerStats[playerid][STATS_AREA_PRIMARY] = AREA_CASINO;
				if(gPlayerStats[playerid][STATS_AREA_SECONDARY]!=i) {
					gPlayerStats[playerid][STATS_AREA_SECONDARY] = i;
					gPlayerAC[playerid][AC_MONEY_GAMBLE][0] = GetPlayerMoney(playerid);
					gPlayerAC[playerid][AC_MONEY_GAMBLE][1] = Time();
				}
				found = 1;
				break;
			}
		}
	}
	// Other area...
	if(!found) {
		for(new i=0; i<MAX_OTHERAREAS; i++) {
			if(pos[0]>=gOtherAreas[i][0] && pos[0]<=gOtherAreas[i][3] && pos[1]>=gOtherAreas[i][1] && pos[1]<=gOtherAreas[i][4] && pos[2]>=gOtherAreas[i][2] && pos[2]<=gOtherAreas[i][5]) {
				gPlayerStats[playerid][STATS_AREA_PRIMARY] = AREA_OTHER;
				if(gPlayerStats[playerid][STATS_AREA_SECONDARY]!=i) {
					gPlayerStats[playerid][STATS_AREA_SECONDARY] = i;
					switch(i) {
						case OA_PIRATESHIP: {
							DisablePlayerCheckpoint(playerid);
							SetPlayerCP(playerid,2000.3132,1538.6012,13.5859,2.0);
						}
						case OA_WANGEXPORTS: {
							DisablePlayerCheckpoint(playerid);
							SetPlayerCP(playerid,-1920.6711,303.1555,41.0469,4.0);
						}
						case OA_HEAVEN: {
							DisablePlayerCheckpoint(playerid);
							SetPlayerCP(playerid,2323.7454,1283.1440,97.5579,1.0);
						}
						case OA_HELL: {
							DisablePlayerCheckpoint(playerid);
							SetPlayerCP(playerid,-2432.6628,-1620.0771,526.8676,1.0);
						}
						case OA_LVTOLCWARP: {
							if(gPlayerTaxi[playerid][TAXI_STATUS]!=-1)  Taxi_Leave(playerid);
							if(gPlayerRace[playerid][PRACE_ID]!=-1)     Race_Leave(playerid);
							if(IsPlayerInAnyVehicle(playerid))          SetVehicleToRespawn(GetPlayerVehicleID(playerid));
							SetPlayerInterior(playerid, 1);
							SetPlayerPos(playerid,-901.4262,460.7170,1349.8750);
						}
						case OA_LIBERTYCITY: {
							SendClientMessage(playerid, COLOUR_YELLOW, "Welcome to Liberty City. Watch your step!");
						}
						case OA_TAXIINFO: {
							SendClientMessage(playerid, COLOUR_YELLOW, "You can live out your childhood dream by becoming a taxi driver! The San Andreas community");
							format(string, MAX_STRING, "welcomes working citizens, so for every %d passengers you successfully drop-off you will be", TAXI_BONUS_PASSENGER_COUNT);
							SendClientMessage(playerid, COLOUR_YELLOW, string);
							format(string, MAX_STRING, "rewarded with a $%d cash bonus.", TAXI_BONUS_CASH);
							SendClientMessage(playerid, COLOUR_YELLOW, string);
						}
						case OA_PATROLINFO: {
							SendClientMessage(playerid, COLOUR_YELLOW, "It's time to fight back! After numerous complaints from friendly citizens of San Andreas the");
							SendClientMessage(playerid, COLOUR_YELLOW, "law enforcement has been directed to bust all suspicious illegal activities. To start");
							SendClientMessage(playerid, COLOUR_YELLOW, "patrolling the streets, type '/patrol'.");
						}
						case OA_SKYDIVEPLANE: {
							SendClientMessage(playerid, COLOUR_YELLOW, "Set your skydive jump location by using the command '/jump [number]'. To view a list");
							SendClientMessage(playerid, COLOUR_YELLOW, "of the jump locations type '/jumplist'. If you jump from the plane without first selecting");
							SendClientMessage(playerid, COLOUR_YELLOW, "a jump location, a random location will be set for you.");
						}
						case OA_CASINOFLOOR: {
							SendClientMessage(playerid, COLOUR_RED, "This is a restricted area. Stay away!");
							OnPlayerSpawn(playerid);
						}
						case OA_PBDRAGONIN: {
							DisablePlayerCheckpoint(playerid);
							SetPlayerCP(playerid,1963.1918,973.3065,994.4688,2.0);
						}
						case OA_PBDRAGONOUT: {
							DisablePlayerCheckpoint(playerid);
							SetPlayerCP(playerid,-2171.2395,645.4052,1057.5937,1.0);
						}
						case OA_PBDRAGONMONEY: {
							if(playerid==gBusinesses[B_DRAGON][BUSINESS_OWNER]) {
								if(gPitBoss[PB_DRAGON][PB_CASH]>0) {
									format(string, MAX_STRING, "There is $%d in Four Dragon's safe. Type '/pbrun' to smuggle the funds out of Las Venturas.", gPitBoss[PB_DRAGON][PB_CASH]);
									SendClientMessage(playerid, COLOUR_YELLOW, string);
								} else {
									SendClientMessage(i, COLOUR_YELLOW, "There are no funds in the Four Dragon's safe. Please return later.");
								}
							} else {
								SendClientMessage(playerid, COLOUR_YELLOW, "You must be the Pit Boss of Four Dragons to access the Casino funds.");
							}
						}
						case OA_PBCALIGULAMONEY: {
							if(playerid==gBusinesses[B_CALIGULA][BUSINESS_OWNER]) {
								if(gPitBoss[PB_CALIGULA][PB_CASH]>0) {
									format(string, MAX_STRING, "There is $%d in Caligula's safe. Type '/pbrun' to smuggle the funds out of Las Venturas.", gPitBoss[PB_CALIGULA][PB_CASH]);
									SendClientMessage(playerid, COLOUR_YELLOW, string);
								} else {
									SendClientMessage(i, COLOUR_YELLOW, "There are no funds in Caligula's safe. Please return later.");
								}
							} else {
								SendClientMessage(playerid, COLOUR_YELLOW, "You must be the Pit Boss of Caligula's to access the Casino funds.");
							}
						}
					}
				}
				found = 1;
				break;
			}
		}
	}
	// Area not found
	if(!found) {
		DisablePlayerCheckpoint(playerid);
		gPlayerStats[playerid][STATS_AREA_PRIMARY] = -1;
		gPlayerStats[playerid][STATS_AREA_SECONDARY] = -1;
	}
	// Were they somewhere previously of interest? ...
	if(parea_primary==AREA_OTHER && parea_secondary==OA_SKYDIVEPLANE && (gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_OTHER || (gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_OTHER && gPlayerStats[playerid][STATS_AREA_SECONDARY]!=OA_SKYDIVEPLANE))) {
		// Previously in skydive plane, so lets jump...
		SkyDive_Jump(playerid);
	} else if(parea_primary==AREA_OTHER && parea_secondary==OA_LIBERTYCITY && (gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_OTHER || (gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_OTHER && gPlayerStats[playerid][STATS_AREA_SECONDARY]!=OA_LIBERTYCITY))) {
		// Previously in Liberty City, so lets warp back to LV...
		SetPlayerInterior(playerid, 0);
		SetPlayerPos(playerid,1743.2925,2165.5466,13.8718);
	} else if(parea_primary==AREA_CASINO && (gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_CASINO || (gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_CASINO && parea_secondary!=gPlayerStats[playerid][STATS_AREA_SECONDARY]))) {
		// Previously gambling, so did they cheat...
		AC_GambleUpdate(playerid);
		AC_ResetGamble(playerid);
	}
}

//------------------------------------------------------------------------------------------------------

Freeroam_EnterCheckpoint(playerid) {
	new string[MAX_STRING];
	switch(gPlayerStats[playerid][STATS_AREA_PRIMARY]) {
		case AREA_BANK: {
			SendClientMessage(playerid, COLOUR_YELLOW, "You are at a bank ATM. To store money use '/bank amount', to withdraw money use");
			SendClientMessage(playerid, COLOUR_YELLOW, "'/withdraw amount', and '/balance' to see your balance.");
		}
		case AREA_AMMUNATION: {
			SendClientMessage(playerid, COLOUR_YELLOW, "You can purchase weapons here so that you have them every time you spawn. To view the list");
			SendClientMessage(playerid, COLOUR_YELLOW, "of weapons type '/weaponlist'. To buy a weapon, type '/buy [weapon number] [purchases]'.");
		}
		case AREA_SKYDIVE: {
			format(string, MAX_STRING, "Welcome to the school of %s.", gSkydives[gPlayerStats[playerid][STATS_AREA_SECONDARY]][SKYDIVE_NAME]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			if(GetPlayerMoney(playerid)<SKYDIVE_FEE) {
				format(string, MAX_STRING, "You cannot go skydiving right now as you don't have enough money ($%d skydiving fee).", SKYDIVE_FEE);
				SendClientMessage(playerid, COLOUR_RED, string);
			} else {
				SendClientMessage(playerid, COLOUR_YELLOW, "Type '/skydive' to go skydiving!");
			}
		}
		case AREA_BUSINESS: {
			format(string, MAX_STRING, "You can '/buy' %s for $%d, or '/sell' it if you own it.", gBusinesses[gPlayerStats[playerid][STATS_AREA_SECONDARY]][BUSINESS_NAME], gBusinesses[gPlayerStats[playerid][STATS_AREA_SECONDARY]][BUSINESS_COST]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			if(gPlayerStats[playerid][STATS_AREA_SECONDARY]==B_CITYPLANNING) {
				format(string, MAX_STRING, "You will earn money from each property or business sale in San Andreas.");
			} else if(gPlayerStats[playerid][STATS_AREA_SECONDARY]==B_DRAGON || gPlayerStats[playerid][STATS_AREA_SECONDARY]==B_CALIGULA) {
				format(string, MAX_STRING, "You will potentially earn atleast $%d regularly.", gBusinesses[gPlayerStats[playerid][STATS_AREA_SECONDARY]][BUSINESS_VALUE]);
			} else {
				format(string, MAX_STRING, "You will earn $%d regularly.", gBusinesses[gPlayerStats[playerid][STATS_AREA_SECONDARY]][BUSINESS_VALUE]);
			}
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			if(gBusinesses[gPlayerStats[playerid][STATS_AREA_SECONDARY]][BUSINESS_OWNER]!=INVALID_PLAYER_ID) {
				format(string, MAX_STRING, "This business is currently owned by %s.", gPlayerStats[gBusinesses[gPlayerStats[playerid][STATS_AREA_SECONDARY]][BUSINESS_OWNER]][STATS_NAME]);
				SendClientMessage(playerid, COLOUR_RED, string);
			}
		}
		case AREA_AIRPORT: {
			format(string, MAX_STRING, "Welcome to the %s.", gAirports[gPlayerStats[playerid][STATS_AREA_SECONDARY]][AIRPORT_NAME]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			SendClientMessage(playerid, COLOUR_YELLOW, "You can fly to any major city by using the command '/fly lv', '/fly sf', or '/fly ls'.");
		}
		case AREA_OTHER: {
			switch(gPlayerStats[playerid][STATS_AREA_SECONDARY]) {
				case OA_HEAVEN: {
					if(gPlayerTaxi[playerid][TAXI_STATUS]!=-1)  Taxi_Leave(playerid);
					if(gPlayerRace[playerid][PRACE_ID]!=-1)     Race_Leave(playerid);
					if(IsPlayerInAnyVehicle(playerid))          SetVehicleToRespawn(GetPlayerVehicleID(playerid));
					SendClientMessage(playerid, COLOUR_YELLOW, "It's a stairway to heaven baby.");
					SetPlayerPos(playerid,2096.1462,1285.2556,1000.000);
				}
				case OA_HELL: {
					if(gPlayerTaxi[playerid][TAXI_STATUS]!=-1)  Taxi_Leave(playerid);
					if(gPlayerRace[playerid][PRACE_ID]!=-1)     Race_Leave(playerid);
					if(IsPlayerInAnyVehicle(playerid))          SetVehicleToRespawn(GetPlayerVehicleID(playerid));
					SendClientMessage(playerid, COLOUR_YELLOW, "It's a gateway to hell baby.");
					SetPlayerPos(playerid,-2458.7756,-1399.5762,1000.000);
				}
				case OA_PIRATESHIP: {
					SendClientMessage(playerid, COLOUR_YELLOW, "You can hold the pirate ship area to gain money.");
				}
				case OA_WANGEXPORTS: {
					WangExport_SellVehicle(playerid);
				}
				case OA_PBDRAGONIN: {
					DisablePlayerCheckpoint(playerid);
					SetPlayerInterior(playerid, 1);
					SetPlayerPos(playerid,-2169.8464,642.3659,1057.5861);
				}
				case OA_PBDRAGONOUT: {
					DisablePlayerCheckpoint(playerid);
					SetPlayerInterior(playerid, 10);
					SetPlayerPos(playerid,1960.8048,977.5516,993.9652);
				}
				case OA_PBDRAGONSAFEHOUSE: {
					PitBoss_TransportComplete(playerid, PB_DRAGON, B_DRAGON);
				}
				case OA_PBDRAGONTRANSCP: {
					DisablePlayerCheckpoint(playerid);
					SetPlayerCP(playerid,1000.0359,-659.0001,121.1484,4.0);
					SetPlayerInterior(playerid, 0);
					SetPlayerPos(playerid,1922.7131,961.1198,10.8203);
					SetVehicleToRespawn(gPitBoss[PB_DRAGON][PB_VEHICLE_SECURICAR]);
					SetVehicleParamsForPlayer(gPitBoss[PB_DRAGON][PB_VEHICLE_SECURICAR], playerid, 0, 0);
					gPlayerStats[playerid][STATS_AREA_SECONDARY] = OA_PBDRAGONSAFEHOUSE;
				}
				case OA_PBCALIGULASAFEHOUSE: {
					PitBoss_TransportComplete(playerid, PB_CALIGULA, B_CALIGULA);
				}
				case OA_PBCALIGULATRANSCP: {
					DisablePlayerCheckpoint(playerid);
					SetPlayerCP(playerid,295.3627,-1166.8506,80.9099,4.0);
					SetPlayerInterior(playerid, 0);
					SetPlayerPos(playerid,2295.5859,1569.8411,10.8203);
					SetVehicleToRespawn(gPitBoss[PB_CALIGULA][PB_VEHICLE_SECURICAR]);
					SetVehicleParamsForPlayer(gPitBoss[PB_CALIGULA][PB_VEHICLE_SECURICAR], playerid, 0, 0);
					gPlayerStats[playerid][STATS_AREA_SECONDARY] = OA_PBCALIGULASAFEHOUSE;
				}
			}
		}
	}
}

//------------------------------------------------------------------------------------------------------

Freeroam_Speedo(playerid, text[]) {
	#pragma unused text
	gPlayerPref[playerid][PREF_SPEEDO] = !gPlayerPref[playerid][PREF_SPEEDO];
	if(gPlayerPref[playerid][PREF_SPEEDO]) SendClientMessage(playerid, COLOUR_YELLOW, "Speedo is now active. To set the metic (KMH/MPH) type '/pref metric'.");
	else SendClientMessage(playerid, COLOUR_YELLOW, "Speedo is now deactivated.");
	return 1;
}

//------------------------------------------------------------------------------------------------------
// Spawn weapons
//------------------------------------------------------------------------------------------------------

SpawnWeapons_Buy(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /buy [weaponid/name] [repeats]");
	} else {
		new weapon[MAX_STRING], weaponid, repeat[MAX_STRING], repeats, money = GetPlayerMoney(playerid), string[MAX_STRING], idx;
		weapon = strtok(text,idx);
		if(IsNumeric(weapon)) {
			weaponid = strval(weapon);
		} else {
			weaponid = -1;
			for(new i=0; i<MAX_SPAWNWEAPONS; i++) {
				if(equal(gWeapons[gSpawnWeapons[i][SPAWNWEAPON_ID]][WEAPON_NAME],weapon,false)) {
					weaponid = i;
					break;
				}
			}
		}
		if(weaponid<0 || weaponid>=MAX_SPAWNWEAPONS) {
			format(string, MAX_STRING, "Invalid weapon (id: %d)! Range is 0 to %d.", weaponid, MAX_SPAWNWEAPONS-1);
			SendClientMessage(playerid, COLOUR_RED, string);
		} else {
			repeat = strtok(text,idx);
			if(!repeat[0]) repeats = 1;
			else if(IsNumeric(repeat)) repeats = strval(repeat);
			else repeats = 1;
			if(money>gSpawnWeapons[weaponid][SPAWNWEAPON_COST]*repeats) {
				GivePlayerPocketMoney(playerid, -gSpawnWeapons[weaponid][SPAWNWEAPON_COST]*repeats);
				GivePlayerWeapon(playerid, gSpawnWeapons[weaponid][SPAWNWEAPON_ID], gSpawnWeapons[weaponid][SPAWNWEAPON_AMMO]*repeats);
				gPlayerSpawnWeapons[playerid][weaponid] += repeats;
				format(string, MAX_STRING, "You purchased %dx%s for when you spawn.", repeats, gWeapons[gSpawnWeapons[weaponid][SPAWNWEAPON_ID]][WEAPON_NAME]);
				SendClientMessage(playerid, COLOUR_GREEN, string);
			} else {
				SendClientMessage(playerid, COLOUR_RED, "You don't have enough pocket money!");
			}
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

SpawnWeapons_ShowList(playerid, text[]) {
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_AMMUNATION || !IsPlayerInCheckpoint(playerid)) {
		SendClientMessage(playerid, COLOUR_RED, "You can only use this feature from within an ammunation area!");
		return 1;
	}
	new index = 0, page = strval(text), pages = (MAX_SPAWNWEAPONS+(MAX_CHATLINES-1))/MAX_CHATLINES, string[MAX_STRING], weapontype[MAX_STRING];
	if(page>1) index = (page-1)*(MAX_CHATLINES-1); else page = 1;
	if(page>pages) {
		format(string, MAX_STRING, "Invalid page number! Available page range is 1 to %d", pages);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		new money = GetPlayerMoney(playerid);
		format(string, MAX_STRING, "Available Spawn Weapons (page %d of %d). Type /weaponlist [number] to view other pages.", page, pages);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		for(new i=index; i<index+(MAX_CHATLINES-1); i++) {
			if(i<MAX_SPAWNWEAPONS) {
				switch(gWeapons[gSpawnWeapons[i][SPAWNWEAPON_ID]][WEAPON_TYPE]) {
					case WEAPON_TYPE_MELEE: weapontype = "melee";
					case WEAPON_TYPE_PROJECTIVE: weapontype = "projective";
					case WEAPON_TYPE_PISTOL: weapontype = "pistol";
					case WEAPON_TYPE_SHOTGUN: weapontype = "shotgun";
					case WEAPON_TYPE_MACHINEGUN: weapontype = "machine gun";
					case WEAPON_TYPE_ASSAULT: weapontype = "assualt";
					case WEAPON_TYPE_RIFLE: weapontype = "rifle";
					case WEAPON_TYPE_HEAVYASSAULT: weapontype = "heavy assault";
					case WEAPON_TYPE_SPECIAL: weapontype = "special";
					default: weapontype = "n/a";
				}
				format(string, MAX_STRING, "%d. %s (type: %s, ammo: %d) - $%d", i, gWeapons[gSpawnWeapons[i][SPAWNWEAPON_ID]][WEAPON_NAME], weapontype, gSpawnWeapons[i][SPAWNWEAPON_AMMO], gSpawnWeapons[i][SPAWNWEAPON_COST]);
				if(money<gSpawnWeapons[i][SPAWNWEAPON_COST]) SendClientMessage(playerid, COLOUR_RED, string);
				else SendClientMessage(playerid, COLOUR_YELLOW, string);
			}
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

SpawnWeapons_ConvertToString(playerid) {
	new string[MAX_STRING];
	for(new i=0; i<MAX_SPAWNWEAPONS; i++) {
		format(string, MAX_STRING, "%s%d,", string, gPlayerSpawnWeapons[playerid][i]);
	}
	string[strlen(string)-1] = EOS;
	return string;
}

//------------------------------------------------------------------------------------------------------

SpawnWeapons_RestoreFromString(playerid, string[]) {
	new ammo, x=0;
	for(new i=0; i<MAX_SPAWNWEAPONS; i++) {
		ammo = strval(strtok(string,x,','));
		if(ammo>0) {
			gPlayerSpawnWeapons[playerid][i] = ammo;
			GivePlayerWeapon(playerid, gSpawnWeapons[i][SPAWNWEAPON_ID], gSpawnWeapons[i][SPAWNWEAPON_AMMO]*ammo);
		} else {
			gPlayerSpawnWeapons[playerid][i] = 0;
		}
	}
}

//------------------------------------------------------------------------------------------------------

SpawnWeapons_Issue(playerid) {
	for(new i=0; i<MAX_SPAWNWEAPONS; i++) {
		if(gPlayerSpawnWeapons[playerid][i]>0) {
			GivePlayerWeapon(playerid, gSpawnWeapons[i][SPAWNWEAPON_ID], gSpawnWeapons[i][SPAWNWEAPON_AMMO]*gPlayerSpawnWeapons[playerid][i]);
		}
	}
}

//------------------------------------------------------------------------------------------------------

SpawnWeapons_Reset(playerid) {
	for(new i=0; i<MAX_SPAWNWEAPONS; i++) {
		gPlayerSpawnWeapons[playerid][i] = 0;
	}
}

//------------------------------------------------------------------------------------------------------
// Spawn info
//------------------------------------------------------------------------------------------------------

Spawn_Set(playerid) {
	if(gPlayerSpawn[playerid][SPAWN_TYPE]==SPAWN_PROPERTY) {
		SetPlayerPos(playerid,gProperties[gPlayerSpawn[playerid][SPAWN_POSITION]][PROPERTY_MARKER][0],gProperties[gPlayerSpawn[playerid][SPAWN_POSITION]][PROPERTY_MARKER][1],gProperties[gPlayerSpawn[playerid][SPAWN_POSITION]][PROPERTY_MARKER][2]);
	} else {
		new rand;
		if(gPlayerSpawn[playerid][SPAWN_CLASS]==SPAWN_COP) {
			rand = random(MAX_SPAWNS-SPAWN_COP_OFFSET) + SPAWN_COP_OFFSET;
		} else {
			rand = random(SPAWN_COP_OFFSET);
		}
		SetPlayerPos(playerid, gSpawns[rand][0], gSpawns[rand][1], gSpawns[rand][2]);
		SetPlayerFacingAngle(playerid, gSpawns[rand][3]);
		gPlayerSpawn[playerid][SPAWN_POSITION] = rand;
	}
}

//------------------------------------------------------------------------------------------------------

Float:Spawn_GetSpawnCoordinates(playerid) {
	new Float:pos[3];
	switch(gPlayerSpawn[playerid][SPAWN_TYPE]) {
		case SPAWN_PROPERTY: {
			pos[0] = gProperties[gPlayerSpawn[playerid][SPAWN_POSITION]][PROPERTY_MARKER][0];
			pos[1] = gProperties[gPlayerSpawn[playerid][SPAWN_POSITION]][PROPERTY_MARKER][1];
			pos[2] = gProperties[gPlayerSpawn[playerid][SPAWN_POSITION]][PROPERTY_MARKER][2];
		}
		case SPAWN_DM: {
			if(gPlayerDM[playerid][DM_SPAWN]==1) {
				pos[0] = gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN1][0];
				pos[1] = gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN1][1];
				pos[2] = gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN1][2];
			} else {
				pos[0] = gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN2][0];
				pos[1] = gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN2][1];
				pos[2] = gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN2][2];
			}
		}
		case SPAWN_RANDOM: {
			pos[0] = gSpawns[gPlayerSpawn[playerid][SPAWN_POSITION]][0];
			pos[1] = gSpawns[gPlayerSpawn[playerid][SPAWN_POSITION]][1];
			pos[2] = gSpawns[gPlayerSpawn[playerid][SPAWN_POSITION]][2];
		}
	}
	return pos;
}

//------------------------------------------------------------------------------------------------------

Spawn_SetHome(playerid, text[]) {
	new home, string[MAX_STRING];
	if(!text[0]) {
		if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_PROPERTY) {
			home = gPlayerStats[playerid][STATS_AREA_SECONDARY];
			format(string, MAX_STRING, "Home starting point changed to %s.", gProperties[home][PROPERTY_NAME]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			SendClientMessage(playerid, COLOUR_YELLOW, "To set random home point, type '/home -1'.");
			gPlayerSpawn[playerid][SPAWN_TYPE] = SPAWN_PROPERTY;
			gPlayerSpawn[playerid][SPAWN_POSITION] = home;
		} else {
			SendClientMessage(playerid, COLOUR_RED, "You are not at a property marker. Type '/home [number]'.");
		}
	} else {
		home = strval(text);
		if(home>=0 && home<MAX_PROPERTIES) {
			if(gProperties[home][PROPERTY_OWNER]==playerid) {
				format(string, MAX_STRING, "Home starting point changed to %s. To set random point, type '/home -1'.", gProperties[home][PROPERTY_NAME]);
				SendClientMessage(playerid, COLOUR_YELLOW, string);
				gPlayerSpawn[playerid][SPAWN_TYPE] = SPAWN_PROPERTY;
				gPlayerSpawn[playerid][SPAWN_POSITION] = home;
			} else {
				format(string, MAX_STRING, "You do not own property %s!", gProperties[home][PROPERTY_NAME]);
				SendClientMessage(playerid, COLOUR_RED, string);
			}
		} else if(home==-1) {
			gPlayerSpawn[playerid][SPAWN_TYPE] = SPAWN_RANDOM;
			gPlayerSpawn[playerid][SPAWN_POSITION] = SPAWN_RANDOM;
			SendClientMessage(playerid, COLOUR_YELLOW, "Random spawn point set.");
		} else {
			format(string, MAX_STRING, "Invalid property number! Available range is 0 to %d or -1 for random.", MAX_PROPERTIES-1);
			SendClientMessage(playerid, COLOUR_RED, string);
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Spawn_SetupClassSelection(playerid) {
	switch (gPlayerSpawn[playerid][SPAWN_SCREEN]) {
		case 0: {
			// LS Beach View
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,380.7409,-2020.7327,10.2500);
			SetPlayerFacingAngle(playerid, 153.0111);
			SetPlayerCameraPos(playerid,379.4443,-2024.7115,10.3075);
			SetPlayerCameraLookAt(playerid,380.7409,-2020.7327,10.2500);
		}
		case 1: {
			// LS Call Girls Only billboard
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,407.2467,-1377.2729,42.6563);
			SetPlayerFacingAngle(playerid, 194.8367);
			SetPlayerCameraPos(playerid,408.4313,-1381.5542,42.6563);
			SetPlayerCameraLookAt(playerid,407.2467,-1377.2729,42.6563);
		}
		case 2: {
			// LS City View
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,2141.9114,-1041.7058,71.8125);
			SetPlayerFacingAngle(playerid, 294.5335);
			SetPlayerCameraPos(playerid,2146.6421,-1039.2510,71.8125);
			SetPlayerCameraLookAt(playerid,2141.9114,-1041.7058,71.8125);
		}
		case 3: {
			// SF Gant Bridge
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,-2541.8586,1377.2490,7.0391);
			SetPlayerFacingAngle(playerid, 210.2330);
			SetPlayerCameraPos(playerid,-2539.6711,1373.4955,7.0391);
			SetPlayerCameraLookAt(playerid,-2541.8586,1377.2490,7.0391);
		}
		case 4: {
			// SF City View
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,-1528.6282,833.8856,7.0391);
			SetPlayerFacingAngle(playerid, 288.5003);
			SetPlayerCameraPos(playerid,-1523.0333,835.7573,7.1875);
			SetPlayerCameraLookAt(playerid,-1528.6282,833.8856,7.0391);
		}
		case 5: {
			// SF Foster Valley
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,-2050.4214,-859.0068,32.1719);
			SetPlayerFacingAngle(playerid, 330.7435);
			SetPlayerCameraPos(playerid,-2048.5317,-855.5908,32.1719);
			SetPlayerCameraLookAt(playerid,-2050.4214,-859.0068,32.1719);
		}
		case 6: {
			// LV Welcome Sign
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,958.7595,2566.3040,10.6762);
			SetPlayerFacingAngle(playerid, 73.0266);
			SetPlayerCameraPos(playerid,952.5722,2568.8020,10.6493);
			SetPlayerCameraLookAt(playerid,958.7595,2566.3040,10.6762);
		}
		case 7: {
			// LV Rock Hotel
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,2645.9673,2270.5615,18.1360);
			SetPlayerFacingAngle(playerid, 217.0452);
			SetPlayerCameraPos(playerid,2648.4231,2267.3083,18.1360);
			SetPlayerCameraLookAt(playerid,2645.9673,2270.5615,18.1360);
		}
		case 8: {
			// LV Old Strip
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,2370.6733,2165.4172,26.9844);
			SetPlayerFacingAngle(playerid, 290.6556);
			SetPlayerCameraPos(playerid,2373.7168,2166.5835,26.9844);
			SetPlayerCameraLookAt(playerid,2370.6733,2165.4172,26.9844);
		}
		case 9: {
			// Country The Big Pecker
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,-416.8759,2710.6060,62.3981);
			SetPlayerFacingAngle(playerid, 39.5556);
			SetPlayerCameraPos(playerid,-419.8005,2714.1479,62.2690);
			SetPlayerCameraLookAt(playerid,-416.8759,2710.6060,62.3981);
		}
		case 10: {
			// Country Bait Shop (Angel Pine)
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,-2055.1760,-2462.4214,35.2889);
			SetPlayerFacingAngle(playerid, 294.2983);
			SetPlayerCameraPos(playerid,-2052.7932,-2461.3457,34.8259);
			SetPlayerCameraLookAt(playerid,-2055.1760,-2462.4214,35.2889);
		}
		case 11: {
			// Country Fern Ridge
		 	SetPlayerInterior(playerid,0);
			SetPlayerPos(playerid,861.5573,-27.3402,64.2777);
			SetPlayerFacingAngle(playerid, 296.8486);
			SetPlayerCameraPos(playerid,866.3002,-25.4593,64.2777);
			SetPlayerCameraLookAt(playerid,861.5573,-27.3402,64.2777);
		}
		case 12: {
			// Special Millie's Bedroom
		 	SetPlayerInterior(playerid,6);
			SetPlayerPos(playerid,345.3391,303.3166,999.9382);
			SetPlayerFacingAngle(playerid, 358.5782);
			SetPlayerCameraPos(playerid,345.4481,307.7208,999.9382);
			SetPlayerCameraLookAt(playerid,345.3391,303.3166,999.9382);
		}
		case 13: {
			// Special Denise's Bedroom
		 	SetPlayerInterior(playerid,1);
			SetPlayerPos(playerid,245.9927,303.4679,1000.0068);
			SetPlayerFacingAngle(playerid, 23.6664);
			SetPlayerCameraPos(playerid,244.9366,305.8774,1000.0068);
			SetPlayerCameraLookAt(playerid,245.9927,303.4679,1000.0068);
		}
		case 14: {
			// Special Fanny Batter's Whore House
		 	SetPlayerInterior(playerid,6);
			SetPlayerPos(playerid,744.6722,1442.6976,1102.7031);
			SetPlayerFacingAngle(playerid, 218.4377);
			SetPlayerCameraPos(playerid,746.8713,1439.9269,1102.9531);
			SetPlayerCameraLookAt(playerid,744.6722,1442.6976,1102.7031);
		}
	}
}

//------------------------------------------------------------------------------------------------------
// Vehicle locks
//------------------------------------------------------------------------------------------------------

Vehicle_Lock(playerid, text[]) {
	#pragma unused text
	if(GetPlayerState(playerid)==PLAYER_STATE_DRIVER) {
		new ok = 1, vehicle = GetPlayerVehicleID(playerid);
		for(new i=0; i<MAX_PATROL_VEHICLES; i++) {
			if(vehicle==gPatrolVehicles[i]) {
				ok = 0;
				break;
			}
		}
		for(new i=0; i<MAX_CASINO; i++) {
			if(vehicle==gPitBoss[i][PB_VEHICLE_SECURICAR] || vehicle==gPitBoss[i][PB_VEHICLE_1] || vehicle==gPitBoss[i][PB_VEHICLE_2] || vehicle==gPitBoss[i][PB_VEHICLE_3]) {
				ok = 0;
				break;
			}
		}
		if(ok) {
			for(new i=0; i<MAX_PLAYERS; i++) {
				if(i!=playerid) SetVehicleParamsForPlayer(vehicle, i, 0, 1);
			}
			SendClientMessage(playerid, COLOUR_YELLOW, "Vehicle locked.");
			PlaySoundForPlayer(playerid, SOUND_BLIP1);
		} else {
			SendClientMessage(playerid, COLOUR_YELLOW, "You cannot lock this vehicle.");
		}
	}
	else {
		SendClientMessage(playerid, COLOUR_RED, "You're not in a vehicle!");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Vehicle_UnLock(playerid, text[]) {
	#pragma unused text
	if(GetPlayerState(playerid)==PLAYER_STATE_DRIVER) {
		new ok = 1, vehicle = GetPlayerVehicleID(playerid);
		for(new i=0; i<MAX_PATROL_VEHICLES; i++) {
			if(vehicle==gPatrolVehicles[i]) {
				ok = 0;
				break;
			}
		}
		for(new i=0; i<MAX_CASINO; i++) {
			if(vehicle==gPitBoss[i][PB_VEHICLE_SECURICAR] || vehicle==gPitBoss[i][PB_VEHICLE_1] || vehicle==gPitBoss[i][PB_VEHICLE_2] || vehicle==gPitBoss[i][PB_VEHICLE_3]) {
				ok = 0;
				break;
			}
		}
		if(ok) {
			for(new i=0; i<MAX_PLAYERS; i++) {
				if(i!=playerid) SetVehicleParamsForPlayer(vehicle, i, 0, 0);
			}
			SendClientMessage(playerid, COLOUR_YELLOW, "Vehicle unlocked.");
			PlaySoundForPlayer(playerid, SOUND_BLIP1);
		} else {
			SendClientMessage(playerid, COLOUR_YELLOW, "You cannot unlock this vehicle.");
		}
	}
	else {
		SendClientMessage(playerid, COLOUR_RED, "You're not in a vehicle!");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

vehicle_AutoUnlock() {
	for(new i=0; i<MAX_VEHICLES; i++) {
		if(!IsVehicleDriver(i)) {
			for(new j=0; j<MAX_PLAYERS; j++) {
				if(IsPlayerConnected(j)) {
					SetVehicleParamsForPlayer(i, j, 0, 0);
				}
			}
		}
	}
}

//------------------------------------------------------------------------------------------------------
// Gangs
//------------------------------------------------------------------------------------------------------

Gang_Reset(playerid) {
	gPlayerGang[playerid][PGANG_ID] = gPlayerGang[playerid][PGANG_INVITE] = -1;
}

//------------------------------------------------------------------------------------------------------

Gang_Initialise(gang) {
	gGangs[gang][GANG_NAME][0] = 0;
	gGangs[gang][GANG_TOTALMEMBERS] = 0;
	gGangs[gang][GANG_BANK] = 0;
	for(new i=0; i<MAX_GANG_MEMBERS; i++) gGangs[gang][GANG_MEMBERS][i] = INVALID_PLAYER_ID;
}

//------------------------------------------------------------------------------------------------------

Gang_Action(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /gang [info/create/join/invite/kick/quit] [name/number]");
		return 1;
	}
	dcmd2(info, 4, Gang_Info);
	dcmd2(create, 6, Gang_Create);
	dcmd2(join, 4, Gang_Join);
	dcmd2(invite, 6, Gang_Invite);
	dcmd2(kick, 4, Gang_Kick);
	dcmd2(quit, 4, Gang_Leave);
	return 0;
}

//------------------------------------------------------------------------------------------------------

Gang_ShowList(playerid, text[]) {
	#pragma unused text
	new string[MAX_STRING], x=0, gangs = 0;
	SendClientMessage(playerid, COLOUR_GREEN, "Gangs...");
	for(new i=0; i<MAX_GANGS; i++) {
		if(gGangs[i][GANG_TOTALMEMBERS]>0) {
			gangs = 1;
			format(string, MAX_STRING, "%s%s (id: %d) - %d members", string, gGangs[i][GANG_NAME], i, gGangs[i][GANG_TOTALMEMBERS]);
			x++;
			if(x>2) {
				SendClientMessage(playerid, COLOUR_YELLOW, string);
				x = 0;
				string[0] = 0;
			} else {
				format(string, MAX_STRING, "%s, ", string);
			}
		}
	}
	if(x>0 && x<=2) {
		string[strlen(string)-2] = '.';
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	}
	if(!gangs) SendClientMessage(playerid, COLOUR_YELLOW, "No active gangs");
	return 1;			
}

//------------------------------------------------------------------------------------------------------

Gang_Info(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /gang info [number]");
		return 1;
	}
	new gang = strval(text), string[MAX_STRING], x=0;
	if(gang<0 || gang>MAX_GANGS || gGangs[gang][GANG_TOTALMEMBERS]==0) {
		SendClientMessage(playerid, COLOUR_RED, "Gang does not exist!");
		return 1;
	}
	format(string, MAX_STRING, "Gang '%s' (id: %d)...", gGangs[gang][GANG_NAME], gang);
	SendClientMessage(playerid, COLOUR_GREEN, string);
	string[0] = 0;
	for(new i=0; i<gGangs[gang][GANG_TOTALMEMBERS]; i++) {
		format(string, MAX_STRING, "%s%s (id: %d)", string, gPlayerStats[gGangs[gang][GANG_MEMBERS][i]][STATS_NAME], gGangs[gang][GANG_MEMBERS][i]);
		if(i==0) format(string, MAX_STRING, "%s - leader", string);
		x++;
		if(x>3) {
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			x = 0;
			string[0] = 0;
		} else {
			format(string, MAX_STRING, "%s, ", string);
		}
	}
	if(x>0 && x<=3) {
		string[strlen(string)-2] = '.';
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	}
	format(string, MAX_STRING, "Positions available: %d", MAX_GANG_MEMBERS-gGangs[gang][GANG_TOTALMEMBERS]);
	SendClientMessage(playerid, COLOUR_YELLOW, string);
	return 1;
}

//------------------------------------------------------------------------------------------------------

Gang_Create(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /gang create [name]");
		return 1;
	}	
	if(gPlayerGang[playerid][PGANG_ID]==-1) {
		new string[MAX_STRING];
		for(new i=0; i<MAX_GANGS; i++) {
			if(gGangs[i][GANG_TOTALMEMBERS]==0) {
				format(gGangs[i][GANG_NAME], MAX_GANG_NAME, "%s", text);
				gGangs[i][GANG_COLOUR] = GetPlayerColor(playerid);
				gGangs[i][GANG_MEMBERS][0] = playerid;
				gGangs[i][GANG_TOTALMEMBERS] = 1;
				gGangs[i][GANG_BANK] = 0;
				gPlayerGang[playerid][PGANG_ID] = i;
				format(string, MAX_STRING, "You have created the gang '%s' (id: %d)", gGangs[i][GANG_NAME], i);
				SendClientMessage(playerid, COLOUR_GREEN, string);
				return 1;
			}
		}
		SendClientMessage(playerid, COLOUR_RED, "No available gang slots. Please join an existing gang.");
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You are already in a gang!");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Gang_Join(playerid, text[]) {
	#pragma unused text
	new gang = gPlayerGang[playerid][PGANG_INVITE], i, string[MAX_STRING];
	if(gang==-1) {
		SendClientMessage(playerid, COLOUR_RED, "You do not have a gang invite!");
	} else if(gGangs[gang][GANG_TOTALMEMBERS]<MAX_GANG_MEMBERS) {
		format(string, MAX_STRING, "%s has joined your gang.", gPlayerStats[playerid][STATS_NAME]);
		for(i=0; i<gGangs[gang][GANG_TOTALMEMBERS]; i++) {
			if(IsPlayerConnected(gGangs[gang][GANG_MEMBERS][i])) {
				SendClientMessage(gGangs[gang][GANG_MEMBERS][i], COLOUR_ORANGE, string);
			}
		}
		gGangs[gang][GANG_MEMBERS][i] = playerid;
		gPlayerGang[playerid][PGANG_ID] = gang;
		gPlayerGang[playerid][PGANG_INVITE] = -1;
		gGangs[gang][GANG_TOTALMEMBERS]++;
		PitBoss_AutoLockVehicles(playerid);
		format(string, MAX_STRING, "You have joined gang '%s' (id: %d)", gGangs[gang][GANG_NAME], gang);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		if(!gPlayerPatrol[playerid][PATROL_ONDUTY] && gPlayerTaxi[playerid][TAXI_STATUS]!=TAXI_DRIVER) {
			SetPlayerColor(playerid, gGangs[gang][GANG_COLOUR]);
		}
	} else {
		format(string, MAX_STRING, "Sorry, the gang '%s' is full.", gGangs[gang][GANG_NAME]);
		SendClientMessage(playerid, COLOUR_RED, string);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Gang_Invite(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /gang invite [playerid/name]");
		return 1;
	}
	new player = GetPlayerID(text), gang = gPlayerGang[playerid][PGANG_ID], string[MAX_STRING];
	if(player==INVALID_PLAYER_ID) {
		SendClientMessage(playerid, COLOUR_RED, "Player does not exist!");
		return 1;
	}
	if(gang!=-1 && playerid!=player) {
		gPlayerGang[player][PGANG_INVITE] = gang;
		format(string, MAX_STRING, "You have sent a gang invite to %s.", gPlayerStats[player][STATS_NAME]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		format(string, MAX_STRING, "You have recieved a gang invite from %s to '%s' (id: %d)", gPlayerStats[playerid][STATS_NAME], gGangs[gang][GANG_NAME], gang);
		SendClientMessage(player, COLOUR_ORANGE, string);
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You must belong to a gang before you can send a gang invite!");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Gang_Kick(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /gang kick [playerid/name]");
		return 1;
	}
	new player = GetPlayerID(text), gang = gPlayerGang[playerid][PGANG_ID];
	if(player==INVALID_PLAYER_ID) {
		SendClientMessage(playerid, COLOUR_RED, "Player does not exist!");
		return 1;
	}
	if(gang!=-1 && gang==gPlayerGang[player][PGANG_ID] && player!=playerid) {
		new string[MAX_STRING];
		if(gGangs[gang][GANG_MEMBERS][0]==playerid) {
			format(string, MAX_STRING, "You have kicked %s from gang '%s'.", gPlayerStats[player][STATS_NAME], gGangs[gang][GANG_NAME]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			Gang_Leave(player, "");
			format(string, MAX_STRING, "You have been kicked from gang '%s' by %s.", gGangs[gang][GANG_NAME], gPlayerStats[playerid][STATS_NAME]);
			SendClientMessage(player, COLOUR_RED, string);
		} else {
			format(string, MAX_STRING, "You must be the gang leader to kick members. The gang leader is %s.", gPlayerStats[gGangs[gang][GANG_MEMBERS][0]][STATS_NAME]);
			SendClientMessage(playerid, COLOUR_RED, string);
		}
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You can only kick fellow gang members!");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Gang_Leave(playerid, text[]) {
	#pragma unused text
	new string[MAX_STRING], gang = gPlayerGang[playerid][PGANG_ID];
	if(gang==-1) return 1;
	for(new i=0; i<gGangs[gang][GANG_TOTALMEMBERS]; i++) {
		if(gGangs[gang][GANG_MEMBERS][i]==playerid) {
			format(string, MAX_STRING, "You have quit gang '%s' (id: %d)", gGangs[gang][GANG_NAME], gang);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			gPlayerGang[playerid][PGANG_ID] = -1;
			gGangs[gang][GANG_TOTALMEMBERS]--;
			if(gGangs[gang][GANG_TOTALMEMBERS]==0) {
				Gang_Initialise(gang);
			} else {
				format(string, MAX_STRING, "%s has quit your gang.", gPlayerStats[playerid][STATS_NAME]);
				for(new j=0; j<MAX_GANG_MEMBERS-1; j++) {
					if(j>=i) gGangs[gang][GANG_MEMBERS][j] = gGangs[gang][GANG_MEMBERS][j+1];
					if(IsPlayerConnected(gGangs[gang][GANG_MEMBERS][j]) && gGangs[gang][GANG_MEMBERS][j]!=playerid) SendClientMessage(gGangs[gang][GANG_MEMBERS][j], COLOUR_ORANGE, string);
				}
				gGangs[gang][GANG_MEMBERS][MAX_GANG_MEMBERS-1] = INVALID_PLAYER_ID;
				PitBoss_AutoLockVehicles(gGangs[gang][GANG_MEMBERS][0]);
			}
			PitBoss_AutoLockVehicles(playerid);
			if(!gPlayerPatrol[playerid][PATROL_ONDUTY] && gPlayerTaxi[playerid][TAXI_STATUS]!=TAXI_DRIVER) {
				SetPlayerColor(playerid, gPlayerColours[playerid]);
			}
			break;
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------
// Bank
//------------------------------------------------------------------------------------------------------

Bank_Deposit(playerid, text[]) {
	if(!text[0] || !IsNumeric(text)) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /bank [amount]");
		return 1;
	}
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_BANK && IsPlayerInCheckpoint(playerid)) {
		new money = strval(text), string[MAX_STRING];
		if(money<1 || money>GetPlayerMoney(playerid)) {
			format(string, MAX_STRING, "Invalid transaction amount ($%d)!", money);
			SendClientMessage(playerid, COLOUR_RED, string);
		} else {
			if(money+gPlayerStats[playerid][STATS_MONEY_BANK]>gGMConfig[GMC_MAXBANK]) {
				money = gPlayerStats[playerid][STATS_MONEY_BANK] - gGMConfig[GMC_MAXBANK];
				string = " (bank limit)";
			}
			gPlayerStats[playerid][STATS_MONEY_BANK] += money;
			format(string, MAX_STRING, "$%d deposited to your bank account%s. Total balance is $%d.", money, string, gPlayerStats[playerid][STATS_MONEY_BANK]);
			GivePlayerPocketMoney(playerid, -money);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
		}
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You must be in a bank area to use this feature. Bank ATMs are located in 24x7 stores.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Bank_Gang_Deposit(playerid, text[]) {
	if(!text[0] || !IsNumeric(text)) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /gbank [amount]");
		return 1;
	}
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_BANK && IsPlayerInCheckpoint(playerid)) {
		new gang = gPlayerGang[playerid][PGANG_ID], money = strval(text), string[MAX_STRING];
		if(money<1 || money>GetPlayerMoney(playerid)) {
			format(string, MAX_STRING, "Invalid transaction amount ($%d)!", money);
			SendClientMessage(playerid, COLOUR_RED, string);
		} else {
			if(gang!=-1) {
				if(money+gGangs[gang][GANG_BANK]>gGMConfig[GMC_MAXBANK]) {
					money = gGangs[gang][GANG_BANK] - gGMConfig[GMC_MAXBANK];
					string = " (bank limit)";
				}
				gGangs[gang][GANG_BANK] += money;
				format(string, MAX_STRING, "$%d deposited to your gangs bank account%s. Total balance is $%d.", money, string, gGangs[gang][GANG_BANK]);
				GivePlayerPocketMoney(playerid, -money);
				SendClientMessage(playerid, COLOUR_YELLOW, string);
			} else {
				SendClientMessage(playerid, COLOUR_RED, "You need to belong to a gang to use this feature!");
			}
		}
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You must be in a bank area to use this feature. Bank ATMs are located in 24x7 stores.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Bank_Withdraw(playerid, text[]) {
	if(!text[0] || !IsNumeric(text)) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /withdraw [amount]");
		return 1;
	}
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_BANK && IsPlayerInCheckpoint(playerid)) {
		new money = strval(text), string[MAX_STRING];
		if(money<1 || money>gPlayerStats[playerid][STATS_MONEY_BANK]) {
			format(string, MAX_STRING, "Invalid transaction amount ($%d)! Your bank balance is $%d.", money, gPlayerStats[playerid][STATS_MONEY_BANK]);
			SendClientMessage(playerid, COLOUR_RED, string);
		} else {
			GivePlayerPocketMoney(playerid, money);
			gPlayerStats[playerid][STATS_MONEY_BANK] -= money;
			format(string, MAX_STRING, "You have withdrawn $%d. Current balance is $%d.", money, gPlayerStats[playerid][STATS_MONEY_BANK]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
		}
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You must be in a bank area to use this feature. Bank ATMs are located in 24x7 stores.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Bank_Gang_Withdraw(playerid, text[]) {
	if(!text[0] || !IsNumeric(text)) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /gwithdraw [amount]");
		return 1;
	}
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_BANK && IsPlayerInCheckpoint(playerid)) {
		new gang = gPlayerGang[playerid][PGANG_ID], money = strval(text), string[MAX_STRING];
		if(gang!=-1) {
			if(money<1 || money>gGangs[gang][GANG_BANK]) {
				format(string, MAX_STRING, "Invalid transaction amount ($%d)! Your gang's bank balance is $%d.", money, gGangs[gang][GANG_BANK]);
				SendClientMessage(playerid, COLOUR_RED, string);
			} else {
				GivePlayerPocketMoney(playerid, money);
				gGangs[gang][GANG_BANK] -= money;
				format(string, MAX_STRING, "You have withdrawn $%d. Current gang balance is $%d.", money, gGangs[gang][GANG_BANK]);
				SendClientMessage(playerid, COLOUR_YELLOW, string);
			}
		} else {
			SendClientMessage(playerid, COLOUR_RED, "You need to belong to a gang to use this feature!");
		}
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You must be in a bank area to use this feature. Bank ATMs are located in 24x7 stores.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Bank_Transfer(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /transfer [playerid/name] [amount]");
		return 1;
	}
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_BANK && IsPlayerInCheckpoint(playerid)) {
		new player, money, idx, string[MAX_STRING];
		player = GetPlayerID(strtok(text,idx));
		if(player==INVALID_PLAYER_ID) {
			SendClientMessage(playerid, COLOUR_RED, "No such player exists!");
		} else if(player==playerid) {
			SendClientMessage(playerid, COLOUR_RED, "Nice try, you cannot transfer cash to yourself!");
		} else {
			money = strval(strtok(text,idx));
			if(money<1 || money>gPlayerStats[playerid][STATS_MONEY_BANK]) {
				format(string, MAX_STRING, "Invalid transaction amount ($%d)!", money);
				SendClientMessage(playerid, COLOUR_RED, string);
			} else {
				if(money+gPlayerStats[player][STATS_MONEY_BANK]>gGMConfig[GMC_MAXBANK]) {
					money = gGMConfig[GMC_MAXBANK] - gPlayerStats[player][STATS_MONEY_BANK];
					string = " (bank limit)";
				}
				gPlayerStats[playerid][STATS_MONEY_BANK] -= money;
				format(string, MAX_STRING, "You have transferred $%d to %s (id: %d)%s. Your balance is now $%d.", gGMConfig[GMC_MAXBANK]-gPlayerStats[player][STATS_MONEY_BANK], gPlayerStats[player][STATS_NAME], player, string, gPlayerStats[playerid][STATS_MONEY_BANK]);
				gPlayerStats[player][STATS_MONEY_BANK] += money;
				SendClientMessage(playerid, COLOUR_YELLOW, string);
				format(string, MAX_STRING, "You have received a $%d bank transfer from %s (id: %d).", money, gPlayerStats[playerid][STATS_NAME], playerid);
				SendClientMessage(player, COLOUR_GREEN, string);
			}
		}
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You must be in a bank area to use this feature. Bank ATMs are located in 24x7 stores.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Bank_Gang_Transfer(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /gtransfer [playerid/name] [amount]");
		return 1;
	}
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_BANK && IsPlayerInCheckpoint(playerid)) {
		new player, money, idx, string[MAX_STRING];
		player = GetPlayerID(strtok(text,idx));
		if(player==INVALID_PLAYER_ID) {
			SendClientMessage(playerid, COLOUR_RED, "No such player exists!");
		} else if(player==playerid) {
			SendClientMessage(playerid, COLOUR_RED, "Nice try, you cannot transfer cash to yourself!");
		} else if(gPlayerGang[playerid][PGANG_ID]==-1) {
			SendClientMessage(playerid, COLOUR_RED, "You do not belong to a gang!");
		} else if(gPlayerGang[player][PGANG_ID]==-1) {
			SendClientMessage(playerid, COLOUR_RED, "Player does not belong to a gang!");
		} else if(gPlayerGang[playerid][PGANG_ID]==gPlayerGang[player][PGANG_ID]) {
			SendClientMessage(playerid, COLOUR_RED, "Player is in the same gang as you!");
		} else {
			money = strval(strtok(text,idx));
			if(money<1 || money>gGangs[gPlayerGang[playerid][PGANG_ID]][GANG_BANK]) {
				format(string, MAX_STRING, "Invalid transaction amount ($%d)!", money);
				SendClientMessage(playerid, COLOUR_RED, string);
			} else {
				if(money+gGangs[gPlayerGang[player][PGANG_ID]][GANG_BANK]>gGMConfig[GMC_MAXBANK]) {
					money = gGMConfig[GMC_MAXBANK] - gGangs[gPlayerGang[player][PGANG_ID]][GANG_BANK];
					string = " (bank limit)";
				}
				gGangs[gPlayerGang[playerid][PGANG_ID]][GANG_BANK] -= money;
				format(string, MAX_STRING, "You have transferred $%d of gang money to %s (id: %d, gang: %s)%s. Your gang's balance is now $%d.", money, gPlayerStats[player][STATS_NAME], player, gGangs[gPlayerGang[player][PGANG_ID]][GANG_NAME], string, gGangs[gPlayerGang[playerid][PGANG_ID]][GANG_BANK]);
				SendClientMessage(playerid, COLOUR_YELLOW, string);
				gGangs[gPlayerGang[player][PGANG_ID]][GANG_BANK] += money;
				format(string, MAX_STRING, "Your gang has received a $%d bank transfer from %s (id: %d, gang: %s).", money, gPlayerStats[playerid][STATS_NAME], playerid, gGangs[gPlayerGang[playerid][PGANG_ID]][GANG_NAME]);
				for(new i=0; i<gGangs[gPlayerGang[player][PGANG_ID]][GANG_TOTALMEMBERS]; i++) {
					if(IsPlayerConnected(gGangs[gPlayerGang[player][PGANG_ID]][GANG_MEMBERS][i])) {
						SendClientMessage(gGangs[gPlayerGang[player][PGANG_ID]][GANG_MEMBERS][i], COLOUR_GREEN, string);
					}
				}
			}
		}
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You must be in a bank area to use this feature. Bank ATMs are located in 24x7 stores.");
	}
	return 1;
}

Bank_Balance(playerid, text[]) {
	#pragma unused text
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_BANK && IsPlayerInCheckpoint(playerid)) {
		new string[MAX_STRING];
		format(string, MAX_STRING, "Current bank balance is $%d.", gPlayerStats[playerid][STATS_MONEY_BANK]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You must be in a bank area to use this feature. Bank ATMs are located in 24x7 stores.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Bank_Gang_Balance(playerid, text[]) {
	#pragma unused text
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_BANK && IsPlayerInCheckpoint(playerid)) {
		new gang = gPlayerGang[playerid][PGANG_ID], string[MAX_STRING];
		if(gang!=-1) {
			format(string, MAX_STRING, "Current gang bank balance is $%d.", gGangs[gang][GANG_BANK]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
		} else {
			SendClientMessage(playerid, COLOUR_RED, "You need to belong to a gang to use this feature!");
		}
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You must be in a bank area to use this feature. Bank ATMs are located in 24x7 stores.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------
// Fly (via airport)
//------------------------------------------------------------------------------------------------------

Fly_Action(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /fly [lv or ls or sf]");
		SendClientMessage(playerid, COLOUR_YELLOW, "...where 'lv' is Las Venturas, 'ls' is Los Santos and 'sf' is San Fierro.");
		return 1;
	}
	dcmd2(sf, 2, Fly_SF);
	dcmd2(ls, 2, Fly_LS);
	dcmd2(lv, 2, Fly_LV);
	Fly_Action(playerid, "");
	return 1;
}

//------------------------------------------------------------------------------------------------------

Fly_SF(playerid, text[]) {
	#pragma unused text
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_AIRPORT || !IsPlayerInCheckpoint(playerid)) {
		SendClientMessage(playerid, COLOUR_YELLOW, "You must be within a airport checkpoint to use this feature.");
	} else if(gPlayerStats[playerid][STATS_AREA_SECONDARY]==AIRPORT_SF) {
		new string[MAX_STRING];
		format(string, MAX_STRING, "You are already at %s!", gAirports[AIRPORT_SF][AIRPORT_NAME]);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		Fly(playerid, AIRPORT_SF);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Fly_LS(playerid, text[]) {
	#pragma unused text
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_AIRPORT || !IsPlayerInCheckpoint(playerid)) {
		SendClientMessage(playerid, COLOUR_YELLOW, "You must be within a airport checkpoint to use this feature.");
	} else if(gPlayerStats[playerid][STATS_AREA_SECONDARY]==AIRPORT_LS) {
		new string[MAX_STRING];
		format(string, MAX_STRING, "You are already at %s!", gAirports[AIRPORT_LS][AIRPORT_NAME]);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		Fly(playerid, AIRPORT_LS);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Fly_LV(playerid, text[]) {
	#pragma unused text
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_AIRPORT || !IsPlayerInCheckpoint(playerid)) {
		SendClientMessage(playerid, COLOUR_YELLOW, "You must be within a airport checkpoint to use this feature.");
	} else if(gPlayerStats[playerid][STATS_AREA_SECONDARY]==AIRPORT_LV) {
		new string[MAX_STRING];
		format(string, MAX_STRING, "You are already at %s!", gAirports[AIRPORT_LV][AIRPORT_NAME]);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		Fly(playerid, AIRPORT_LV);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Fly(playerid, airport) {
	new money = GetPlayerMoney(playerid), fee = AIRPORT_FLIGHT_FEE, string[MAX_STRING];
	if(IsPlayerInAnyVehicle(playerid)) fee = floatround(AIRPORT_FLIGHT_FEE*AIRPORT_FLIGHT_VEHICLEMULTIPLIER);
	if(money<fee) {
		format(string, MAX_STRING, "You cannot afford to fly! The flight cost is $%d.", fee);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		GivePlayerPocketMoney(playerid, -fee);
		if(fee==AIRPORT_FLIGHT_FEE) {
			SetPlayerPos(playerid, gAirports[airport][AIRPORT_MARKER][0], gAirports[airport][AIRPORT_MARKER][1], gAirports[airport][AIRPORT_MARKER][2]);
		} else {
			SetVehiclePos(GetPlayerVehicleID(playerid), gAirports[airport][AIRPORT_MARKER][0], gAirports[airport][AIRPORT_MARKER][1], gAirports[airport][AIRPORT_MARKER][2]);
		}
		format(string, MAX_STRING, "~g~Welcome to~n~~w~%s", gAirports[airport][AIRPORT_NAME]);
		ShowGameTextForPlayer(playerid, string, 3000, 6);
	}
}

//------------------------------------------------------------------------------------------------------
// Skydive
//------------------------------------------------------------------------------------------------------

SkyDive_Enter(playerid, text[]) {
	#pragma unused text
	new money = GetPlayerMoney(playerid), string[MAX_STRING];
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_SKYDIVE || !IsPlayerInCheckpoint(playerid)) {
		SendClientMessage(playerid, COLOUR_RED, "You must be within a skydive area to use this feature.");
	} else if(money<SKYDIVE_FEE) {
		format(string, MAX_STRING, "You have insufficient funds to go skydiving ($%d fee required).", SKYDIVE_FEE);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		if(gPlayerTaxi[playerid][TAXI_STATUS]==TAXI_DRIVER) Taxi_Leave(playerid);
		GivePlayerPocketMoney(playerid, -SKYDIVE_FEE);
		format(string, MAX_STRING, "The skydive fee $%d has been deducted from your funds.", SKYDIVE_FEE);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		DisablePlayerCheckpoint(playerid);
		SetPlayerInterior(playerid, 9);
		SetPlayerPos(playerid,315.8452,973.8031,1961.4797);
		SetPlayerFacingAngle(playerid,359.6261);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

SkyDive_Jump(playerid) {
	if(!IsPlayerConnected(playerid)) return;
	new string[MAX_STRING];
	if(gPlayerSkydive[playerid]==-1) {
		gPlayerSkydive[playerid] = random(MAX_SKYDIVEJUMPS);
		format(string, MAX_STRING, "Skydive jump point set to %s (random)", gSkydiveJumps[gPlayerSkydive[playerid]][SKYDIVE_JUMP_NAME]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	}
	SetPlayerInterior(playerid, 0);
	GivePlayerWeapon(playerid, WEAPON_PARACHUTE, 0);
	SetPlayerPos(playerid, gSkydiveJumps[gPlayerSkydive[playerid]][SKYDIVE_JUMP_MARKER][0], gSkydiveJumps[gPlayerSkydive[playerid]][SKYDIVE_JUMP_MARKER][1], gSkydiveJumps[gPlayerSkydive[playerid]][SKYDIVE_JUMP_MARKER][2]);
	gPlayerStats[playerid][STATS_SKYDIVES]++;
	gPlayerSkydive[playerid] = -1;
}

//------------------------------------------------------------------------------------------------------

SkyDive_SetJump(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_RED, "You must enter a jump location!");
		return 1;
	}
	new jump = strval(text), string[MAX_STRING];
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_OTHER || gPlayerStats[playerid][STATS_AREA_SECONDARY]!=OA_SKYDIVEPLANE) {
		SendClientMessage(playerid, COLOUR_RED, "You must be within a skydive plane to use this feature.");
	} else if(jump<0 || jump>(MAX_SKYDIVEJUMPS-1)) {
		format(string, MAX_STRING, "Invalid jump location (id: %d).", jump);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else if(jump==-1) {
		gPlayerSkydive[playerid] = random(MAX_SKYDIVEJUMPS);
		format(string, MAX_STRING, "Skydive location randomly changed to %s (id: %d).", gSkydiveJumps[gPlayerSkydive[playerid]][SKYDIVE_JUMP_NAME], gPlayerSkydive[playerid]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	} else {
		gPlayerSkydive[playerid] = jump;
		format(string, MAX_STRING, "Skydive location changed to %s (id: %d).", gSkydiveJumps[gPlayerSkydive[playerid]][SKYDIVE_JUMP_NAME], gPlayerSkydive[playerid]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

SkyDive_ShowJumps(playerid, text[]) {
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_OTHER || gPlayerStats[playerid][STATS_AREA_SECONDARY]!=OA_SKYDIVEPLANE) {
		SendClientMessage(playerid, COLOUR_RED, "You must be within a skydive plane to use this feature.");
		return 1;
	}
	new index = 0, page = strval(text), pages = (MAX_SKYDIVEJUMPS+(MAX_CHATLINES-1))/MAX_CHATLINES, string[MAX_STRING];
	if(page>1) index = (page-1)*(MAX_CHATLINES-1); else page = 1;
	if(page>pages) {
		format(string, MAX_STRING, "Invalid page number! Available page range is 1 to %d", pages);
		SendClientMessage(playerid, COLOUR_RED, string);
		return 1;
	}
	format(string, MAX_STRING, "Skydiving Jumps (page %d of %d). Type '/jumplist [number]' to view other pages.", page, pages);
	SendClientMessage(playerid, COLOUR_GREEN, string);
	for(new i=index; i<index+(MAX_CHATLINES-1); i++) {
		if(i<MAX_SKYDIVEJUMPS) {
			format(string, MAX_STRING, "%d. %s", i, gSkydiveJumps[i][SKYDIVE_JUMP_NAME]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------
// Wang Exports
//------------------------------------------------------------------------------------------------------

WangExport_Update() {
	new n = random(MAX_WANGEXPORT_VEHICLES);
	gWantedWangExportVehicle = gWantedWangExportVehicles[n];
	if(gGMConfig[GMC_WE_TEXT]) {
		new string[MAX_STRING];
		format(string, MAX_STRING,"*** Wang Exports are currently buying %s's ***", gVehicleInfo[gWantedWangExportVehicles[n]-VEHICLE_MODEL_OFFSET][VEHICLEINFO_NAME]);
		SendClientMessageToAll(COLOUR_YELLOW, string);
	}
}

//------------------------------------------------------------------------------------------------------

WangExport_ShowExportVehicle(playerid, text[]) {
	#pragma unused text
	new string[MAX_STRING];
	if(gWantedWangExportVehicle==-1) {
		format(string, MAX_STRING, "Sorry, Wang Exports are not buying any vehicles at this time.");
	} else {
		format(string, MAX_STRING, "Wang Exports are currently buying %s's.", gVehicleInfo[gWantedWangExportVehicle-VEHICLE_MODEL_OFFSET][VEHICLEINFO_NAME]);
	}
	SendClientMessage(playerid, COLOUR_YELLOW, string);
	if(IsPlayerInAnyVehicle(playerid)) {
		format(string, MAX_STRING, "You are currently driving a %s.", gVehicleInfo[gVehicles[GetPlayerVehicleID(playerid)-1][VEHICLE_MODEL]-VEHICLE_MODEL_OFFSET][VEHICLEINFO_NAME]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

WangExport_SellVehicle(playerid) {
	if(GetPlayerState(playerid)!=PLAYER_STATE_DRIVER) return;
	new string[MAX_STRING], vehicle = GetPlayerVehicleID(playerid);
	if(gVehicles[vehicle-1][VEHICLE_MODEL]==gWantedWangExportVehicle) {
		new payment = MIN_WANGEXPORT_CASH + random(MAX_WANGEXPORT_CASH-MIN_WANGEXPORT_CASH+1);
		format(string, MAX_STRING, "Excellent, we will export your %s at once! Here is $%d for your services.", gVehicleInfo[gWantedWangExportVehicle-VEHICLE_MODEL_OFFSET][VEHICLEINFO_NAME], payment);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		GivePlayerPocketMoney(playerid, payment);
		SetVehicleToRespawn(vehicle);
	} else {
		SendClientMessage(playerid, COLOUR_YELLOW, "Sorry, we're not buying that particular vehicle at this time.");
		format(string, MAX_STRING, "We are currently buying %s's for export.", gVehicleInfo[gWantedWangExportVehicle-VEHICLE_MODEL_OFFSET][VEHICLEINFO_NAME]);
		SendClientMessage(playerid, COLOUR_GREEN, string);
	}
}

//------------------------------------------------------------------------------------------------------
// Taxi driver
//------------------------------------------------------------------------------------------------------

Taxi_Initialise(playerid) {
	Taxi_Reset(playerid);
	gPlayerTaxi[playerid][TAXI_METER_FEE] = MIN_TAXI_METER_FEE;
}

//------------------------------------------------------------------------------------------------------

Taxi_Reset(playerid) {
	gPlayerTaxi[playerid][TAXI_STATUS] = -1;
	gPlayerTaxi[playerid][TAXI_VEHICLE] = -1;
	gPlayerTaxi[playerid][TAXI_METER] = 0;
	gPlayerTaxi[playerid][TAXI_PASSENGERS] = 0;
}

//------------------------------------------------------------------------------------------------------

Taxi_Driver(playerid, text[]) {
	#pragma unused text
	if(gPlayerPatrol[playerid][PATROL_ONDUTY]) {
		SendClientMessage(playerid, COLOUR_RED, "Patrolling officers cannot become taxi drivers. To quit patrol duties, type '/patrol'.");
	} else if(gPlayerTaxi[playerid][TAXI_STATUS]==TAXI_DRIVER) {
		Taxi_Leave(playerid);
	} else if(GetPlayerState(playerid)==PLAYER_STATE_DRIVER) {
		new vehicle = GetPlayerVehicleID(playerid), string[MAX_STRING];
		for(new i=0; i<MAX_PLAYERS; i++) {
			if(i!=playerid && gPlayerTaxi[i][TAXI_VEHICLE]==vehicle) {
				SendClientMessage(playerid, COLOUR_RED, "You cannot start your taxi services with passengers already in your vehicle!");
				return 1;
			}
		}
		if(gVehicles[vehicle-1][VEHICLE_MODEL]!=VEHICLE_CABBIE && gVehicles[vehicle-1][VEHICLE_MODEL]!=VEHICLE_TAXI) {
			if(GetPlayerMoney(playerid)>=TAXI_REGFEE) {
				format(string, MAX_STRING, "Your vehicle is not registered as a taxi. A $%d registration fee has been deducted from your funds.", TAXI_REGFEE);
				SendClientMessage(playerid, COLOUR_YELLOW, string);
				GivePlayerPocketMoney(playerid, -TAXI_REGFEE);
			} else {
				SendClientMessage(playerid, COLOUR_YELLOW, "Your vehicle is not registered as a taxi. Either find a registered taxi or earn enough funds to cover");
				SendClientMessage(playerid, COLOUR_YELLOW, "the registration fee.");
				format(string, MAX_STRING, "The taxi registration fee is $%d.", TAXI_REGFEE);
				SendClientMessage(playerid, COLOUR_YELLOW, string);
				return 1;
			}
		}
		SendClientMessage(playerid, COLOUR_YELLOW, "You are now a taxi driver. Pickup players and drive them to a destination to run up the");
		SendClientMessage(playerid, COLOUR_YELLOW, "meter. When all passengers have left your vehicle you will be paid the taxi fare. To stop");
		SendClientMessage(playerid, COLOUR_YELLOW, "your taxi services, either leave your vehicle or type '/taxi' again.");
		format(string, MAX_STRING, "For every %d passengers you drop-off you will receive a $%d cash bonus.", TAXI_BONUS_PASSENGER_COUNT, TAXI_BONUS_CASH);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		SetPlayerColor(playerid, COLOUR_TAXIYELLOW);
		gPlayerTaxi[playerid][TAXI_STATUS] = TAXI_DRIVER;
		gPlayerTaxi[playerid][TAXI_VEHICLE] = vehicle;
		gPlayerTaxi[playerid][TAXI_METER] = 0;
		gPlayerTaxi[playerid][TAXI_PASSENGERS] = 0;
	} else {
		SendClientMessage(playerid, COLOUR_YELLOW, "You must be a vehicle driver to use this feature.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Taxi_Enter(playerid, taxidriver) {
	new string[MAX_STRING];
	gPlayerTaxi[playerid][TAXI_STATUS] = TAXI_PASSENGER;
	gPlayerTaxi[playerid][TAXI_VEHICLE] = gPlayerTaxi[taxidriver][TAXI_VEHICLE];
	gPlayerTaxi[taxidriver][TAXI_PASSENGERS]++;
	if(gPlayerTaxi[taxidriver][TAXI_PASSENGERS]>1) {
		format(string, MAX_STRING, "You have entered a taxi. The current fare is $%d.", gPlayerTaxi[taxidriver][TAXI_METER]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		SendClientMessage(playerid, COLOUR_YELLOW, "The last passenger to leave the taxi must pay the fare!");
	} else {
		new Float:pos[3];
		GetPlayerPos(playerid, pos[0], pos[1], pos[2]);
		gPlayerTaxi[taxidriver][TAXI_METER] = TAXI_PICKUPFEE;
		gPlayerTaxi[taxidriver][TAXI_POS][0] = pos[0];
		gPlayerTaxi[taxidriver][TAXI_POS][1] = pos[1];
		gPlayerTaxi[taxidriver][TAXI_POS][2] = pos[2];
		format(string, MAX_STRING, "You have entered a taxi. Current fare is $%d (pickup cost).", TAXI_PICKUPFEE);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		ShowGameTextForPlayer(playerid, "~b~Taxi Meter Started", 3000, 6);
	}
	gPlayerStats[playerid][STATS_TAXI_RIDES]++;
	ShowGameTextForPlayer(taxidriver, "~y~Passenger Collected", 4000, 4);
	PlaySoundForPlayer(taxidriver, SOUND_BLIP1);
}

//------------------------------------------------------------------------------------------------------

Taxi_Leave(playerid) {
	new string[MAX_STRING], taxidriver = -1;
	if(gPlayerTaxi[playerid][TAXI_STATUS]==TAXI_DRIVER) {
		if(gPlayerTaxi[playerid][TAXI_PASSENGERS]>0) {
			for(new i=0; i<MAX_PLAYERS; i++) {
				if(IsPlayerConnected(i) && gPlayerTaxi[i][TAXI_STATUS]==TAXI_PASSENGER && gPlayerTaxi[i][TAXI_VEHICLE]==gPlayerTaxi[playerid][TAXI_VEHICLE]) {
					SendClientMessage(i, COLOUR_YELLOW, "Your taxi ride is over (driver ran away). The meter has been stopped.");
					gPlayerTaxi[playerid][TAXI_PASSENGERS]--;
					gPlayerTaxi[i][TAXI_STATUS] = -1;
					gPlayerTaxi[i][TAXI_VEHICLE] = -1;
				}
			}
		}
		SendClientMessage(playerid, COLOUR_YELLOW, "You have stopped your taxi services.");
		if(gPlayerGang[playerid][PGANG_ID]!=-1) {
			SetPlayerColor(playerid, gGangs[gPlayerGang[playerid][PGANG_ID]][GANG_COLOUR]);
		} else {
			SetPlayerColor(playerid, gPlayerColours[playerid]);
		}
	} else if(gPlayerTaxi[playerid][TAXI_STATUS]==TAXI_PASSENGER) {
		for(new i=0; i<MAX_PLAYERS; i++) {
			if(IsPlayerConnected(i) && gPlayerTaxi[i][TAXI_STATUS]==TAXI_DRIVER && gPlayerTaxi[i][TAXI_VEHICLE]==gPlayerTaxi[playerid][TAXI_VEHICLE]) {
				taxidriver = i;
				break;
			}
		}
		if(taxidriver!=-1) {
			gPlayerTaxi[taxidriver][TAXI_PASSENGERS]--;
			if(gPlayerTaxi[taxidriver][TAXI_PASSENGERS]==0) {
				if(GetPlayerMoney(playerid)<gPlayerTaxi[taxidriver][TAXI_METER]) {
					format(string, MAX_STRING, "Your taxi ride is complete. The $%d fare has been paid with your credit card.", gPlayerTaxi[taxidriver][TAXI_METER]);
				} else {
					format(string, MAX_STRING, "Your taxi ride is complete. The $%d fare has been deducted from your funds.", gPlayerTaxi[taxidriver][TAXI_METER]);
				}
				SendClientMessage(playerid, COLOUR_YELLOW, string);
				GivePlayerPocketMoney(playerid, -gPlayerTaxi[taxidriver][TAXI_METER]);
				format(string, MAX_STRING, "You have earnt $%d from your taxi services.", gPlayerTaxi[taxidriver][TAXI_METER]);
				SendClientMessage(taxidriver, COLOUR_GREEN, string);
				GivePlayerPocketMoney(taxidriver, gPlayerTaxi[taxidriver][TAXI_METER]);
				gPlayerStats[taxidriver][STATS_TAXI_PASSENGERS]++;
			}			
		}
		if(!(gPlayerStats[taxidriver][STATS_TAXI_PASSENGERS]%TAXI_BONUS_PASSENGER_COUNT)) {
			format(string, MAX_STRING, "~y~Taxi bonus ~g~$%d ~y~received!", TAXI_BONUS_CASH);
			ShowGameTextForPlayer(taxidriver, string, 4000, 4);
			GivePlayerPocketMoney(taxidriver, TAXI_BONUS_CASH);
			PlaySoundForPlayer(taxidriver, SOUND_MUSIC_MISSIONCOMPLETE);
			gPlayerStats[taxidriver][STATS_MUSIC_COUNT] = 7;
		}
	}
	Taxi_Reset(playerid);
}

//------------------------------------------------------------------------------------------------------

Taxi_ShowFee(playerid) {
	if(gPlayerTaxi[playerid][TAXI_STATUS]!=TAXI_DRIVER) {
		SendClientMessage(playerid, COLOUR_RED, "You must be a taxi driver to use this feature!");
	} else {
		new string[MAX_STRING];
		format(string, MAX_STRING, "Your current taxi mileage fee is $%d per %s. To change the fee, type '/taxifee [amount]'.", gPlayerTaxi[playerid][TAXI_METER_FEE], (gPlayerPref[playerid][PREF_METRIC]==0) ? "kilometer" : "mile");
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	}
}

//------------------------------------------------------------------------------------------------------

Taxi_SetFee(playerid, text[]) {
	if(!text[0]) {
		Taxi_ShowFee(playerid);
	} else if(gPlayerTaxi[playerid][TAXI_STATUS]!=TAXI_DRIVER) {
		SendClientMessage(playerid, COLOUR_RED, "You must be a taxi driver to use this feature!");
	} else if(gPlayerTaxi[playerid][TAXI_PASSENGERS]>0) {
		SendClientMessage(playerid, COLOUR_RED, "You cannot change your taxi mileage fee while you have passengers in your vehicle!");
	} else {
		new string[MAX_STRING], fee = strval(text);
		if(fee<MIN_TAXI_METER_FEE || fee>MAX_TAXI_METER_FEE) {
			format(string, MAX_STRING, "Mileage fee invalid ($%d)! Available range is $%d to $%d.", fee, MIN_TAXI_METER_FEE, MAX_TAXI_METER_FEE);
			SendClientMessage(playerid, COLOUR_RED, string);
			return 1;
		}
		format(string, MAX_STRING, "Taxi driver %s has changed their mileage fee to $%d per %s.", gPlayerStats[playerid][STATS_NAME], fee, (gPlayerPref[playerid][PREF_METRIC]==0) ? "kilometer" : "mile");
		SendClientMessageToAll(COLOUR_ORANGE, string);
		gPlayerTaxi[playerid][TAXI_METER_FEE] = fee;
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Taxi_Update(playerid) {
	if(gPlayerTaxi[playerid][TAXI_STATUS]!=TAXI_DRIVER || gPlayerTaxi[playerid][TAXI_PASSENGERS]==0) return;
	new updated = 0, Float:distance, Float:pos1[3], Float:pos2[3], string[MAX_STRING];
	pos1[0] = gPlayerTaxi[playerid][TAXI_POS][0];
	pos1[1] = gPlayerTaxi[playerid][TAXI_POS][1];
	pos1[2] = gPlayerTaxi[playerid][TAXI_POS][2];
	for(new i=0; i<MAX_PLAYERS; i++) {
		if(IsPlayerConnected(i) && gPlayerTaxi[i][TAXI_STATUS]==TAXI_PASSENGER && gPlayerTaxi[i][TAXI_VEHICLE]==gPlayerTaxi[playerid][TAXI_VEHICLE]) {
			if(!updated) {
				GetPlayerPos(i, pos2[0], pos2[1], pos2[2]);
				distance = GetDistanceBetweenPoints(pos1, pos2);
				if(distance<250.0) {
					gPlayerTaxi[playerid][TAXI_METER] += gPlayerTaxi[playerid][TAXI_METER_FEE];
				} else {
					gPlayerTaxi[playerid][TAXI_METER] += floatround((gPlayerTaxi[playerid][TAXI_METER_FEE]/4.0)*(distance/250.0));
					gPlayerTaxi[playerid][TAXI_POS][0] = pos2[0];
					gPlayerTaxi[playerid][TAXI_POS][1] = pos2[1];
					gPlayerTaxi[playerid][TAXI_POS][2] = pos2[2];
				}
				updated = 1;
			}
			format(string, MAX_STRING, "~y~Taxi Fare: ~w~$%d", gPlayerTaxi[playerid][TAXI_METER]);
			ShowGameTextForPlayer(i, string, 3000, 1);
		}
	}
	if(updated) ShowGameTextForPlayer(playerid, string, 3000, 1);
}

//------------------------------------------------------------------------------------------------------
// Officer patrol
//------------------------------------------------------------------------------------------------------

Patrol_Reset(playerid) {
	gPlayerPatrol[playerid][PATROL_ONDUTY] = 0;
	gPlayerPatrol[playerid][PATROL_SUSPECT] = INVALID_PLAYER_ID;
	gPlayerPatrol[playerid][PATROL_WARNINGS] = 0;
	gPlayerPatrol[playerid][PATROL_WARNINGREASON] = -1;
}

//------------------------------------------------------------------------------------------------------

Patrol_OnDuty(playerid, text[]) {
	#pragma unused text
	if(gPlayerRace[playerid][PRACE_ID]!=-1) {
		SendClientMessage(playerid, COLOUR_RED, "You must quit your current race before you can go on patrol.");
	} else if(gPlayerDM[playerid][DM_ZONE]!=-1) {
		SendClientMessage(playerid, COLOUR_RED, "You must quit your current deathmatch before you can go on patrol.");
	} else if(gPlayerTaxi[playerid][TAXI_STATUS]==TAXI_DRIVER) {
		SendClientMessage(playerid, COLOUR_RED, "You must stop offering your taxi services before you can go on patrol.");
	} else if(gPlayerSpawn[playerid][SPAWN_CLASS]==SPAWN_COP) {
		new vehicle = GetPlayerVehicleID(playerid);
		if(vehicle>0) {
			for(new i=0; i<MAX_PLAYERS; i++) {
				if(i!=playerid && IsPlayerConnected(i) && IsPlayerInVehicle(i, vehicle)) {
					SendClientMessage(playerid, COLOUR_RED, "You cannot go on patrol with other players in your vehicle.");
					return 1;
				}
			}
		}
		gPlayerPatrol[playerid][PATROL_ONDUTY] = !gPlayerPatrol[playerid][PATROL_ONDUTY];
		gPlayerPatrol[playerid][PATROL_SUSPECT] = INVALID_PLAYER_ID;
		gPlayerPatrol[playerid][PATROL_WARNINGS] = 0;
		gPlayerPatrol[playerid][PATROL_WARNINGREASON] = -1;
		if(gPlayerPatrol[playerid][PATROL_ONDUTY]) {
			for(new i=0; i<MAX_PATROL_VEHICLES; i++) SetVehicleParamsForPlayer(gPatrolVehicles[i], playerid, 0, 0);
			SetPlayerColor(playerid, COLOUR_POLICEBLUE);
			SendClientMessage(playerid, COLOUR_YELLOW, "You are now on patrol. To quit patrol duties, type '/patrol'.");
		} else {
			for(new i=0; i<MAX_PATROL_VEHICLES; i++) SetVehicleParamsForPlayer(gPatrolVehicles[i], playerid, 0, 1);
			SendClientMessage(playerid, COLOUR_YELLOW, "You are no longer on patrol.");
			if(gPlayerGang[playerid][PGANG_ID]!=-1) {
				SetPlayerColor(playerid, gGangs[gPlayerGang[playerid][PGANG_ID]][GANG_COLOUR]);
			} else {
				SetPlayerColor(playerid, gPlayerColours[playerid]);
			}
		}
	} else {
		SendClientMessage(playerid, COLOUR_YELLOW, "You are not an officer of the law!");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Patrol_Update(playerid) {
	if(!gPlayerPatrol[playerid][PATROL_ONDUTY]) return;
	new tmp_reason, reason = -1, sreason[MAX_STRING], Float:tmp_distance, Float:distance = MAX_WORLDBOUNDS*2.0, casino, vehicle, player = INVALID_PLAYER_ID, string[MAX_STRING];
	for(new i=0; i<MAX_PLAYERS; i++) {
		if(i!=playerid && IsPlayerConnected(i) && !gPlayerPatrol[i][PATROL_ONDUTY]) {
			if(gPlayerRace[i][PRACE_ID]!=-1 && gPlayerRace[i][PRACE_STARTTIME]!=-1 && !IsPlayerInCheckpoint(i)) {
				tmp_reason = BUST_RACER;
			} else if(i==gPitBoss[PB_DRAGON][PB_OWNER] && gPitBoss[PB_DRAGON][PB_TRANSPORTING]) {
				tmp_reason = BUST_PITBOSS;
				casino = PB_DRAGON;
			} else if(i==gPitBoss[PB_CALIGULA][PB_OWNER] && gPitBoss[PB_CALIGULA][PB_TRANSPORTING]) {
				tmp_reason = BUST_PITBOSS;
				casino = PB_CALIGULA;
			} else {
				tmp_reason = -1;
			}
			if(tmp_reason!=-1) {
				tmp_distance = GetDistanceBetweenPlayers(playerid, i);
				if(tmp_distance<distance) {
					distance = tmp_distance;
					reason = tmp_reason;
					player = i;
				}
			}
		}
	}
	if(player==INVALID_PLAYER_ID || reason==-1) return;
	if(distance<=MAX_PATROL_PROXIMITY) {
		if(gPlayerPatrol[playerid][PATROL_SUSPECT]==player && gPlayerPatrol[playerid][PATROL_WARNINGREASON]==reason) {
			gPlayerPatrol[playerid][PATROL_WARNINGS]++;
		} else {
			gPlayerPatrol[playerid][PATROL_SUSPECT] = player;
			gPlayerPatrol[playerid][PATROL_WARNINGS] = 1;
			gPlayerPatrol[playerid][PATROL_WARNINGREASON] = reason;
		}
		switch(gPlayerPatrol[playerid][PATROL_WARNINGREASON]) {
			case BUST_RACER: sreason = "illegal racing";
			case BUST_PITBOSS: sreason = "illegal gambling conduct";
		}
		if(gPlayerPatrol[playerid][PATROL_WARNINGS]>MAX_PATROL_WARNINGS) {
			switch(gPlayerPatrol[playerid][PATROL_WARNINGREASON]) {
				case BUST_RACER: {
					if(IsPlayerInAnyVehicle(gPlayerPatrol[playerid][PATROL_SUSPECT])) {
						vehicle = GetPlayerVehicleID(gPlayerPatrol[playerid][PATROL_SUSPECT]);
						SetVehiclePos(vehicle,2227.4263,2458.2297,-7.8278); //impound car
						SetVehicleZAngle(vehicle, 268.9779);
						for(new i=0; i<MAX_PLAYERS; i++) {
							if(IsPlayerConnected(i) && IsPlayerInVehicle(i,vehicle)) {
								RemovePlayerFromVehicle(i);
								SetPlayerHealth(i, 0.0);
								format(string, MAX_STRING, "You have been busted by patrolling officer %s for %s!", gPlayerStats[playerid][STATS_NAME], sreason);
								SendClientMessage(i, COLOUR_RED, string);
								ShowGameTextForPlayer(i,"~r~Busted!",1000,2);
							}
						}
						format(string, MAX_STRING, "You have busted %s and any vehicle occupants for %s!", gPlayerStats[gPlayerPatrol[playerid][PATROL_SUSPECT]][STATS_NAME], sreason);
					} else {
						SetPlayerHealth(gPlayerPatrol[playerid][PATROL_SUSPECT], 0.0);
						format(string, MAX_STRING, "You have been busted by patrolling officer %s for %s!", gPlayerStats[playerid][STATS_NAME], sreason);
						SendClientMessage(gPlayerPatrol[playerid][PATROL_SUSPECT], COLOUR_RED, string);
						ShowGameTextForPlayer(gPlayerPatrol[playerid][PATROL_SUSPECT],"~r~Busted!",1000,2);
						format(string, MAX_STRING, "You have busted %s for %s activities!", gPlayerStats[gPlayerPatrol[playerid][PATROL_SUSPECT]][STATS_NAME], sreason);
					}
				}
				case BUST_PITBOSS: {
					if(IsPlayerInAnyVehicle(gPlayerPatrol[playerid][PATROL_SUSPECT])) {
						vehicle = GetPlayerVehicleID(gPlayerPatrol[playerid][PATROL_SUSPECT]);
						SetVehiclePos(vehicle,2227.4263,2458.2297,-7.8278); //impound car
						SetVehicleZAngle(vehicle, 268.9779);
						RemovePlayerFromVehicle(gPlayerPatrol[playerid][PATROL_SUSPECT]);
					}
					SetPlayerHealth(gPlayerPatrol[playerid][PATROL_SUSPECT], 0.0);
					format(string, MAX_STRING, "You have been busted by officer %s for %s!", gPlayerStats[playerid][STATS_NAME], sreason);
					SendClientMessage(gPlayerPatrol[playerid][PATROL_SUSPECT], COLOUR_RED, string);
					ShowGameTextForPlayer(gPlayerPatrol[playerid][PATROL_SUSPECT],"~r~Busted!",1000,2);
					format(string, MAX_STRING, "You have busted %s for %s!", gPlayerStats[gPlayerPatrol[playerid][PATROL_SUSPECT]][STATS_NAME], sreason);
					// Collect the cash...
					new cash = floatround(gPitBoss[casino][PB_CASH]*0.5);
					gPitBoss[casino][PB_CASH] -= cash;
					GivePlayerPocketMoney(playerid, cash);
				}
			}
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			ShowGameTextForPlayer(playerid, "~b~Suspect Busted!", 3000, 1);
			gPlayerPatrol[playerid][PATROL_SUSPECT] = INVALID_PLAYER_ID;
			gPlayerPatrol[playerid][PATROL_WARNINGS] = 0;
			gPlayerPatrol[playerid][PATROL_WARNINGREASON] = -1;
		} else {
			if(gPlayerPatrol[playerid][PATROL_WARNINGS]==1) {
				format(string, MAX_STRING, "Patrolling officer %s has issued you a warning (%s).", gPlayerStats[playerid][STATS_NAME], sreason);
				SendClientMessage(gPlayerPatrol[playerid][PATROL_SUSPECT], COLOUR_RED, string);
				format(string, MAX_STRING, "You have issued %s a warning (%s).", gPlayerStats[gPlayerPatrol[playerid][PATROL_SUSPECT]][STATS_NAME], sreason);
				SendClientMessage(playerid, COLOUR_ORANGE, string);
			}
			format(string, MAX_STRING, "~y~Warning ~w~%d ~y~of ~w~%d ~y~received!", gPlayerPatrol[playerid][PATROL_WARNINGS], MAX_PATROL_WARNINGS);
			ShowGameTextForPlayer(gPlayerPatrol[playerid][PATROL_SUSPECT], string, 2000, 6);
			format(string, MAX_STRING, "~y~Warning ~w~%d ~y~of ~w~%d ~y~issued!", gPlayerPatrol[playerid][PATROL_WARNINGS], MAX_PATROL_WARNINGS);
			ShowGameTextForPlayer(playerid, string, 2000, 6);
		}
	} else {
		if(gPlayerPatrol[playerid][PATROL_SUSPECT]==player && gPlayerPatrol[playerid][PATROL_WARNINGS]>0) {
			ShowGameTextForPlayer(gPlayerPatrol[playerid][PATROL_SUSPECT], "~w~Police evaded", 10, 1);
			ShowGameTextForPlayer(playerid, "~w~Suspect evaded", 10, 1);
		}
		gPlayerPatrol[playerid][PATROL_SUSPECT] = INVALID_PLAYER_ID;
		gPlayerPatrol[playerid][PATROL_WARNINGS] = 0;
		gPlayerPatrol[playerid][PATROL_WARNINGREASON] = -1;
	}
}

//------------------------------------------------------------------------------------------------------
// Pit Boss
//------------------------------------------------------------------------------------------------------

PitBoss_Initialise(casino) {
	gPitBoss[casino][PB_CASH] = 0;
	gPitBoss[casino][PB_TRANSPORTING] = 0;
	gPitBoss[casino][PB_TRANSPORT_COUNT] = -1;
}

//------------------------------------------------------------------------------------------------------

PitBoss_AutoLockVehicles(playerid) {
	if(!IsPlayerConnected(playerid)) return;
	new contract = random(30)*1000, player, playername[MAX_PLAYER_NAME], string[MAX_STRING], gang;
	for(new i=0; i<MAX_CASINO; i++) {
		if(gPitBoss[i][PB_OWNER]==playerid && gPitBoss[i][PB_TRANSPORTING]) {
			SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_SECURICAR], playerid, 0, 0);
		} else {
			SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_SECURICAR], playerid, 0, 1);
		}
		gang = gPlayerGang[playerid][PGANG_ID];
		if(gang!=-1) {
			if(gPitBoss[i][PB_OWNER]!=INVALID_PLAYER_ID && gang==gPlayerGang[gPitBoss[i][PB_OWNER]][PGANG_ID]) {
				for(new j=0; j<gGangs[gang][GANG_TOTALMEMBERS]; j++) {
					player = gGangs[gang][GANG_MEMBERS][j];
					if(IsPlayerConnected(player)) {
						SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_1], player, 0, 0);
						SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_2], player, 0, 0);
						SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_3], player, 0, 0);
					}
				}
			} else {
				if(gPitBoss[i][PB_OWNER]==INVALID_PLAYER_ID) playername = "[ADMIN]"; else format(playername, MAX_PLAYER_NAME, "%s", gPlayerStats[gPitBoss[i][PB_OWNER]][STATS_NAME]);
				for(new j=0; j<gGangs[gang][GANG_TOTALMEMBERS]; j++) {
					player = gGangs[gang][GANG_MEMBERS][j];
					if(IsPlayerConnected(player)) {
						SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_1], player, 0, 1);
						SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_2], player, 0, 1);
						SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_3], player, 0, 1);
						if(IsPlayerInVehicle(player, gPitBoss[i][PB_VEHICLE_1]) || IsPlayerInVehicle(player, gPitBoss[i][PB_VEHICLE_2]) || IsPlayerInVehicle(player, gPitBoss[i][PB_VEHICLE_3])) {
							format(string, MAX_STRING,"%s is in a stolen limousine. Pit Boss %s has issued a $%d contract.", gPlayerStats[player][STATS_NAME], playername, contract);
							SendClientMessageToAll(COLOUR_ORANGE, string);
							gPlayerStats[player][STATS_BOUNTY] += contract;	
						}
					}
				}
			}
		} else {
			if(playerid==gPitBoss[i][PB_OWNER]) {
				SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_1], playerid, 0, 0);
				SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_2], playerid, 0, 0);
				SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_3], playerid, 0, 0);
			} else {
				if(gPitBoss[i][PB_OWNER]==INVALID_PLAYER_ID) playername = "[ADMIN]"; else format(playername, MAX_PLAYER_NAME, "%s", gPlayerStats[gPitBoss[i][PB_OWNER]][STATS_NAME]);
				SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_1], playerid, 0, 1);
				SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_2], playerid, 0, 1);
				SetVehicleParamsForPlayer(gPitBoss[i][PB_VEHICLE_3], playerid, 0, 1);
				if(IsPlayerInVehicle(playerid, gPitBoss[i][PB_VEHICLE_1]) || IsPlayerInVehicle(playerid, gPitBoss[i][PB_VEHICLE_2]) || IsPlayerInVehicle(playerid, gPitBoss[i][PB_VEHICLE_3])) {
					format(string, MAX_STRING,"%s is in a stolen limousine. Pit Boss %s has issued a $%d contract.", gPlayerStats[playerid][STATS_NAME], playername, contract);
					SendClientMessageToAll(COLOUR_ORANGE, string);
					gPlayerStats[playerid][STATS_BOUNTY] += contract;	
				}
			}
		}
	}
}

//------------------------------------------------------------------------------------------------------

PitBoss_Transport(playerid, text[]) {
	#pragma unused text
	new casino, business, location[25], Float:cp[4], area;
	if(playerid==gPitBoss[PB_DRAGON][PB_OWNER] && gPlayerStats[playerid][STATS_AREA_SECONDARY]==OA_PBDRAGONMONEY && gPitBoss[PB_DRAGON][PB_CASH]>0) {
		casino = PB_DRAGON;
		business = B_DRAGON;
		location = "Los Santos (Red County)";
		cp[0] = -2158.9031; cp[1] = 642.3148; cp[2] = 1052.3750; cp[3] = 3.0;
		area = OA_PBDRAGONTRANSCP;
	} else if(playerid==gPitBoss[PB_CALIGULA][PB_OWNER] && gPlayerStats[playerid][STATS_AREA_SECONDARY]==OA_PBCALIGULAMONEY && gPitBoss[PB_CALIGULA][PB_CASH]>0) {
		casino = PB_CALIGULA;
		business = B_CALIGULA;
		location = "Los Santos (Richman)";
		cp[0] = 2166.4385; cp[1] = 1618.7120; cp[2] = 999.9765; cp[3] = 2.0;
		area = OA_PBCALIGULATRANSCP;
	} else {
		SendClientMessage(playerid, COLOUR_RED, "Only Pit Bosses can use this feature from within a casino safe area (safe must contain funds)!");
		return 1;
	}
	if(!gPitBoss[casino][PB_TRANSPORTING]) {
		new string[MAX_STRING];
		gPitBoss[casino][PB_TRANSPORTING] = 1;
		format(string, MAX_STRING, "You have opened the safe of %s containing $%d.", gBusinesses[business][BUSINESS_NAME], gPitBoss[casino][PB_CASH]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		SendClientMessage(playerid, COLOUR_ORANGE, "No further funds will be deposited while the safe is open.");
		format(string, MAX_STRING, "Transport these funds to your safehouse in %s to be paid. You must leave", location);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		SendClientMessage(playerid, COLOUR_YELLOW, "the Casino via the red marker on the radar. An automatic timer will relock the safe if you fail");
		SendClientMessage(playerid, COLOUR_YELLOW, "to deliver the funds to your safehouse.");
		SendClientMessage(playerid, COLOUR_RED, "If you are killed while the safe is open the killer will pocket half the safe cash!");
		DisablePlayerCheckpoint(playerid);
		SetPlayerCP(playerid,cp[0],cp[1],cp[2],cp[3]);
		gPitBoss[casino][PB_TRANSPORT_COUNT] = PB_MAXTRANSPORTTIME;
		gPlayerStats[playerid][STATS_AREA_PRIMARY] = AREA_OTHER;
		gPlayerStats[playerid][STATS_AREA_SECONDARY] = area;
	} else {
		SendClientMessage(playerid, COLOUR_YELLOW, "You have already opened the safe and should now be onroute to your safehouse.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

PitBoss_TransportUpdate(playerid) {
	new casino;
	if(playerid==gPitBoss[PB_DRAGON][PB_OWNER] && gPitBoss[PB_DRAGON][PB_TRANSPORTING] && gPitBoss[PB_DRAGON][PB_TRANSPORT_COUNT]>=0) casino = PB_DRAGON;
	else if(playerid==gPitBoss[PB_CALIGULA][PB_OWNER] && gPitBoss[PB_CALIGULA][PB_TRANSPORTING] && gPitBoss[PB_CALIGULA][PB_TRANSPORT_COUNT]>=0) casino = PB_CALIGULA;
	else return;
	new cash, string[MAX_STRING];
	if(gPitBoss[casino][PB_TRANSPORT_COUNT]==0) {
		SendClientMessage(playerid, COLOUR_RED, "You failed to transport your Casino funds in time!");
		cash = floatround(gPitBoss[casino][PB_CASH]*0.2);
		gPitBoss[casino][PB_CASH] -= cash;
		format(string, MAX_STRING, "The Las Venturas gambling board are suspicious of your activities and have fined your Casino $%d.", cash);
		SendClientMessage(playerid, COLOUR_RED, string);
		SendClientMessage(playerid, COLOUR_YELLOW, "The casino safe is now locked and collecting funds.");
		gPitBoss[casino][PB_TRANSPORTING] = 0;
		DisablePlayerCheckpoint(playerid);
	} else {
		if(gPitBoss[casino][PB_TRANSPORT_COUNT]==1){
			ShowGameTextForPlayer(playerid, "~r~HURRY!~n~~y~You have~n~~w~1 minute~n~~y~to smuggle your funds to your safehouse in Los Santos", 5500, 3);
		} else if(gPitBoss[casino][PB_TRANSPORT_COUNT]<=3) {
			format(string, MAX_STRING, "~r~HURRY!~n~~y~You have~n~~w~%d minutes~n~~y~to smuggle your funds to your safehouse in Los Santos", gPitBoss[casino][PB_TRANSPORT_COUNT]);
			ShowGameTextForPlayer(playerid, string, 5500, 3);
		}
	}
	gPitBoss[casino][PB_TRANSPORT_COUNT]--;
}

//------------------------------------------------------------------------------------------------------

PitBoss_TransportComplete(playerid, casino, business) {
	new string[MAX_STRING];
	DisablePlayerCheckpoint(playerid);
	GivePlayerPocketMoney(playerid, gPitBoss[casino][PB_CASH]);
	format(string, MAX_STRING, "You have earnt $%d courtesy of %s's.", gPitBoss[casino][PB_CASH], gBusinesses[business][BUSINESS_NAME]);
	SendClientMessage(playerid, COLOUR_GREEN, string);
	SetVehicleToRespawn(gPitBoss[casino][PB_VEHICLE_SECURICAR]);
	SetVehicleParamsForPlayer(gPitBoss[casino][PB_VEHICLE_SECURICAR], playerid, 0, 1);
	gPitBoss[casino][PB_CASH] = 0;
	gPitBoss[casino][PB_TRANSPORTING] = 0;
	format(string, MAX_STRING, "The %s safe is now closed and collecting funds.", gBusinesses[business][BUSINESS_NAME]);
	SendClientMessage(playerid, COLOUR_YELLOW, string);
	gPlayerStats[playerid][STATS_MUSIC_COUNT] = 8;
	PlaySoundForPlayer(playerid, SOUND_MUSIC_MISSIONCOMPLETE);
}

//------------------------------------------------------------------------------------------------------

PitBoss_ShowFee(playerid) {
	new pitboss = 0, string[MAX_STRING];
	if(playerid==gBusinesses[B_DRAGON][BUSINESS_OWNER]) {
		format(string, MAX_STRING, "The gambling fee for %s is $%d.", gBusinesses[B_DRAGON][BUSINESS_NAME], gPitBoss[PB_DRAGON][PB_GFEE]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		pitboss = 1;
	}
	if(playerid==gBusinesses[B_CALIGULA][BUSINESS_OWNER]) {
		format(string, MAX_STRING, "The gambling fee for %s is $%d.", gBusinesses[B_CALIGULA][BUSINESS_NAME], gPitBoss[PB_CALIGULA][PB_GFEE]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		pitboss = 1;
	}
	if(!pitboss) SendClientMessage(playerid, COLOUR_RED, "Only Pit Bosses can use this feature!");
}

//------------------------------------------------------------------------------------------------------

PitBoss_SetFee(playerid, text[]) {
	new string[MAX_STRING], fee;
	if(!text[0]) {
		PitBoss_ShowFee(playerid);
	} else if(playerid==gBusinesses[B_DRAGON][BUSINESS_OWNER] && playerid==gBusinesses[B_CALIGULA][BUSINESS_OWNER]) {
		if(IsNumeric(text)) {
			SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /pbfee caligula [fee] OR /pbfee dragon [fee]");
			SendClientMessage(playerid, COLOUR_YELLOW, "As you own more than one casino, you must specific the casino!");
		} else {
			new tmp[MAX_STRING], idx;
			if(strcmp(text, "dragon", false, 6)==0) {
				tmp = strtok(text, idx);
				if(strlen(tmp)>0) {
					fee = strval(tmp);
					format(string, MAX_STRING, "Gambling fee for %s has been set to $%d.", gBusinesses[B_DRAGON][BUSINESS_NAME], fee);
					SendClientMessage(playerid, COLOUR_YELLOW, string);
					gPitBoss[PB_DRAGON][PB_GFEE] = fee;
					format(string, MAX_STRING, "Gambling fee for %s has been set to $%d by Pit Boss %s.", gBusinesses[B_DRAGON][BUSINESS_NAME], fee, gPlayerStats[playerid][STATS_NAME]);
					SendClientMessageToAll(COLOUR_ORANGE, string);
					return 1;
				}
			} else if(strcmp(text, "caligula", false, 8)==0) {
				tmp = strtok(text, idx);
				if(strlen(tmp)>0) {
					fee = strval(tmp);
					format(string, MAX_STRING, "Gambling fee for %s has been set to $%d.", gBusinesses[B_CALIGULA][BUSINESS_NAME], fee);
					SendClientMessage(playerid, COLOUR_YELLOW, string);
					gPitBoss[PB_CALIGULA][PB_GFEE] = fee;
					format(string, MAX_STRING, "Gambling fee for %s has been set to $%d by Pit Boss %s.", gBusinesses[B_CALIGULA][BUSINESS_NAME], fee, gPlayerStats[playerid][STATS_NAME]);
					SendClientMessageToAll(COLOUR_ORANGE, string);
					return 1;
				}
			}
			SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /pbfee caligula [fee] OR /pbfee dragon [fee]");
			SendClientMessage(playerid, COLOUR_YELLOW, "As you own more than one casino, you must specific the casino!");
		}
	} else {
		fee = strval(text);
		if(fee<MIN_GFEE || fee>MAX_GFEE) {
			format(string, MAX_STRING, "Gambling fee is invalid ($%d)! Available range is $%d to $%d.", fee, MIN_GFEE, MAX_GFEE);
			SendClientMessage(playerid, COLOUR_RED, string);
		} else if(playerid==gBusinesses[B_DRAGON][BUSINESS_OWNER]) {
			format(string, MAX_STRING, "Gambling fee for %s has been set to $%d.", gBusinesses[B_DRAGON][BUSINESS_NAME], fee);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			gPitBoss[PB_DRAGON][PB_GFEE] = fee;
			format(string, MAX_STRING, "Gambling fee for %s has been set to $%d by Pit Boss %s.", gBusinesses[B_DRAGON][BUSINESS_NAME], fee, gPlayerStats[playerid][STATS_NAME]);
			SendClientMessageToAll(COLOUR_ORANGE, string);
		} else if(playerid==gBusinesses[B_CALIGULA][BUSINESS_OWNER]) {
			format(string, MAX_STRING, "Gambling fee for %s has been set to $%d.", gBusinesses[B_CALIGULA][BUSINESS_NAME], fee);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			gPitBoss[PB_CALIGULA][PB_GFEE] = fee;
			format(string, MAX_STRING, "Gambling fee for %s has been set to $%d by Pit Boss %s.", gBusinesses[B_CALIGULA][BUSINESS_NAME], fee, gPlayerStats[playerid][STATS_NAME]);
			SendClientMessageToAll(COLOUR_ORANGE, string);
		} else {
			SendClientMessage(playerid, COLOUR_RED, "Only Pit Bosses can use this feature!");
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

PitBoss_ShowCash(playerid, text[]) {
	#pragma unused text
	new pitboss = 0, string[MAX_STRING];
	if(playerid==gBusinesses[B_DRAGON][BUSINESS_OWNER]) {
		format(string, MAX_STRING, "The current safe funds for %s is $%d.", gBusinesses[B_DRAGON][BUSINESS_NAME], gPitBoss[PB_DRAGON][PB_CASH]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		pitboss = 1;
	}
	if(playerid==gBusinesses[B_CALIGULA][BUSINESS_OWNER]) {
		format(string, MAX_STRING, "The current safe funds for %s is $%d.", gBusinesses[B_CALIGULA][BUSINESS_NAME], gPitBoss[PB_CALIGULA][PB_CASH]);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		pitboss = 1;
	}
	if(!pitboss) SendClientMessage(playerid, COLOUR_RED, "Only Pit Bosses can use this feature!");
	return 1;
}

//------------------------------------------------------------------------------------------------------

PitBoss_GambleUpdate(playerid) {
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_CASINO) {
		new casino = gPlayerStats[playerid][STATS_AREA_SECONDARY];
		if(playerid!=gPitBoss[casino][PB_OWNER]) {
			new money = GetPlayerMoney(playerid), playername[MAX_PLAYER_NAME], string[MAX_STRING];
			if(money>=-1000000) {
				if(gPitBoss[casino][PB_OWNER]==INVALID_PLAYER_ID) playername = "[ADMIN]"; else format(playername, MAX_PLAYER_NAME, "%s", gPlayerStats[gPitBoss[casino][PB_OWNER]][STATS_NAME]);
				format(string, MAX_STRING, "You don't own this casino! Pay a $%d gambling fee to Pit Boss %s at once!", gPitBoss[casino][PB_GFEE], playername);
				SendClientMessage(playerid, COLOUR_RED, string);
				GivePlayerPocketMoney(playerid, -gPitBoss[casino][PB_GFEE]);
				gPitBoss[casino][PB_CASH] += gPitBoss[casino][PB_GFEE];
			} else {
				SendClientMessage(playerid, COLOUR_RED, "You cannot gamble here (bad credit)!");
				OnPlayerSpawn(playerid);
			}
		}
	}
}

//------------------------------------------------------------------------------------------------------
// Deathmatch arena
//------------------------------------------------------------------------------------------------------

DMA_Reset(playerid) {
	gPlayerDM[playerid][DM_ZONE] = -1;
	gPlayerDM[playerid][DM_SPAWN] = -1;
}

//------------------------------------------------------------------------------------------------------

DMA_Action(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /dm [zone] OR /dm quit");
		return 1;
	}
	if(IsNumeric(text)) {
		new string[MAX_STRING], zone = strval(text), Float:health;
		GetPlayerHealth(playerid, health);
		if(health<50.0) {
			SendClientMessage(playerid, COLOUR_YELLOW, "You need atleast 50% health to join a deathmatch arena.");
		} else if(zone<0 || zone>MAX_DMARENAS) {
			format(string, MAX_STRING, "Invalid zone (id: %d)! Available zones are 0 to %d.", zone, MAX_DMARENAS-1);
			SendClientMessage(playerid, COLOUR_RED, string);
		} else if(gPlayerRace[playerid][PRACE_ID]!=-1) {
			SendClientMessage(playerid, COLOUR_YELLOW, "You must quit your current race before you can join a deathmatch.");
		} else if(gPlayerPatrol[playerid][PATROL_ONDUTY]) {
			SendClientMessage(playerid, COLOUR_YELLOW, "Patrolling officers cannot join deathmatch zones. To quit patrol duties, type '/patrol'.");
		} else if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_AMMUNATION) {
			SendClientMessage(playerid, COLOUR_YELLOW, "You cannot join a deathmatch zone from within an Ammuncation store.");
		} else {
			if(gPlayerTaxi[playerid][TAXI_VEHICLE]!=-1) {
				Taxi_Leave(playerid);
			}
			DMA_Enter(playerid, zone);
			if(gGMConfig[GMC_DM_TEXT]) {
				format(string, MAX_STRING, "%s has entered Deathmatch %s (id: %d) : %d players", gPlayerStats[playerid][STATS_NAME], gDMArenas[zone][DM_NAME], zone, gDMArenas[zone][DM_SPAWN1_COUNT]+gDMArenas[zone][DM_SPAWN2_COUNT]);
				if(gDMArenas[zone][DM_SPAWN1_COUNT]+gDMArenas[zone][DM_SPAWN2_COUNT]==1) string[strlen(string)-1] = '\0';
				SendClientMessageToAll(COLOUR_YELLOW, string);
			}
		}
	} else if(strcmp(text, "quit", true, 4)==0 || strcmp(text, "leave", true, 5)==0) {
		DMA_Leave(playerid);
	} else {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /dm [zone] OR /dm quit");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

DMA_Enter(playerid, zone) {
	if(IsPlayerInAnyVehicle(playerid)) RemovePlayerFromVehicle(playerid);
	new money = GetPlayerMoney(playerid);
	if(money>0 && gGMConfig[GMC_DM_BANK]) {
		new string[MAX_STRING];
		gPlayerStats[playerid][STATS_MONEY_BANK] += money;
		if(gPlayerStats[playerid][STATS_MONEY_BANK]>gGMConfig[GMC_MAXBANK]) gPlayerStats[playerid][STATS_MONEY_BANK] = gGMConfig[GMC_MAXBANK];
		format(string, MAX_STRING, "Your $%d has been banked.", money);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		GivePlayerPocketMoney(playerid, -money);
	}
	new gang = gPlayerGang[playerid][PGANG_ID];
	if(gGMConfig[GMC_DM_GROUPGANGS] && gang!=-1) {
		new player;
		for(new i=0; i<gGangs[gang][GANG_TOTALMEMBERS]; i++) {
			player = gGangs[gang][GANG_MEMBERS][i];
			if(player!=playerid && IsPlayerConnected(player) && gPlayerDM[player][DM_ZONE]==zone) {
				if(gPlayerDM[player][DM_SPAWN]==1) {
					gPlayerDM[playerid][DM_SPAWN] = 1;
					gDMArenas[zone][DM_SPAWN1_COUNT]++;
				} else {
					gPlayerDM[playerid][DM_SPAWN] = 2;
					gDMArenas[zone][DM_SPAWN2_COUNT]++;
				}
				break;
			}
		}
	} else {
		if(gDMArenas[zone][DM_SPAWN2_COUNT]>gDMArenas[zone][DM_SPAWN1_COUNT]) {
			gPlayerDM[playerid][DM_SPAWN] = 1;
			gDMArenas[zone][DM_SPAWN1_COUNT]++;
		} else {
			gPlayerDM[playerid][DM_SPAWN] = 2;
			gDMArenas[zone][DM_SPAWN2_COUNT]++;
		}
	}
	gPlayerSpawn[playerid][SPAWN_TYPE] = SPAWN_DM;
	SetPlayerInterior(playerid, 0);
	if(gPlayerDM[playerid][DM_SPAWN]==1) {
		SetPlayerPos(playerid,gDMArenas[zone][DM_SPAWN1][0],gDMArenas[zone][DM_SPAWN1][1],gDMArenas[zone][DM_SPAWN1][2]);
		SetPlayerFacingAngle(playerid,gDMArenas[zone][DM_SPAWN1][3]);
	} else {
		SetPlayerPos(playerid,gDMArenas[zone][DM_SPAWN2][0],gDMArenas[zone][DM_SPAWN2][1],gDMArenas[zone][DM_SPAWN2][2]);
		SetPlayerFacingAngle(playerid,gDMArenas[zone][DM_SPAWN2][3]);
	}
	SetPlayerWorldBounds(playerid,gDMArenas[zone][DM_AREA][2],gDMArenas[zone][DM_AREA][0],gDMArenas[zone][DM_AREA][3],gDMArenas[zone][DM_AREA][1]);
	SetPlayerHealth(playerid,100.0);
	ResetPlayerWeapons(playerid);
	GivePlayerWeapon(playerid, gDMArenas[zone][DM_WEAPON1][0], gDMArenas[zone][DM_WEAPON1][1]);
	GivePlayerWeapon(playerid, gDMArenas[zone][DM_WEAPON2][0], gDMArenas[zone][DM_WEAPON2][1]);
	gPlayerDM[playerid][DM_ZONE] = zone;
	if(gGMConfig[GMC_DM_STEALTH]) SetPlayerColourAlpha(playerid, 0);
}

//------------------------------------------------------------------------------------------------------

DMA_Leave(playerid) {
	if(gPlayerDM[playerid][DM_ZONE]==-1) {
		SendClientMessage(playerid, COLOUR_YELLOW, "You must be in a deathmatch zone to use this feature.");
	} else {
		new string[MAX_STRING];
		if(IsPlayerConnected(playerid)) {
			format(string, MAX_STRING, "You have quit deathmatch arena %s.", gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_NAME]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
		}
		format(string, MAX_STRING, "%s has quit the deathmatch arena. Players remaining: %d.", gPlayerStats[playerid][STATS_NAME], gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN1_COUNT]+gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN2_COUNT]-1);
		for(new i=0; i<MAX_PLAYERS; i++) {
			if(i!=playerid && IsPlayerConnected(i) && gPlayerDM[i][DM_ZONE]==gPlayerDM[playerid][DM_ZONE]) {
				SendClientMessage(i, COLOUR_YELLOW, string);
			}
		}
		if(gPlayerDM[playerid][DM_SPAWN]==1) gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN1_COUNT]--;
		else if(gPlayerDM[playerid][DM_SPAWN]==2) gDMArenas[gPlayerDM[playerid][DM_ZONE]][DM_SPAWN2_COUNT]--;
		DMA_Reset(playerid);
		SetPlayerColor(playerid, gPlayerColours[playerid]);
		gPlayerSpawn[playerid][SPAWN_TYPE] = SPAWN_RANDOM;
		SetPlayerHealth(playerid, 0.0);
	}
}

//------------------------------------------------------------------------------------------------------

DMA_ShowList(playerid, text[]) {
	new index = 0, page = strval(text), pages = (MAX_DMARENAS+(MAX_CHATLINES-1))/MAX_CHATLINES, string[MAX_STRING], weapons[MAX_STRING], players;
	if(page>1) index = (page-1)*(MAX_CHATLINES-1); else page = 1;
	if(page>pages) {
		format(string, MAX_STRING, "Invalid page number! Available page range is 1 to %d", pages);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		format(string, MAX_STRING, "Deathmatch Arena Locations (page %d of %d). Type '/dmlist [number]' to view other pages.", page, pages);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		for(new i=index; i<index+(MAX_CHATLINES-1); i++) {
			if(i<MAX_DMARENAS) {
				if(gDMArenas[i][DM_WEAPON1][0]!=WEAPON_FIST && gDMArenas[i][DM_WEAPON1][0]!=WEAPON_PARACHUTE) {
					format(weapons, MAX_STRING, "%s, ", gWeapons[gDMArenas[i][DM_WEAPON1][0]][WEAPON_NAME]);
				}
				if(gDMArenas[i][DM_WEAPON2][0]!=WEAPON_FIST && gDMArenas[i][DM_WEAPON2][0]!=WEAPON_PARACHUTE) {
					format(weapons, MAX_STRING, "%s%s, ", weapons, gWeapons[gDMArenas[i][DM_WEAPON2][0]][WEAPON_NAME]);
				}
				weapons[strlen(weapons)-2] = '\0';
				players = gDMArenas[i][DM_SPAWN1_COUNT]+gDMArenas[i][DM_SPAWN2_COUNT];
				format(string, MAX_STRING, "%d. %s (%s) : %d players", i, gDMArenas[i][DM_NAME], weapons, players);
				if(players==1) string[strlen(string)-1] = '\0';
				SendClientMessage(playerid, COLOUR_YELLOW, string);
			}
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

DMA_Update(playerid) {
	if(gPlayerDM[playerid][DM_ZONE]!=-1) return;
	new Float:pos[4];
	for(new i=0; i<MAX_DMARENAS; i++) {
		pos[0] = gDMArenas[i][DM_AREA][0];
		pos[1] = gDMArenas[i][DM_AREA][1];
		pos[2] = gDMArenas[i][DM_AREA][2];
		pos[3] = gDMArenas[i][DM_AREA][3];
		if(IsPlayerIn2DArea(playerid, pos) && (gDMArenas[i][DM_SPAWN1_COUNT]>0 || gDMArenas[i][DM_SPAWN2_COUNT]>0)) {
			ShowGameTextForPlayer(playerid, "~r~YOU ARE IN A DEATHMATCH ZONE~n~~g~Leave for your own safety or be ~r~SHOT", 10000, 5);
			gPlayerStats[playerid][STATS_WARNINGS_DMZONE]++;
			if(gPlayerStats[playerid][STATS_WARNINGS_DMZONE]>gGMConfig[GMC_DM_ZONEWARNINGS]) {
				SetPlayerHealth(playerid, 0.0);
				gPlayerStats[playerid][STATS_WARNINGS_DMZONE] = 0;
			}
			return;
		}
	}
}

//------------------------------------------------------------------------------------------------------
// Landgrab
//------------------------------------------------------------------------------------------------------

Business_Buy(playerid) {
	new business = gPlayerStats[playerid][STATS_AREA_SECONDARY], string[MAX_STRING];
	if(GetPlayerMoney(playerid)<gBusinesses[business][BUSINESS_COST]) {
		SendClientMessage(playerid, COLOUR_RED, "You have insufficient funds to /buy this business!");
	} else if(gBusinesses[business][BUSINESS_OWNER]==playerid) {
		SendClientMessage(playerid, COLOUR_RED, "You already own this business!");
	} else if((business==B_DRAGON && gPitBoss[PB_DRAGON][PB_TRANSPORTING]) || (business==B_CALIGULA && gPitBoss[PB_CALIGULA][PB_TRANSPORTING])) {
		format(string, MAX_STRING, "You cannot /buy %s right now. %s has the Casino safe open.", gBusinesses[business][BUSINESS_NAME], gPlayerStats[gBusinesses[business][BUSINESS_OWNER]][STATS_NAME]);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		new player = gBusinesses[business][BUSINESS_OWNER], money;
		if(IsPlayerConnected(player)) {
			if(business==B_DRAGON && gPitBoss[PB_DRAGON][PB_OWNER]==player) gPitBoss[PB_DRAGON][PB_OWNER] = INVALID_PLAYER_ID;
			else if(business==B_CALIGULA && gPitBoss[PB_CALIGULA][PB_OWNER]==player) gPitBoss[PB_CALIGULA][PB_OWNER] = INVALID_PLAYER_ID;
			format(string, MAX_STRING, "Your business %s has been bought out by %s (id: %d).", gBusinesses[business][BUSINESS_NAME], gPlayerStats[playerid][STATS_NAME], player);
			SendClientMessage(player, COLOUR_RED, string);
			money = floatround(gBusinesses[business][BUSINESS_COST]*B_CITYPLANNING_CUT);
			if(business!=B_CITYPLANNING && IsPlayerConnected(gBusinesses[B_CITYPLANNING][BUSINESS_OWNER])) {
				format(string, MAX_STRING, "You have earnt $%d from the sale of %s.", money, gBusinesses[business][BUSINESS_NAME]);
				SendClientMessage(gBusinesses[B_CITYPLANNING][BUSINESS_OWNER], COLOUR_GREEN, string);
				GivePlayerPocketMoney(gBusinesses[B_CITYPLANNING][BUSINESS_OWNER], money);
			}
			GivePlayerPocketMoney(player, gBusinesses[business][BUSINESS_COST]-money);
			gBusinesses[business][BUSINESS_OWNER] = INVALID_PLAYER_ID;
		}
		GivePlayerPocketMoney(playerid, -gBusinesses[business][BUSINESS_COST]);
		gBusinesses[business][BUSINESS_OWNER] = playerid;
		format(string, MAX_STRING, "You have purchased %s!", gBusinesses[business][BUSINESS_NAME]);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		ShowGameTextForPlayer(playerid, "Business Purchased!", 3000, 1);
		PlaySoundForPlayer(playerid, SOUND_PURCHASE);
		// Some PitBoss code here...
		if(business==B_DRAGON || business==B_CALIGULA) {
			if(business==B_DRAGON) {
				gPitBoss[PB_DRAGON][PB_OWNER] = playerid;
				gProperties[PB_DRAGON][PROPERTY_OWNER] = playerid;
			} else {
				gPitBoss[PB_CALIGULA][PB_OWNER] = playerid;
				gProperties[PB_CALIGULA][PROPERTY_OWNER] = playerid;
			}
			if(gGMConfig[GMC_PB_TEXT]) {
				format(string, MAX_STRING,"~y~%s~w~ is the ~g~Pit Boss ~w~of ~y~%s", gPlayerStats[playerid][STATS_NAME], gBusinesses[business][BUSINESS_NAME]);
				ShowGameTextForAll(string, 5000, 3);
			} else {
				format(string, MAX_STRING,"%s is the Pit Boss of %s", gPlayerStats[playerid][STATS_NAME], gBusinesses[business][BUSINESS_NAME]);
				SendClientMessageToAll(COLOUR_YELLOW, string);
			}
			format(string, MAX_STRING,"The %s limousine's are now available to you and any gang members.", gBusinesses[business][BUSINESS_NAME]);
			SendClientMessage(playerid, COLOUR_ORANGE, string);
			SendClientMessage(playerid, COLOUR_YELLOW, "The Las Venturas gambling board recently declared it illegal to profit from local citizens");
			SendClientMessage(playerid, COLOUR_YELLOW, "bad gambling habits. Therefore to earn money from this casino you will need to smuggle the");
			SendClientMessage(playerid, COLOUR_YELLOW, "safe cash out of Las Venturas and transport it to your safehouse in Los Santos. Once there,");
			SendClientMessage(playerid, COLOUR_YELLOW, "you will be able to pocket all the safe cash undetected from the authorities. There is a");
			SendClientMessage(playerid, COLOUR_YELLOW, "time limit on opening the safe and getting to your safehouse so prepare your dash for cash");
			SendClientMessage(playerid, COLOUR_YELLOW, "wisely. If you are stopped by a patrolling officer or killed while transporting the cash you");
			SendClientMessage(playerid, COLOUR_YELLOW, "will lose 50% of the safe funds.");
			if(IsPlayerConnected(player)) PitBoss_AutoLockVehicles(player);
			PitBoss_AutoLockVehicles(playerid);
		}
	}
}

//------------------------------------------------------------------------------------------------------

Business_Sell(playerid) {
	new business = gPlayerStats[playerid][STATS_AREA_SECONDARY], string[MAX_STRING];
	if(gBusinesses[business][BUSINESS_OWNER]!=playerid) {
		SendClientMessage(playerid, COLOUR_RED, "You need to own this business to /sell it!");
	} else if((business==B_DRAGON && gPitBoss[PB_DRAGON][PB_TRANSPORTING]) || (business==B_CALIGULA && gPitBoss[PB_CALIGULA][PB_TRANSPORTING])) {
		format(string, MAX_STRING, "You cannot /sell %s right now. You need to transport the safe funds to Los Santos.", gBusinesses[business][BUSINESS_NAME]);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		new money = floatround(gBusinesses[business][BUSINESS_COST]*B_CITYPLANNING_CUT);
		if(business!=B_CITYPLANNING && IsPlayerConnected(gBusinesses[B_CITYPLANNING][BUSINESS_OWNER])) {
			format(string, MAX_STRING, "You have earnt $%d from the sale of %s.", money, gBusinesses[business][BUSINESS_NAME]);
			SendClientMessage(gBusinesses[B_CITYPLANNING][BUSINESS_OWNER], COLOUR_GREEN, string);
			GivePlayerPocketMoney(gBusinesses[B_CITYPLANNING][BUSINESS_OWNER], money);
		}
		GivePlayerPocketMoney(playerid, gBusinesses[business][BUSINESS_COST]-money);
		gBusinesses[business][BUSINESS_OWNER] = INVALID_PLAYER_ID;
		format(string, MAX_STRING, "You have sold %s!", gBusinesses[business][BUSINESS_NAME]);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		ShowGameTextForPlayer(playerid, "Business Sold!", 3000, 1);
		// Some PitBoss code here...
		if(business==B_DRAGON) {
			gPitBoss[PB_DRAGON][PB_OWNER] = INVALID_PLAYER_ID;
			PitBoss_AutoLockVehicles(playerid);
			format(string, MAX_STRING, "You are no longer the Pit Boss of %s.", gBusinesses[business][BUSINESS_NAME]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
		} else if(business==B_CALIGULA) {
			gPitBoss[PB_CALIGULA][PB_OWNER] = INVALID_PLAYER_ID;
			PitBoss_AutoLockVehicles(playerid);
			format(string, MAX_STRING, "You are no longer the Pit Boss of %s.", gBusinesses[business][BUSINESS_NAME]);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
		}
	}
}

//------------------------------------------------------------------------------------------------------

Business_ShowList(playerid, text[]) {
	new index = 0, page = strval(text), pages = (MAX_BUSINESSES+(MAX_CHATLINES-1))/MAX_CHATLINES, string[MAX_STRING], playername[MAX_PLAYER_NAME], money = GetPlayerMoney(playerid);
	if(page>1) index = (page-1)*(MAX_CHATLINES-1); else page = 1;
	if(page>pages) {
		format(string, MAX_STRING, "Invalid page number! Available page range is 1 to %d", pages);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		format(string, MAX_STRING, "Available Businesses (page %d of %d). Type '/businesses [number]' to view other pages.", page, pages);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		for(new i=index; i<index+(MAX_CHATLINES-1); i++) {
			if(i<MAX_BUSINESSES) {
				if(gBusinesses[i][BUSINESS_OWNER]==INVALID_PLAYER_ID) playername = "None"; else format(playername, MAX_PLAYER_NAME, "%s", gPlayerStats[gBusinesses[i][BUSINESS_OWNER]][STATS_NAME]);
				format(string, MAX_STRING, "%d. %s  Owner: %s", i, gBusinesses[i][BUSINESS_NAME], playername);
				if(gBusinesses[i][BUSINESS_OWNER]==playerid) SendClientMessage(playerid, COLOUR_WHITE, string);
				else if(money<gBusinesses[i][BUSINESS_COST]) SendClientMessage(playerid, COLOUR_RED, string);
				else SendClientMessage(playerid, COLOUR_YELLOW, string);
			}
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Business_ScoreUpdate(playerid) {
	if(gPlayerDM[playerid][DM_ZONE]!=-1) return; // exclude dm players from receiving cash
	new string[MAX_STRING], cash = 0;
	for(new i=0; i<MAX_BUSINESSES; i++) {
		if(gBusinesses[i][BUSINESS_OWNER]==playerid) {
			if(i==B_DRAGON) {
				if(!gPitBoss[PB_DRAGON][PB_TRANSPORTING]) gPitBoss[PB_DRAGON][PB_CASH] += gBusinesses[i][BUSINESS_VALUE];
			} else if(i==B_CALIGULA) {
				if(!gPitBoss[PB_CALIGULA][PB_TRANSPORTING]) gPitBoss[PB_CALIGULA][PB_CASH] += gBusinesses[i][BUSINESS_VALUE];
			} else {
				cash += gBusinesses[i][BUSINESS_VALUE];
			}
		}
	}
	if(cash>0) {
		GivePlayerPocketMoney(playerid, cash);
		format(string, MAX_STRING, "You earned $%d from your businesses.", cash);
		SendClientMessage(playerid, COLOUR_GREEN, string);
	}
}

//------------------------------------------------------------------------------------------------------

Property_Buy(playerid) {
	new property = gPlayerStats[playerid][STATS_AREA_SECONDARY], string[MAX_STRING];
	if(GetPlayerMoney(playerid)<gProperties[property][PROPERTY_COST]) {
		SendClientMessage(playerid, COLOUR_RED, "You have insufficient funds to /buy this property!");
	} else if(gProperties[property][PROPERTY_OWNER]==playerid) {
		SendClientMessage(playerid, COLOUR_RED, "You already own this property!");
	} else {
		new player = gProperties[property][PROPERTY_OWNER], money;
		if(IsPlayerConnected(player)) {
			format(string, MAX_STRING, "Your property %s has been bought out by %s (id: %d).", gProperties[property][PROPERTY_NAME], gPlayerStats[playerid][STATS_NAME], player);
			SendClientMessage(player, COLOUR_RED, string);
			money = floatround(gProperties[property][PROPERTY_COST]*B_CITYPLANNING_CUT);
			if(IsPlayerConnected(gBusinesses[B_CITYPLANNING][BUSINESS_OWNER])) {
				format(string, MAX_STRING, "You have earnt $%d from the sale of %s.", money, gProperties[property][PROPERTY_NAME]);
				SendClientMessage(gBusinesses[B_CITYPLANNING][BUSINESS_OWNER], COLOUR_GREEN, string);
				GivePlayerPocketMoney(gBusinesses[B_CITYPLANNING][BUSINESS_OWNER], money);
			}
			GivePlayerPocketMoney(player, gProperties[property][PROPERTY_COST]-money);
			// If property was a spawn point then remove it...
			if(gPlayerSpawn[player][SPAWN_TYPE]==SPAWN_PROPERTY && gPlayerSpawn[player][SPAWN_POSITION]==property) {
				gPlayerSpawn[player][SPAWN_TYPE] = SPAWN_RANDOM;
				gPlayerSpawn[player][SPAWN_POSITION] = SPAWN_RANDOM;
				SendClientMessage(player, COLOUR_YELLOW, "Your property home point has been removed. Random spawn location set.");
			}
		}
		GivePlayerPocketMoney(playerid, -gProperties[property][PROPERTY_COST]);
		gProperties[property][PROPERTY_OWNER] = playerid;
		format(string, MAX_STRING, "You have purchased %s!", gProperties[property][PROPERTY_NAME]);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		ShowGameTextForPlayer(playerid, "Property Purchased!", 3000, 1);
		PlaySoundForPlayer(playerid, SOUND_PURCHASE);
		// Advise possible spawn location...
		SendClientMessage(playerid, COLOUR_YELLOW, "You can set this property as your home starting point by typing '/home' now.");
		format(string, MAX_STRING, "To set the home starting point later, type '/home %d' anytime while you own this property.", property);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	}
}

//------------------------------------------------------------------------------------------------------

Property_Sell(playerid) {
	new property = gPlayerStats[playerid][STATS_AREA_SECONDARY], string[MAX_STRING];
	if(gProperties[property][PROPERTY_OWNER]!=playerid) {
		SendClientMessage(playerid, COLOUR_RED, "You need to own this property to /sell it!");
	} else {
		new money = floatround(gProperties[property][PROPERTY_COST]*B_CITYPLANNING_CUT);
		if(IsPlayerConnected(gProperties[B_CITYPLANNING][PROPERTY_OWNER])) {
			format(string, MAX_STRING, "You have earnt $%d from the sale of %s.", money, gProperties[property][PROPERTY_NAME]);
			SendClientMessage(gProperties[B_CITYPLANNING][PROPERTY_OWNER], COLOUR_GREEN, string);
			GivePlayerPocketMoney(gProperties[B_CITYPLANNING][PROPERTY_OWNER], money);
		}
		GivePlayerPocketMoney(playerid, gProperties[property][PROPERTY_COST]-money);
		gProperties[property][PROPERTY_OWNER] = INVALID_PLAYER_ID;
		format(string, MAX_STRING, "You have sold %s!", gProperties[property][PROPERTY_NAME]);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		ShowGameTextForPlayer(playerid, "Property Sold!", 3000, 1);
		// If property was a spawn point then remove it...
		if(gPlayerSpawn[playerid][SPAWN_TYPE]==SPAWN_PROPERTY && gPlayerSpawn[playerid][SPAWN_POSITION]==property) {
			gPlayerSpawn[playerid][SPAWN_TYPE] = SPAWN_RANDOM;
			gPlayerSpawn[playerid][SPAWN_POSITION] = SPAWN_RANDOM;
			SendClientMessage(playerid, COLOUR_YELLOW, "Your property home point has been removed. Random spawn location set.");
		}
	}
}

//------------------------------------------------------------------------------------------------------

Property_ShowList(playerid, text[]) {
	new index = 0, page = strval(text), pages = (MAX_PROPERTIES+(MAX_CHATLINES-1))/MAX_CHATLINES, string[MAX_STRING], playername[MAX_PLAYER_NAME], money = GetPlayerMoney(playerid);
	if(page>1) index = (page-1)*(MAX_CHATLINES-1); else page = 1;
	if(page>pages) {
		format(string, MAX_STRING, "Invalid page number! Available page range is 1 to %d", pages);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		format(string, MAX_STRING, "Available Properties (page %d of %d). Type '/properties [number]' to view other pages.", page, pages);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		for(new i=index; i<index+(MAX_CHATLINES-1); i++) {
			if(i<MAX_PROPERTIES) {
				if(gProperties[i][PROPERTY_OWNER]==INVALID_PLAYER_ID) playername = "None"; else format(playername, MAX_PLAYER_NAME, "%s", gPlayerStats[gProperties[i][PROPERTY_OWNER]][STATS_NAME]);
				format(string, MAX_STRING, "%d. %s  Owner: %s", i, gProperties[i][PROPERTY_NAME], playername);
				if(gProperties[i][PROPERTY_OWNER]==playerid) SendClientMessage(playerid, COLOUR_WHITE, string);
				else if(money<gProperties[i][PROPERTY_COST]) SendClientMessage(playerid, COLOUR_RED, string);
				else SendClientMessage(playerid, COLOUR_YELLOW, string);
			}
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Property_ScoreUpdate(playerid) {
	if(gPlayerDM[playerid][DM_ZONE]!=-1) return; // exclude dm players from paying cash (lucky aren't they...)
	new string[MAX_STRING], cash = 0, money = GetPlayerMoney(playerid), i, cut;
	for(i=0; i<MAX_PROPERTIES; i++) {
		if(gProperties[i][PROPERTY_OWNER]==playerid) {
			cash += gProperties[i][PROPERTY_UPKEEP];
		}
	}
	i = 0;
	while(money<cash && cash>0) {
		for( ; i<MAX_PROPERTIES; i++) {
			if(gProperties[i][PROPERTY_OWNER]==playerid) {
				cut = floatround(gProperties[i][PROPERTY_COST]*B_CITYPLANNING_CUT);
				if(IsPlayerConnected(gProperties[B_CITYPLANNING][PROPERTY_OWNER])) {
					format(string, MAX_STRING, "You have earnt $%d from the sale of %s.", cut, gProperties[i][PROPERTY_NAME]);
					SendClientMessage(gProperties[B_CITYPLANNING][PROPERTY_OWNER], COLOUR_GREEN, string);
					GivePlayerPocketMoney(gProperties[B_CITYPLANNING][PROPERTY_OWNER], cut);
				}
				GivePlayerPocketMoney(playerid, gProperties[i][PROPERTY_COST]-cut);
				gProperties[i][PROPERTY_OWNER] = INVALID_PLAYER_ID;
				format(string, MAX_STRING, "You have insufficient funds to keep %s. This property has been sold.", gProperties[i][PROPERTY_NAME]);
				SendClientMessage(playerid, COLOUR_RED, string);
				cash -= gProperties[i][PROPERTY_UPKEEP];
				money += (gProperties[i][PROPERTY_COST]-cut);

				if(gPlayerSpawn[playerid][SPAWN_TYPE]==SPAWN_PROPERTY && gPlayerSpawn[playerid][SPAWN_POSITION]==i) {
					gPlayerSpawn[playerid][SPAWN_TYPE] = SPAWN_RANDOM;
					gPlayerSpawn[playerid][SPAWN_POSITION] = SPAWN_RANDOM;
					SendClientMessage(playerid, COLOUR_YELLOW, "Your property home point has been removed. Random spawn location set.");
				}
				break;
			}
		}
	}
	if(cash>0) {
		format(string, MAX_STRING, "You have paid $%d in upkeep for your properties.", cash);
		SendClientMessage(playerid, COLOUR_WHITE, string);
		GivePlayerPocketMoney(playerid, -cash);
	}
}

//------------------------------------------------------------------------------------------------------
// Race
//------------------------------------------------------------------------------------------------------

Race_ResetProgress(playerid) {
	gPlayerRace[playerid][PRACE_ID] = -1;
	gPlayerRace[playerid][PRACE_CP] = -1;
	gPlayerRace[playerid][PRACE_STARTTIME] = -1;
	gPlayerRace[playerid][PRACE_LAPCOUNT] = -1;
}

//------------------------------------------------------------------------------------------------------

Race_Action(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /race [join/start/quit/info/members] [number]");
		return 1;
	}
	dcmd2(join, 4, Race_Join);
	dcmd2(start, 5, Race_Start);
	dcmd2(quit, 4, Race_Quit);
	dcmd2(info, 4, Race_Info);
	dcmd2(members, 7, Race_Members);
	return 0;
}

//------------------------------------------------------------------------------------------------------

Race_Join(playerid, text[]) {
	if((!text[0] && gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_RACE) || (strlen(text)>0 && !IsNumeric(text))) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /race join [number]");
	} else if(gPlayerPatrol[playerid][PATROL_ONDUTY]) {
		SendClientMessage(playerid, COLOUR_YELLOW, "Patrolling officers cannot join a race. To quit patrol duties, type '/patrol'.");
	} else if(gPlayerDM[playerid][DM_ZONE]!=-1) {
		SendClientMessage(playerid, COLOUR_YELLOW, "You must quit your current deathmatch before you can join a race. To quit, type '/dm quit'.");
	} else if(gPlayerRace[playerid][PRACE_ID]!=-1) {
		SendClientMessage(playerid, COLOUR_YELLOW, "You must quit your current race before you can join another. To quit, type '/race quit'.");
	} else {
		new race, string[MAX_STRING], directions=1;
		if(!text[0]) {
			race = gPlayerStats[playerid][STATS_AREA_SECONDARY];
			directions = 0;
		} else {
			race = strval(text);
			if(race<0 || race>MAX_RACES) {
				format(string, MAX_STRING, "Invalid race number (%d)! Available range is 0 to %d.", race, MAX_RACES-1);
				SendClientMessage(playerid, COLOUR_RED, string);
				return 1;
			}
		}
		gPlayerRace[playerid][PRACE_ID] = race;
		gPlayerRace[playerid][PRACE_CP] = gRaces[race][RACE_CPSTART];
		gPlayerRace[playerid][PRACE_STARTTIME] = 0;
		gPlayerRace[playerid][PRACE_LAPCOUNT] = 0;
		DisablePlayerCheckpoint(playerid);
		SetPlayerCP(playerid, gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][0], gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][1], gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][2], gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][3]);
		format(string, MAX_STRING, "You have joined race \"%s\" (id: %d).", gRaces[race][RACE_NAME], race);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		Race_ShowDetails(playerid, race);
		if(directions) {
			SendClientMessage(playerid, COLOUR_YELLOW, "Get to the red marker on the map to start the race. To quit the race type '/race quit'.");
		}
		format(string, MAX_STRING, "Racer %s (id: %d) has joined race \"%s\".", gPlayerStats[playerid][STATS_NAME], playerid, gRaces[race][RACE_NAME]);
		for(new i=0; i<MAX_PLAYERS; i++) {
			if(i!=playerid && IsPlayerConnected(i) && gPlayerRace[i][PRACE_ID]==race && gPlayerRace[i][PRACE_STARTTIME]==0) {
				SendClientMessage(i, COLOUR_YELLOW, string);
			}
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Race_VehicleCheck(playerid, race) {
	new vehicle, playerstate = GetPlayerState(playerid);
	vehicle = GetPlayerVehicleID(playerid);
	if(gRaces[race][RACE_REQVEHICLE]!=-1) {
		if(vehicle>0 && gVehicles[vehicle-1][VEHICLE_MODEL]==gRaces[race][RACE_REQVEHICLE] && playerstate==PLAYER_STATE_DRIVER) return 1;
	} else if(gRaces[race][RACE_REQVEHICLETYPE]!=-1) {
		if(gRaces[race][RACE_REQVEHICLETYPE]==VEHICLE_CLASS_FOOT && vehicle==0) {
			return 1;
		} else if(vehicle>0) {
			switch(gRaces[race][RACE_REQVEHICLETYPE]) {
				case VEHICLE_TYPE_BIKE, VEHICLE_TYPE_BICYCLE, VEHICLE_TYPE_BOAT, VEHICLE_TYPE_AMPHIBIOUS, VEHICLE_TYPE_CAR, VEHICLE_TYPE_HELICOPTER, VEHICLE_TYPE_MONSTER, VEHICLE_TYPE_PLANE, VEHICLE_TYPE_QUADBIKE, VEHICLE_TYPE_TRAIN: {
					if(gVehicleInfo[gVehicles[vehicle-1][VEHICLE_MODEL]-VEHICLE_MODEL_OFFSET][VEHICLEINFO_TYPE]==gRaces[race][RACE_REQVEHICLETYPE] && playerstate==PLAYER_STATE_DRIVER) return 1;
				}
				case VEHICLE_CLASS_LAND: {
					switch(gVehicleInfo[gVehicles[vehicle-1][VEHICLE_MODEL]-VEHICLE_MODEL_OFFSET][VEHICLEINFO_TYPE]) {
						case VEHICLE_TYPE_BIKE, VEHICLE_TYPE_BICYCLE, VEHICLE_TYPE_AMPHIBIOUS, VEHICLE_TYPE_CAR, VEHICLE_TYPE_MONSTER, VEHICLE_TYPE_QUADBIKE, VEHICLE_TYPE_TRAIN: {
							if(playerstate==PLAYER_STATE_DRIVER) return 1;
						}
					}
				}
				case VEHICLE_CLASS_WATER: {
					switch(gVehicleInfo[gVehicles[vehicle-1][VEHICLE_MODEL]-VEHICLE_MODEL_OFFSET][VEHICLEINFO_TYPE]) {
						case VEHICLE_TYPE_BOAT, VEHICLE_TYPE_AMPHIBIOUS: {
							if(playerstate==PLAYER_STATE_DRIVER) return 1;
						}
					}
				}
				case VEHICLE_CLASS_AIR: {
					switch(gVehicleInfo[gVehicles[vehicle-1][VEHICLE_MODEL]-VEHICLE_MODEL_OFFSET][VEHICLEINFO_TYPE]) {
						case VEHICLE_TYPE_HELICOPTER, VEHICLE_TYPE_PLANE: {
							if(playerstate==PLAYER_STATE_DRIVER) return 1;
						}
					}
				}
			}
		}
	} else {
		return 1;
	}
	return 0;
}

//------------------------------------------------------------------------------------------------------

Race_Start(playerid, text[]) {
	#pragma unused text
	new race = gPlayerRace[playerid][PRACE_ID], string[MAX_STRING];
	if(race==-1) {
		SendClientMessage(playerid, COLOUR_RED, "You must join a race before you can start it. To join a race, type '/race join [number]'");
	} else if(!IsPlayerInCheckpoint(playerid)) {
		SendClientMessage(playerid, COLOUR_YELLOW, "You must be at the race start marker to start the race.");
	} else if(gPlayerRace[playerid][PRACE_CP]>gRaces[race][RACE_CPSTART]) {
		SendClientMessage(playerid, COLOUR_RED, "You are already racing!");
	} else if(gRaces[race][RACE_STARTTIME]>0) {
		format(string, MAX_STRING, "A race is already in progress. Please wait for the race to complete (players racing: %d).", gRaces[race][RACE_TOTALRACERS]);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else if(GetPlayerMoney(playerid)<gRaces[race][RACE_REQCASH]) {
		format(string, MAX_STRING, "You have insufficient funds to pay the race entry fee of $%d.", gRaces[race][RACE_REQCASH]);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else if(gPlayerStats[playerid][STATS_RACE_POINTS]<gRaces[race][RACE_REQPOINTS]) {
		format(string, MAX_STRING, "You have insufficient race points to meet the race entry requirement of %d points.", gRaces[race][RACE_REQPOINTS]);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else if(!Race_VehicleCheck(playerid, race)) {
		SendClientMessage(playerid, COLOUR_RED, "Your vehicle does not satisify the race requirements.");
	} else {
		// Race checks complete, lets start racing...
		new ok, money;

		format(string, MAX_STRING, "Race \"%s\" (id: %d) has been started by %s...", gRaces[race][RACE_NAME], race, gPlayerStats[playerid][STATS_NAME]);

		gRaces[race][RACE_TOTALRACERS] = 0;
		gRaces[race][RACE_COMPLETEDRACERS] = 0;

		for(new i=0; i<MAX_PLAYERS; i++) {
			if(IsPlayerConnected(i) && gPlayerRace[i][PRACE_ID]==race) {
				ok = 0, money = GetPlayerMoney(i);
				if(i!=playerid && IsPlayerInCheckpoint(i) && gPlayerRace[i][PRACE_CP]==gRaces[race][RACE_CPSTART] && money>=gRaces[race][RACE_REQCASH] && gPlayerStats[i][STATS_RACE_POINTS]>=gRaces[race][RACE_REQPOINTS] && Race_VehicleCheck(i, race)) {
					ok = 1;
				}
				if(ok || i==playerid) {
					SendClientMessage(i, COLOUR_GREY, string);
					gPlayerStats[i][STATS_RACE_STARTS]++;
					gRaces[race][RACE_TOTALRACERS]++;
					if(gRaces[race][RACE_REQCASH]>0) {
						GivePlayerPocketMoney(i,-gRaces[race][RACE_REQCASH]);
					}
					TogglePlayerControllable(i, 0);									
					DisablePlayerCheckpoint(i);
					gPlayerRace[i][PRACE_CP]++;
					SetPlayerCP(i, gRaceCheckpoints[gPlayerRace[i][PRACE_CP]][0], gRaceCheckpoints[gPlayerRace[i][PRACE_CP]][1], gRaceCheckpoints[gPlayerRace[i][PRACE_CP]][2], gRaceCheckpoints[gPlayerRace[i][PRACE_CP]][3]);
				}
			}
		}

		//Start the race countdown
		gRaces[race][RACE_COUNTDOWN] = 5;
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Race_Quit(playerid, text[]) {
	#pragma unused text
	new race = gPlayerRace[playerid][PRACE_ID], string[MAX_STRING];
	if(race==-1) {
		SendClientMessage(playerid, COLOUR_RED, "You are not in a race!");
	} else {
		format(string, MAX_STRING, "You have left race \"%s\" (id: %d).", gRaces[race][RACE_NAME], race);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
		format(string, MAX_STRING, "%s (id: %d) has quit race \"%s\".", gPlayerStats[playerid][STATS_NAME], playerid, gRaces[race][RACE_NAME]);
		for(new i=0; i<MAX_PLAYERS; i++) {
			if(i!=playerid && IsPlayerConnected(i) && gPlayerRace[i][PRACE_ID]==race) {
				if((gPlayerRace[playerid][PRACE_STARTTIME]==0 && gPlayerRace[i][PRACE_STARTTIME]==0) ||
				   (gPlayerRace[playerid][PRACE_STARTTIME]>0 && gPlayerRace[i][PRACE_STARTTIME]>0)) {
					SendClientMessage(i, COLOUR_YELLOW, string);
				}
			}
		}
		Race_Leave(playerid);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Race_Leave(playerid) {
	new race = gPlayerRace[playerid][PRACE_ID];
	if(race==-1) return;
	TogglePlayerControllable(playerid, 1);
	DisablePlayerCheckpoint(playerid);
	if(gPlayerRace[playerid][PRACE_STARTTIME]>0) gPlayerStats[playerid][STATS_RACE_DNF]++;
	gRaces[race][RACE_TOTALRACERS]--;
	if(gRaces[race][RACE_TOTALRACERS]==0) {
		gPlayerRace[playerid][PRACE_STARTTIME] = -1;
	}
	Race_ResetProgress(playerid);
}

//------------------------------------------------------------------------------------------------------

Race_Info(playerid, text[]) {
	if((!text[0] && gPlayerStats[playerid][STATS_AREA_PRIMARY]!=AREA_RACE) || (strlen(text)>0 && !IsNumeric(text))) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /race info [number]");
	} else {
		new race, string[MAX_STRING];
		if(!text[0]) {
			race = gPlayerStats[playerid][STATS_AREA_SECONDARY];
		} else {
			race = strval(text);
			if(race<0 || race>MAX_RACES) {
				format(string, MAX_STRING, "Invalid race number (%d)! Available range is 0 to %d.", race, MAX_RACES-1);
				SendClientMessage(playerid, COLOUR_RED, string);
				return 1;
			}
		}
		Race_ShowDetails(playerid, race);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Race_ShowDetails(playerid, race) {
	new race_type[MAX_STRING], race_vehicle[MAX_STRING], string[MAX_STRING];
	switch(gRaces[race][RACE_TYPE]) {
		case RACE_TYPE_CIRCUIT: format(race_type, MAX_STRING, "Circuit (laps: %d)", gRaces[race][RACE_REQLAPS]);
		case RACE_TYPE_SPRINT: race_type = "Sprint";
		default: race_type = "n/a";
	}
	if(gRaces[race][RACE_REQVEHICLE]!=-1) {
		format(race_vehicle, MAX_STRING, "%s", gVehicleInfo[gRaces[race][RACE_REQVEHICLE]-VEHICLE_MODEL_OFFSET][VEHICLEINFO_NAME]);
	} else if(gRaces[race][RACE_REQVEHICLETYPE]!=-1) {
		switch(gRaces[race][RACE_REQVEHICLETYPE]) {
			case VEHICLE_TYPE_BIKE: race_vehicle = "Any bike";
			case VEHICLE_TYPE_BICYCLE: race_vehicle = "Any bicycle";
			case VEHICLE_TYPE_BOAT: race_vehicle = "Any boat";
			case VEHICLE_TYPE_AMPHIBIOUS: race_vehicle = "Any amphibious vehicle";
			case VEHICLE_TYPE_CAR: race_vehicle = "Any car, bus or truck";
			case VEHICLE_TYPE_HELICOPTER: race_vehicle = "Any helicopter";
			case VEHICLE_TYPE_MONSTER: race_vehicle = "Any monster truck";
			case VEHICLE_TYPE_PLANE: race_vehicle = "Any plane";
			case VEHICLE_TYPE_QUADBIKE: race_vehicle = "Any quad bike";
			case VEHICLE_TYPE_TRAIN: race_vehicle = "Any train";
			case VEHICLE_CLASS_LAND: race_vehicle = "Any land-based vehicle";
			case VEHICLE_CLASS_WATER: race_vehicle = "Any water-based vehicle";
			case VEHICLE_CLASS_AIR: race_vehicle = "Any air-based vehicle";
			case VEHICLE_CLASS_FOOT: race_vehicle = "On foot";
			default: race_vehicle = "n/a";
		}
	} else {
		race_vehicle = "Any";
	}
	format(string, MAX_STRING, "Race \"%s\" (id: %d)  Type: %s", gRaces[race][RACE_NAME], race, race_type);
	if(gRaces[race][RACE_TOTALRACERS]>0) SendClientMessage(playerid, COLOUR_YELLOW, "Race is currently in progress.");
	SendClientMessage(playerid, COLOUR_GREEN, string);
	format(string, MAX_STRING, "Requirements... Entry Fee: $%d  Points: %d  Vehicle: %s", gRaces[race][RACE_REQCASH], gRaces[race][RACE_REQPOINTS], race_vehicle);
	format(string, MAX_STRING, "Maximum winnings... Cash: $%d  Points: %d", gRaces[race][RACE_CASH], gRaces[race][RACE_POINTS]);
	SendClientMessage(playerid, COLOUR_WHITE, string);
	format(string, MAX_STRING, "Record... %s", gRaces[race][RACE_FORMATTEDRECORD]);
	SendClientMessage(playerid, COLOUR_WHITE, string);
}

//------------------------------------------------------------------------------------------------------

Race_Members(playerid, text[]) {
	new race = gPlayerRace[playerid][PRACE_ID];
	if((!text[0] && race==-1) || (strlen(text)>0 && !IsNumeric(text))) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /race members [number]");
	} else {
		new string[MAX_STRING], x=0, racers=0;
		if(strlen(text)>0) {
			race = strval(text);
			if(race<0 || race>MAX_RACES) {
				format(string, MAX_STRING, "Invalid race number (%d)! Available range is 0 to %d.", race, MAX_RACES-1);
				SendClientMessage(playerid, COLOUR_RED, string);
				return 1;
			}
		}
		format(string, MAX_STRING, "Race \"%s\" (id: %d) Members...", gRaces[race][RACE_NAME], race);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		string[0] = 0;
		for(new i=0; i<MAX_PLAYERS; i++) {
			if(IsPlayerConnected(i) && gPlayerRace[i][PRACE_ID]==race) {
				racers = 1;
				format(string, MAX_STRING, "%s%s (id: %d)", string, gPlayerStats[i][STATS_NAME], i);
				if(gPlayerRace[i][PRACE_STARTTIME]>0) format(string, MAX_STRING, "%s - racing", string);
				else if(IsPlayerInCheckpoint(i)) format(string, MAX_STRING, "%s - at start line", string);
				x++;
				if(x>2) {
					SendClientMessage(playerid, COLOUR_YELLOW, string);
					x = 0;
					string[0] = 0;
				} else {
					format(string, MAX_STRING, "%s, ", string);
				}
			}
		}
		if(x>0 && x<=2) {
			string[strlen(string)-2] = '.';
			SendClientMessage(playerid, COLOUR_YELLOW, string);
		}
		if(!racers) SendClientMessage(playerid, COLOUR_YELLOW, "No active racers.");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Race_Rescue(playerid, text[]) {
	#pragma unused text
	new race = gPlayerRace[playerid][PRACE_ID], vehicle;
	if(race!=-1 && gPlayerRace[playerid][PRACE_STARTTIME]>0) {
		vehicle = GetPlayerVehicleID(playerid);
		if(vehicle>0) {
			SetVehicleZAngle(vehicle, 0.0);
			SetVehiclePos(vehicle, gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]-1][0], gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]-1][1], gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]-1][2]+5.0);
		} else {
			SetPlayerPos(playerid, gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]-1][0], gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]-1][1], gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]-1][2]);
		}
	} else {
		SendClientMessage(playerid, COLOUR_RED, "You must be racing to use this feature!");
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Race_ShowList(playerid, text[]) {
	new index = 0, page = strval(text), pages = (MAX_RACES+(MAX_CHATLINES-1))/MAX_CHATLINES, string[MAX_STRING], race_type[MAX_STRING], race_vehicle[MAX_STRING], money = GetPlayerMoney(playerid), Float:cp[3];
	if(page>1) index = (page-1)*(MAX_CHATLINES-1); else page = 1;
	if(page>pages) {
		format(string, MAX_STRING, "Invalid page number! Available page range is 1 to %d", pages);
		SendClientMessage(playerid, COLOUR_RED, string);
	} else {
		format(string, MAX_STRING, "Available Races (page %d of %d). Type /racelist [number] to view other pages.", page, pages);
		SendClientMessage(playerid, COLOUR_GREEN, string);
		for(new i=index; i<index+(MAX_CHATLINES-1); i++) {
			if(i<MAX_RACES) {
				switch(gRaces[i][RACE_TYPE]) {
					case RACE_TYPE_CIRCUIT: format(race_type, MAX_STRING, "Circuit (laps: %d)", gRaces[i][RACE_REQLAPS]);
					case RACE_TYPE_SPRINT: race_type = "Sprint";
					default: race_type = "n/a";
				}
				if(gRaces[i][RACE_REQVEHICLE]!=-1) {
					format(race_vehicle, MAX_STRING, "%s", gVehicleInfo[gRaces[i][RACE_REQVEHICLE]-VEHICLE_MODEL_OFFSET][VEHICLEINFO_NAME]);
				} else if(gRaces[i][RACE_REQVEHICLETYPE]!=-1) {
					switch(gRaces[i][RACE_REQVEHICLETYPE]) {
						case VEHICLE_TYPE_BIKE: race_vehicle = "Any bike";
						case VEHICLE_TYPE_BICYCLE: race_vehicle = "Any bicycle";
						case VEHICLE_TYPE_BOAT: race_vehicle = "Any boat";
						case VEHICLE_TYPE_AMPHIBIOUS: race_vehicle = "Any amphibious vehicle";
						case VEHICLE_TYPE_CAR: race_vehicle = "Any car, bus or truck";
						case VEHICLE_TYPE_HELICOPTER: race_vehicle = "Any helicopter";
						case VEHICLE_TYPE_MONSTER: race_vehicle = "Any monster truck";
						case VEHICLE_TYPE_PLANE: race_vehicle = "Any plane";
						case VEHICLE_TYPE_QUADBIKE: race_vehicle = "Any quad bike";
						case VEHICLE_TYPE_TRAIN: race_vehicle = "Any train";
						case VEHICLE_CLASS_LAND: race_vehicle = "Any land-based vehicle";
						case VEHICLE_CLASS_WATER: race_vehicle = "Any water-based vehicle";
						case VEHICLE_CLASS_AIR: race_vehicle = "Any air-based vehicle";
						case VEHICLE_CLASS_FOOT: race_vehicle = "On foot";
						default: race_vehicle = "n/a";
					}
				} else {
					race_vehicle = "Any";
				}

				cp[0] = gRaceCheckpoints[gRaces[i][RACE_CPSTART]][0];
				cp[1] = gRaceCheckpoints[gRaces[i][RACE_CPSTART]][1];
				cp[2] = gRaceCheckpoints[gRaces[i][RACE_CPSTART]][2];

				format(string, MAX_STRING, "%d. \"%s\" - %s  Location: %s  Vehicle: %s", i, gRaces[i][RACE_NAME], race_type, GetSAZone(cp), race_vehicle);
				if(money>=gRaces[i][RACE_REQCASH] && gPlayerStats[playerid][STATS_RACE_POINTS]>=gRaces[i][RACE_REQPOINTS]) SendClientMessage(playerid, COLOUR_YELLOW, string);
				else SendClientMessage(playerid, COLOUR_RED, string);
			}
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Race_EnterCheckpoint(playerid) {
	new race, vehicle, string[MAX_STRING];
	if(gPlayerStats[playerid][STATS_AREA_PRIMARY]==AREA_RACE) race = gPlayerStats[playerid][STATS_AREA_SECONDARY]; else race = gPlayerRace[playerid][PRACE_ID];
	vehicle = GetPlayerVehicleID(playerid);
	if(gPlayerRace[playerid][PRACE_CP]==gRaces[race][RACE_CPSTART] || gPlayerRace[playerid][PRACE_CP]==-1) {
		if(gPlayerRace[playerid][PRACE_CP]==-1) Race_ShowDetails(playerid, race);
		format(string, MAX_STRING, "~y~%s", gRaces[race][RACE_NAME]);
		ShowGameTextForPlayer(playerid, string, 3000, 1);
		string[0] = 0;
		if(GetPlayerMoney(playerid)<gRaces[race][RACE_REQCASH]) format(string, MAX_STRING, "%s", "money, ");
		if(gPlayerStats[playerid][STATS_RACE_POINTS]<gRaces[race][RACE_REQPOINTS]) format(string, MAX_STRING, "%srace points, ", string);
		if(!Race_VehicleCheck(playerid, race)) format(string, MAX_STRING, "%svehicle, ", string);
		if(!string[0]) {
			if(gPlayerRace[playerid][PRACE_CP]==-1) {
				SendClientMessage(playerid, COLOUR_YELLOW, "Type '/race join' to enter this race.");
			} else {
				SendClientMessage(playerid, COLOUR_YELLOW, "When all players are ready, you can start the race by using the command '/race start'. If you");
				SendClientMessage(playerid, COLOUR_YELLOW, "manage to get lost while racing type the command '/rescue' to warp back to your last checkpoint.");
				SendClientMessage(playerid, COLOUR_YELLOW, "To view racers in this race, type '/race members'. To quit the race, type '/race quit'.");
				// Show direction of next checkpoint
				if(gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]+1][1]+10.0>gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][1]) string = "North ";
				else if(gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]+1][1]-10.0>gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][1]) string = "South ";
				if(gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]+1][0]+10.0>gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][0]) format(string, MAX_STRING, "%sEast", string);
				else if(gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]+1][0]-10.0<gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][0]) format(string, MAX_STRING, "%sWest", string);
				format(string, MAX_STRING, "First race checkpoint is %s from your current location.", string);
				SendClientMessage(playerid, COLOUR_WHITE, string);
			}
		} else {
			SendClientMessage(playerid, COLOUR_RED, "You do not meet one or more of the race requirements!");
			string[strlen(string)-2] = '\0';
			format(string, MAX_STRING, "Failed requirement(s): %s", string);
			SendClientMessage(playerid, COLOUR_RED, string);
			SendClientMessage(playerid, COLOUR_YELLOW, "Type '/race info' to view the race requirements.");
		}
	} else if(!Race_VehicleCheck(playerid, race)) {
		return;
	} else {
		new timenow = GetTickCount();
		new hour, minute, second, ms;
		new shour[3], sminute[3], ssecond[3], sms[4];
		ms = timenow - gPlayerRace[playerid][PRACE_STARTTIME];
		hour = floatround(ms/3600000.0,floatround_tozero);
		ms -= 3600000*hour;
		minute = floatround(ms/60000.0,floatround_tozero);
		ms -= 60000*minute;
		second = floatround(ms/1000.0,floatround_tozero);
		ms -= 1000*second;

		if(hour<10) format(shour, 3, "0%d", hour); else format(shour, 3, "%d", hour);
		if(minute<10) format(sminute, 3, "0%d", minute); else format(sminute, 3, "%d", minute);
		if(second<10) format(ssecond, 3, "0%d", second); else format(ssecond, 3, "%d", second);
		if(ms<10) format(sms, 4, "00%d", ms); else if(ms<100) format(sms, 4, "0%d", ms); else format(sms, 4, "%d", ms);

		if(gRaces[race][RACE_TYPE]==RACE_TYPE_CIRCUIT && gPlayerRace[playerid][PRACE_CP]==gRaces[race][RACE_CPEND]) {
			// lap increase
			gPlayerRace[playerid][PRACE_LAPCOUNT]++;
			if(gPlayerRace[playerid][PRACE_LAPCOUNT]<=gRaces[race][RACE_REQLAPS]) {
				gPlayerRace[playerid][PRACE_CP] = gRaces[race][RACE_CPSTART]; // still racing
			}
		}

		if(gPlayerRace[playerid][PRACE_CP]==gRaces[race][RACE_CPEND]) {
			// end of race
			gRaces[race][RACE_COMPLETEDRACERS]++;

			new formattedtime[MAX_STRING];
			new numstr[][] = {"th","st","nd","rd"};
			new numstrpos = 1;
			new winnings = 0;
			new racepoints = 0;

			if(!(gRaces[race][RACE_COMPLETEDRACERS]%10>3)) numstrpos = gRaces[race][RACE_COMPLETEDRACERS]%10;
			if(gRaces[race][RACE_TOTALRACERS]-1>0) {
				format(string, MAX_STRING, "~w~%s ~y~has finished ~g~%d%s", gPlayerStats[playerid][STATS_NAME], gRaces[race][RACE_COMPLETEDRACERS], numstr[numstrpos]);
				for(new i=0; i<MAX_PLAYERS; i++) {
					if(i!=playerid && IsPlayerConnected(i) && gPlayerRace[i][PRACE_ID]==race && gPlayerRace[i][PRACE_STARTTIME]>0) {
						ShowGameTextForPlayer(i, string, 5000, 4);
					}
				}
			}

			if(gRaces[race][RACE_CASH]>0) {
				switch(gRaces[race][RACE_COMPLETEDRACERS]) {
					case 1: winnings = floatround(1.00*gRaces[race][RACE_CASH]);
					case 2: winnings = floatround(0.70*gRaces[race][RACE_CASH]);
					case 3: winnings = floatround(0.30*gRaces[race][RACE_CASH]);
				}
			}
			if(gRaces[race][RACE_POINTS]>0) {
				switch(gRaces[race][RACE_COMPLETEDRACERS]) {
					case 1: racepoints = floatround(1.00*gRaces[race][RACE_POINTS]);
					case 2: racepoints = floatround(0.70*gRaces[race][RACE_POINTS]);
					case 3: racepoints = floatround(0.30*gRaces[race][RACE_POINTS]);
				}
			}

			if(hour>1) format(formattedtime, MAX_STRING, "%d hrs, ", hour); else if(hour==1) format(formattedtime, MAX_STRING, "%d hr, ", hour); else formattedtime = "";
			if(minute>1) format(formattedtime, MAX_STRING, "%s%d mins, ", formattedtime, minute); else if(minute==1) format(formattedtime, MAX_STRING, "%s%d min, ", formattedtime, minute);
			if(second>1) format(formattedtime, MAX_STRING, "%s%d secs, ", formattedtime, second); else if(second==1) format(formattedtime, MAX_STRING, "%s%d sec, ", formattedtime, second);
			if(ms>1) format(formattedtime, MAX_STRING, "%s%d msecs, ", formattedtime, ms); else if(ms==1) format(formattedtime, MAX_STRING, "%s%d msec, ", formattedtime, ms);
			formattedtime[strlen(formattedtime)-2] = '\0';
			format(string, MAX_STRING, "~y~You have finished ~w~%d%s", gRaces[race][RACE_COMPLETEDRACERS], numstr[numstrpos]);
			if(Race_NewRecord(playerid, race, (timenow-gPlayerRace[playerid][PRACE_STARTTIME]), formattedtime, vehicle)) {
				format(string, MAX_STRING, "%s~n~~g~NEW RACE RECORD!", string);
				PlaySoundForPlayer(playerid, SOUND_MUSIC_RACERECORD);
			} else {
				PlaySoundForPlayer(playerid, SOUND_MUSIC_RACEFINISH);
			}
			ShowGameTextForPlayer(playerid, string, 5000, 4);
			format(string, MAX_STRING,"Your final race time was %s.", formattedtime);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
			format(string, MAX_STRING, "Your position (%d%s) has earnt you $%d and %d race points.", gRaces[race][RACE_COMPLETEDRACERS], numstr[numstrpos],winnings,racepoints);
			SendClientMessage(playerid, COLOUR_GREEN, string);
			GivePlayerPocketMoney(playerid, winnings);
			gPlayerStats[playerid][STATS_RACE_POINTS] += racepoints;
			if(gRaces[race][RACE_COMPLETEDRACERS]==1) gPlayerStats[playerid][STATS_RACE_WINS]++;
			gPlayerRace[playerid][PRACE_STARTTIME] = 0;
			Race_Leave(playerid);
			gPlayerStats[playerid][STATS_MUSIC_COUNT] = 10;
		} else {
			// race marker
			if(gRaces[race][RACE_TYPE]==RACE_TYPE_CIRCUIT) {
				if(gPlayerRace[playerid][PRACE_CP]==gRaces[race][RACE_CPSTART]) {
					format(string, MAX_STRING, "~g~Lap ~w~%d/%d", gPlayerRace[playerid][PRACE_LAPCOUNT], gRaces[race][RACE_REQLAPS]);
				} else {
					format(string, MAX_STRING, "~y~%s:%s.%s ~w~%.0f%%", sminute, ssecond, sms, (0.0+gPlayerRace[playerid][PRACE_CP]-gRaces[race][RACE_CPSTART]+(gPlayerRace[playerid][PRACE_LAPCOUNT]-1)*(gRaces[race][RACE_CPEND]-gRaces[race][RACE_CPSTART]))/((gRaces[race][RACE_CPEND]-gRaces[race][RACE_CPSTART])*gRaces[race][RACE_REQLAPS])*100);
				}
			} else {
				format(string, MAX_STRING,"~y~%s:%s.%s ~w~%.0f%%",sminute,ssecond,sms,(0.0+gPlayerRace[playerid][PRACE_CP]-gRaces[race][RACE_CPSTART])/(gRaces[race][RACE_CPEND]-gRaces[race][RACE_CPSTART])*100);
			}
			ShowGameTextForPlayer(playerid, string, 3000, gRaces[race][RACE_SPLITDISPLAY]);
			PlaySoundForPlayer(playerid, SOUND_CHECKPOINT);
			DisablePlayerCheckpoint(playerid);
			gPlayerRace[playerid][PRACE_CP]++;
			SetPlayerCP(playerid, gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][0], gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][1], gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][2],gRaceCheckpoints[gPlayerRace[playerid][PRACE_CP]][3]);
		}
	}
}

//------------------------------------------------------------------------------------------------------

Race_Update() {
	for(new i=0; i<MAX_RACES; i++) {
		if(gRaces[i][RACE_TOTALRACERS]>0) {
			if(gRaces[i][RACE_COUNTDOWN]>=0) Race_CountDown(i);
			else Race_Timeout(i);
		}
	}
}
			
//------------------------------------------------------------------------------------------------------

Race_CountDown(race) {
	new string[MAX_STRING];
	if(gRaces[race][RACE_COUNTDOWN]>0) {
		format(string, MAX_STRING, "~y~%d", gRaces[race][RACE_COUNTDOWN]);
	} else {
		string = "~g~GO!";
		gRaces[race][RACE_STARTTIME] = Time();
	}
	for(new i=0; i<MAX_PLAYERS; i++) {
		if(IsPlayerConnected(i) && gPlayerRace[i][PRACE_ID]==race && gPlayerRace[i][PRACE_STARTTIME]==0) {
			ShowGameTextForPlayer(i, string, 5000, 5);
			if(gRaces[race][RACE_COUNTDOWN]>0) {
				PlaySoundForPlayer(i, SOUND_BLIP1);
			} else {
				PlaySoundForPlayer(i, SOUND_BLIP2);
				TogglePlayerControllable(i, 1);
				gPlayerRace[i][PRACE_STARTTIME] = GetTickCount();
				if(gRaces[race][RACE_TYPE]==RACE_TYPE_CIRCUIT) {
					gPlayerRace[i][PRACE_LAPCOUNT]++;
					format(string, MAX_STRING, "~g~Lap ~w~%d/%d", gPlayerRace[i][PRACE_LAPCOUNT], gRaces[race][RACE_REQLAPS]);
					ShowGameTextForPlayer(i, string, 3000, gRaces[race][RACE_SPLITDISPLAY]);
				}
			}
		}
	}
	gRaces[race][RACE_COUNTDOWN]--;
}

//------------------------------------------------------------------------------------------------------

Race_Timeout(race) {
	if(Time()-gRaces[race][RACE_STARTTIME]>gRaces[race][RACE_TIMEOUT]) {
		for(new i=0; i<MAX_PLAYERS; i++) {
			if(gPlayerRace[i][PRACE_ID]==race && IsPlayerConnected(i)) {
				Race_Leave(i);
				ShowGameTextForPlayer(i, "~r~Race Timeout Reached!", 5000, 5);
				SendClientMessage(i, COLOUR_RED, "Race Timeout Reached!");
			}
		}
	}
}

//------------------------------------------------------------------------------------------------------

Race_NewRecord(playerid, race, record, formattedrecord[], vehicle) {
	if(gRaces[race][RACE_RECORD]<1 || record<gRaces[race][RACE_RECORD]) {
		if(udb_RaceExists(gRaces[race][RACE_NAME])) {
			if(!gPlayerStats[playerid][STATS_AUTHENTICATED]) {
				SendClientMessage(playerid, COLOUR_RED, "New record NOT saved as you have not /signin!");
			} else {
				if(vehicle>0) vehicle = gVehicles[vehicle-1][VEHICLE_MODEL];

				udb_setRacePlayer(gRaces[race][RACE_NAME], gPlayerStats[playerid][STATS_NAME]);
				udb_setRaceRecord(gRaces[race][RACE_NAME], record);
				udb_setRaceFormattedRecord(gRaces[race][RACE_NAME], formattedrecord);
				udb_setRaceVehicle(gRaces[race][RACE_NAME], vehicle);

				gRaces[race][RACE_RECORD] = record;
				format(gRaces[race][RACE_FORMATTEDRECORD], MAX_STRING, "%s by %s (%s)", formattedrecord, gPlayerStats[playerid][STATS_NAME], gVehicleInfo[vehicle-VEHICLE_MODEL_OFFSET][VEHICLEINFO_NAME]);

			}
		} else {
			SendClientMessage(playerid, COLOUR_RED, "New record NOT saved. There is a communication problem with the server.");
		}
		return 1;
	}
	return 0;
}

//------------------------------------------------------------------------------------------------------
// Anti cheat stuff
//------------------------------------------------------------------------------------------------------

AC_Reset(playerid) {
	gPlayerAC[playerid][AC_KICK] = false;
	gPlayerAC[playerid][AC_MONEY][0] = 0;
	gPlayerAC[playerid][AC_MONEY][1] = 0;
	gPlayerAC[playerid][AC_MONEY_GAMBLE][0] = 0;
	gPlayerAC[playerid][AC_MONEY_GAMBLE][1] = 0;
}

//------------------------------------------------------------------------------------------------------

AC_ResetGamble(playerid) {
	gPlayerAC[playerid][AC_MONEY_GAMBLE][0] = 0;
	gPlayerAC[playerid][AC_MONEY_GAMBLE][1] = 0;
}

//------------------------------------------------------------------------------------------------------

AC_MoneyUpdate(playerid) {
	new money = GetPlayerMoney(playerid);
	if(money>gPlayerStats[playerid][STATS_MONEY_POCKET]) {
		gPlayerAC[playerid][AC_MONEY][0]++;
		if(gPlayerAC[playerid][AC_MONEY][0]>3) {
			KickPlayer(playerid, KICK_CHEAT_MONEY);
		}
	} else {
		gPlayerAC[playerid][AC_MONEY][0] = 0;
		gPlayerAC[playerid][AC_MONEY][1]++;
		if(gPlayerAC[playerid][AC_MONEY][1]>3) {
			gPlayerAC[playerid][AC_MONEY] = 0;
			gPlayerStats[playerid][STATS_MONEY_POCKET] = money;
		}
	}
}

//------------------------------------------------------------------------------------------------------

AC_OnPlayerDeath(playerid, killerid, reason) {
	if(reason==WEAPON_FIST || reason==WEAPON_VEHICLE || reason==WEAPON_SELFKILL) return;
	if(gGMConfig[GMC_AC_SPOOFKILL] && GetDistanceBetweenPlayers(playerid, killerid)>200.0 && reason!=WEAPON_FLAMETHROWER) {
		KickPlayer(playerid, KICK_CHEAT_SPOOFKILL);
	} else {
		if(gGMConfig[GMC_AC_WEAPON]) {
			if(gPlayerDM[killerid][DM_ZONE]!=-1) {
				if(reason!=gDMArenas[gPlayerDM[killerid][DM_ZONE]][DM_WEAPON1][0] && reason!=gDMArenas[gPlayerDM[killerid][DM_ZONE]][DM_WEAPON2][0]) {
					KickPlayer(killerid, KICK_CHEAT_WEAPON_DM);
					gPlayerStats[killerid][STATS_KILLS_DM]--;  // penalise them
				}
			} else {
				new cheater = 1;
				for(new i=0; i<MAX_SPAWNWEAPONS; i++) {
					if(reason==gSpawnWeapons[i][SPAWNWEAPON_ID] && gPlayerSpawnWeapons[killerid][i]>0) {
						cheater = 0;
						break;
					}
				}
				for(new i=0; i<MAX_FREEROAMWEAPONS; i++) {
					if(reason==gFreeroamWeapons[i]) {
						cheater = 0;
						break;
					}
				}
				if(cheater) {
					KickPlayer(killerid, KICK_CHEAT_WEAPON_FREEROAM);
				}
			}
		}
		if(gGMConfig[GMC_AC_SPAWNKILL]) {
			new Float:pos[3], string[MAX_STRING];
			pos = Spawn_GetSpawnCoordinates(playerid);
			if(GetDistanceToPoint(playerid, pos)<gGMConfig[GMC_AC_SPAWNKILL_DIST]) {
				gPlayerStats[killerid][STATS_WARNINGS_SPAWNKILLS]++;
				if(gPlayerStats[killerid][STATS_WARNINGS_SPAWNKILLS]>gGMConfig[GMC_AC_SPAWNKILL_KILLS]) {
					KickPlayer(killerid, KICK_SPAWNKILL);
				} else {
					format(string, MAX_STRING, "~w~Do not spawn kill!~n~You have ~r~%d warnings~w~ remaining!", gGMConfig[GMC_AC_SPAWNKILL_KILLS]-gPlayerStats[killerid][STATS_WARNINGS_SPAWNKILLS]);
					ShowGameTextForPlayer(killerid, string, 5500, 3);
				}
			}
		}
	}
}

//------------------------------------------------------------------------------------------------------

AC_GambleUpdate(playerid) {
	if(gPlayerAC[playerid][AC_MONEY_GAMBLE][1]==-1) return;
	new admin = IsPlayerAdmin(playerid), money = GetPlayerMoney(playerid), cashdiff, timenow = Time(), timediff;
	if(money>gPlayerAC[playerid][AC_MONEY_GAMBLE][0] && (admin && !gGMConfig[GMC_AC_PROTECTADMINS]) || !admin) {
		// a bit of trial and error here...
		timediff = floatround((timenow-gPlayerAC[playerid][AC_MONEY_GAMBLE][1])/60.0);  // in minutes
		cashdiff = money-gPlayerAC[playerid][AC_MONEY_GAMBLE][0];
		if((timediff<1&&cashdiff>20000) || (timediff<5&&cashdiff>500000) || (timediff<30&&cashdiff>2500000) || cashdiff>5000000) {
			ShowGameTextForPlayer(playerid, "~r~[Anti-Cheat]~n~~w~Maximum gambling limit exceeded~n~~r~Automatic money adjustment applied~n~~g~Have a nice day", 5000, 4);
			SetPlayerMoney(playerid, gPlayerAC[playerid][AC_MONEY_GAMBLE][0]);  // sometimes you win, sometimes you lose. playerid loses
		} else {
			gPlayerStats[playerid][STATS_MONEY_POCKET] = money;
		}
	}
}

//------------------------------------------------------------------------------------------------------
// Admin features
//------------------------------------------------------------------------------------------------------

Admin_Action(playerid, text[]) {
	if(!IsPlayerAdmin(playerid)) {
		SendClientMessage(playerid, COLOUR_RED, "Nice try, your not an admin!");
		return 1;
	}
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /admin [action] where action is one of the following...");
		SendClientMessage(playerid, COLOUR_WHITE, "udbdelete udblock udbunlock udbpassword racekill toggle time");
		return 1;
	}
	dcmd2(udbdelete, 9, Admin_Reg_DeleteAcc);
	dcmd2(udblock, 7, Admin_Reg_LockAcc);
	dcmd2(udbunlock, 9, Admin_Reg_UnlockAcc);
	dcmd2(udbpassword, 11, Admin_Reg_PwdChange);
	dcmd2(racekill, 8, Admin_Race_Kill);
	dcmd2(toggle, 6, Admin_Config_Toggle);
	dcmd2(time, 4, Admin_Time_Action);
	return 0;
}

//------------------------------------------------------------------------------------------------------

Admin_Reg_DeleteAcc(playerid, text[]) {
	new player, playername[MAX_PLAYER_NAME], string[MAX_STRING];
	player = GetPlayerID(text);
	if(player==INVALID_PLAYER_ID) format(playername, MAX_PLAYER_NAME, "%s", text); else format(playername, MAX_PLAYER_NAME, "%s", gPlayerStats[player][STATS_NAME]);
	if(udb_Remove(playername)) {
		if(gPlayerStats[playerid][STATS_AUTHENTICATED]) gPlayerStats[playerid][STATS_AUTHENTICATED] = !gPlayerStats[playerid][STATS_AUTHENTICATED];
		format(string, MAX_STRING, "%s udb account deleted!", playername);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	} else {
		format(string, MAX_STRING, "%s udb account not deleted. Account does not exist or there is a server connection error.", playername);
		SendClientMessage(playerid, COLOUR_RED, string);
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Admin_Reg_PwdChange(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /admin udbpassword [playerid/name] [new password]");
	} else {
		new splayer[MAX_STRING], player, pwd[MAX_STRING], playername[MAX_PLAYER_NAME], string[MAX_STRING], idx;
		splayer = strtok(text,idx);
		pwd = strtok(text,idx);
		if(!splayer[0] || !pwd[0]) {
			SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /udbpassword [playerid/name] [password]");
		} else {
			player = GetPlayerID(splayer);
			if(player==INVALID_PLAYER_ID) format(playername, MAX_PLAYER_NAME, "%s", splayer); else format(playername, MAX_PLAYER_NAME, "%s", gPlayerStats[player][STATS_NAME]);
			if(udb_Exists(playername)) {
				if(udb_setPassword(playername,pwd)) {
					format(string, MAX_STRING, "Password for %s successfully changed to '%s'.", playername, pwd);
					SendClientMessage(playerid, COLOUR_YELLOW, string);
				} else {
					SendClientMessage(playerid, COLOUR_RED, "Connection with server error. Password not changed.");
				}
			} else {
				SendClientMessage(playerid, COLOUR_RED, "Player does not exist!");
			}
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Admin_Reg_LockAcc(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /admin udblock [playerid/name]");
	} else {
		new player = GetPlayerID(text), playername[MAX_PLAYER_NAME], string[MAX_STRING];
		if(player==INVALID_PLAYER_ID) format(playername, MAX_PLAYER_NAME, "%s", text); else format(playername, MAX_PLAYER_NAME, "%s", gPlayerStats[player][STATS_NAME]);
		if(udb_Exists(playername)) {
			if(udb_setAccState(playername,0)) {
				format(string, MAX_STRING, "%s udb account has been locked.", playername);
				SendClientMessage(playerid, COLOUR_YELLOW, string);
			} else {
				SendClientMessage(playerid, COLOUR_RED, "Connection with server error. Account state not changed.");
			}
		} else {
			SendClientMessage(playerid, COLOUR_RED, "Player does not exist!");
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Admin_Reg_UnlockAcc(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /admin udbunlock [playerid/name]");
	} else {
		new player = GetPlayerID(text), playername[MAX_PLAYER_NAME], string[MAX_STRING];
		if(player==INVALID_PLAYER_ID) format(playername, MAX_PLAYER_NAME, "%s", text); else format(playername, MAX_PLAYER_NAME, "%s", gPlayerStats[player][STATS_NAME]);
		if(udb_Exists(playername)) {
			if(udb_setAccState(playername,1)) {
				format(string, MAX_STRING, "%s udb account unlocked!", playername);
				SendClientMessage(playerid, COLOUR_YELLOW, string);
			} else {
				SendClientMessage(playerid, COLOUR_RED, "Connection with server error. Account state not changed.");
			}
		} else {
			SendClientMessage(playerid, COLOUR_RED, "Player does not exist!");
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Admin_Race_Kill(playerid, text[]) {
	if(!text[0] || !IsNumeric(text)) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /admin racekill [number]");
	} else {
		new race, string[MAX_STRING];
		race = strval(text);
		if(race<0 || race>MAX_RACES) {
			format(string, MAX_STRING, "Invalid race number (%d)! Available range is 0 to %d.", race, MAX_RACES-1);
			SendClientMessage(playerid, COLOUR_RED, string);
			return 1;
		}
		for(new i=0; i<MAX_PLAYERS; i++) {
			if(gPlayerRace[i][PRACE_ID]==race) {
				if(IsPlayerConnected(i)) SendClientMessage(i, COLOUR_RED, "Your race has been killed by an administrator.");
				Race_Leave(i);
			}
		}
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

Admin_Config_Toggle(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /admin toggle [action] where action is one of the following...");
		SendClientMessage(playerid, COLOUR_WHITE, "acprotectadmins acmoney acweapon acspoofkill acspawnkill pbtext wetext dmtext dmgroupgangs");
		SendClientMessage(playerid, COLOUR_WHITE, "dmstealth dmbankcash vehiclelock tax");
		return 1;
	}
	new string[MAX_STRING];
	if(equal(text,"acprotectadmins",true)) {
		gGMConfig[GMC_AC_PROTECTADMINS] = (gGMConfig[GMC_AC_PROTECTADMINS]) ? 0 : 1;
		format(string, MAX_STRING, "Anti-cheat protect admins: %s", (gGMConfig[GMC_AC_PROTECTADMINS]) ? "on" : "off");
	} else if(equal(text,"acmoney",true)) {
		gGMConfig[GMC_AC_MONEY] = (gGMConfig[GMC_AC_MONEY]) ? 0 : 1;
		format(string, MAX_STRING, "Anti-cheat detect money hax: %s", (gGMConfig[GMC_AC_MONEY]) ? "on" : "off");
	} else if(equal(text,"acweapon",true)) {
		gGMConfig[GMC_AC_WEAPON] = (gGMConfig[GMC_AC_WEAPON]) ? 0 : 1;
		format(string, MAX_STRING, "Anti-cheat detect weapon hax: %s", (gGMConfig[GMC_AC_WEAPON]) ? "on" : "off");
	} else if(equal(text,"acspoofkill",true)) {
		gGMConfig[GMC_AC_SPOOFKILL] = (gGMConfig[GMC_AC_SPOOFKILL]) ? 0 : 1;
		format(string, MAX_STRING, "Anti-cheat detect spoof kills: %s", (gGMConfig[GMC_AC_SPOOFKILL]) ? "on" : "off");
	} else if(equal(text,"acspawnkill",true)) {
		gGMConfig[GMC_AC_SPAWNKILL] = (gGMConfig[GMC_AC_SPAWNKILL]) ? 0 : 1;
		format(string, MAX_STRING, "Anti-cheat detect spawn kills: %s", (gGMConfig[GMC_AC_SPAWNKILL]) ? "on" : "off");
	} else if(equal(text,"pbtext",true)) {
		gGMConfig[GMC_PB_TEXT] = (gGMConfig[GMC_PB_TEXT]) ? 0 : 1;
		format(string, MAX_STRING, "Pit Boss on-screen text: %s", (gGMConfig[GMC_PB_TEXT]) ? "on" : "off");
	} else if(equal(text,"wetext",true)) {
		gGMConfig[GMC_WE_TEXT] = (gGMConfig[GMC_WE_TEXT]) ? 0 : 1;
		format(string, MAX_STRING, "Wang Exports chat text: %s", (gGMConfig[GMC_WE_TEXT]) ? "on" : "off");
	} else if(equal(text,"dmtext",true)) {
		gGMConfig[GMC_DM_TEXT] = (gGMConfig[GMC_DM_TEXT]) ? 0 : 1;
		format(string, MAX_STRING, "Deathmatch player enter chat text: %s", (gGMConfig[GMC_DM_TEXT]) ? "on" : "off");
	} else if(equal(text,"dmbankcash",true)) {
		gGMConfig[GMC_DM_BANK] = (gGMConfig[GMC_DM_BANK]) ? 0 : 1;
		format(string, MAX_STRING, "Deathmatch player enter bank cash: %s", (gGMConfig[GMC_DM_BANK]) ? "on" : "off");
	} else if(equal(text,"dmgroupgangs",true)) {
		gGMConfig[GMC_DM_GROUPGANGS] = (gGMConfig[GMC_DM_GROUPGANGS]) ? 0 : 1;
		format(string, MAX_STRING, "Deathmatch group gang spawns: %s", (gGMConfig[GMC_DM_GROUPGANGS]) ? "on" : "off");
	} else if(equal(text,"dmstealth",true)) {
		gGMConfig[GMC_DM_STEALTH] = (gGMConfig[GMC_DM_STEALTH]) ? 0 : 1;
		format(string, MAX_STRING, "Deathmatch stealth player tags: %s", (gGMConfig[GMC_DM_STEALTH]) ? "on" : "off");
	} else if(equal(text,"vehiclelock",true)) {
		gGMConfig[GMC_VEHICLELOCK] = (gGMConfig[GMC_VEHICLELOCK]) ? 0 : 1;
		format(string, MAX_STRING, "Vehicles lockable: %s", (gGMConfig[GMC_VEHICLELOCK]) ? "on" : "off");
	} else if(equal(text,"tax",true)) {
		gGMConfig[GMC_TAX] = (gGMConfig[GMC_TAX]) ? 0 : 1;
		format(string, MAX_STRING, "Game tax: %s", (gGMConfig[GMC_TAX]) ? "on" : "off");
	}
	if(!string[0]) {
		format(string, MAX_STRING, "Unknown command (%s).", text);
	}
	SendClientMessage(playerid, COLOUR_YELLOW, string);
	return 1;
}

//------------------------------------------------------------------------------------------------------

Admin_Time_Action(playerid, text[]) {
	if(!text[0]) {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /admin time [set/get] [number]");
		return 1;
	}
	new action[MAX_STRING], idx, ntime, string[MAX_STRING];
	action = strtok(text,idx);
	if(equal(action,"set",true)) {
		ntime = strval(strtok(text,idx));
		if(ntime<0 || ntime>23) {
			SendClientMessage(playerid, COLOUR_RED, "Invalid number! Range is 0 to 23.");
		} else {
			SetWorldTime(ntime);
			gWorldTime = ntime;
			if(gWorldTime>9) format(string, MAX_STRING, "Game time changed to %d:00 (24hr time)", gWorldTime);
			else format(string, MAX_STRING, "Game time changed to 0%d:00 (24hr time)", gWorldTime);
			SendClientMessage(playerid, COLOUR_YELLOW, string);
		}
	} else if(equal(action,"get",true)) {
		if(gWorldTime>9) format(string, MAX_STRING, "Current game time is %d:00 (24hr time)", gWorldTime);
		else format(string, MAX_STRING, "Current game time is 0%d:00 (24hr time)", gWorldTime);
		SendClientMessage(playerid, COLOUR_YELLOW, string);
	} else {
		SendClientMessage(playerid, COLOUR_WHITE, "USAGE: /admin time [set/get] [number]");
	}
	return 1;
}

//******************************************************************************************************
// Misc functions...
//******************************************************************************************************

public Timer_GM_OneSecond() {
	new admin, timenow=Time();
	gOneSecondCount++, gOneSecondCount%=60;
	for(new i=0; i<MAX_PLAYERS; i++) {
		if(IsPlayerConnected(i)) {
			Speedo_Update(i);
			Freeroam_PlayerAreaUpdate(i);
			Freeroam_ScoreUpdate(i);
			MusicOffUpdate(i);
			KickPlayerUpdate(i, timenow);

			if(gOneSecondCount==0) {     Freeroam_MoneyArea_PirateShip(i); Patrol_Update(i); }
			if(gOneSecondCount==17)      PitBoss_TransportUpdate(i);
			if(gOneSecondCount==33)      PitBoss_GambleUpdate(i);
			if(gOneSecondCount==43)      Business_ScoreUpdate(i);
			if(!(gOneSecondCount%2))     Freeroam_MoneyArea_PirateShip(i);
			if(!(gOneSecondCount%4))     Patrol_Update(i);
			if(!(gOneSecondCount%20)) {  DMA_Update(i); Taxi_Update(i); }
			if(gOneSecondCount==13 && (gWorldTime==1 || gWorldTime==13))  Property_ScoreUpdate(i);
			if(gOneSecondCount==27 && !gWorldTime)  Freeroam_TaxUpdate(i);
			if(gOneSecondCount==57 && !(gOneMinuteCount%gGMConfig[GMC_STAT_SAVEINT])) { Stats_Save(i); Pref_Save(i); }

			if(!(gOneSecondCount%5)) { 
				admin = IsPlayerAdmin(i);
				if((admin && !gGMConfig[GMC_AC_PROTECTADMINS]) || !admin)  {
					if(gGMConfig[GMC_AC_MONEY])  AC_MoneyUpdate(i);
				}
			}
		}
	}
	Race_Update();
	if(gOneSecondCount==3) {
		Time_Update();
		if(!(gWorldTime%6)) WangExport_Update();
	}
	if(gOneSecondCount==0) {
		gOneMinuteCount++, gOneMinuteCount%=60;
		if(gGMConfig[GMC_VEHICLELOCK] && gOneMinuteCount==gGMConfig[GMC_VEHICLELOCK_AUTOUNLOCK]) vehicle_AutoUnlock();
	}
}

//------------------------------------------------------------------------------------------------------

Speedo_Update(playerid) {
	if(gPlayerPref[playerid][PREF_SPEEDO_DELAY]>0) {
		gPlayerPref[playerid][PREF_SPEEDO_DELAY] -= 1000;
	} else if(gPlayerPref[playerid][PREF_SPEEDO] && IsPlayerInAnyVehicle(playerid)) {
		new Float:pos[3], string[16];
		pos[0] = gPlayerStats[playerid][STATS_POSITION][0];
		pos[1] = gPlayerStats[playerid][STATS_POSITION][1];
		pos[2] = gPlayerStats[playerid][STATS_POSITION][2];
		if(gPlayerPref[playerid][PREF_METRIC]==0) {
			format(string, 16, "~y~%.0f ~w~KM/H", GetDistanceToPoint(playerid, pos)*3600/1000);
		} else {
			format(string, 16, "~y~%.0f ~w~MP/H", GetDistanceToPoint(playerid, pos)*3600/1610);
		}
		GameTextForPlayer(playerid, "\n", 1, 4);
		GameTextForPlayer(playerid, string, 1200, 4);
	}
}

//------------------------------------------------------------------------------------------------------

Time_Update() {
	gWorldTime++, gWorldTime%=24;
	SetWorldTime(gWorldTime);
}

//------------------------------------------------------------------------------------------------------

SetPlayerPocketMoney(playerid, money) {
	gPlayerStats[playerid][STATS_MONEY_POCKET] = money;
	GivePlayerMoney(playerid, money-GetPlayerMoney(playerid));
}

//------------------------------------------------------------------------------------------------------

GivePlayerPocketMoney(playerid, money) {
	SetPlayerPocketMoney(playerid, money+gPlayerStats[playerid][STATS_MONEY_POCKET]);
}

//------------------------------------------------------------------------------------------------------

KickPlayer(playerid, reason) {
	new string[MAX_STRING];
	switch(reason) {
		case KICK_CHEAT_MONEY: string = "suspected money cheat";
		case KICK_CHEAT_MONEY_GAMBLING: string = "suspected gambling cheat";
		case KICK_CHEAT_WEAPON_FREEROAM: string = "weapon cheat";
		case KICK_CHEAT_WEAPON_DM: string = "invalid deathmatch weapon";
		case KICK_CHEAT_SPOOFKILL: string = "spoof killing";
		case KICK_SPAWNKILL: string = "spawn killing";
		case KICK_SIGNINERROR: string = "forgot to sign in";
		default: string = "no real reason";
	}
	format(gPlayerAC[playerid][AC_KICK_MSG], MAX_STRING, "*** %s (id: %d) has been kicked (%s). ***", gPlayerStats[playerid][STATS_NAME], playerid, string);
	if(IsPlayerConnected(playerid)) {
		format(string, MAX_STRING, "~r~[Anti-Cheat]~n~~w~You have been kicked~n~~r~(%s)~n~~g~Have a nice day", string);
		ShowGameTextForPlayer(playerid, string, 5000, 4);
	}
	gPlayerAC[playerid][AC_KICK_TIME] = Time();
	gPlayerAC[playerid][AC_KICK] = true;
}

//------------------------------------------------------------------------------------------------------

KickPlayerUpdate(playerid, timenow) {
	if(gPlayerAC[playerid][AC_KICK] && timenow-gPlayerAC[playerid][AC_KICK_TIME]>=5) {
		if(IsPlayerConnected(playerid)) {
			SendClientMessageToAll(COLOUR_RED, gPlayerAC[playerid][AC_KICK_MSG]);
			Kick(playerid);
		}
		AC_Reset(playerid);
	}
}

//------------------------------------------------------------------------------------------------------

ShowGameTextForPlayer(playerid, msg[], time, type) {
	gPlayerPref[playerid][PREF_SPEEDO_DELAY] = time+200;
	GameTextForPlayer(playerid, msg, time, type);
}

//------------------------------------------------------------------------------------------------------

ShowGameTextForAll(msg[], time, type) {
	for(new i=0; i<MAX_PLAYERS; i++) {
		if(IsPlayerConnected(i)) gPlayerPref[i][PREF_SPEEDO_DELAY] = time+200;
	}
	GameTextForAll(msg, time, type);
}

//------------------------------------------------------------------------------------------------------

Float:GetDistanceBetweenPlayers(player1, player2) {
	if(IsPlayerConnected(player1) && IsPlayerConnected(player2) && player1!=player2) {
		new Float:pos1[3], Float:pos2[3];
		GetPlayerPos(player1,pos1[0],pos1[1],pos1[2]);
		GetPlayerPos(player2,pos2[0],pos2[1],pos2[2]);
		return GetDistanceBetweenPoints(pos1, pos2);
	}
	return MAX_WORLDBOUNDS*2.0;
}

//------------------------------------------------------------------------------------------------------

Float:GetDistanceToPoint(playerid, Float:data[3]) {
	if(IsPlayerConnected(playerid)) {
		new Float:pos[3];
		GetPlayerPos(playerid, pos[0], pos[1], pos[2]);
		return GetDistanceBetweenPoints(pos, data);
	}
	return MAX_WORLDBOUNDS*2.0;
}

//------------------------------------------------------------------------------------------------------
/* NOT USED
NearestPlayerID(playerid) {
	new Float:distance = MAX_WORLDBOUNDS*2.0, Float:tmp;
	new player = INVALID_PLAYER_ID;
	for(new i=0; i<MAX_PLAYERS; i++) {
		if(IsPlayerConnected(i) && i!=playerid) {
			tmp = GetDistanceBetweenPlayers(playerid,i);
			if(tmp<distance) {
				distance=tmp;
				player = i;
			}
		}
	}
	return player;
}
*/

//------------------------------------------------------------------------------------------------------

Float:GetDistanceBetweenPoints(Float:pos1[3], Float:pos2[3]) {
	return floatsqroot(floatpower(floatabs(floatsub(pos2[0],pos1[0])),2)+floatpower(floatabs(floatsub(pos2[1],pos1[1])),2)+floatpower(floatabs(floatsub(pos2[2],pos1[2])),2));
}

//------------------------------------------------------------------------------------------------------

PlaySoundForPlayer(playerid, sound) {
	new Float:pos[3];
	GetPlayerPos(playerid,pos[0],pos[1],pos[2]);
	PlayerPlaySound(playerid, sound, pos[0], pos[1], pos[2]);
}

//------------------------------------------------------------------------------------------------------

SetPlayerCP(playerid, Float:x, Float:y, Float:z, Float:size) {
	DisablePlayerCheckpoint(playerid);
	SetPlayerCheckpoint(playerid, 0.0, 0.0, 0.0, size);
	DisablePlayerCheckpoint(playerid);
	SetPlayerCheckpoint(playerid, x, y, z, size);
}

//------------------------------------------------------------------------------------------------------

GetSAZone(Float:pos[3]) {
	new zone[MAX_STRING];
	zone = "San Andreas";
	for(new i=0; i<sizeof(gSAZones); i++) {
		if(pos[0]>=gSAZones[i][SAZONE_AREA][0] && pos[0]<=gSAZones[i][SAZONE_AREA][3] && pos[1]>=gSAZones[i][SAZONE_AREA][1] && pos[1]<=gSAZones[i][SAZONE_AREA][4] && pos[2]>=gSAZones[i][SAZONE_AREA][2] && pos[2]<=gSAZones[i][SAZONE_AREA][5]) {
			format(zone, MAX_STRING, "%s", gSAZones[i][SAZONE_NAME]);
			break;
		}
	}
	return zone;
}

//------------------------------------------------------------------------------------------------------

GetPlayerID(string[]) {
	if(IsNumeric(string)) {
		new player = strval(string);
		if(IsPlayerConnected(player)) return player;
	} else {
		for(new i=0; i<MAX_PLAYERS; i++) {
			if(IsPlayerConnected(i)) {
				if(equal(string, gPlayerStats[i][STATS_NAME], true)) return i;
			}
		}
	}
	return INVALID_PLAYER_ID;
}

//------------------------------------------------------------------------------------------------------

IsNumeric(string[]) {
	if((string[0]>'9' || string[0]<'0') && (string[0]!='-')) return 0;
	for(new i=1, j=strlen(string); i<j; i++) {
		if(string[i]>'9' || string[i]<'0') return 0;
	}
	return 1;
}

//------------------------------------------------------------------------------------------------------

IsPlayerIn2DArea(playerid, Float:data[4]) {
	new Float:pos[3];
	GetPlayerPos(playerid, pos[0], pos[1], pos[2]);
	if(pos[0] >= data[0] && pos[0] <= data[2] && pos[1] >= data[1] && pos[1] <= data[3]) return 1;
	return 0;
}

//------------------------------------------------------------------------------------------------------
/* NOT USED
IsPlayerIn3DArea(playerid, Float:data[6]) {
	new Float:pos[3];
	GetPlayerPos(playerid, pos[0], pos[1], pos[2]);
	if(pos[0] >= data[0] && pos[0] <= data[3] && pos[1] >= data[1] && pos[1] <= data[4] && pos[2] >= data[2] && pos[2] <= data[5]) return 1;
	return 0;
}
*/
//------------------------------------------------------------------------------------------------------

MusicOffUpdate(playerid) {
	if(gPlayerStats[playerid][STATS_MUSIC_COUNT]>=0) gPlayerStats[playerid][STATS_MUSIC_COUNT]--;
	if(gPlayerStats[playerid][STATS_MUSIC_COUNT]==0) {
		PlaySoundForPlayer(playerid, SOUND_OFF);
		PlaySoundForPlayer(playerid, SOUND_EXPLOSION);
	}
}

//------------------------------------------------------------------------------------------------------

ClearScreen(playerid, text[]) {
	#pragma unused text
	for(new i=0; i<10; i++) SendClientMessage(playerid, COLOUR_WHITE, "\n");
	return 1;
}

//------------------------------------------------------------------------------------------------------

IsVehicleDriver(vehicleid) {
	for(new i=0; i<MAX_PLAYERS; i++) {
		if(IsPlayerConnected(i)) {
			if(GetPlayerVehicleID(i)==vehicleid && GetPlayerState(i)==PLAYER_STATE_DRIVER) {
				return 1;
			}
		}
	}
	return 0;
}

//------------------------------------------------------------------------------------------------------

SetPlayerColourAlpha(playerid, alpha) {
	new r, g, b, a;
	HexToRGBA(GetPlayerColor(playerid), r, g, b, a);
	SetPlayerColor(playerid, RGBAToHex(r, g, b, alpha));
}

//------------------------------------------------------------------------------------------------------

RGBAToHex(r, g, b, a) {
	return (r<<24 | g<<16 | b<<8 | a);
}

//------------------------------------------------------------------------------------------------------

HexToRGBA(colour, &r, &g, &b, &a) {
	r = (colour >> 24) & 0xFF;
	g = (colour >> 16) & 0xFF;
	b = (colour >> 8) & 0xFF;
	a = colour & 0xFF;
}

//EOF