/*
					-----------------------------------------------------
					|///////////////////////////////////////////////////|
					|///////////////////////////////////////////////////|
					|////                                           ////|
					|////          tAxI's ADVANCED HOUSING          ////|
                    |////                  SYSTEM                   ////|
					|////                                           ////|
					|////     COPYRIGHT: RELEASED UNDER the GNU     ////|
					|////                 LICENCE                   ////|
					|////                                           ////|
					|///////////////////////////////////////////////////|
					|///////////////////////////////////////////////////|
                    -----------------------------------------------------


    tAxI's Advanced House system - INC Package for SA-MP Multiplayer Modification
    of Grand Theft Auto - San Andreas.

    Copyright (C) 2008  Chris Johnstone (tAxI/Necrioss)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.

	-=============================================================================================-
	|=============================================================================================|
	|-----------------------------------------DESCRIPTION-----------------------------------------|
	|=============================================================================================|
	|THIS SYSTEM WILL ADD A HOUSING SYSTEM SIMILAR TO THAT OF PEN1 ONTO ANY SA-MP SERVER. IT      |
	|FEATURES HOUSE VEHICLES WITH PERMANENT MODSAVING, PERMANENT BUYING AND                       |
	|SELLING OF HOUSES, UP TO 250 HOUSES PER SERVER, HOUSE INTERIORS WITH INTERIOR SHARING VIA THE|
	|WORLD ID MANAGEMENT SYSTEM INCORPORATED, HOUSE LOCKING ETC, THINK OF IT AS PEN1 ONLY BETTER  |
 	|=============================================================================================|
	|NOTES:                                                                                       |
	|=============================================================================================|
	|THIS SYSTEM REQUIRES A SETUP FILE TO BE ENCORPORATED INTO YOUR SCRIPTFILES WITH APPROPRIATE  |
	|HOUSING INFORMATION CONTAINED WITHIN IT - WITHOUT THIS FILE THE SYSTEM WILL AUTOMATICALLY    |
	|THE LOADING PROCESS TO PREVENT GAMEMODE CRASHES. SEE THE README FILE INCLUDED IN THE DOWNLOAD|
	|FOR DETAILS ON HOW TO SET UP THIS FILE CORRECTLY WITH ALL OF THE APPROPRIATE INFORMATION     |
	|                                                                                             |
	|IT IS WORTH NOTING THAT THIS SYSTEM USES A STREAMER TO MANAGE EACH PLAYER'S INDIVIDUAL MAP   |
	|ICON USAGE AND ALLOWS UP TO 250 HOUSES TO BE INSTALLED ONTO THE CURRENT SYSTEM. EACH HOUSE IS|
	|REPRESENTED ON THE MINIMAP BY A GREEN HOUSE SYMBOL IF IT IS UNSOLD OR A RED HOUSE SYMBOL IF  |
	|IT IS SOLD                                                                                   |
	|=============================================================================================|
	|NATIVE AND AVAILLABLE COMMAND FUNCTIONS:                                                     |
	|=============================================================================================|
	|native tAxI_OnGameModeInit()                                                                 |
	|native tAxI_OnGameModeExit()                                                                 |
	|native tAxI_OnPlayerPickupPickup(playerid,pickupid)                                          |
	|native tAxI_OnPlayerDisconnect(playerid)                                                     |
	|native tAxI_OnPlayerConnect(playerid)                                                        |
	|native tAxI_OnPlayerEnterVehicle(playerid,vehicleid)                                         |
	|native tAxI_OnPlayerStateChange(playerid,newstate)                                           |
	|native tAxI_OnPlayerPickupPickup(playerid,pickupid)                                          |
	|native tAxI_OnVehicleDeath(vehicleid)                                                        |
	|native tAxI_OnVehicleMod(vehicleid,componentid)                                              |
	|native tAxI_OnVehiclePaintjob(vehicleid,paintjobid)                                          |
	|native tAxI_OnVehicleRespray(vehicleid,color1,color2)                                        |
	|native tAxI_OnPlayerSpawn(playerid)                                                          |
	|native LogPlayerIntoHouseSystem(playerid)                                                    |
	|native SetSpawnAtHouse(bool:toggle)                                                          |
	|=============================================================================================|
	-=============================================================================================-
	
*/

//=================SYSTEM REQUIRED INCLUDES===================//

#include <dudb>

//=================SYSTEM REQUIRED DEFINES===================//

#define DEFAULT_HOUSE_OWNER "[null]"
#define HOUSE_FILE "tAxI_houses.cfg"
#define PLAYER_FILE_TEMPLATE "%d.tpf"
#define MAX_HOUSE_VARIABLES 42
#define MAX_HOUSES 250
#define MAX_ACTIVE_ICONS 32
#define MAX_SECTORS 256
#define MAX_SECTOR_HOUSES 200
#define HOUSE_SOLD_ICON 32
#define HOUSE_UNSOLD_ICON 31
#define HOUSE_ICON_TYPE 2
#define HOUSE_PICKUP 1274
#define RED 0xFF0000AA
#define BLUE 0x0000BBAA
#define GREEN 0x0AFF0AAA

//===============SYSTEM VARIABLES **DO NOT TOUCH!!!!**==========================//

new spoiler[20][0] = {
	{1000},
	{1001},
	{1002},
	{1003},
	{1014},
	{1015},
	{1016},
	{1023},
	{1058},
	{1060},
	{1049},
	{1050},
	{1138},
	{1139},
	{1146},
	{1147},
	{1158},
	{1162},
	{1163},
	{1164}
};

new nitro[3][0] = {
    {1008},
    {1009},
    {1010}
};

new fbumper[23][0] = {
    {1117},
    {1152},
    {1153},
    {1155},
    {1157},
    {1160},
    {1165},
    {1167},
    {1169},
    {1170},
    {1171},
    {1172},
    {1173},
    {1174},
    {1175},
    {1179},
    {1181},
    {1182},
    {1185},
    {1188},
    {1189},
    {1192},
    {1193}
};

new rbumper[22][0] = {
    {1140},
    {1141},
    {1148},
    {1149},
    {1150},
    {1151},
    {1154},
    {1156},
    {1159},
    {1161},
    {1166},
    {1168},
    {1176},
    {1177},
    {1178},
    {1180},
    {1183},
    {1184},
    {1186},
    {1187},
    {1190},
    {1191}
};

new exhaust[28][0] = {
    {1018},
    {1019},
    {1020},
    {1021},
    {1022},
    {1028},
    {1029},
    {1037},
    {1043},
    {1044},
    {1045},
    {1046},
    {1059},
    {1064},
    {1065},
    {1066},
    {1089},
    {1092},
    {1104},
    {1105},
    {1113},
    {1114},
    {1126},
    {1127},
    {1129},
    {1132},
    {1135},
    {1136}
};

new bventr[2][0] = {
    {1042},
    {1044}
};

new bventl[2][0] = {
    {1043},
    {1045}
};

new bscoop[4][0] = {
	{1004},
	{1005},
	{1011},
	{1012}
};

new rscoop[13][0] = {
    {1006},
    {1032},
    {1033},
    {1035},
    {1038},
    {1053},
    {1054},
    {1055},
    {1061},
    {1067},
    {1068},
    {1088},
    {1091}
};

new lskirt[21][0] = {
    {1007},
    {1026},
    {1031},
    {1036},
    {1039},
    {1042},
    {1047},
    {1048},
    {1056},
    {1057},
    {1069},
    {1070},
    {1090},
    {1093},
    {1106},
    {1108},
    {1118},
    {1119},
    {1133},
    {1122},
    {1134}
};

new rskirt[21][0] = {
    {1017},
    {1027},
    {1030},
    {1040},
    {1041},
    {1051},
    {1052},
    {1062},
    {1063},
    {1071},
    {1072},
    {1094},
    {1095},
    {1099},
    {1101},
    {1102},
    {1107},
    {1120},
    {1121},
    {1124},
    {1137}
};

new hydraulics[1][0] = {
    {1087}
};

new bass[1][0] = {
    {1086}
};

new rbbars[2][0] = {
    {1109},
    {1110}
};

new fbbars[2][0] = {
    {1115},
    {1116}
};

new wheels[17][0] = {
    {1025},
    {1073},
    {1074},
    {1075},
    {1076},
    {1077},
    {1078},
    {1079},
    {1080},
    {1081},
    {1082},
    {1083},
    {1084},
    {1085},
    {1096},
    {1097},
    {1098}
};

new lights[2][0] = {
	{1013},
	{1024}
};
new bool:allowhousespawn;
new housecount = 0;
new streamcount[MAX_PLAYERS];
new MMactive[MAX_PLAYERS][MAX_HOUSES]
new SectorHouses[MAX_SECTORS][MAX_SECTOR_HOUSES];
new SectorHouseCount[MAX_SECTORS];
new vSecActive[MAX_SECTORS];
new SystemSafe = 0;
new lastd[700];

enum pInfo
{
	name[256];
	howner,
	howned,
	logged,
	lastv,
}
new PlInfo[MAX_PLAYERS][pInfo];

enum hInfo
{
	//======Core House Variables======//
    hcost,
	howned,
	password[256],
	description[256],
  	howner[256],
	Float:x_ent,
	Float:y_ent,
	Float:z_ent,
	Float:x_int,
	Float:y_int,
	Float:z_int,
	intworldid,
 	intid,
	mmid,
	puid,
	hsecure,
	hsafe,
	//======House Car Variables======//
	Float:vposx,
	Float:vposy,
	Float:vposz,
	Float:vposza,
	vid,
	vmodel,
	vsecure,
	//======House Car Mod Information======//
	vmod1,
	vmod2,
	vmod3,
	vmod4,
	vmod5,
	vmod6,
	vmod7,
	vmod8,
	vmod9,
	vmod10,
	vmod11,
	vmod12,
	vmod13,
	vmod14,
	vmod15,
	vmod16,
	vmod17,
	vcolor_1,
	vcolor_2,
	vpaintjob,
};
new HouseVar[MAX_HOUSES][hInfo];

//========SYSTEM FORWARDS========//

forward SectorScan();
forward ModVehicle(vehicleid);
forward SpawnPlayerAtHouse(playerid);
forward BackupFiles();
forward SafeRespawnHouseVehicle(Houseid);

//============SYSTEM CORE PROCESSES ** NO FIDDLING WITH THESE!!! **==========//

stock CountHouses() {
    new File:HouseFile;
    new blank[256];
    new count = 0;
    if (fexist(HOUSE_FILE)) {
        HouseFile = fopen(HOUSE_FILE);
        while(fread(HouseFile, blank, sizeof blank)) {
            count++;
        }
        fclose(HouseFile);
    }
    return count;
}

stock String_Split(const strsrc[], strdest[][], delimiter)
{
	new i, li;
	new aNum;
	new len;
	while(i <= strlen(strsrc)){
	    if(strsrc[i]==delimiter || i==strlen(strsrc)){
	        len = strmid(strdest[aNum], strsrc, li, i, 128);
	        strdest[aNum][len] = 0;
	        li = i+1;
	        aNum++;
		}
		i++;
	}
	return 1;
}

stock GetPlayerSector(playerid)
{
	new Float:pos[3];
	if(IsPlayerConnected(playerid)) {
		GetPlayerPos(playerid,pos[0],pos[1],pos[2]);
		new xsec = floatround(((pos[0] +4000) / 500), floatround_floor);
		new ysec = floatround(((pos[1] +4000) / 500), floatround_floor);
		return (xsec * 16) + ysec;
	}
	return 999;
}

public SectorScan()
{
    new psec[MAX_PLAYERS];
    for(new i = 0;i<MAX_SECTORS;i++) {
		vSecActive[i] = 0;
	}
    for(new i = 0;i<MAX_PLAYERS;i++) {
        if(IsPlayerConnected(i)) {
			psec[i] = GetPlayerSector(i);
   			if(vSecActive[psec[i]] == 0) {
			    vSecActive[psec[i]] = 1;
			}
			if(vSecActive[psec[i]+1] == 0) {
	    		vSecActive[psec[i]+1] = 1;
			}
			if(vSecActive[psec[i]-1] == 0) {
			    vSecActive[psec[i]-1] = 1;
			}
			if(vSecActive[psec[i]-15] == 0) {
			    vSecActive[psec[i]-15] = 1;
			}
			if(vSecActive[psec[i]-16] == 0) {
			    vSecActive[psec[i]-16] = 1;
			}
			if(vSecActive[psec[i]-17] == 0) {
	    		vSecActive[psec[i]-17] = 1;
			}
			if(vSecActive[psec[i]+15] == 0) {
			    vSecActive[psec[i]+15] = 1;
			}
			if(vSecActive[psec[i]+16] == 0) {
			    vSecActive[psec[i]+16] = 1;
			}
			if(vSecActive[psec[i]+17] == 0) {
			    vSecActive[psec[i]+17] = 1;
			}
    		StreamProcess(i,psec[i],psec[i]+1,psec[i]-1,psec[i]+15,psec[i]-15,psec[i]+16,psec[i]-16,psec[i]+17,psec[i]-17);
		}
	}
}

stock StreamProcess(playerid,v1,v2,v3,v4,v5,v6,v7,v8,v9)
{
    new p,i;
    new sec[9];
    sec[0] = v1;
    sec[1] = v2;
    sec[2] = v3;
    sec[3] = v4;
    sec[4] = v5;
    sec[5] = v6;
    sec[6] = v7;
    sec[7] = v8;
    sec[8] = v9;
    for(new k = 0;k<7;k++) {
        i = sec[k];
        if(vSecActive[i] == 1) {
    		for(new j = 1;j<=SectorHouseCount[i];j++) {
        		p = SectorHouses[i][j];
        		if(HouseVar[p][valid] == 1) {
					if(MMactive[playerid][p] == 0 && PlayerClose(playerid,HouseVar[p][x_ext],HouseVar[p][y_ext],HouseVar[p][z_ext],300) == 1) {
						if(streamcount[playerid] < MAX_ACTIVE_HOUSE_ICONS) {
							if(HouseVar[p][howned] == 1) {
							    streamcount[playerid]++;
							    SetPlayerMapIcon(playerid,p,HouseVar[p][x_ext],HouseVar[p][y_ext],HouseVar[p][z_ext],HOUSE_SOLD_ICON,1);
							    MMactive[playerid][p] == 1;
							}
							else {
							    streamcount[playerid]++;
							    SetPlayerMapIcon(playerid,p,HouseVar[p][x_ext],HouseVar[p][y_ext],HouseVar[p][z_ext],HOUSE_UNSOLD_ICON,1);
							    MMactive[playerid][p] == 1;
							}
						}
					}
				}
			}
    	}
 	}
 	for(new n = 0;n<MAX_HOUSES;n++) {
        if(MMactive[playerid][n] == 1 && PlayerClose(playerid,HouseVar[n][x_ext],HouseVar[n][y_ext],HouseVar[n][z_ext],300) == 0) {
		   	RemovePlayerMapIcon(playerid,n);
		   	streamcount[playerid]--;
		   	MMactive[playerid][n] == 0;
		}
    }
}

stock GetPointSector(Float:x,Float:y)
{
	new xsec = floatround(((x +4000) / 500), floatround_floor);
	new ysec = floatround(((y +4000) / 500), floatround_floor);
	return (xsec * 16) + ysec;
}

stock PlayerClose(playerid,Float:x,Float:y,Float:z,Float:MAX)
{
	new Float:PPos[3];
	if(IsPlayerConnected(playerid)) {
			GetPlayerPos(playerid, PPos[0], PPos[1], PPos[2]);
			if (PPos[0] >= floatsub(x, MAX) && PPos[0] <= floatadd(x, MAX)
			&& PPos[1] >= floatsub(y, MAX) && PPos[1] <= floatadd(y, MAX)
			&& PPos[2] >= floatsub(z, MAX) && PPos[2] <= floatadd(z, MAX))
			{
				return 1;
			}
	}
	return 0;
}

stock PlayersClose(Float:x,Float:y,Float:z,Float:MAX)
{
	new Float:PPos[3];
	for(new i = 0;i<MAX_PLAYERS;i++) {
		if(IsPlayerConnected(i)) {
			GetPlayerPos(i, PPos[0], PPos[1], PPos[2]);
			if (PPos[0] >= floatsub(x, MAX) && PPos[0] <= floatadd(x, MAX)
			&& PPos[1] >= floatsub(y, MAX) && PPos[1] <= floatadd(y, MAX)
			&& PPos[2] >= floatsub(z, MAX) && PPos[2] <= floatadd(z, MAX))
			{
				return 1;
			}
		}
	}
	return 0;
}

stock UpdateHouseSectorInfo()
{
    new secnum;
	for(new i = 0;i<MAX_SECTORS;i++) {
	    SectorHouseCount[i] = 0;
	}
   	for(new i = 0;i<MAX_HOUSES;i++) {
	    if(HouseVar[i][valid] == 1) {
			secnum = GetHouseSpawnSector(i);
			SectorHouseCount[secnum]++;
			SectorHouses[secnum][SectorHouseCount[secnum]] = i;
		}
	}
	return 1;
}

stock GetHouseVehicleValue(houseid)
{
	new vehprice = 1500;
	new finalprice;
	if(HouseVar[vehicle_house_id][vmod1] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod2] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod3] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod4] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod5] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod6] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod7] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod8] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod9] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod10] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod11] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod12] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod13] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod14] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod15] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod16] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vmod17] != 0) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vcolor_1] > -1 || HouseVar[vehicle_house_id][vcolor_2] > -1) {finalprice = vehprice+100; vehprice = finalprice;}
	if(HouseVar[vehicle_house_id][vpaintjob] > -1) {finalprice = vehprice+100; vehprice = finalprice;}
	return finalprice;
}

LoadHouseFile()
{
    if(fexist(HOUSE_FILE)) {
        new SplitVar[MAX_HOUSE_VARIABLES][256];
		new filestring[256];
		new File: file = fopen(HOUSE_FILE, io_read);
		if (file) {
	    	for(new Houseid = 0;Houseid<housecount;Houseid++)
			{
		    	fread(file, filestring);
				Split_String(filestring, SplitVar, ',');
				HouseVar[Houseid][hcost] = strval(SplitVar[0]);
				HouseVar[Houseid][howned] = strval(SplitVar[1]);
				strmid(HouseVar[Houseid][password], SplitVar[2], 0, strlen(SplitVar[2]), 256);
				strmid(HouseVar[Houseid][description], SplitVar[3], 0, strlen(SplitVar[3]), 256);
				strmid(HouseVar[Houseid][howner], SplitVar[4], 0, strlen(SplitVar[4]), 256);
				HouseVar[Houseid][x_ent] = floatstr(SplitVar[5]);
				HouseVar[Houseid][y_ent] = floatstr(SplitVar[6]);
				HouseVar[Houseid][z_ent] = floatstr(SplitVar[7]);
				HouseVar[Houseid][x_int] = floatstr(SplitVar[8]);
				HouseVar[Houseid][y_int] = floatstr(SplitVar[9]);
				HouseVar[Houseid][z_int] = floatstr(SplitVar[10]);
				HouseVar[Houseid][intworldid] = strval(SplitVar[11]);
 				HouseVar[Houseid][intid] = strval(SplitVar[12]);
				HouseVar[Houseid][hsecure] = strval(SplitVar[13]);
				HouseVar[Houseid][vposx] = floatstr(SplitVar[14]);
				HouseVar[Houseid][vposy] = floatstr(SplitVar[15]);
				HouseVar[Houseid][vposz] = floatstr(SplitVar[16]);
				HouseVar[Houseid][vposza] = floatstr(SplitVar[17]);
				HouseVar[Houseid][vid] = strval(SplitVar[18]);
				HouseVar[Houseid][vmodel] = strval(SplitVar[19]);
				HouseVar[Houseid][vsecure] = strval(SplitVar[20]);
				HouseVar[Houseid][vmod1] = strval(SplitVar[21]);
				HouseVar[Houseid][vmod2] = strval(SplitVar[22]);
				HouseVar[Houseid][vmod3] = strval(SplitVar[23]);
				HouseVar[Houseid][vmod4] = strval(SplitVar[24]);
				HouseVar[Houseid][vmod5] = strval(SplitVar[25]);
				HouseVar[Houseid][vmod6] = strval(SplitVar[26]);
				HouseVar[Houseid][vmod7] = strval(SplitVar[27]);
				HouseVar[Houseid][vmod8] = strval(SplitVar[28]);
				HouseVar[Houseid][vmod9] = strval(SplitVar[29]);
				HouseVar[Houseid][vmod10] = strval(SplitVar[30]);
				HouseVar[Houseid][vmod11] = strval(SplitVar[31]);
				HouseVar[Houseid][vmod12] = strval(SplitVar[32]);
				HouseVar[Houseid][vmod13] = strval(SplitVar[33]);
				HouseVar[Houseid][vmod14] = strval(SplitVar[34]);
				HouseVar[Houseid][vmod15] = strval(SplitVar[35]);
				HouseVar[Houseid][vmod16] = strval(SplitVar[36]);
				HouseVar[Houseid][vmod17] = strval(SplitVar[37]);
				HouseVar[Houseid][vcolor_1] = strval(SplitVar[38]);
				HouseVar[Houseid][vcolor_2] = strval(SplitVar[39]);
				HouseVar[Houseid][vpaintjob] = strval(SplitVar[40]);
				HouseVar[Houseid][hsafe] = strval(SplitVar[41]);
				HouseVar[Houseid][vvalue] = GetHouseVehicleValue(Houseid);
				new addmess[256];
				HouseVar[Houseid][puid] = CreatePickup(HOUSE_PICKUP,HOUSE_ICON_TYPE,HouseVar[Houseid][spawn_x],HouseVar[Houseid][spawn_y],HouseVar[Houseid][spawn_z]);
				HouseVar[Houseid][vid] = CreateVehicle(HouseVar[Houseid][vmodel],HouseVar[Houseid][vposx],HouseVar[Houseid][vposy],HouseVar[Houseid][vposz],HouseVar[Houseid][vposza],HouseVar[Houseid][vcolor_1],HouseVar[Houseid][vcolor_2],30000);
				SetTimerEx("ModVehicle",100,0,"i",HouseVar[Houseid][vid]);
				format(addmess,sizeof(addmess),"--:: House %d (%s) successfully loaded - owner: %s ::--",Houseid,HouseVar[Houseid][description],HouseVar[Houseid][howner]);
				printf(addmess);
			}
		}
		fclose(file);
		UpdateHouseSectorInfo();
		SetTimer("SectorScan",1000,1);
	}
	else {
		print("tAxI HOUSING SYSTEM ERROR! - HOUSE FILE ('tAxI_houses.cfg') NOT FOUND IN SCRIPTFILES. HOUSE SYSTEM DEACTIVATED ON SERVER LOADUP.");
	}
}

stock SaveHouseFile()
{
	new filestring[256];
	new File: hfile = fopen(HOUSE_FILE, io_write);
	for(new houseid = 0;houseid<housecount;houseid++)
 	{
		format(filestring, sizeof(filestring), "%d,%d,%s,%s,%s,%f,%f,%f,%f,%f,%f,%d,%d,%d,%f,%f,%f,%f,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
		HouseVar[Houseid][hcost],
		HouseVar[Houseid][howned],
		HouseVar[Houseid][password],
		HouseVar[Houseid][description],
		HouseVar[Houseid][howner],
		HouseVar[Houseid][x_ent],
		HouseVar[Houseid][y_ent],
		HouseVar[Houseid][z_ent],
		HouseVar[Houseid][x_int],
		HouseVar[Houseid][y_int],
		HouseVar[Houseid][z_int],
		HouseVar[Houseid][intworldid],
		HouseVar[Houseid][intid],
		HouseVar[Houseid][hsecure],
		HouseVar[Houseid][vposx],
		HouseVar[Houseid][vposy],
		HouseVar[Houseid][vposz],
		HouseVar[Houseid][vposza],
		HouseVar[Houseid][vid],
		HouseVar[Houseid][vmodel],
		HouseVar[Houseid][vsecure],
		HouseVar[Houseid][vmod1],
		HouseVar[Houseid][vmod2],
		HouseVar[Houseid][vmod3],
		HouseVar[Houseid][vmod4],
		HouseVar[Houseid][vmod5],
		HouseVar[Houseid][vmod6],
		HouseVar[Houseid][vmod7],
		HouseVar[Houseid][vmod8],
		HouseVar[Houseid][vmod9],
		HouseVar[Houseid][vmod10],
		HouseVar[Houseid][vmod11],
		HouseVar[Houseid][vmod12],
		HouseVar[Houseid][vmod13],
		HouseVar[Houseid][vmod14],
		HouseVar[Houseid][vmod15],
		HouseVar[Houseid][vmod16],
		HouseVar[Houseid][vmod17],
		HouseVar[Houseid][vcolor_1],
		HouseVar[Houseid][vcolor_2],
		HouseVar[Houseid][vpaintjob],
		HouseVar[Houseid][hsafe]
		);
		fwrite(bhfile, filestring);
	}
	fclose(hfile);
}

public ModVehicle(vehicle_house_id)
{
	if(HouseVar[vehicle_house_id][vmod1] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod1]);}
	if(HouseVar[vehicle_house_id][vmod2] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod2]);}
	if(HouseVar[vehicle_house_id][vmod3] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod3]);}
	if(HouseVar[vehicle_house_id][vmod4] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod4]);}
	if(HouseVar[vehicle_house_id][vmod5] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod5]);}
	if(HouseVar[vehicle_house_id][vmod6] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod6]);}
	if(HouseVar[vehicle_house_id][vmod7] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod7]);}
	if(HouseVar[vehicle_house_id][vmod8] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod8]);}
	if(HouseVar[vehicle_house_id][vmod9] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod9]);}
	if(HouseVar[vehicle_house_id][vmod10] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod10]);}
	if(HouseVar[vehicle_house_id][vmod11] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod11]);}
	if(HouseVar[vehicle_house_id][vmod12] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod12]);}
	if(HouseVar[vehicle_house_id][vmod13] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod13]);}
	if(HouseVar[vehicle_house_id][vmod14] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod14]);}
	if(HouseVar[vehicle_house_id][vmod15] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod15]);}
	if(HouseVar[vehicle_house_id][vmod16] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod16]);}
	if(HouseVar[vehicle_house_id][vmod17] != 0) {AddVehicleComponent(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vmod17]);}
	if(HouseVar[vehicle_house_id][vcolor_1] > -1 || HouseVar[vehicle_house_id][vcolor_2] > -1) {ChangeVehicleColor(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vcolor_1],HouseVar[vehicle_house_id][vcolor_2]);}
	if(HouseVar[vehicle_house_id][vpaintjob] > -1) {ChangeVehiclePaintjob(HouseVar[vehicle_house_id][vid],HouseVar[vehicle_house_id][vpaintjob]);}
}

stock IsPlayerHouseOwner(playerid,houseid)
{
	if(strcmp(HouseVar[houseid][howner],PlInfo[playerid][name],false) == 0) {
	    return 1;
	}
	return 0;
}

stock IsPlayerVehicleHouseOwner(playerid,vehicleid)
{
	if(PlInfo[playerid][howner] == 1 && HouseVar[PlInfo[playerid][howned]][vid] == vehicleid) {
	    return 1;
	}
	return 0;
}

stock GetDriverID(vehicleid)
{
    for(new i=0; i<700; i++) {
        if(IsPlayerConnected(i)) {
            if(IsPlayerInAnyVehicle(i)) {
                if(GetPlayerVehicleID(i) == vehicleid) {
					return i;
                }
            }
        }
    }
    return -1;
}

stock LoadPlayerFile(playerid)
{
    new fname[256],playername[256],filestring[256];
    GetPlayerName(playerid,playername,sizeof(playername))
 	new SplitDiv[2][256];
	new File: file;
 	format(fname,sizeof(fname),PLAYER_FILE_TEMPLATE,udb_encode(playername));
 	if(fexist(fname)) {
 	    file = fopen(fname, io_read);
		if (file) {
 			fread(file, filestring);
			Split_String(filestring, SplitDiv, ',');
			PlayerInfo[playerid][howner] = strval(SplitDiv[0]);
			PlayerInfo[playerid][howned] = strval(SplitDiv[1]);
			fclose(file);
		}
 	}
 	else {
 	    CreatePlayerFile(playerid);
 	}
}

stock SavePlayerFile(playerid)
{
    new fname[256],playername[256],filestring[256];
	new File: file;
	GetPlayerName(playerid, playername, sizeof(playername));
 	format(fname,sizeof(fname),PLAYER_FILE_TEMPLATE,udb_encode(playername));
 	if(!fexist(fname)) {}
 	else {
	    file = fopen(fname, io_write);
	    if(file) {
	        PlayerInfo[playerid][pcash] = GetPlayerMoney(playerid);
  			format(filestring,sizeof(filestring),"%d,%d",PlInfo[playerid][howner],PlInfo[playerid][howned]);
   			fwrite(file,filestring);
	   		fclose(file);
		}
	}
}

stock CreatePlayerFile(playerid)
{
	new fname[256],playername[256];
	new File: file;
	GetPlayerName(playerid, playername, sizeof(playername));
 	format(fname,sizeof(fname),PLAYER_FILE_TEMPLATE,udb_encode(playername));
  	file = fopen(fname, io_write);
  	if(file) {
		fwrite(file,"0,0");
		fclose(file);
	}
	LoadPlayerFile(playerid);
}

public SpawnPlayerAtHouse(playerid)
{
	new houseid = PlInfo[playerid][howned];
	SetPlayerPos(playerid,HouseVar[houseid][x_int],HouseVar[houseid][y_int],HouseVar[houseid][z_int]);
	return 1;
}

public BackupFiles()
{
	SaveHouseFile();
	for(new s=0; s<MAX_PLAYERS; s++) {
	    if(IsPlayerConnected(s) && PlInfo[playerid][logged]) {
	        SavePlayerFile(playerid);
	    }
	}
}

public SafeRespawnHouseVehicle(Houseid)
{
	DestroyVehicle(HouseVar[Houseid][vid]);
	HouseVar[Houseid][vid] = CreateVehicle(HouseVar[Houseid][vmodel],HouseVar[Houseid][vposx],HouseVar[Houseid][vposy],HouseVar[Houseid][vposz],HouseVar[Houseid][vposza],HouseVar[Houseid][vcolor_1],HouseVar[Houseid][vcolor_2],30000);
	SetTimerEx("ModVehicle",100,0,"i",HouseVar[Houseid][vid]);
}

stock GetVehicleHouseID(vehicleid)
{
    for(new s=0; s<MAX_HOUSES; s++) {
        if(HouseVar[s][vid] == vehicleid) {
            return s;
        }
    }
    return 999;
}

//====================NATIVES REQUIRED FOR SYSTEM TO START PROPERLY===================================

public tAxI_OnPlayerStateChange(playerid, newstate)
{
	if(newstate == PLAYER_STATE_DRIVER) {
	    new string[256];
		new houseid = GetVehicleHouseID(vehicleid);
        if (strcmp(HouseVar[houseid][howner],PlInfo[playerid][name],false) == 0) {
			if(HouseVar[houseid][vsecure] == 0) {
				SendClientMessage(playerid, GREEN, "Your house vehicle security system is currently deactivated.");
		    	return 1;
			}
	 		if(HouseVar[houseid][vsecure] == 1) {
				SendClientMessage(playerid, GREEN, "Your house vehicle security system is currently set to eject any intruders.");
		    	return 1;
			}
		}
		else {
		    if(HouseVar[houseid][vsecure] == 0) {
				format(string, sizeof(string), "The owner of this vehicle (%s), has set the vehicle to allow any person to use it. Drive carefully or you will pay for the repairs!",HouseVar[houseid][howner]);
			}
	 		if(HouseVar[houseid][vsecure] == 1) {
				format(string, sizeof(string), "The owner of this vehicle (%s), has set the vehicle to eject intruders. Enjoy the walk!",HouseVar[houseid][howner]);
			}
			SendClientMessage(playerid,BLUE,string);
		}
	}
	return 1;
}

stock tAxI_OnVehicleDeath(vehicleid)
{
	new houseid = GetVehicleHouseID(vehicleid);
    SetTimerEx("SafeRespawnHouseVehicle",5000,0,"i",houseid);
    for(new s=0; s<MAX_PLAYERS; s++) {
        if(PlInfo[s][lastv] == vehicleid && lastd[vehicleid] == s) {
            new pmon = GetPlayerMoney(s)-HouseVar[houseid][vvalue];
            new hmon = HouseVar[houseid][hsafe]+HouseVar[houseid][vvalue];
            new string[256];
            format(string,sizeof(string),"You have been billed for the destruction of %s's house vehicle ($%d).",HouseVar[houseid][howner],HouseVar[houseid][vvalue]);
            ResetPlayerMoney(s);
            GivePlayerMoney(s,pmon);
            HouseVar[houseid][hsafe] = hmon;
            SentClientMeassage(s,RED,string);
            return 1;
        }
    }
}

stock tAxI_OnPlayerSpawn(playerid)
{
	if(allowhousespawn == true && PlInfo[playerid][howner] == 1) {
	    SetTimerEx("SpawnPlayerAtHouse",750,0,"i",playerid);
	}
}

stock tAxI_OnGameModeInit()
{
	housecount = CountHouses();
    LoadHouseFile();
    SetTimerEx("BackupFiles",120000,1);
	return 1;
}

stock tAxI_OnGameModeExit()
{
    SaveHouseFile();
	return 1;
}

stock tAxI_OnPlayerPickupPickup(playerid,pickupid)
{
    for(new s=0; s<MAX_HOUSES; s++) {
        if(HouseVar[s][puid] == pickupid) {
            new houseowner[256],lockmes[256];
            format(lockmes,256,"Unlocked");
            if(HouseVar[s][hsecure] == 1) {
                format(lockmes,256,"Locked");
            }
			format(houseowner,256,"%s",HouseVar[s][howner]);
			if(strcmp(HouseVar[s][howner],DEFAULT_HOUSE_OWNER,false) == 0) {
	    		format(houseowner,256,"<Still For Sale>");
			}
			new housemes[256];
			format(housemes,256,"~n~~n~~r~Description: ~g~%s~n~~r~Price: ~g~$%d ~r~~n~~r~Owner: ~g~%s~n~~r~Security: ~g~%s",HouseVar[s][name],HouseVar[s][hcost],houseowner,lockmes);
    		GameTextForPlayer(playerid,housemes,5000,3);
			return 1;
        }
    }
}

stock tAxI_OnVehicleMod(vehicleid,componentid)
{
    new playerid = GetDriverID(vehicleid);
    new Houseid = PlInfo[playerid][howned];
	if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER) {
    	    if (IsPlayerVehicleHouseOwner(playerid,vehicleid) == 1) {
				for(new s=0; s<20; s++) {
     				if(componentid == spoiler[s][0]) {
       					HouseVar[Houseid][vmod1] = componentid;
   	        		}
				}
				for(new s=0; s<3; s++) {
     				if(componentid == nitro[s][0]) {
       					HouseVar[Houseid][vmod2] = componentid;
   	        		}
				}
				for(new s=0; s<23; s++) {
     				if(componentid == fbumper[s][0]) {
       					HouseVar[Houseid][vmod3] = componentid;
   	        		}
				}
				for(new s=0; s<22; s++) {
     				if(componentid == rbumper[s][0]) {
       					HouseVar[Houseid][vmod4] = componentid;
   	        		}
				}
				for(new s=0; s<28; s++) {
     				if(componentid == exhaust[s][0]) {
       					HouseVar[Houseid][vmod5] = componentid;
   	        		}
				}
				for(new s=0; s<2; s++) {
     				if(componentid == bventr[s][0]) {
       					HouseVar[Houseid][vmod6] = componentid;
   	        		}
				}
				for(new s=0; s<2; s++) {
     				if(componentid == bventl[s][0]) {
       					HouseVar[Houseid][vmod7] = componentid;
   	        		}
				}
				for(new s=0; s<4; s++) {
     				if(componentid == bscoop[s][0]) {
       					HouseVar[Houseid][vmod8] = componentid;
   	        		}
				}
				for(new s=0; s<13; s++) {
     				if(componentid == rscoop[s][0]) {
       					HouseVar[Houseid][vmod9] = componentid;
   	        		}
				}
				for(new s=0; s<21; s++) {
     				if(componentid == lskirt[s][0]) {
       					HouseVar[Houseid][vmod10] = componentid;
   	        		}
				}
				for(new s=0; s<21; s++) {
     				if(componentid == rskirt[s][0]) {
       					HouseVar[Houseid][vmod11] = componentid;
   	        		}
				}
				for(new s=0; s<1; s++) {
     				if(componentid == hydraulics[s][0]) {
       					HouseVar[Houseid][vmod12] = componentid;
   	        		}
				}
				for(new s=0; s<1; s++) {
     				if(componentid == base[s][0]) {
       					HouseVar[Houseid][vmod13] = componentid;
   	        		}
				}
				for(new s=0; s<2; s++) {
     				if(componentid == rbbars[s][0]) {
       					HouseVar[Houseid][vmod14] = componentid;
   	        		}
				}
				for(new s=0; s<2; s++) {
     				if(componentid == fbbars[s][0]) {
       					HouseVar[Houseid][vmod15] = componentid;
   	        		}
				}
				for(new s=0; s<17; s++) {
     				if(componentid == wheels[s][0]) {
       					HouseVar[Houseid][vmod16] = componentid;
   	        		}
				}
				for(new s=0; s<2; s++) {
     				if(componentid == lights[s][0]) {
       					HouseVar[Houseid][vmod17] = componentid;
   	        		}
				}
				HouseVar[Houseid][vvalue] = GetHouseVehicleValue(Houseid);
				return 1;
			}
	}
	return 0;
}

stock tAxI_OnVehiclePaintjob(vehicleid,paintjobid)
{
    new playerid = GetDriverID(vehicleid);
	if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER) {
    	    if (IsPlayerVehicleHouseOwner(playerid,vehicleid) == 1) {
				HouseVar[PlInfo[playerid][howned]][vpaintjob] = paintjobid;
				return 1;
			}
	}
	return 0;
}

stock tAxI_OnVehicleRespray(vehicleid,color1,color2)
{
    new playerid = GetDriverID(vehicleid);
	if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER) {
    	    if (IsPlayerVehicleHouseOwner(playerid,vehicleid) == 1) {
				HouseVar[PlInfo[playerid][howned]][vcolor_1] = color1;
    	        HouseVar[PlInfo[playerid][howned]][vcolor_2] = color2;
				return 1;
			}
	}
	return 0;
}

stock tAxI_OnPlayerConnect(playerid)
{
	GetPlayerName(playerid, PlInfo[playerid][name],256);
	LoadPlayerFile(playerid);
}

stock tAxI_OnPlayerDisconnect(playerid)
{
	if(PlInfo[playerid][logged] == 1) {
		SavePlayerFile(playerid);
		SaveHouseFile();
	}
}

tAxI_OnPlayerEnterVehicle(playerid,vehicleid)
{
	PlInfo[playerid][lastv] = vehicleid;
	lastd[vehicleid] = playerid;
}

//==================AVAILLABLE COMMAND FUNCTIONS FOR THE HOUSES================//

LogPlayerInToHouseSystem(playerid)
{
	PlInfo[playerid][logged] = 1;
	return 1;
}

SetSpawnAtHouse(bool:toggle)
{
	allowhousespawn = toggle;
	return 1;
}
