/*----------------------------------------------------------------------------*-
					==================================
					Y Sever Includes - Properties Core
					==================================
Description:
	Handles properties and other common features for some modes.
Legal:
	Copyright (C) 2007 Alex "Y_Less" Cole

	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 2
	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, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
	MA 02110-1301, USA.
Version:
	0.1
Changelog:
	03/08/07:
		Updated timer system.
	31/07/07:
		Made some functions safe.
		Added tracking stats.
	03/07/07:
		Added invert option on CreateRestrictedArea.
	24/06/07:
		Modifed a few functions to use Bit_GetBit for speed.
	19/06/07:
		Added minor functions (IsValid, GetType and GetLink)
	18/06/07:
		Added commands.
	14/06/07:
		Updated functions to use checkpoint and area lookups
	18/04/07:
		First version.
Functions:
	Public:
		Property_Loop - Does the main system processing.
		Property_AddPropRemote - Adds a property from another script.
		Property_AddBankRemote - Adds a bank from another script.
		Property_AddAmmuRemote - Adds an ammunation from another script.
		Property_AddMARemote - Adds a money area from another script.
		Property_AddMPRemote - Adds a money point from another script.
		Property_AddTeleRemote - Adds a teleport from another script.
		Property_AddFobRemote - Adds a forbidden area from another script.
		Property_GetPropertyBitsReceive - Passes a player's properties.
		Property_Remote - Remote wrapper for most minor functions.
		YSIM_Properties - Master system callback.
		Property_Broadcast - Called to save properties on master shutdown.
		Property_PickupTimeCheck - Checks if a player is still stood on a pickup.
	Core:
		Property_OnPlayerSelectedMenuRow - Called when someone selects something.
		Property_OnPlayerExitedMenu - Called when someone exits a menu.
		Property_OnPlayerEnterCheckpointEx - Called when someone enters a checkpoint (public).
		Property_OnPlayerLeaveCheckpointEx - Called when someone leaves a checkpoint (public).
		Property_OnPlayerPickUpPickup - Called when someone picks up a pickup (public).
		Property_OnPlayerSpawn - Called when someone spawns.
		Property_OnPlayerConnect - Called when comaone connects.
		Property_OnPlayerLeaveArea - Called when someone leaves an area (public).
		Property_OnPlayerEnterArea - Called when someone enters an area (public).
	Stock:
		Property_GetPlayerPropCount - Gets the number of properties for a player.
		Property_GetLink - Gets the area or checkpoint for a property.
		Property_GetType - Gets a property's type.
		Property_IsValid - Checks if a property is valid.
		Property_Bank - Moves money to/from an account.
		Property_SavePlayerWeapon - Saves a players weapon for spawn.
		Property_SaveWeapons - Saves a player's spawn weapons.
		Property_LoadWeapons - Loads a player's spawn weapons.
		Property_SaveBank - Saves a player's banked money.
		Property_LoadBank - Loads a player's banked money.
		Property_GetBank - Gets a player's banked money.
		Property_GetSlotWeapon - Gets a player's spawn weapons.
		Property_GetPropertyBits - Gets a player's owned properties.
		Property_SetRebuyDelay - Set a delay on rebuying properties.
	Static:
		Property_GetWeapon - Gets weapon data for a slotid slot.
		Property_WeaponName - Gets a weapon name for a slotid.
		Property_GetWeaponFromSlot - Gets a weaponid from a slotid.
		Property_GenerateAmmuMenu - Generates the menu for ammunation.
	Inline:
		Property_SetOption - Sets a property's custom flag.
		Property_IsActive - Checks if a property is active.
		Property_GetOption - Gets a property's custom flag.
		Property_GivePlayerWeapon - Gives a player a weapon from it's slot.
		Property_WeaponCost - Gets the cost of a slot,
		Property_WeaponAmmo - Gets the ammo of a slot.
		Property_IsPlayerProperty - Checks if a player can have a property.
	API:
		CreateProperty - Creates a business.
		CreateBank - Creates a bank.
		CreateAmmunation - Creates an ammunation.
		CreateMoneyArea - Creates a money area.
		CreateMoneyPoint - Creates a money point.
		CreateTeleport - Creates a teleport.
		CreateForbiddenArea - Creates a forbidden area.
		DestroyProperty - Deletes a property from the array.
Callbacks:
	-
Definitions:
	PROPERTY_LOOP_GRANULARITY - Number of itterations of the main loop a second.
	MAX_PROP_NAME - Max length of the name of a property.
	MAX_PROPERTIES - Max number of properties.
	NO_PROPERTY - Invalid return.
	WEAPON_ARMOUR - Type for salling armour at ammunation.
	PROPERTY_SELL_PERCENT - % of money got back for a reduced sale.
Enums:
	e_PROP_FLAGS - Flags for property data.
	E_PROP_DATA - Data for a property.
	E_PROP_AMMU - Data for a persons current ammunation menu.
	<unnamed> - Tagless remote instructions, must have new ones added to the end.
Macros:
	WEAPON_DATA_OFFSET - Offset for saving weapons with variable size arrays,
	WEAPON_DATA - Gets ammo and cost from parameters and compresses them.
	WEAPON_DATA_REM - Like WEAPON_DATA but reads from an array instead.
	WEAPON - Saves a weapon id in the top byte of a cell.
Tags:
	e_PROP_FLAGS - Flags.
Variables:
	Global:
		-
	Static:
		YSI_g_sProperties - Array of all property data.
		YSI_g_sMoney - Array of player's banked money.
		YSI_g_sPlayerProperties - Bit array of properties a player has.
		YSI_g_sSpawnWeapons - Array of weapons a player will spawn with.
		YSI_g_sShopMenu - Array of players current menus.
		YSI_g_sAreaPointers - Array of properties for each area.
		YSI_g_sCheckpointPointers - Array of properties for each checkpoint.
		YSI_g_sTempPropReq - Script has requested a player's properties.
		YSI_g_sTempProp - Temporary store for properties.
		YSI_g_sIsMaster - Is this script the global master.
Commands:
	buy - Lets you buy your current property.
	bank - Lets you bank money.
	properties - Lists properties and their owners.
	balance - Displays your current balance.
	withdraw - Allows you to take out money.
	sell - Allows you to sell a property.
Properties:
	LReqProp - Return data from a remote script.
	110953013 - Return properties for a player.
Compile options:
	-
Operators:
	-
-*----------------------------------------------------------------------------*/

#if !defined PROPERTY_LOOP_GRANULARITY
	#define PROPERTY_LOOP_GRANULARITY 2
#endif

#if defined MAX_PROP_NAME
	#if MAX_PROP_NAME < (39 - PLAYER_BIT_ARRAY)
		#undef MAX_PROP_NAME
	#endif
#endif

#if !defined MAX_PROP_NAME
	#define MAX_PROP_NAME (39 - PLAYER_BIT_ARRAY)
#endif

#if !defined MAX_PROPERTIES
	#define MAX_PROPERTIES 256
#endif

#if !defined GROUP_PROPERTY_BITS
	#if MAX_PROPERTIES <= 32
		#define GROUP_PROPERTY_BITS 2
	#else
		#define GROUP_PROPERTY_BITS Bit_Bits(MAX_PROPERTIES)
	#endif
#endif

#define NO_PROPERTY -1

#define WEAPON_ARMOUR 100

#define PROPERTY_SELL_PERCENT 60

#define PROPERTY_INCREASE_PERCENT 125

#define WEAPON_DATA_OFFSET (PLAYER_BIT_ARRAY - 2)

#define WEAPON_DATA (((getarg(pos++) & 0xFFF) << 20) | (getarg(pos++) & 0xFFFFF))

#define WEAPON_DATA_REM (((dat[pos++] & 0xFFF) << 20) | (dat[pos++] & 0xFFFFF))

#define WEAPON(%1) ((%1) << 24)

#define Property_OnPlayerLeaveCheckpointEx Property_OnPlayerLeaveCP
#define Property_OnPlayerEnterCheckpointEx Property_OnPlayerEnterCP

enum e_PROP_FLAGS (+= 0x10000)
{
	e_PROP_FLAGS_LINK		= 0x0000FFFF,
	e_PROP_FLAGS_TYPES		= 0x00FF0000,
	e_PROP_FLAGS_TYPE_PROP	= 0x00010000,
	e_PROP_FLAGS_TYPE_BANK,
	e_PROP_FLAGS_TYPE_AMMU,
	e_PROP_FLAGS_TYPE_TELS,
	e_PROP_FLAGS_TYPE_TELT,
	e_PROP_FLAGS_TYPE_MONP,
	e_PROP_FLAGS_TYPE_HOUS,
	e_PROP_FLAGS_TYPE_MONA	= 0x00100000,
	e_PROP_FLAGS_TYPE_RSRC,
	e_PROP_FLAGS_FLAGS		= 0xFF000000,
	e_PROP_FLAGS_CUST_1		= 0x01000000,
	e_PROP_FLAGS_CUST_2		= 0x02000000,
	e_PROP_FLAGS_CUST_3		= 0x04000000,
	e_PROP_FLAGS_CUST_4		= 0x08000000,
	e_PROP_FLAGS_CUST_5		= 0x10000000,
	e_PROP_FLAGS_ACTIVE		= 0x80000000
}

enum E_PROP_DATA
{
	E_PROP_DATA_NAME[MAX_PROP_NAME],
	e_PROP_FLAGS:E_PROP_DATA_FLAGS,
	E_PROP_DATA_DATA_1,
	E_PROP_DATA_DATA_2,
	#if defined _YSI_SETUP_MASTER
		E_PROP_DATA_MASTER,
	#endif
	Bit:E_PROP_DATA_PLAYERS[PLAYER_BIT_ARRAY]
}

enum E_PROP_AMMU
{
	Menu:E_PROP_AMMU_MENU,
	E_PROP_AMMU_DATA
}

enum
{
	E_PROP_REMOTE_LINK,
	E_PROP_REMOTE_PROBITS,
	E_PROP_REMOTE_PPCO,
	E_PROP_REMOTE_BANK,
	E_PROP_REMOTE_LBANK,
	E_PROP_REMOTE_GBANK,
	E_PROP_REMOTE_LWEAP,
	E_PROP_REMOTE_SWEAP,
	E_PROP_REMOTE_GOWEAP,
	E_PROP_REMOTE_SAVEWEAP,
	E_PROP_REMOTE_DELETE,
	E_PROP_REMOTE_TYPE,
	E_PROP_REMOTE_VALID,
	E_PROP_REMOTE_SET_MAX,
	E_PROP_REMOTE_SET_HMX,
	E_PROP_REMOTE_REBUY
}

static
	YSI_g_sProperties[MAX_PROPERTIES][E_PROP_DATA],
	YSI_g_sMoney[MAX_PLAYERS],
	YSI_g_sPropCount[MAX_PLAYERS],
	YSI_g_sHouseCount[MAX_PLAYERS],
	Bit:YSI_g_sPlayerProperties[MAX_PLAYERS][GROUP_PROPERTY_BITS],
	YSI_g_sSpawnWeapons[MAX_PLAYERS][13],
	YSI_g_sShopMenu[MAX_PLAYERS][E_PROP_AMMU],
	YSI_g_sRebuyDelay,
	#if defined _YSI_SETUP_MASTER
		YSI_g_sTempPropReq,
		Bit:YSI_g_sTempProp[GROUP_PROPERTY_BITS],
		YSI_g_sIsMaster,
	#endif
	#if defined _YSI_VISUAL_PICKUPS
		YSI_g_sPickupPointers[MAX_DYN_PICKUPS],
		YSI_g_sPickupProps,
		YSI_g_sPickupTimer[MAX_PLAYERS] = {-1, ...},
		YSI_g_sPlayerPickup[MAX_PLAYERS] = {NO_PICKUP, ...},
	#endif
	YSI_g_sAreaPointers[MAX_AREAS],
	YSI_g_sCheckpointPointers[MAX_CHECKPOINTS],
	YSI_g_sMaxPlayerHouses = cellmax,
	YSI_g_sMaxPlayerProps = cellmax,
	YSI_g_sCurrentHouse[MAX_PLAYERS] = {-1, ...};

forward Property_Loop();
forward ycmd_sell(playerid, params[], help);
forward ycmd_bank(playerid, params[], help);
forward ycmd_balance(playerid, params[], help);
forward ycmd_buy(playerid, params[], help);
forward ycmd_withdraw(playerid, params[], help);
forward ycmd_properties(playerid, params[], help);
forward Property_ResetRebuy(prop);
forward ycmd_exit(playerid, params[], help);
forward ycmd_enter(playerid, params[], help);

#if defined _YSI_VISUAL_PICKUPS
	forward Property_PickupTimeCheck(playerid, pickupid);
#endif

#if defined _YSI_SETUP_MASTER
	forward Property_AddHouseRemote(master, Float:extX, Float:extY, Float:extZ, Float:intX, Float:intY, Float:intZ, interior, world, price, checkpoint);
	forward Property_AddPropRemote(master, name[], Float:x, Float:y, Float:z, price, reward, interval, sell, multi, reduce, increase, pickup);
	forward Property_AddBankRemote(master, Float:x, Float:y, Float:z, name[]);
	forward Property_AddAmmuRemote(master, Float:x, Float:y, Float:z, spawn, instant, dat[], num);
	forward Property_AddMARemote(master, area, money, interval);
	forward Property_AddMPRemote(master, Float:x, Float:y, Float:z, Float:s, money, interval);
	forward Property_AddTeleRemote(master, Float:sx, Float:sy, Float:sz, Float:tx, Float:ty, Float:tz, cost, name[]);
	forward Property_AddFobRemote(master, area, kick, health, invert, name[]);
	forward Property_OnPlayerEnterCheckpointEx(playerid, cpid);
	forward Property_OnPlayerLeaveCheckpointEx(playerid, cpid);
	#if defined _YSI_VISUAL_PICKUPS
		forward Property_OnPlayerPickUpPickup(playerid, pickupid, Float:x, Float:y, Float:z);
	#endif
	forward Property_OnPlayerLeaveArea(playerid, area);
	forward Property_OnPlayerEnterArea(playerid, area);
	forward Property_GetPropertyBitsReceive(playerid, Bit:properties[], count);
	forward Property_Remote(ident, info, instruction);
	forward YSIM_Properties(command);
	forward Property_Broadcast(id, name[], nlength, e_PROP_FLAGS:flags, data1, data2, master, Bit:players[], plength);
#endif

Text_RegisterTag(ysi_properties);

/*----------------------------------------------------------------------------*-
Function:
	Property_IsActive
Params:
	prop - Property to check.
Return:
	-
Notes:
	-
-*----------------------------------------------------------------------------*/

#define Property_IsActive(%1) \
	((%1) < MAX_PROPERTIES && (%1) >= 0 && YSI_g_sProperties[(%1)][E_PROP_DATA_FLAGS] & e_PROP_FLAGS_ACTIVE)

/*----------------------------------------------------------------------------*-
Function:
	Property_ResetMaxProperties
Params:
	-
Return:
	-
Notes:
	Allows people to own as many properties as they like at
	once.
-*----------------------------------------------------------------------------*/

#define Property_ResetMaxProperties() \
	Property_SetMaxProperties(cellmax)

/*----------------------------------------------------------------------------*-
Function:
	Property_SetOption
Params:
	slot - Custom flag to set.
	value - Value to set it to.
Return:
	-
Notes:
	Can't be changed except from 0 to 1.
-*----------------------------------------------------------------------------*/

#define Property_SetOption(%1,%2) \
	((%2) ? e_PROP_FLAGS_CUST_%1 : e_PROP_FLAGS:0)

/*----------------------------------------------------------------------------*-
Function:
	Property_GetOption
Params:
	slot - Custom flag to get.
	flags - flags cell to get it from.
Return:
	-
Notes:
	-
-*----------------------------------------------------------------------------*/

#define Property_GetOption(%1,%2) \
	(e_PROP_FLAGS_CUST_%1 & e_PROP_FLAGS:(%2))

/*----------------------------------------------------------------------------*-
Function:
	Property_GivePlayerWeapon
Params:
	playerid - Player to gice a weapon to.
	slot - Weapon slot to give.
	ammo - Ammo to give.
Return:
	-
Notes:
	Gives a player a weapon by slot instead of weaponid or assignes armour.
-*----------------------------------------------------------------------------*/

#define Property_GivePlayerWeapon(%1,%2,%3) \
	if ((%2) == 39) SetPlayerArmour((%1), 100.0); else GivePlayerWeapon(%1, Property_GetWeaponFromSlot(%2), %3)

/*----------------------------------------------------------------------------*-
Function:
	Property_SetRebuyDelay
Params:
	delay - Time till a property can be bought again.
Return:
	-
Notes:
	-
-*----------------------------------------------------------------------------*/

stock Property_SetRebuyDelay(delay)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			YSI_g_sRebuyDelay = delay;
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", 0, delay, E_PROP_REMOTE_REBUY);
		}
	#endif
}

/*----------------------------------------------------------------------------*-
Function:
	Property_IsValid
Params:
	property - Property to check.
Return:
	Is the property a valid active property.
Notes:
	-
-*----------------------------------------------------------------------------*/

stock Property_IsValid(property)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			return Property_IsActive(property);
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", 0, property, E_PROP_REMOTE_VALID);
			return getproperty(0, "YSIReq");
		}
	#endif
}

/*----------------------------------------------------------------------------*-
Function:
	Property_IsOwner
Params:
	playerid - Player to check.
	prop - Property to check.
	flags - Property flags for ownership type.
Return:
	-
Notes:
	-
-*----------------------------------------------------------------------------*/

#define Property_IsOwner(%1,%2,%3) \
	((Property_GetOption(2, (%3))) ? (!Bit_GetBit(YSI_g_sProperties[(%2)][E_PROP_DATA_PLAYERS], (%1))) : (!(_:YSI_g_sProperties[(%2)][E_PROP_DATA_PLAYERS][0] == (%1))))

/*----------------------------------------------------------------------------*-
Function:
	Property_SetMaxProperties
Params:
	count - Number of ownable properties.
Return:
	-
Notes:
	Sets the number of properties a player can own at once.
-*----------------------------------------------------------------------------*/

stock Property_SetMaxProperties(count)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			YSI_g_sMaxPlayerProps = count;
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", count, 0, E_PROP_REMOTE_SET_MAX);
		}
	#endif
}

/*----------------------------------------------------------------------------*-
Function:
	Property_SetMaxHouses
Params:
	count - Number of ownable houses.
Return:
	-
Notes:
	Sets the number of houses a player can own at once.
-*----------------------------------------------------------------------------*/

stock Property_SetMaxHouses(count)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			YSI_g_sMaxPlayerHouses = count;
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", count, 0, E_PROP_REMOTE_SET_HMX);
		}
	#endif
}

/*----------------------------------------------------------------------------*-
Function:
	Property_GetType
Params:
	property - Property to get the type of.
Return:
	0 if invalid or type.
Notes:
	-
-*----------------------------------------------------------------------------*/

stock Property_GetType(property)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			if (!Property_IsActive(property)) return 0;
			return _:(YSI_g_sProperties[property][E_PROP_DATA_FLAGS] & e_PROP_FLAGS_TYPES);
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", property, 0, E_PROP_REMOTE_TYPE);
			return getproperty(0, "YSIReq");
		}
	#endif
}

/*----------------------------------------------------------------------------*-
Function:
	Property_Property
Params:
	-
Return:
	-
Notes:
	Sets variable initial states.
-*----------------------------------------------------------------------------*/

Property_Property()
{
	DBGP2("Property_Property() start");
	#if defined _YSI_SETUP_MASTER
		YSI_g_sIsMaster = Master_Add("YSIM_Properties");
	#endif
	DBGP5("Property_Property() 0");
	Timer_Add("Property_Loop", PROPERTY_LOOP_GRANULARITY);
	DBGP5("Property_Property() 1");
	#if defined _YSI_CORE_COMMANDS
		ycmd("buy");
		ycmd("bank");
		ycmd("properties");
		ycmd("balance");
		ycmd("withdraw");
		ycmd("sell");
		ycmd("enter");
		ycmd("exit");
	#endif
	DBGP5("Property_Property() 2");
	for (new i = 0; i < MAX_AREAS; i++) YSI_g_sAreaPointers[i] = NO_PROPERTY;
	DBGP5("Property_Property() 3");
	for (new i = 0; i < MAX_CHECKPOINTS; i++) YSI_g_sCheckpointPointers[i] = NO_PROPERTY;
	#if defined _YSI_VISUAL_PICKUPS
		DBGP4("Property_Property() 4 " #MAX_DYN_PICKUPS);
		for (new i = 0; i < MAX_DYN_PICKUPS; i++) YSI_g_sPickupPointers[i] = NO_PROPERTY;
	#endif
	DBGP2("Property_Property() end");
	return 1;
}

#if defined _YSI_SETUP_MASTER

/*----------------------------------------------------------------------------*-
Function:
	YSIM_Properties
Params:
	command - Instruction from the master system.
Return:
	-
Notes:
	Called when the properties master is being shut down to handle arbitration.
-*----------------------------------------------------------------------------*/

	public YSIM_Properties(command)
	{
		switch (command & 0xFF000000)
		{
			case E_MASTER_SET_MASTER:
			{
				YSI_g_sIsMaster = 1;
			}
			case E_MASTER_RELINQUISH:
			{
				new
					master = (command & 0x00FFFFFF);
				if (master == YSI_gMasterID)
				{
					for (new i = 0; i < MAX_CHECKPOINTS; i++)
					{
						if (Property_IsActive(i))
						{
							if (YSI_g_sProperties[i][E_PROP_DATA_MASTER] != master)
							{
								CallRemoteFunction("Property_Broadcast", "iaiiiiiai", i,
									YSI_g_sProperties[i][E_PROP_DATA_NAME], MAX_PROP_NAME,
									_:YSI_g_sProperties[i][E_PROP_DATA_FLAGS],
									YSI_g_sProperties[i][E_PROP_DATA_DATA_1],
									YSI_g_sProperties[i][E_PROP_DATA_DATA_2],
									YSI_g_sProperties[i][E_PROP_DATA_MASTER],
									_:YSI_g_sProperties[i][E_PROP_DATA_PLAYERS], PLAYER_BIT_ARRAY
								);
							}
						}
					}
				}
				else
				{
					for (new i = 0; i < MAX_CHECKPOINTS; i++)
					{
						if (Property_IsActive(i))
						{
							if (YSI_g_sProperties[i][E_PROP_DATA_MASTER] == master)
							{
								new
									e_PROP_FLAGS:flags = YSI_g_sProperties[i][E_PROP_DATA_FLAGS];
								YSI_g_sProperties[i][E_PROP_DATA_FLAGS] = e_PROP_FLAGS:0;
								if (flags & e_PROP_FLAGS_TYPES >= e_PROP_FLAGS_TYPE_MONA)
								{
									YSI_g_sAreaPointers[_:(flags & e_PROP_FLAGS_LINK)] = NO_PROPERTY;
									Area_Delete(_:(flags & e_PROP_FLAGS_LINK));
								}
								else
								{
									YSI_g_sCheckpointPointers[_:(flags & e_PROP_FLAGS_LINK)] = NO_PROPERTY;
									DestroyCheckpoint(_:(flags & e_PROP_FLAGS_LINK));
								}
								for (new j = 0; j < MAX_PLAYERS; j++) Bit_Set(YSI_g_sPlayerProperties[j], i, 0, GROUP_PROPERTY_BITS);
							}
						}
					}
				}
			}
			case E_MASTER_NOT_MASTER:
			{
				YSI_g_sIsMaster = 0;
			}
		}
	}

/*----------------------------------------------------------------------------*-
Function:
	Property_Broadcast
Params:
	id - Property being transferred.
	name[] - Data in name array for property.
	nlength - Size of name data.
	e_PROP_FLAGS:flags - Flags for the property.
	data1 - Data for the property.
	data2 - More data for the property.
	master - Which script owns the property.
	Bit:players[] - Array of player data for the property.
	plength - Size of player data.
Return:
	-
Notes:
	Recieves data on existing properties when the property master is changed.
	The old master broadcasts data for properties not owned by itself and this
	function recieves the data in the new master and saves it for seamless
	processing.
-*----------------------------------------------------------------------------*/

	public Property_Broadcast(id, name[], nlength, e_PROP_FLAGS:flags, data1, data2, master, Bit:players[], plength)
	{
		if (!YSI_g_sIsMaster) return;
		for (new i = 0; i < nlength && i < MAX_PROP_NAME; i++)
		{
			YSI_g_sProperties[id][E_PROP_DATA_NAME][i] = name[i];
		}
		YSI_g_sProperties[id][E_PROP_DATA_FLAGS] = flags;
		YSI_g_sProperties[id][E_PROP_DATA_DATA_1] = data1;
		YSI_g_sProperties[id][E_PROP_DATA_DATA_2] = data2;
		YSI_g_sProperties[id][E_PROP_DATA_MASTER] = master;
		for (new i = 0; i < plength && i < PLAYER_BIT_ARRAY; i++)
		{
			YSI_g_sProperties[id][E_PROP_DATA_PLAYERS][i] = players[i];
		}
		if (flags & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_PROP)
		{
			if (Property_GetOption(2, flags))
			{
				foreach (Player, i)
				{
					if (Bit_Get(players, i, plength))
					{
						Bit_Set(YSI_g_sPlayerProperties[i], id, 1, GROUP_PROPERTY_BITS);
						YSI_g_sPropCount[i]++;
					}
				}
			}
			else
			{
				if (IsPlayerConnected(_:players[0]))
				{
					Bit_Set(YSI_g_sPlayerProperties[_:players[0]], id, 1, GROUP_PROPERTY_BITS);
					YSI_g_sPropCount[_:players[0]]++;
				}
			}
		}
		if (flags & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_HOUS)
		{
			if (IsPlayerConnected(_:players[0]))
			{
				Bit_Set(YSI_g_sPlayerProperties[_:players[0]], id, 1, GROUP_PROPERTY_BITS);
				YSI_g_sHouseCount[_:players[0]]++;
			}
		}
		if (flags & e_PROP_FLAGS_TYPES >= e_PROP_FLAGS_TYPE_MONA)
		{
			YSI_g_sAreaPointers[_:(flags & e_PROP_FLAGS_LINK)] = id;
		}
		else
		{
			YSI_g_sCheckpointPointers[_:(flags & e_PROP_FLAGS_LINK)] = id;
		}
	}
#endif

/*----------------------------------------------------------------------------*-
Function:
	DestroyProperty
Params:
	property - Property to destroy.
Return:
	-
Notes:
	-
-*----------------------------------------------------------------------------*/

stock DestroyProperty(property)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			if (!Property_IsActive(property)) return 0;
			new
				e_PROP_FLAGS:flags = YSI_g_sProperties[property][E_PROP_DATA_FLAGS];
			YSI_g_sProperties[property][E_PROP_DATA_FLAGS] = e_PROP_FLAGS:0;
			if (flags & e_PROP_FLAGS_TYPES >= e_PROP_FLAGS_TYPE_MONA)
			{
				YSI_g_sAreaPointers[_:(flags & e_PROP_FLAGS_LINK)] = NO_PROPERTY;
				Area_Delete(_:(flags & e_PROP_FLAGS_LINK));
			}
			else
			{
				#if defined _YSI_VISUAL_PICKUPS
					if ((flags & e_PROP_FLAGS_TYPES > e_PROP_FLAGS_TYPE_PROP) && Property_GetOption(5, flags))
					{
						Pickup_Remove(_:(flags & e_PROP_FLAGS_LINK));
						YSI_g_sPickupPointers[_:(flags & e_PROP_FLAGS_LINK)] = NO_PROPERTY;
					}
					else
				#endif
				{
					YSI_g_sCheckpointPointers[_:(flags & e_PROP_FLAGS_LINK)] = NO_PROPERTY;
					DestroyCheckpoint(_:(flags & e_PROP_FLAGS_LINK));
				}
			}
			for (new i = 0; i < MAX_PLAYERS; i++) Bit_Set(YSI_g_sPlayerProperties[i], property, 0, GROUP_PROPERTY_BITS);
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", property, 0, E_PROP_REMOTE_DELETE);
		}
	#endif
	return 1;
}

/*----------------------------------------------------------------------------*-
Function:
	CreateHouse
Params:
	Float:extX - X position of the external marker.
	Float:extY - Y position of the external marker.
	Float:extZ - Z position of the external marker.
	Float:intX - X position of the internal marker.
	Float:intY - Y position of the internal marker.
	Float:intZ - Z position of the internal marker.
	interior - Interior ID of the house.
	world - Virtual world of the house.
	price - Price of the house.
	checkpoint - Use a checkpoint instead of a pickup.
Return:
	-
Notes:
	Creates a buyable property (business).
-*----------------------------------------------------------------------------*/

stock CreateHouse(Float:extX, Float:extY, Float:extZ, Float:intX, Float:intY, Float:intZ, interior, world, price, checkpoint = 0)
{
	DBGP2("CreateHouse() start 1");
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
			return Property_AddHouseRemote(YSI_gMasterID, extX, extY, extZ, intX, intY, intZ, interior, world, price, checkpoint);
		}
		else
		{
			CallRemoteFunction("Property_AddHouseRemote", "iffffffiiii", YSI_gMasterID, extX, extY, extZ, intX, intY, intZ, interior, world, price, checkpoint);
			return getproperty(0, "YSIReq");
		}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_AddRemote
Params:
	master - Which script owns the property.
	Float:extX - X position of the external marker.
	Float:extY - Y position of the external marker.
	Float:extZ - Z position of the external marker.
	Float:intX - X position of the internal marker.
	Float:intY - Y position of the internal marker.
	Float:intZ - Z position of the internal marker.
	interior - Interior ID of the house.
	world - Virtual world of the house.
	price - Price of the house.
	checkpoint - Use a checkpoint instead of a pickup.
Return:
	-
Notes:
	Remote wrapper for CreateProperty.
-*----------------------------------------------------------------------------*/

public Property_AddHouseRemote(master, Float:extX, Float:extY, Float:extZ, Float:intX, Float:intY, Float:intZ, interior, world, price, checkpoint)
{
	if (!YSI_g_sIsMaster) return NO_PROPERTY;
	setproperty(0, "YSIReq", NO_PROPERTY);
#endif
	DBGP2("CreateHouse() start 2");
	new
		i;
	while (i < MAX_PROPERTIES && Property_IsActive(i))
	{
		i++;
	}
	if (i == MAX_PROPERTIES) return NO_PROPERTY;
	new
		cp;
	DBGP4("CreateHouse() Make");
	#if defined _YSI_VISUAL_PICKUPS
		if (!checkpoint)
		{
			if ((cp = Pickup_Add(1273, extX, extY, extZ, 0, -1)) == NO_PICKUP) return NO_PROPERTY;
			YSI_g_sPickupProps++;
		}
		else
	#else
		checkpoint = 1;
	#endif
	#pragma tabsize 4
			if ((cp = CreateCheckpoint(extX, extY, extZ, 3.0)) == NO_CHECKPOINT) return NO_PROPERTY;
	#pragma tabsize 4
	DBGP4("CreateHouse() Made");
	YSI_g_sProperties[i][E_PROP_DATA_FLAGS] = e_PROP_FLAGS_TYPE_HOUS | e_PROP_FLAGS_ACTIVE | e_PROP_FLAGS:cp | Property_SetOption(1, checkpoint);
	YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][0] = Bit:INVALID_PLAYER_ID;
	YSI_g_sProperties[i][E_PROP_DATA_DATA_1] = interior;
	YSI_g_sProperties[i][E_PROP_DATA_DATA_2] = world;
	
	DBGP4("CreateHouse() Save pos");
	YSI_g_sProperties[i][E_PROP_DATA_NAME][0] = _:extX;
	YSI_g_sProperties[i][E_PROP_DATA_NAME][1] = _:extY;
	YSI_g_sProperties[i][E_PROP_DATA_NAME][2] = _:extZ;
	YSI_g_sProperties[i][E_PROP_DATA_NAME][3] = _:intX;
	YSI_g_sProperties[i][E_PROP_DATA_NAME][4] = _:intY;
	YSI_g_sProperties[i][E_PROP_DATA_NAME][5] = _:intZ;
	YSI_g_sProperties[i][E_PROP_DATA_NAME][6] = price;

	DBGP4("CreateHouse() Save ID");
	#if defined _YSI_VISUAL_PICKUPS
		if (!checkpoint)
		{
			YSI_g_sPickupPointers[cp] = i;
		}
		else
	#endif
	#pragma tabsize 4
			YSI_g_sCheckpointPointers[cp] = i;
	#pragma tabsize 4
	#if defined _YSI_SETUP_MASTER
		YSI_g_sProperties[i][E_PROP_DATA_MASTER] = master;
		setproperty(0, "YSIReq", i);
	#endif
	return i;
}

/*----------------------------------------------------------------------------*-
Function:
	CreateProperty
Params:
	name[] - Name of the property.
	Float:x - X position.
	Float:y - Y position.
	Float:z - Z position.
	price - Cost of the property.
	reward - Money earnt from the property periodically.
	interval - How often you earn money.
	sell - Wether you need to seel the property of people can just buy you out.
	multi - Wether more than one person can own this property at once.
	reduce - Wether selling this property gets you less then you paid for it.
	increase - Wether buying this property will put the price up for the future.
	property - Wether this property uses a pickup instead of a checkpoint.
Return:
	-
Notes:
	Creates a buyable property (business).
-*----------------------------------------------------------------------------*/

stock CreateProperty(name[], Float:x, Float:y, Float:z, price, reward, interval = 60000, sell = 0, multi = 0, reduce = 0, increase = 0, pickup = 0)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
			return Property_AddPropRemote(YSI_gMasterID, name, x, y, z, price, reward, interval, sell, multi, reduce, increase, pickup);
		}
		else
		{
			if (name[0]) CallRemoteFunction("Property_AddPropRemote", "isfffiiiiiii", YSI_gMasterID, name, x, y, z, price, reward, interval, sell, multi, reduce, increase, pickup);
			else CallRemoteFunction("Property_AddPropRemote", "isfffiiiiiii", YSI_gMasterID, NULL, x, y, z, price, reward, interval, sell, multi, reduce, increase, pickup);
			return getproperty(0, "YSIReq");
		}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_AddRemote
Params:
	master - Which script owns the property.
	name[] - Name of the property.
	Float:x - X position.
	Float:y - Y position.
	Float:z - Z position.
	price - Cost of the property.
	reward - Money gained from the property.
	interval - Time between money rewards.
	sell - Property must be sold.
	multi - Property can have multiple owners.
	reduce - Property gives you less money on sale.
	increase - Property costs more for people to buy off you.
Return:
	-
Notes:
	Remote wrapper for CreateProperty.
-*----------------------------------------------------------------------------*/

public Property_AddPropRemote(master, name[], Float:x, Float:y, Float:z, price, reward, interval, sell, multi, reduce, increase, pickup)
{
	if (!YSI_g_sIsMaster) return NO_PROPERTY;
	setproperty(0, "YSIReq", NO_PROPERTY);
#endif
	new
		i;
	while (i < MAX_PROPERTIES && Property_IsActive(i))
	{
		i++;
	}
	if (i == MAX_PROPERTIES) return NO_PROPERTY;
	new
		cp;
	#if defined _YSI_VISUAL_PICKUPS
		if (pickup)
		{
			if ((cp = Pickup_Add(1273, x, y, z, 0, -1)) == NO_PICKUP) return NO_PROPERTY;
			YSI_g_sPickupProps++;
		}
		else
	#endif
	#pragma tabsize 4
			if ((cp = CreateCheckpoint(x, y, z, 3.0)) == NO_CHECKPOINT) return NO_PROPERTY;
	#pragma tabsize 4
	YSI_g_sProperties[i][E_PROP_DATA_FLAGS] = e_PROP_FLAGS_TYPE_PROP | e_PROP_FLAGS_ACTIVE | e_PROP_FLAGS:cp | Property_SetOption(1, sell) | Property_SetOption(2, multi) | Property_SetOption(3, reduce) | Property_SetOption(4, increase) | Property_SetOption(5, pickup);
	if (multi) Bit_SetAll(YSI_g_sProperties[i][E_PROP_DATA_PLAYERS], 0, PLAYER_BIT_ARRAY);
	else YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][0] = Bit:INVALID_PLAYER_ID;
	YSI_g_sProperties[i][E_PROP_DATA_NAME][MAX_PROP_NAME - 1] = interval & 0xFFFFF;
	YSI_g_sProperties[i][E_PROP_DATA_DATA_1] = (interval & 0xFFFFF) | ((price & 0x00000FFF) << 20);
	YSI_g_sProperties[i][E_PROP_DATA_DATA_2] = (reward & 0x3FFFF) | ((price & 0x03FFF000) << 6);
	if (!isnull(name)) strcpy(YSI_g_sProperties[i][E_PROP_DATA_NAME], name, MAX_PROP_NAME - 1);
	else YSI_g_sProperties[i][E_PROP_DATA_NAME][0] = '\0';
	#if defined _YSI_VISUAL_PICKUPS
		if (pickup)
		{
			YSI_g_sPickupPointers[cp] = i;
		}
		else
	#endif
	#pragma tabsize 4
			YSI_g_sCheckpointPointers[cp] = i;
	#pragma tabsize 4
	#if defined _YSI_SETUP_MASTER
		YSI_g_sProperties[i][E_PROP_DATA_MASTER] = master;
		setproperty(0, "YSIReq", i);
	#endif
	return i;
}

/*----------------------------------------------------------------------------*-
Function:
	CreateBank
Params:
	Float:x - X position.
	Float:y - Y position.
	Float:z - Z position.
	name[] - Name of the bank.
Return:
	-
Notes:
	-
-*----------------------------------------------------------------------------*/

stock CreateBank(Float:x, Float:y, Float:z, name[] = "")
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
			return Property_AddBankRemote(YSI_gMasterID, x, y, z, name);
		}
		else
		{
			if (name[0]) CallRemoteFunction("Property_AddBankRemote", "ifffs", YSI_gMasterID, x, y, z, name);
			else CallRemoteFunction("Property_AddBankRemote", "ifffs", YSI_gMasterID, x, y, z, NULL);
			return getproperty(0, "YSIReq");
		}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_AddBankRemote
Params:
	master - Which script owns the bank.
	Float:x - X position.
	Float:y - Y position.
	Float:z - Z position.
	name[] - Name of the bank.
Return:
	-
Notes:
	Remote wrapper for CreateBank.
-*----------------------------------------------------------------------------*/

public Property_AddBankRemote(master, Float:x, Float:y, Float:z, name[])
{
	if (!YSI_g_sIsMaster) return NO_PROPERTY;
	setproperty(0, "YSIReq", NO_PROPERTY);
#endif
	new
		i;
	while (i < MAX_PROPERTIES)
	{
		if (!Property_IsActive(i)) break;
		i++;
	}
	if (i == MAX_PROPERTIES) return NO_PROPERTY;
	new
		cp = CreateCheckpoint(x, y, z, 3.0);
	if (cp == NO_CHECKPOINT) return NO_PROPERTY;
	YSI_g_sProperties[i][E_PROP_DATA_FLAGS] = e_PROP_FLAGS_TYPE_BANK | e_PROP_FLAGS_ACTIVE | e_PROP_FLAGS:cp;
	if (!isnull(name)) strcpy(YSI_g_sProperties[i][E_PROP_DATA_NAME], name, MAX_PROP_NAME);
	else YSI_g_sProperties[i][E_PROP_DATA_NAME][0] = '\0';
	YSI_g_sCheckpointPointers[cp] = i;
	#if defined _YSI_SETUP_MASTER
		YSI_g_sProperties[i][E_PROP_DATA_MASTER] = master;
		setproperty(0, "YSIReq", i);
	#endif
	return i;
}

/*----------------------------------------------------------------------------*-
Function:
	CreateAmmunation
Params:
	Float:x - X position.
	Float:y - Y position.
	Float:z - Z position.
	spawn - Wether you spawn with the weapon.
	instant - Wether you get the weapon as soon as you buy it.
	...
Return:
	-
Notes:
	spawn and instant can BOTH be 1.  The format of the additional parameters
	is:
	
	weapon, ammo, price
	
	They MUST come in sets of three of the function will fail.  Weapon is in
	the form of the WEAPON_ defines in a_samp or WEAPON_ARMOUR.
-*----------------------------------------------------------------------------*/

stock CreateAmmunation(Float:x, Float:y, Float:z, spawn, instant, ...)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			new
				num = numargs();
			if (((num) <= 5) || (((num - 5) / 3) * 3 != (num - 5))) return NO_PROPERTY;
			new
				i;
			while (i < MAX_PROPERTIES)
			{
				if (!Property_IsActive(i)) break;
				i++;
			}
			if (i == MAX_PROPERTIES) return NO_PROPERTY;
			new
				cp = CreateCheckpoint(x, y, z, 3.0);
			if (cp == NO_CHECKPOINT) return NO_PROPERTY;
			YSI_g_sProperties[i][E_PROP_DATA_FLAGS] = e_PROP_FLAGS_TYPE_AMMU | e_PROP_FLAGS_ACTIVE | e_PROP_FLAGS:cp | Property_SetOption(1, spawn) | Property_SetOption(2, instant);
			new
				pos = 5,
				count;
			while (pos < num)
			{
				switch (getarg(pos++))
				{
					case WEAPON_BRASSKNUCKLE:
						YSI_g_sProperties[i][E_PROP_DATA_DATA_1] = WEAPON_DATA;
					case WEAPON_GOLFCLUB:
						YSI_g_sProperties[i][E_PROP_DATA_DATA_2] = WEAPON_DATA;
					case WEAPON_NITESTICK:
						YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][0] = Bit:WEAPON_DATA;
					case WEAPON_KNIFE:
						YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][1] = Bit:WEAPON_DATA;
					case WEAPON_BAT:
						#if PLAYER_BIT_ARRAY > 2
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][2] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][0 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_SHOVEL:
						#if PLAYER_BIT_ARRAY > 3
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][3] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][1 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_POOLSTICK:
						#if PLAYER_BIT_ARRAY > 4
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][4] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][2 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_KATANA:
						#if PLAYER_BIT_ARRAY > 5
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][5] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][3 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_CHAINSAW:
						#if PLAYER_BIT_ARRAY > 6
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][6] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][4 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_DILDO:
						#if PLAYER_BIT_ARRAY > 7
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][7] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][5 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_DILDO2:
						#if PLAYER_BIT_ARRAY > 8
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][8] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][6 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_VIBRATOR:
						#if PLAYER_BIT_ARRAY > 9
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][9] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][7 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_VIBRATOR2:
						#if PLAYER_BIT_ARRAY > 10
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][10] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][8 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_FLOWER:
						#if PLAYER_BIT_ARRAY > 11
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][11] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][9 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_CANE:
						#if PLAYER_BIT_ARRAY > 12
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][12] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][10 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_GRENADE:
						#if PLAYER_BIT_ARRAY > 13
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][13] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][11 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_TEARGAS:
						#if PLAYER_BIT_ARRAY > 14
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][14] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][12 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_MOLTOV:
						#if PLAYER_BIT_ARRAY > 15
							YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][15] = Bit:WEAPON_DATA;
						#else
							YSI_g_sProperties[i][E_PROP_DATA_NAME][13 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
						#endif
					case WEAPON_COLT45:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][14 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_SILENCED:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][15 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_DEAGLE:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][16 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_SHOTGUN:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][17 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_SAWEDOFF:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][18 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_SHOTGSPA:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][19 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_UZI:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][20 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_MP5:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][21 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_AK47:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][22 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_M4:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][23 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_TEC9:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][24 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_RIFLE:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][25 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_SNIPER:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][26 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_ROCKETLAUNCHER:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][27 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_FLAMETHROWER:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][28 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_MINIGUN:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][29 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_SATCHEL:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][30 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_SPRAYCAN:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][31 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_FIREEXTINGUISHER:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][32 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_CAMERA:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][33 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_PARACHUTE:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][34 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					case WEAPON_ARMOUR:
						YSI_g_sProperties[i][E_PROP_DATA_NAME][35 - WEAPON_DATA_OFFSET] = WEAPON_DATA;
					default:
					{
						pos += 2;
						count--;
					}
				}
				count++;
			}
			YSI_g_sProperties[i][E_PROP_DATA_NAME][MAX_PROP_NAME - 1] = count;
			YSI_g_sCheckpointPointers[cp] = i;
			#if defined _YSI_SETUP_MASTER
				YSI_g_sProperties[i][E_PROP_DATA_MASTER] = YSI_gMasterID;
			#endif
			return i;
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			new
				num = numargs();
			if (((num) <= 5) || (((num - 5) / 3) * 3 != (num - 5))) return NO_PROPERTY;
			new
				pos = 5,
				idx,
				arr[128];
			while (pos < num && idx < sizeof (arr))
			{
				arr[idx++] = getarg(pos++);
			}
			CallRemoteFunction("Property_AddAmmuRemote", "ifffiiai", YSI_gMasterID, x, y, z, spawn, instant, arr, idx);
			return getproperty(0, "YSIReq");
		}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_AddAmmuRemote
Params:
	master - Which script owns the ammunation.
	Float:x - X position.
	Float:y - Y position.
	Float:z - Z position.
	spawn - Wether you spawn with the weapon.
	instant - Wether you get the weapon straight away.
	dat[] - Weapon data for the ammunation.
	num - Ammount of data.
Return:
	-
Notes:
	Remote wrapper for CreateAmmunation.
-*----------------------------------------------------------------------------*/

public Property_AddAmmuRemote(master, Float:x, Float:y, Float:z, spawn, instant, dat[], num)
{
	if (!YSI_g_sIsMaster) return NO_PROPERTY;
	setproperty(0, "YSIReq", NO_PROPERTY);
	new
		i;
	while (i < MAX_PROPERTIES)
	{
		if (!Property_IsActive(i)) break;
		i++;
	}
	if (i == MAX_PROPERTIES) return NO_PROPERTY;
	new
		cp = CreateCheckpoint(x, y, z, 3.0);
	if (cp == NO_CHECKPOINT) return NO_PROPERTY;
	YSI_g_sProperties[i][E_PROP_DATA_FLAGS] = e_PROP_FLAGS_TYPE_AMMU | e_PROP_FLAGS_ACTIVE | e_PROP_FLAGS:cp | Property_SetOption(1, spawn) | Property_SetOption(2, instant);
	new
		pos,
		count;
	while (pos < num)
	{
		switch (dat[pos++])
		{
			case WEAPON_BRASSKNUCKLE:
				YSI_g_sProperties[i][E_PROP_DATA_DATA_1] = WEAPON_DATA_REM;
			case WEAPON_GOLFCLUB:
				YSI_g_sProperties[i][E_PROP_DATA_DATA_2] = WEAPON_DATA_REM;
			case WEAPON_NITESTICK:
				YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][0] = Bit:WEAPON_DATA_REM;
			case WEAPON_KNIFE:
				YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][1] = Bit:WEAPON_DATA_REM;
			case WEAPON_BAT:
				#if PLAYER_BIT_ARRAY > 2
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][2] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][0 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_SHOVEL:
				#if PLAYER_BIT_ARRAY > 3
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][3] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][1 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_POOLSTICK:
				#if PLAYER_BIT_ARRAY > 4
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][4] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][2 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_KATANA:
				#if PLAYER_BIT_ARRAY > 5
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][5] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][3 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_CHAINSAW:
				#if PLAYER_BIT_ARRAY > 6
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][6] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][4 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_DILDO:
				#if PLAYER_BIT_ARRAY > 7
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][7] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][5 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_DILDO2:
				#if PLAYER_BIT_ARRAY > 8
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][8] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][6 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_VIBRATOR:
				#if PLAYER_BIT_ARRAY > 9
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][9] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][7 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_VIBRATOR2:
				#if PLAYER_BIT_ARRAY > 10
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][10] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][8 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_FLOWER:
				#if PLAYER_BIT_ARRAY > 11
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][11] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][9 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_CANE:
				#if PLAYER_BIT_ARRAY > 12
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][12] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][10 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_GRENADE:
				#if PLAYER_BIT_ARRAY > 13
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][13] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][11 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_TEARGAS:
				#if PLAYER_BIT_ARRAY > 14
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][14] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][12 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_MOLTOV:
				#if PLAYER_BIT_ARRAY > 15
					YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][15] = Bit:WEAPON_DATA_REM;
				#else
					YSI_g_sProperties[i][E_PROP_DATA_NAME][13 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
				#endif
			case WEAPON_COLT45:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][14 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_SILENCED:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][15 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_DEAGLE:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][16 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_SHOTGUN:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][17 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_SAWEDOFF:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][18 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_SHOTGSPA:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][19 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_UZI:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][20 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_MP5:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][21 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_AK47:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][22 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_M4:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][23 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_TEC9:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][24 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_RIFLE:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][25 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_SNIPER:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][26 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_ROCKETLAUNCHER:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][27 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_FLAMETHROWER:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][28 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_MINIGUN:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][29 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_SATCHEL:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][30 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_SPRAYCAN:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][31 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_FIREEXTINGUISHER:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][32 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_CAMERA:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][33 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_PARACHUTE:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][34 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			case WEAPON_ARMOUR:
				YSI_g_sProperties[i][E_PROP_DATA_NAME][35 - WEAPON_DATA_OFFSET] = WEAPON_DATA_REM;
			default:
			{
				pos += 2;
				count--;
			}
		}
		count++;
	}
	YSI_g_sProperties[i][E_PROP_DATA_NAME][MAX_PROP_NAME - 1] = count;
	YSI_g_sCheckpointPointers[cp] = i;
	YSI_g_sProperties[i][E_PROP_DATA_MASTER] = master;
	setproperty(0, "YSIReq", i);
	return i;
	#endif
}

/*----------------------------------------------------------------------------*-
Function:
	CreateMoneyArea
Params:
	area - Reference to a defined area.
	money - How much you earn.
	interval - How often you earn.
Return:
	-
Notes:
	This function has internal checking for invalid areas so you can just pass
	the return from an Area_ funtion directly.
-*----------------------------------------------------------------------------*/

stock CreateMoneyArea(area, money = 100, interval = 10000)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
			return Property_AddMARemote(YSI_gMasterID, area, money, interval);
		}
		else
		{
			CallRemoteFunction("Property_AddMARemote", "iiii", YSI_gMasterID, area, money, interval);
			return getproperty(0, "YSIReq");
		}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_AddMARemote
Params:
	master - Which script owns the area.
	area - Pointer to the area.
	manoey - Money awarded.
	interval - Time between money awards.
Return:
	-
Notes:
	Remote wrapper for CreateMoneyArea.
-*----------------------------------------------------------------------------*/

public Property_AddMARemote(master, area, money, interval)
{
	if (!YSI_g_sIsMaster) return NO_PROPERTY;
	setproperty(0, "YSIReq", NO_PROPERTY);
#endif
	if (area == NO_AREA) return NO_PROPERTY;
	new
		i;
	while (i < MAX_PROPERTIES)
	{
		if (!Property_IsActive(i)) break;
		i++;
	}
	if (i == MAX_PROPERTIES) return NO_PROPERTY;
	YSI_g_sProperties[i][E_PROP_DATA_FLAGS] = e_PROP_FLAGS_TYPE_MONA | e_PROP_FLAGS_ACTIVE | e_PROP_FLAGS:area;
	YSI_g_sProperties[i][E_PROP_DATA_DATA_1] = money;
	YSI_g_sProperties[i][E_PROP_DATA_DATA_2] = interval;
	YSI_g_sProperties[i][E_PROP_DATA_NAME][0] = interval;
	YSI_g_sAreaPointers[area] = i;
	#if defined _YSI_SETUP_MASTER
		YSI_g_sProperties[i][E_PROP_DATA_MASTER] = master;
		setproperty(0, "YSIReq", i);
	#endif
	return i;
}

/*----------------------------------------------------------------------------*-
Function:
	CreateMoneyPoint
Params:
	Float:x - X position.
	Float:y - Y position.
	Float:z - Z position.
	Float:s - Size of checkpoint.
	money - How much you earn.
	interval - How often you earn.
Return:
	-
Notes:
	Like CreateMoneyArea but you must be in a checkpoint.
-*----------------------------------------------------------------------------*/

stock CreateMoneyPoint(Float:x, Float:y, Float:z, Float:s, money = 100, interval = 10000)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
			return Property_AddMPRemote(YSI_gMasterID, x, y, z, s, money, interval);
		}
		else
		{
			CallRemoteFunction("Property_AddMPRemote", "iffffii", YSI_gMasterID, x, y, z, s, money, interval);
			return getproperty(0, "YSIReq");
		}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_AddMPRemote
Params:
	master - Which script owns the point.
	Float:x - X position.
	Float:y - Y position.
	Float:z - Z position.
	Float:s - Size of the point.
	money - Money earnt.
	interval - Time between money awards.
Return:
	-
Notes:
	Remote wrapper for CreateMoneyPoint.
-*----------------------------------------------------------------------------*/

public Property_AddMPRemote(master, Float:x, Float:y, Float:z, Float:s, money, interval)
{
	if (!YSI_g_sIsMaster) return NO_PROPERTY;
	setproperty(0, "YSIReq", NO_PROPERTY);
#endif
	new
		i;
	while (i < MAX_PROPERTIES)
	{
		if (!Property_IsActive(i)) break;
		i++;
	}
	if (i == MAX_PROPERTIES) return NO_PROPERTY;
	new
		cp = CreateCheckpoint(x, y, z, s);
	if (cp == NO_CHECKPOINT) return NO_PROPERTY;
	YSI_g_sProperties[i][E_PROP_DATA_FLAGS] = e_PROP_FLAGS_TYPE_MONP | e_PROP_FLAGS_ACTIVE | e_PROP_FLAGS:cp;
	YSI_g_sProperties[i][E_PROP_DATA_DATA_1] = money;
	YSI_g_sProperties[i][E_PROP_DATA_DATA_2] = interval;
	YSI_g_sProperties[i][E_PROP_DATA_NAME][0] = interval;
	YSI_g_sCheckpointPointers[cp] = i;
	#if defined _YSI_SETUP_MASTER
		YSI_g_sProperties[i][E_PROP_DATA_MASTER] = master;
		setproperty(0, "YSIReq", i);
	#endif
	return i;
}

/*----------------------------------------------------------------------------*-
Function:
	CreateTeleport
Params:
	Float:sx - Start X.
	Float:sy - Start Y.
	Float:sz - Start Z.
	Float:tz - Target X.
	Float:ty - Target Y.
	Float:tz - Target Z.
	cost - Price to use the teleport.
	name[] - Name of the destination.
Return:
	-
Notes:
	Will teleport you the moment you step in.
-*----------------------------------------------------------------------------*/

stock CreateTeleport(Float:sx, Float:sy, Float:sz, Float:tx, Float:ty, Float:tz, cost = 0, name[] = "")
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
			return Property_AddTeleRemote(YSI_gMasterID, sx, sy, sz, tx, ty, tz, cost, name);
		}
		else
		{
			if (name[0]) CallRemoteFunction("Property_AddTeleRemote", "iffffffis", YSI_gMasterID, sx, sy, sz, tx, ty, tz, cost, name);
			else CallRemoteFunction("Property_AddTeleRemote", "iffffffis", YSI_gMasterID, sx, sy, sz, tx, ty, tz, cost, NULL);
			return getproperty(0, "YSIReq");
		}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_AddTeleRemote
Params:
	master - Script which owns the teleport.
	Float:sx - Start x point of the teleport.
	Float:sy - Start y point of the teleport.
	Float:sz - Start z point of the teleport.
	Float:tx - End x point of the teleport.
	Float:ty - End y point of the teleport.
	Float:tz - End z point of the teleport.
	cost - Cost of teleporting.
	name[] - Name of the teleport.
Return:
	-
Notes:
	Remote wrapper for CreateTeleport.
-*----------------------------------------------------------------------------*/

public Property_AddTeleRemote(master, Float:sx, Float:sy, Float:sz, Float:tx, Float:ty, Float:tz, cost, name[])
{
	if (!YSI_g_sIsMaster) return NO_PROPERTY;
	setproperty(0, "YSIReq", NO_PROPERTY);
#endif
	new
		i;
	while (i < MAX_PROPERTIES)
	{
		if (!Property_IsActive(i)) break;
		i++;
	}
	if (i == MAX_PROPERTIES) return NO_PROPERTY;
	new
		cp = CreateCheckpoint(sx, sy, sz, 3.0);
	if (cp == NO_CHECKPOINT) return NO_PROPERTY;
	YSI_g_sProperties[i][E_PROP_DATA_FLAGS] = e_PROP_FLAGS_TYPE_TELS | e_PROP_FLAGS_ACTIVE | e_PROP_FLAGS:cp;
	YSI_g_sProperties[i][E_PROP_DATA_DATA_1] = cost;
	YSI_g_sProperties[i][E_PROP_DATA_DATA_2] = _:tx;
	YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][0] = Bit:ty;
	YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][1] = Bit:tz;
	if (!isnull(name)) strcpy(YSI_g_sProperties[i][E_PROP_DATA_NAME], name, MAX_PROP_NAME);
	else YSI_g_sProperties[i][E_PROP_DATA_NAME][0] = '\0';
	YSI_g_sCheckpointPointers[cp] = i;
	#if defined _YSI_SETUP_MASTER
		YSI_g_sProperties[i][E_PROP_DATA_MASTER] = master;
		setproperty(0, "YSIReq", i);
	#endif
	return i;
}

/*----------------------------------------------------------------------------*-
Function:
	CreateForbiddenArea
Params:
	area - Reference to a defined area.
	kick - Wether they should be kicked out not hurt.
	health - How much health should be removed every itteration they're in.
	invert - Not allowed to leave the area rather than enter.
	name[] - Name of the area.
Return:
	-
Notes:
	If kick is 1 people will simply be constantly replaced outside the area
	from the direction they came.
-*----------------------------------------------------------------------------*/

stock CreateForbiddenArea(area, kick = 0, health = 1000, invert = 0, name[] = "")
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
			return Property_AddFobRemote(YSI_gMasterID, area, kick, health, invert, name);
		}
		else
		{
			if (name[0]) CallRemoteFunction("Property_AddFobRemote", "iiiiis", YSI_gMasterID, area, kick, health, invert, name);
			else CallRemoteFunction("Property_AddFobRemote", "iiiiis", YSI_gMasterID, area, kick, health, invert, NULL);
			return getproperty(0, "YSIReq");
		}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_AddFobRemote
Params:
	master - Which script owns the area.
	area - Pointer to the area.
	kick - Wether or not to just kick people out.
	health - How much health to remove per itteration.
	invert - Keep people in instead of out.
	name[] - Name of the area.
Return:
	-
Notes:
	Remote wrapper for CreateForbiddenArea.
-*----------------------------------------------------------------------------*/

public Property_AddFobRemote(master, area, kick, health, invert, name[])
{
	if (!YSI_g_sIsMaster) return NO_PROPERTY;
	setproperty(0, "YSIReq", NO_PROPERTY);
#endif
	if (area == NO_AREA) return NO_PROPERTY;
	new
		i;
	while (i < MAX_PROPERTIES)
	{
		if (!Property_IsActive(i)) break;
		i++;
	}
	if (i == MAX_PROPERTIES) return NO_PROPERTY;
	YSI_g_sProperties[i][E_PROP_DATA_FLAGS] = e_PROP_FLAGS_TYPE_RSRC | e_PROP_FLAGS_ACTIVE | e_PROP_FLAGS:area | Property_SetOption(1, kick) | Property_SetOption(2, invert);
	YSI_g_sProperties[i][E_PROP_DATA_DATA_2] = health;
	if (!isnull(name)) strcpy(YSI_g_sProperties[i][E_PROP_DATA_NAME], name, MAX_PROP_NAME);
	else YSI_g_sProperties[i][E_PROP_DATA_NAME][0] = '\0';
	YSI_g_sAreaPointers[area] = i;
	#if defined _YSI_SETUP_MASTER
		YSI_g_sProperties[i][E_PROP_DATA_MASTER] = master;
		setproperty(0, "YSIReq", i);
	#endif
	return i;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_OnPlayerEnterArea
Params:
	playerid - Player who entered an area.
	area - Area they entered.
Return:
	-
Notes:
	Internal callback from YSI_areas.
-*----------------------------------------------------------------------------*/

#if defined _YSI_SETUP_MASTER
	public Property_OnPlayerEnterArea(playerid, area)
	if (!YSI_g_sIsMaster) return 0;
	else
#else
	Property_OnPlayerEnterArea(playerid, area)
#endif
{
	#if defined _YSI_SETUP_MASTER
		setproperty(0, "YSIReq", 0);
	#endif
	new
		prop = YSI_g_sAreaPointers[area];
	if (prop == NO_PROPERTY)
	{
		return 0;
	}
	if (YSI_g_sProperties[prop][E_PROP_DATA_FLAGS] & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_RSRC)
	{
		if (!Property_GetOption(2, YSI_g_sProperties[prop][E_PROP_DATA_FLAGS]))
		{
			if (YSI_g_sProperties[prop][E_PROP_DATA_NAME][0]) Text_SendFormat(playerid, "YSI_FORBIDDEN_2", YSI_g_sProperties[prop][E_PROP_DATA_NAME]);
			else Text_Send(playerid, "YSI_FORBIDDEN");
			Bit_Set(YSI_g_sPlayerProperties[playerid], prop, 1, GROUP_PROPERTY_BITS);
		}
	}
	else Bit_Set(YSI_g_sPlayerProperties[playerid], prop, 1, GROUP_PROPERTY_BITS);
	#if defined _YSI_SETUP_MASTER
		setproperty(0, "YSIReq", 1);
	#endif
	return 1;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_OnPlayerLeaveArea
Params:
	playerid - Player who left an area.
	areaid - Area they left.
Return:
	-
Notes:
	Internal callback from YSI_areas.
-*----------------------------------------------------------------------------*/

#if defined _YSI_SETUP_MASTER
	public Property_OnPlayerLeaveArea(playerid, area)
	if (!YSI_g_sIsMaster) return 0;
	else
#else
	Property_OnPlayerLeaveArea(playerid, area)
#endif
{
	new
		prop = YSI_g_sAreaPointers[area];
	if (prop == NO_PROPERTY)
	{
		#if defined _YSI_SETUP_MASTER
			setproperty(0, "YSIReq", 0);
		#endif
		return 0;
	}
	if (YSI_g_sProperties[prop][E_PROP_DATA_FLAGS] & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_RSRC && Property_GetOption(2, YSI_g_sProperties[prop][E_PROP_DATA_FLAGS]))
	{
		Bit_Set(YSI_g_sPlayerProperties[playerid], prop, 1, GROUP_PROPERTY_BITS);
	}
	else Bit_Set(YSI_g_sPlayerProperties[playerid], prop, 0, GROUP_PROPERTY_BITS);
	#if defined _YSI_SETUP_MASTER
		setproperty(0, "YSIReq", 1);
	#endif
	return 1;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_OnPlayerConnect
Params:
	playerid - Player who connected.
Return:
	-
Notes:
	Internal callback.
-*----------------------------------------------------------------------------*/

Property_OnPlayerConnect(playerid)
{
	YSI_g_sShopMenu[playerid][E_PROP_AMMU_MENU] = Menu:-1;
	Bit_SetAll(YSI_g_sPlayerProperties[playerid], 0, GROUP_PROPERTY_BITS);
	for (new i = 0; i < 13; i++) YSI_g_sSpawnWeapons[playerid][i] = 0;
	YSI_g_sMoney[playerid] = 0;
	return 1;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_OnPlayerConnect
Params:
	playerid - Player who connected.
Return:
	-
Notes:
	Internal callback.
-*----------------------------------------------------------------------------*/

Property_OnPlayerDisconnect(playerid, reason)
{
	for (new j = 0; j < GROUP_PROPERTY_BITS; j++)
	{
		new
			props = _:YSI_g_sPlayerProperties[playerid][j],
			slot = 1,
			bit;
		while (props)
		{
			if (props & slot)
			{
				new
					prop = (j * 32) + bit,
					e_PROP_FLAGS:flags = YSI_g_sProperties[prop][E_PROP_DATA_FLAGS];
				if (flags & e_PROP_FLAGS_ACTIVE)
				{
					if ((flags & e_PROP_FLAGS_TYPES) == e_PROP_FLAGS_TYPE_PROP)
					{
						if (Property_GetOption(2, flags))
						{
							if (_:Bit_GetBit(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS], playerid))
							{
								Bit_Set(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS], playerid, 0, PLAYER_BIT_ARRAY);
							}
						}
						else
						{
							if (_:(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] == Bit:playerid))
							{
								YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] = Bit:INVALID_PLAYER_ID;
							}
						}
						#pragma tabsize 4
						#if defined _YSI_VISUAL_PICKUPS
							if (Property_GetOption(5, flags))
								Pickup_Show(_:(flags & e_PROP_FLAGS_LINK), 1);
							else
						#endif
								Checkpoint_SetVisible(_:(flags & e_PROP_FLAGS_LINK), 1);
						#pragma tabsize 4
					}
					else if ((flags & e_PROP_FLAGS_TYPES) == e_PROP_FLAGS_TYPE_HOUS)
					{
						if (_:(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] == Bit:playerid))
						{
							YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] = Bit:INVALID_PLAYER_ID;
						}
					}
				}
				props ^= slot;
			}
			slot <<= 1;
			bit++;
		}
		YSI_g_sPlayerProperties[playerid][j] = Bit:0;
	}
	YSI_g_sPropCount[playerid] = 0;
	YSI_g_sHouseCount[playerid] = 0;
	YSI_g_sCurrentHouse[playerid] = -1;
	YSI_g_sPickupTimer[playerid] = -1;
	YSI_g_sPlayerPickup[playerid] = NO_PICKUP;
	#pragma unused reason
	return 1;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_OnPlayerSpawn
Params:
	playerid - Player who spawned.
Return:
	-
Notes:
	Internal callback.
-*----------------------------------------------------------------------------*/

Property_OnPlayerSpawn(playerid)
{
	for (new i = 0; i < 12; i++) if (YSI_g_sSpawnWeapons[playerid][i]) GivePlayerWeapon(playerid, (YSI_g_sSpawnWeapons[playerid][i] >> 24) & 0xFF, YSI_g_sSpawnWeapons[playerid][i] & 0xFFFFFF);
	if (YSI_g_sSpawnWeapons[playerid][12]) SetPlayerArmour(playerid, 100.0);
	return 1;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_OnPlayerLeaveCheckpointEx
Params:
	playerid - Player who left a checkpoint.
	cpid - Checkpoint they left.
Return:
	-
Notes:
	Internal callback from YSI_checkpoints.
-*----------------------------------------------------------------------------*/

#if defined _YSI_SETUP_MASTER
	public Property_OnPlayerLeaveCheckpointEx(playerid, cpid)
	if (!YSI_g_sIsMaster) return 0;
	else
#else
	Property_OnPlayerLeaveCheckpointEx(playerid, cpid)
#endif
	{
		new
			cp = YSI_g_sCheckpointPointers[cpid];
		if (cp == NO_CHECKPOINT)
		{
			#if defined _YSI_SETUP_MASTER
				setproperty(0, "YSIReq", 0);
			#endif
			return 0;
		}
		new
			flags = YSI_g_sProperties[cp][E_PROP_DATA_FLAGS],
			type = _:(_:flags & _:e_PROP_FLAGS_TYPES);
		if ((type != _:e_PROP_FLAGS_TYPE_HOUS || YSI_g_sProperties[cp][E_PROP_DATA_PLAYERS][0] != Bit:playerid) && (type != _:e_PROP_FLAGS_TYPE_PROP || !Property_IsOwner(playerid, cp, flags)))
		{
			Bit_Set(YSI_g_sPlayerProperties[playerid], cp, 0, GROUP_PROPERTY_BITS);
		}
		#if defined _YSI_SETUP_MASTER
			setproperty(0, "YSIReq", 1);
		#endif
		return 1;
	}

#if defined _YSI_VISUAL_PICKUPS

	/*----------------------------------------------------------------------------*-
	Function:
		Property_OnPlayerPickUpPickup
	Params:
		playerid - Player who picked up a pickup.
		pickupid - Pickup they picked up.
		Float:x - Pickup x position.
		Float:y - Pickup y position.
		Float:z - Pickup z position.
	Return:
		-
	Notes:
		Internal callback from YSI_pickups.  Has none-standard
		parameters because it was the easiest way to do it.
	-*----------------------------------------------------------------------------*/

	#if defined _YSI_SETUP_MASTER
		public Property_OnPlayerPickUpPickup(playerid, pickupid, Float:x, Float:y, Float:z)
		if (!YSI_g_sIsMaster) return 0;
		else
	#else
		Property_OnPlayerPickUpPickup(playerid, pickupid, Float:x, Float:y, Float:z)
	#endif
		{
			DBGP2("Property_OnPlayerPickUpPickup() start");
			if (YSI_g_sPickupTimer[playerid] == -1)
			{
				DBGP4("Property_OnPlayerPickUpPickup() No timer");
				#if defined _YSI_SETUP_MASTER
					setproperty(0, "YSIReq", 0);
				#endif
				if (pickupid >= MAX_DYN_PICKUPS)
				{
					return 0;
				}
				DBGP4("Property_OnPlayerPickUpPickup() Valid pickup");
				new
					prop = YSI_g_sPickupPointers[pickupid];
				if (prop == NO_PROPERTY)
				{
					return 0;
				}
				DBGP4("Property_OnPlayerPickUpPickup() Valid property");
				YSI_g_sPlayerPickup[playerid] = pickupid;
				Bit_Set(YSI_g_sPlayerProperties[playerid], prop, 1, GROUP_PROPERTY_BITS);
				switch (_:(YSI_g_sProperties[prop][E_PROP_DATA_FLAGS] & e_PROP_FLAGS_TYPES))
				{
					case e_PROP_FLAGS_TYPE_PROP:
					{
						new
							data1 = YSI_g_sProperties[prop][E_PROP_DATA_DATA_2] & 0x3FFFF,
							data2 = ((YSI_g_sProperties[prop][E_PROP_DATA_DATA_2] >>> 6) & 0x03FFF000) | ((YSI_g_sProperties[prop][E_PROP_DATA_DATA_1] >>> 20) & 0x00000FFF);
						Text_SendFormat(playerid, "YSI_PROP_NAME", YSI_g_sProperties[prop][E_PROP_DATA_NAME], data1, data2);
						if (Property_GetOption(2, YSI_g_sProperties[prop][E_PROP_DATA_FLAGS]))
						{
							if (Bit_GetBit(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS], playerid)) Text_Send(playerid, "YSI_PROP_YOURS");
							else Text_SendFormat(playerid, "YSI_PROP_BUY", "buy");
						}
						else
						{
							new
								owner = _:YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0];
							if (owner == playerid) Text_Send(playerid, "YSI_PROP_YOURS");
							else if (IsPlayerConnected(owner)) Text_SendFormat(playerid, "YSI_PROP_OWNER", ReturnPlayerName(owner), owner);
							if (owner != playerid) Text_SendFormat(playerid, "YSI_PROP_BUY", "buy");
						}
					}
					case e_PROP_FLAGS_TYPE_HOUS:
					{
						new
							owner = _:YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0];
						if (owner == INVALID_PLAYER_ID) Text_SendFormat(playerid, "YSI_PROP_BUY_HOUSE", "buy", YSI_g_sProperties[prop][E_PROP_DATA_NAME][6]);
						else if (owner == playerid) Text_SendFormat(playerid, "YSI_PROP_ENTER", "enter", "exit");
						else Text_SendFormat(playerid, "YSI_PROP_HOUSE_OWNED", ReturnPlayerName(owner));
					}
				}
				YSI_g_sPickupTimer[playerid] = SetTimerEx("Property_PickupTimeCheck", 500, 1, "ii", playerid, pickupid);
			}
			#if defined _YSI_SETUP_MASTER
				setproperty(0, "YSIReq", 1);
			#endif
			DBGP2("Property_OnPlayerPickUpPickup() end");
			return 1;
		}

	/*----------------------------------------------------------------------------*-
	Function:
		Property_PickupTimeCheck
	Params:
		playerid - Player who is on a pickup.
		pickupid - Pickup to check.
	Return:
		-
	Notes:
		Checks if a player has moved away from a pickup.
	-*----------------------------------------------------------------------------*/

	public Property_PickupTimeCheck(playerid, pickupid)
	{
		if (!Pickup_IsPlayerOnPickup(playerid, pickupid))
		{
			KillTimer(YSI_g_sPickupTimer[playerid]);
			YSI_g_sPickupTimer[playerid] = -1;
			YSI_g_sPlayerPickup[playerid] = NO_PICKUP;
			new
				prop = YSI_g_sPickupPointers[pickupid];
			if (prop != NO_PROPERTY)
			{
				new
					flags = _:YSI_g_sProperties[prop][E_PROP_DATA_FLAGS],
					type = flags & _:e_PROP_FLAGS_TYPES;
				if ((type != _:e_PROP_FLAGS_TYPE_HOUS || YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] != Bit:playerid) && (type != _:e_PROP_FLAGS_TYPE_PROP || !Property_IsOwner(playerid, prop, flags)))
				{
					Bit_Set(YSI_g_sPlayerProperties[playerid], prop, 0, GROUP_PROPERTY_BITS);
				}
			}
		}
	}
#endif

/*----------------------------------------------------------------------------*-
Function:
	Property_OnPlayerEnterCheckpointEx
Params:
	playerid - Player who entered a checkpoint.
	cpid - Checkpoint they entered.
Return:
	-
Notes:
	Internal callback from YSI_checkpoints.
-*----------------------------------------------------------------------------*/

#if defined _YSI_SETUP_MASTER
	public Property_OnPlayerEnterCheckpointEx(playerid, cpid)
	if (!YSI_g_sIsMaster) return 0;
	else
#else
	Property_OnPlayerEnterCheckpointEx(playerid, cpid)
#endif
	{
		#if defined _YSI_SETUP_MASTER
			setproperty(0, "YSIReq", 0);
		#endif
		if (cpid >= MAX_CHECKPOINTS)
		{
			return 0;
		}
		new
			prop = YSI_g_sCheckpointPointers[cpid];
		if (prop == NO_PROPERTY)
		{
			return 0;
		}
		new
			e_PROP_FLAGS:flag = YSI_g_sProperties[prop][E_PROP_DATA_FLAGS];
		switch (flag & e_PROP_FLAGS_TYPES)
		{
			case e_PROP_FLAGS_TYPE_PROP:
			{
				Text_SendFormat(playerid, "YSI_PROP_NAME", YSI_g_sProperties[prop][E_PROP_DATA_NAME], ((YSI_g_sProperties[prop][E_PROP_DATA_DATA_2] >>> 6) & 0x03FFF000) | ((YSI_g_sProperties[prop][E_PROP_DATA_DATA_1] >>> 20) & 0x00000FFF), YSI_g_sProperties[prop][E_PROP_DATA_DATA_2] & 0x3FFFF);
				if (Property_GetOption(2, flag))
				{
					if (Bit_GetBit(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS], playerid)) Text_Send(playerid, "YSI_PROP_YOURS");
					else Text_SendFormat(playerid, "YSI_PROP_BUY", "buy");
				}
				else
				{
					new
						owner = _:YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0];
					if (owner == playerid) Text_Send(playerid, "YSI_PROP_YOURS");
					else if (IsPlayerConnected(owner)) Text_SendFormat(playerid, "YSI_PROP_OWNER", ReturnPlayerName(owner), owner);
					if (owner != playerid) Text_SendFormat(playerid, "YSI_PROP_BUY", "buy");
				}
			}
			case e_PROP_FLAGS_TYPE_HOUS:
			{
				new
					owner = _:YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0];
				if (owner == INVALID_PLAYER_ID) Text_SendFormat(playerid, "YSI_PROP_BUY_HOUSE", "buy", YSI_g_sProperties[prop][E_PROP_DATA_NAME][6]);
				else if (owner == playerid) Text_SendFormat(playerid, "YSI_PROP_ENTER", "enter", "exit");
				else Text_SendFormat(playerid, "YSI_PROP_HOUSE_OWNED", ReturnPlayerName(owner));
			}
			case e_PROP_FLAGS_TYPE_AMMU:
			{
				Property_GenerateAmmuMenu(playerid, prop, 0, 0);
				TogglePlayerControllable(playerid, 0);
			}
			case e_PROP_FLAGS_TYPE_BANK:
			{
				if (YSI_g_sProperties[prop][E_PROP_DATA_NAME][0]) Text_SendFormat(playerid, "YSI_BANK_NAME", YSI_g_sProperties[prop][E_PROP_DATA_NAME]);
				else Text_Send(playerid, "YSI_BANK_WELCOME");
				Text_SendFormat(playerid, "YSI_BANK_HELP1", "bank");
				Text_SendFormat(playerid, "YSI_BANK_HELP2", "withdraw");
				Text_SendFormat(playerid, "YSI_BANK_HELP3", "balance");
				Text_SendFormat(playerid, "YSI_BANK_BALANCE", YSI_g_sMoney[playerid]);
			}
			case e_PROP_FLAGS_TYPE_TELS:
			{
				if (GetPlayerMoney(playerid) >= YSI_g_sProperties[prop][E_PROP_DATA_DATA_1])
				{
					GivePlayerMoney(playerid, -YSI_g_sProperties[prop][E_PROP_DATA_DATA_1]);
					SetPlayerPos(playerid, Float:YSI_g_sProperties[prop][E_PROP_DATA_DATA_2], Float:YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0], Float:YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][1]);
					if (YSI_g_sProperties[prop][E_PROP_DATA_NAME][0]) Text_SendFormat(playerid, "YSI_TELS_NAME", YSI_g_sProperties[prop][E_PROP_DATA_NAME]);
					else Text_Send(playerid, "YSI_TELS_TELE");
				}
				else Text_SendFormat(playerid, "YSI_TELS_MONEY", YSI_g_sProperties[prop][E_PROP_DATA_DATA_1]);
				#if defined _YSI_SETUP_MASTER
					setproperty(0, "YSIReq", 1);
				#endif
				return 1;
			}
			case e_PROP_FLAGS_TYPE_MONP: {}
			default:
			{
				#if defined _YSI_SETUP_MASTER
					setproperty(0, "YSIReq", 0);
				#endif
				return 0;
			}
		}
		Bit_Set(YSI_g_sPlayerProperties[playerid], prop, 1, GROUP_PROPERTY_BITS);
		#if defined _YSI_SETUP_MASTER
			setproperty(0, "YSIReq", 1);
		#endif
		return 1;
	}

/*----------------------------------------------------------------------------*-
Function:
	Property_GetWeapon
Params:
	ammu - Ammunation to get the weapon from.
	slot - Number of active slots to skip.
	&page - Start slot.
Return:
	-
Notes:
	Gets the slot active weapon from page start.  If you want the first one
	use page = 0 and slot = 0.  If you want the second use page = 0 and slot
	= 1 or slot = 0 and page > position of first.
-*----------------------------------------------------------------------------*/

static stock Property_GetWeapon(ammu, slot, &page = 0)
{
	new
		weapon;
	while (page < 40)
	{
		if (!page)
		{
			weapon = YSI_g_sProperties[ammu][E_PROP_DATA_DATA_1];
		}
		else if (page == 1)
		{
			weapon = YSI_g_sProperties[ammu][E_PROP_DATA_DATA_2];
		}
		else if (page < PLAYER_BIT_ARRAY + 2)
		{
			weapon = _:YSI_g_sProperties[ammu][E_PROP_DATA_PLAYERS][page - 2];
		}
		else
		{
			weapon = YSI_g_sProperties[ammu][E_PROP_DATA_NAME][page - (PLAYER_BIT_ARRAY + 2)];
		}
		if (weapon)
		{
			if (!slot) return weapon;
			else slot--;
		}
		page++;
	}
	return 0;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_WeaponName
Params:
	weapon - Weapon slot to get the name of.
Return:
	-
Notes:
	Gets a real weapon name based on the slot of the weapon, not the weapon id.
-*----------------------------------------------------------------------------*/

static stock Property_WeaponName(weapon)
{
	static
		names[][18] = 
		{
			"Brassknuckle",			"Golfclub",		"Night Stick",		"Knife",
			"Bat",					"Shovel",		"Poolstick",		"Katana",
			"Chainsaw",				"Dildo",		"Dildo 2",			"Vibrator",
			"Vibrator 2",			"Flower",		"Cane",				"Grenade",
			"Teargas",				"Molotov",		"Colt 45",			"Silenced Pistol",
			"Desert Eagle",			"Shotgun",		"Sawnoff",			"Spaz 9",
			"Uzi",					"MP5",			"AK47",				"M4",
			"TEC9",					"Rifle",		"Sniper Rifle",		"Rocket Launcher",
			"Flame Thrower",		"Minigun",		"Satchel Charge",	"Spraycan",
			"Fire Extinguisher",	"Camera",		"Parachute",		"Armour"
		},
		none[18] = "NONE";
	if (weapon >=0 && weapon < sizeof (names)) return names[weapon];
	else return none;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_WeaponCost
Params:
	data - Compressed data.
Return:
	-
Notes:
	Extracts the cost from the passed data.
-*----------------------------------------------------------------------------*/

#define Property_WeaponCost(%1) \
	((%1) & 0xFFFFF)

/*----------------------------------------------------------------------------*-
Function:
	Property_WeaponAmmo
Params:
	data = Compressed data.
Return:
	-
Notes:
	Extracts the ammo from the passed data.
-*----------------------------------------------------------------------------*/

#define Property_WeaponAmmo(%1) \
	((%1) >> 20)

/*----------------------------------------------------------------------------*-
Function:
	Property_OnPlayerExitedMenu
Params:
	playerid - Player who left a menu.
Return:
	-
Notes:
	Internal callback.
-*----------------------------------------------------------------------------*/

#define Property_OnPlayerExitedMenu Property_OnPlayerExited

Property_OnPlayerExitedMenu(playerid)
{
	#if defined _YSI_SETUP_MASTER
		if (!YSI_g_sIsMaster) return 0;
	#endif
	if (GetPlayerMenu(playerid) == YSI_g_sShopMenu[playerid][E_PROP_AMMU_MENU])
	{
		new
			data = YSI_g_sShopMenu[playerid][E_PROP_AMMU_DATA];
		if (data & 0x01)
		{
			Property_GenerateAmmuMenu(playerid, data >> 16, 0, 0);
			return 1;
		}
	}
	YSI_g_sShopMenu[playerid][E_PROP_AMMU_MENU] = Menu:-1;
	TogglePlayerControllable(playerid, 1);
	YSI_g_sShopMenu[playerid][E_PROP_AMMU_DATA] = 0;
	return 0;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_GetWeaponFromSlot
Params:
	slot - Data slot to translate.
Return:
	weaponid represented by that slot.
Notes:
	-
-*----------------------------------------------------------------------------*/

static stock Property_GetWeaponFromSlot(slot)
{
	if (slot < 18) return slot + 1;
	else if (slot < 33) return slot + 4;
	else if (slot < 36) return slot + 5;
	else if (slot < 38) return slot + 6;
	else if (slot == 38) return WEAPON_PARACHUTE;
	else if (slot == 39) return WEAPON_ARMOUR;
	else return 0;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_SavePlayerWeapon
Params:
	playerid - Player to save the weapon for.
	weaponslot - Slot of the weapon.
	ammo - Ammo to save.
Return:
	-
Notes:
	Saves weapons based on slots so you only have 13 spawn weapons based on
	real weapon slots (armour is slot 12).  This is similar to weapon slot
	sorting but it's sorting slots which are packed from original weapon
	numbers and missing some.
-*----------------------------------------------------------------------------*/

stock Property_SavePlayerWeapon(playerid, weaponslot, ammo)
{
	new
		slot,
		weapon;
	switch (weaponslot)
	{
		case 0: slot = 0, weapon = WEAPON(WEAPON_BRASSKNUCKLE);
		case 1, 2, 3, 4, 5, 6, 7, 8: slot = 1, weapon = WEAPON(weaponslot + 1);
		case 18, 19, 20: slot = 2, weapon = WEAPON(weaponslot + 4);
		case 21, 22, 23: slot = 3, weapon = WEAPON(weaponslot + 4);
		case 24, 25, 28: slot = 4, weapon = WEAPON(weaponslot + 4);
		case 26, 27: slot = 5, weapon = WEAPON(weaponslot + 4);
		case 29, 30: slot = 6, weapon = WEAPON(weaponslot + 4);
		case 31: slot = 7, weapon = WEAPON(WEAPON_ROCKETLAUNCHER); 
		case 32, 33: slot = 7, weapon = WEAPON(weaponslot + 5);
		case 15, 16, 17: slot = 8, weapon = WEAPON(weaponslot + 1);
		case 34: slot = 8, weapon = WEAPON(WEAPON_SATCHEL);
		case 35, 36, 37: slot = 9, weapon = WEAPON(weaponslot + 6);
		case 9, 10, 11, 12, 13, 14: slot = 10, weapon = WEAPON(weaponslot + 1);
		case 38: slot = 11, weapon = WEAPON(WEAPON_PARACHUTE);
		case 39: slot = 12, weapon = 1;
		default: return;
	}
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			if (YSI_g_sSpawnWeapons[playerid][slot] & 0xFF000000 == weapon) YSI_g_sSpawnWeapons[playerid][slot] += ammo & 0x00FFFFFF;
			else YSI_g_sSpawnWeapons[playerid][slot] = (weapon & 0xFF000000) | (ammo & 0x00FFFFFF);
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", ((playerid & 0xFFFF) << 16) | (slot & 0xFFFF), (weapon & 0xFF000000) | (ammo & 0x00FFFFFF), E_PROP_REMOTE_SAVEWEAP);
		}
	#endif
}

/*----------------------------------------------------------------------------*-
Function:
	Property_GetSlotWeapon
Params:
	playerid - Player to get the weapon for.
	slot - Slot to get.
	weaponslot - Return for the weapon type.
	ammo - Return for the ammo.
Return:
	-
Notes:
	Gets a player's stored for spawn weapons.
-*----------------------------------------------------------------------------*/

stock Property_GetSlotWeapon(playerid, slot, &weapon, &ammo)
{
	if (playerid < 0 || playerid >= MAX_PLAYERS || slot < 0 || slot >= 13) return;
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			weapon = (YSI_g_sSpawnWeapons[playerid][slot] & 0xFF000000) >> 24;
			ammo = YSI_g_sSpawnWeapons[playerid][slot] & 0x00FFFFFF;
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", playerid, slot, E_PROP_REMOTE_GOWEAP);
			new
				weaps = getproperty(0, "YSIReq");
			weapon = (weaps & 0xFF000000) >> 24;
			ammo = weaps & 0x00FFFFFF;
		}
	#endif
}

/*----------------------------------------------------------------------------*-
Function:
	Property_SaveWeapons
Params:
	playerid - Player to save weapons for.
Return:
	-
Notes:
	Saves a players current spawn weapon data to an ini (i.e. their save file).
	110953013 is props in adler32
-*----------------------------------------------------------------------------*/

stock Property_SaveWeapons(playerid)
{
	if (playerid >= 0 && playerid < MAX_PLAYERS)
	{
		#if defined _YSI_SETUP_MASTER
			if (YSI_g_sIsMaster)
			{
		#endif
				new
					str[8] = "wslot";
				for (new i = 0; i <= 12; i++)
				{
					if (i >= 10)
					{
						new
							tens = i / 10;
						str[5] = tens + '0';
						str[6] = (i - (tens * 10)) + '0';
						str[7] = '\0';
					}
					else
					{
						str[5] = i + '0';
						str[6] = '\0';
					}
					Player_WriteInt(str, YSI_g_sSpawnWeapons[playerid][i]);
				}
		#if defined _YSI_SETUP_MASTER
			}
			else
			{
				CallRemoteFunction("Property_Remote", "iii", playerid, 0, E_PROP_REMOTE_SWEAP);
				new
					weaps[14];
				getproperty(0, "", 110953013, weaps);
				strunpack(weaps, weaps);
				new
					str[8] = "wslot";
				for (new i = 0; i < 13; i++)
				{
					if (i >= 10)
					{
						new
							tens = i / 10;
						str[5] = tens + '0';
						str[6] = (i - (tens * 10)) + '0';
						str[7] = '\0';
					}
					else
					{
						str[5] = i + '0';
						str[6] = '\0';
					}
					Player_WriteInt(str, weaps[i] >> 1);
				}
			}
		#endif
	}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_LoadWeapons
Params:
	playerid - Player to load weapons for.
	identifier[] - Slot data.
	text[] - Weapon data.
Return:
	-
Notes:
	Called when a player logs in to load their previous weapons.
-*----------------------------------------------------------------------------*/

stock Property_LoadWeapons(playerid, identifier[], text[])
{
	if (playerid >= 0 && playerid < MAX_PLAYERS)
	{
		if (strcmp(identifier, "wslot", false, 5)) return;
		new
			slot = strval(identifier[5]);
		if (slot < 0 || slot > 12) return;
		#if defined _YSI_SETUP_MASTER
			if (YSI_g_sIsMaster)
			{
		#endif
				YSI_g_sSpawnWeapons[playerid][slot] = strval(text);
		#if defined _YSI_SETUP_MASTER
			}
			else
			{
				CallRemoteFunction("Property_Remote", "iii", playerid, ((slot & 0xFFFF) << 16) | (strval(text) & 0xFFFF), E_PROP_REMOTE_LWEAP);
			}
		#endif
	}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_SaveBank
Params:
	playerid - Player to save bank for.
Return:
	-
Notes:
	Saves a players current bank data to an ini (i.e. their save file).
-*----------------------------------------------------------------------------*/

stock Property_SaveBank(playerid)
{
	if (playerid >= 0 && playerid < MAX_PLAYERS)
	{
		#if defined _YSI_SETUP_MASTER
			if (YSI_g_sIsMaster)
			{
		#endif
				Player_WriteInt("bankmoney", YSI_g_sMoney[playerid]);
		#if defined _YSI_SETUP_MASTER
			}
			else
			{
				CallRemoteFunction("Property_Remote", "iii", playerid, 0, E_PROP_REMOTE_GBANK);
				Player_WriteInt("bankmoney", getproperty(0, "YSIReq"));
			}
		#endif
	}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_GetBank
Params:
	playerid - Player to get bank for.
Return:
	Money in bank.
Notes:
-*----------------------------------------------------------------------------*/

stock Property_GetBank(playerid)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			if (playerid >= 0 && playerid < MAX_PLAYERS) return YSI_g_sMoney[playerid];
			return 0;
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", playerid, 0, E_PROP_REMOTE_GBANK);
			return getproperty(0, "YSIReq");
		}
	#endif
}

/*----------------------------------------------------------------------------*-
Function:
	Property_LoadBank
Params:
	playerid - Player to load bank for.
	identifier[] - Identifier name to check.
	text[] - Possibly bank amount.
Return:
	-
Notes:
	Called when a player logs in to load their previous banked money.
-*----------------------------------------------------------------------------*/

stock Property_LoadBank(playerid, identifier[], text[])
{
	if (playerid >= 0 && playerid < MAX_PLAYERS && !strcmp(identifier, "bankmoney"))
	{
		#if defined _YSI_SETUP_MASTER
			if (YSI_g_sIsMaster)
			{
		#endif
				YSI_g_sMoney[playerid] = strval(text);
		#if defined _YSI_SETUP_MASTER
			}
			else
			{
				CallRemoteFunction("Property_Remote", "iii", playerid, strval(text), E_PROP_REMOTE_LBANK);
			}
		#endif
	}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_OnPlayerSelectedMenuRow
Params:
	playerid - Player who selected a row.
	row - Row they selected.
Return:
	-
Notes:
	Internal callback.
-*----------------------------------------------------------------------------*/

#define Property_OnPlayerSelectedMenuRow Property_OnPlayerSelectedRow

Property_OnPlayerSelectedMenuRow(playerid, row)
{
	#if defined _YSI_SETUP_MASTER
		if (!YSI_g_sIsMaster) return 0;
	#endif
	if (GetPlayerMenu(playerid) == YSI_g_sShopMenu[playerid][E_PROP_AMMU_MENU])
	{
		new
			data = YSI_g_sShopMenu[playerid][E_PROP_AMMU_DATA],
			slot = (data >> 8) & 0xFF,
			ammu = data >> 16,
			count = YSI_g_sProperties[ammu][E_PROP_DATA_NAME][MAX_PROP_NAME - 1];
		if (data & 0x01)
		{
			new
				weapon,
				flags = _:YSI_g_sProperties[ammu][E_PROP_DATA_FLAGS],
				wdat;
			wdat = Property_GetWeapon(ammu, slot, weapon);
			if (GetPlayerMoney(playerid) >= Property_WeaponCost(wdat))
			{
				if (Property_GetOption(1, flags)) Property_SavePlayerWeapon(playerid, weapon, Property_WeaponAmmo(wdat));
				if (Property_GetOption(2, flags)) Property_GivePlayerWeapon(playerid, weapon, Property_WeaponAmmo(wdat));
				GivePlayerMoney(playerid, 0 - Property_WeaponCost(wdat));
			}
			else Text_Send(playerid, "YSI_AMMU_NO_MONEY");
			Property_GenerateAmmuMenu(playerid, ammu, 0, 0);
		}
		else
		{
			if (count > slot && row == 11) Property_GenerateAmmuMenu(playerid, ammu, 0, slot);
			else if (count > 12)
			{
				if (slot > 11 && row == 0) Property_GenerateAmmuMenu(playerid, ammu, 0, ((slot - 12) / 11) * 11);
				else Property_GenerateAmmuMenu(playerid, ammu, 1, ((slot - 1) / 11) * 10 + row);
			}
			else
			{
				Property_GenerateAmmuMenu(playerid, ammu, 1, row);
			}
		}
		return 1;
	}
	else YSI_g_sShopMenu[playerid][E_PROP_AMMU_MENU] = Menu:-1;
	return 0;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_GenerateAmmuMenu
Params:
	playerid - Player who watns the menu.
	ammu - Ammunation they're in.
	stage - Current menu view if any.
	page - Current menu page.
Return:
	-
Notes:
	If slot is 0 the main selection will be displayed and page will represent
	the offset from the start if there are more than 12 weapons for sale.  If
	stage is 1 the individual confirmation menu for one weapon will show and
	page will determine which weapon to show.
-*----------------------------------------------------------------------------*/

static stock Property_GenerateAmmuMenu(playerid, ammu, stage, page)
{
	new
		Menu:menu = CreateMenu("Ammunation", 2, 270.0, 150.0, 200.0, 50.0),
		slot = page;
	SetMenuColumnHeader(menu, 0, "Weapon");
	SetMenuColumnHeader(menu, 1, "Price");
	if (stage)
	{
		new
			start,
			weapon = Property_GetWeapon(ammu, page, start);
		if (weapon)
		{
			AddMenuItem(menu, 0, Property_WeaponName(start));
			AddMenuItem(menu, 1, numstr(Property_WeaponCost(weapon)));
		}
	}
	else
	{
		new
			weapon,
			start,
			row,
			end = page + 12,
			next = page,
			money = GetPlayerMoney(playerid);
		if (YSI_g_sProperties[ammu][E_PROP_DATA_NAME][MAX_PROP_NAME - 1] - page > 12) end--;
		if (YSI_g_sProperties[ammu][E_PROP_DATA_NAME][MAX_PROP_NAME - 1] > 12 && page)
		{
			end--;
			AddMenuItem(menu, 0, "Back...");
			AddMenuItem(menu, 1, " ");
		}
		while (slot < end && (weapon = Property_GetWeapon(ammu, next, start)))
		{
			new
				cost = Property_WeaponCost(weapon);
			AddMenuItem(menu, 0, Property_WeaponName(start));
			AddMenuItem(menu, 1, numstr(cost));
			if (cost > money) DisableMenuRow(menu, row);
			slot++;
			row++;
			start++;
			next = 0;
		}
		if (end != 12 && Property_GetWeapon(ammu, 0, start))
		{
			AddMenuItem(menu, 0, "Next...");
			AddMenuItem(menu, 1, " ");
		}
	}
	YSI_g_sShopMenu[playerid][E_PROP_AMMU_MENU] = menu;
	YSI_g_sShopMenu[playerid][E_PROP_AMMU_DATA] = ((ammu & 0xFFFF) << 16) | ((slot & 0xFF) << 8) | (stage ? 1 : 0) | 2;
	ShowMenuForPlayer(menu, playerid);
	DestroyMenu(menu);
}

/*----------------------------------------------------------------------------*-
Command:
	sell
Parameters:
	<id> - Property to sell.
Notes:
	Sells a property you own if it can be sold.
-*----------------------------------------------------------------------------*/

public ycmd_sell(playerid, params[], help)
{
	DBGP2("ycmd_sell() start");
	#if defined _YSI_SETUP_MASTER
		if (!YSI_g_sIsMaster) return 1;
	#endif
	if (help)
	{
		Text_Send(playerid, "YSI_SELL_HELP_1");
		Text_Send(playerid, "YSI_SELL_HELP_2");
		Text_Send(playerid, "YSI_SELL_HELP_3");
		Text_Send(playerid, "YSI_SELL_HELP_4");
	}
	else
	{
		DBGP3("ycmd_sell() not help %d", params[0]);
		if (params[0] >= '0' && params[0] <= '9')
		{
			DBGP5("ycmd_sell() params OK");
			new
				prop = strval(params);
			if (Property_IsActive(prop))
			{
				new
					e_PROP_FLAGS:flag = YSI_g_sProperties[prop][E_PROP_DATA_FLAGS];
				if ((flag & e_PROP_FLAGS_TYPES) == e_PROP_FLAGS_TYPE_PROP)
				{
					if (Property_GetOption(1, flag))
					{
						if (Property_GetOption(2, flag))
						{
							if (Bit_GetBit(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS], playerid)) Bit_Set(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS], playerid, 0, PLAYER_BIT_ARRAY);
							else return Text_Send(playerid, "YSI_SELL_CANT");
						}
						else
						{
							if (_:YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] == playerid) YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] = Bit:INVALID_PLAYER_ID;
							else return Text_Send(playerid, "YSI_SELL_CANT");
						}
						new
							cost = ((((YSI_g_sProperties[prop][E_PROP_DATA_DATA_2] >>> 6) & 0x03FFF000) | ((YSI_g_sProperties[prop][E_PROP_DATA_DATA_1] >>> 20) & 0x00000FFF)) * ((Property_GetOption(3, flag)) ? PROPERTY_SELL_PERCENT : 100)) / 100;
						Text_SendFormat(playerid, "YSI_SELL_SOLD", cost);
						#pragma tabsize 4
						#if defined _YSI_VISUAL_PICKUPS
							if (Property_GetOption(5, flag))
								Pickup_Show(_:(flag & e_PROP_FLAGS_LINK), 1);
							else
						#endif
								Checkpoint_SetVisible(_:(flag & e_PROP_FLAGS_LINK), 1);
						#pragma tabsize 4
						GivePlayerMoney(playerid, cost);
						YSI_g_sPropCount[playerid]--;
						Bit_Set(YSI_g_sPlayerProperties[playerid], prop, 0, GROUP_PROPERTY_BITS);
					}
					else Text_Send(playerid, "YSI_SELL_CANT");
					return 1;
				}
				else if ((flag & e_PROP_FLAGS_TYPES) == e_PROP_FLAGS_TYPE_PROP)
				{
					if (_:YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] == playerid)
					{
						new
							cost = YSI_g_sProperties[prop][E_PROP_DATA_NAME][0];
						Text_SendFormat(playerid, "YSI_SELL_SOLD", cost);
						GivePlayerMoney(playerid, cost);
						YSI_g_sHouseCount[playerid]--;
						Bit_Set(YSI_g_sPlayerProperties[playerid], prop, 0, GROUP_PROPERTY_BITS);
						YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] = Bit:INVALID_PLAYER_ID;
					}
					else Text_Send(playerid, "YSI_SELL_CANT");
					return 1;
				}
			}
		}
		Text_Send(playerid, "YSI_SELL_NO_ID");
	}
	return 1;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_Bank
Params:
	playerid - Player who is banking money.
	amount - Amount of money they're banking.
Return:
	-
Notes:
	Does banks and withdrawls.
-*----------------------------------------------------------------------------*/

stock Property_Bank(playerid, amount)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			if (IsPlayerInCheckpoint(playerid))
			{
				new
					cpid = Checkpoint_Get(playerid),
					prop = YSI_g_sCheckpointPointers[cpid];
				if (prop != NO_PROPERTY)
				{
					new
						e_PROP_FLAGS:flag = YSI_g_sProperties[prop][E_PROP_DATA_FLAGS];
					if (flag & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_BANK)
					{
						if ((amount > 0) ? (GetPlayerMoney(playerid) >= amount) : (YSI_g_sMoney[playerid] + amount >= 0))
						{
							YSI_g_sMoney[playerid] += amount;
							GivePlayerMoney(playerid, -amount);
						}
						else return 0;
					}
					else Text_Send(playerid, "YSI_BANK_NOT");
				}
				else Text_Send(playerid, "YSI_BANK_NOT");
			}
			else Text_Send(playerid, "YSI_BANK_CP");
			return 1;
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", playerid, amount, E_PROP_REMOTE_BANK);
			return getproperty(0, "YSIReq");
		}
	#endif
}

/*----------------------------------------------------------------------------*-
Command:
	bank
Parameters:
	<amount> - Value to bank.
Notes:
	Calls Property_Bank with positive input amount.
-*----------------------------------------------------------------------------*/

public ycmd_bank(playerid, params[], help)
{
	#if defined _YSI_SETUP_MASTER
		if (!YSI_g_sIsMaster) return 1;
	#endif
	if (help)
	{
		Text_Send(playerid, "YSI_BANK_HELP_1");
		Text_Send(playerid, "YSI_BANK_HELP_2");
		Text_Send(playerid, "YSI_BANK_HELP_3");
		Text_SendFormat(playerid, "YSI_BANK_HELP_4", "bank");
	}
	else
	{
		new
			bank = strval(params);
		if (Property_Bank(playerid, bank)) Text_SendFormat(playerid, "YSI_BANK_BANKED", bank, YSI_g_sMoney[playerid]);
		else Text_Send(playerid, "YSI_BANK_INSUFFICIENT");
	}
	return 1;
}

/*----------------------------------------------------------------------------*-
Command:
	balance
Parameters:
	-
Notes:
	Displays how much you have in the bank.  Does not require you to be in a
	bank.
-*----------------------------------------------------------------------------*/

public ycmd_balance(playerid, params[], help)
{
	#if defined _YSI_SETUP_MASTER
		if (!YSI_g_sIsMaster) return 1;
	#endif
	if (help) Text_Send(playerid, "YSI_BAL_HELP");
	else Text_SendFormat(playerid, "YSI_BANK_BALANCE", YSI_g_sMoney[playerid]);
	return 1;
}

/*----------------------------------------------------------------------------*-
Command:
	withdraw
Parameters:
	<amount> - Amount to withdraw.
Notes:
	Calls Property_Bank with negative input amount.
-*----------------------------------------------------------------------------*/

public ycmd_withdraw(playerid, params[], help)
{
	#if defined _YSI_SETUP_MASTER
		if (!YSI_g_sIsMaster) return 1;
	#endif
	if (help)
	{
		Text_Send(playerid, "YSI_WITH_HELP1");
		Text_Send(playerid, "YSI_WITH_HELP2");
		Text_Send(playerid, "YSI_WITH_HELP3");
		Text_SendFormat(playerid, "YSI_WITH_HELP4", "withdraw");
	}
	else
	{
		new
			bank = -strval(params);
		if (Property_Bank(playerid, bank)) Text_SendFormat(playerid, "YSI_WITHDREW", bank, YSI_g_sMoney[playerid]);
		else Text_Send(playerid, "YSI_BANK_INSUFFUCUENT");
	}
	return 1;
}

/*----------------------------------------------------------------------------*-
Command:
	buy
Parameters:
	-
Notes:
	Allows you to purchase the property you are at.
-*----------------------------------------------------------------------------*/

public ycmd_buy(playerid, params[], help)
{
	DBGP2("ycmd_buy() start");
	#if defined _YSI_SETUP_MASTER
		if (!YSI_g_sIsMaster) return 1;
	#endif
	if (help)
	{
		Text_Send(playerid, "YSI_BUY_HELP_1");
		Text_Send(playerid, "YSI_BUY_HELP_2");
		Text_Send(playerid, "YSI_BUY_HELP_3");
		Text_Send(playerid, "YSI_BUY_HELP_4");
	}
	else
	{
		DBGP3("ycmd_buy() Not help");
		new
			cpid,
			prop = NO_PROPERTY;
		if (IsPlayerInCheckpoint(playerid))
		{
			DBGP4("ycmd_buy() Checkpoint");
			cpid = Checkpoint_Get(playerid);
			if (cpid != NO_CHECKPOINT)
			{
				prop = YSI_g_sCheckpointPointers[cpid];
			}
		}
		#if defined _YSI_VISUAL_PICKUPS
			#pragma tabsize 0
			else if (YSI_g_sPickupTimer[playerid] != -1)
			{
				cpid = YSI_g_sPlayerPickup[playerid];
				if (cpid != NO_PICKUP)
				{
					prop = YSI_g_sPickupPointers[cpid];
				}
				DBGP4("ycmd_buy() Pickup %d", cpid);
			}
		#endif
		#pragma tabsize 4
		else
		{
			DBGP4("ycmd_buy() Not in a checkpoint");
			Text_Send(playerid, "YSI_PROP_CP");
			return 1;
		}
		DBGP4("ycmd_buy() Prop %d", prop);
		if (prop != NO_PROPERTY)
		{
			new
				e_PROP_FLAGS:flag = YSI_g_sProperties[prop][E_PROP_DATA_FLAGS];
			if (flag & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_PROP)
			{
				if (YSI_g_sPropCount[playerid] < YSI_g_sMaxPlayerProps)
				{
					new
						price = ((YSI_g_sProperties[prop][E_PROP_DATA_DATA_2] >>> 6) & 0x03FFF000) | ((YSI_g_sProperties[prop][E_PROP_DATA_DATA_1] >>> 20) & 0x00000FFF);
					if (GetPlayerMoney(playerid) >= price)
					{
						if (Property_GetOption(2, flag))
						{
							if (Bit_GetBit(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS], playerid))
							{
								Text_Send(playerid, "YSI_PROP_OWN");
								return 1;
							}
							Bit_Set(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS], playerid, 1, PLAYER_BIT_ARRAY);
						}
						else
						{
							new
								owner = _:YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0];
							if (owner == playerid)
							{
								Text_Send(playerid, "YSI_PROP_OWN");
								return 1;
							}
							if (IsPlayerConnected(owner))
							{
								GivePlayerMoney(owner, price);
								Text_SendFormat(owner, "YSI_PROP_OUT", YSI_g_sProperties[prop][E_PROP_DATA_NAME], ReturnPlayerName(playerid), playerid);
							}
							YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] = Bit:playerid;
							if (Property_GetOption(1, flag))
							{
								#if defined _YSI_VISUAL_PICKUPS
									if (Property_GetOption(5, flag))
										Pickup_Show(cpid, 0);
									else
								#endif
										Checkpoint_SetVisible(cpid, 0);
							}
							else if (YSI_g_sRebuyDelay)
							{
								SetTimerEx("Property_ResetRebuy", YSI_g_sRebuyDelay, 0, "i", prop);
								#if defined _YSI_VISUAL_PICKUPS
									if (Property_GetOption(5, flag))
										Pickup_Show(cpid, 0);
									else
								#endif
										Checkpoint_SetVisible(cpid, 0);
							}
						}
						YSI_g_sPropCount[playerid]++;
						GivePlayerMoney(playerid, -price);
						Text_SendFormat(playerid, "YSI_PROP_BOUGHT", YSI_g_sProperties[prop][E_PROP_DATA_NAME], price);
						Text_SendToAllFormat("YSI_PROP_ANN", ReturnPlayerName(playerid), YSI_g_sProperties[prop][E_PROP_DATA_NAME]);
						if (Property_GetOption(4, flag))
						{
							price = (price * PROPERTY_INCREASE_PERCENT) / 100;
							YSI_g_sProperties[prop][E_PROP_DATA_DATA_1] = (YSI_g_sProperties[prop][E_PROP_DATA_DATA_1] & 0xFFFFF) | ((price & 0x00000FFF) << 20);
							YSI_g_sProperties[prop][E_PROP_DATA_DATA_2] = (YSI_g_sProperties[prop][E_PROP_DATA_DATA_2] & 0x3FFFF) | ((price & 0x03FFF000) << 6);
						}
						if (Property_GetOption(1, flag)) Text_SendFormat(playerid, "YSI_PROP_SELL", "sell", prop, (price * ((Property_GetOption(3, flag)) ? PROPERTY_SELL_PERCENT : 100)) / 100);
					}
					else Text_Send(playerid, "YSI_PROP_AFFORD");
				}
				else Text_Send(playerid, "YSI_PROP_MAX");
			}
			else if (flag & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_HOUS)
			{
				if (YSI_g_sHouseCount[playerid] < YSI_g_sMaxPlayerHouses)
				{
					new
						owner = _:YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0];
					if (owner == INVALID_PLAYER_ID)
					{
						new
							price = YSI_g_sProperties[prop][E_PROP_DATA_NAME][6];
						if (GetPlayerMoney(playerid) >= price)
						{
							YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] = Bit:playerid;
							YSI_g_sHouseCount[playerid]++;
							GivePlayerMoney(playerid, -price);
							Text_SendFormat(playerid, "YSI_PROP_BOUGHT_HOUSE", price);
							Text_SendFormat(playerid, "YSI_PROP_SELL", "sell", prop, price);
						}
						else Text_Send(playerid, "YSI_PROP_AFFORD");
					}
					else if (owner == playerid) Text_Send(playerid, "YSI_PROP_YOURS");
					else Text_SendFormat(playerid, "YSI_PROP_HOUSE_OWNED", ReturnPlayerName(owner));
				}
				else Text_Send(playerid, "YSI_PROP_MAX_HOUSE");
			}
			else Text_Send(playerid, "YSI_PROP_NOT");
		}
		else Text_Send(playerid, "YSI_PROP_NOT");
	}
	return 1;
	#pragma unused params
}

/*----------------------------------------------------------------------------*-
Function:
	Property_ResetRebuy
Params:
	prop - Property to make available.
Return:
	-
Notes:
	Makes a property available for purchase after a delay.
-*----------------------------------------------------------------------------*/

public Property_ResetRebuy(prop)
{
	if (Property_IsActive(prop))
	{
		new
			e_PROP_FLAGS:flag = YSI_g_sProperties[prop][E_PROP_DATA_FLAGS];
		if ((flag & e_PROP_FLAGS_TYPES) == e_PROP_FLAGS_TYPE_PROP)
		{
			#pragma tabsize 4
			#if defined _YSI_VISUAL_PICKUPS
				if (Property_GetOption(5, flag))
					Pickup_Show(_:(flag & e_PROP_FLAGS_LINK), 1);
				else
			#endif
					Checkpoint_SetVisible(_:(flag & e_PROP_FLAGS_LINK), 1);
			#pragma tabsize 4
		}
	}
}

/*----------------------------------------------------------------------------*-
Function:
	Property_Loop
Params:
	-
Return:
	-
Notes:
	Does the main processing for the library.  Removes or kills people in areas
	they shouldn't be and gives out money to people who earnt it.
-*----------------------------------------------------------------------------*/

public Property_Loop()
{
	#if defined _YSI_SETUP_MASTER
		if (!YSI_g_sIsMaster) return;
	#endif
	static
		Float:s_fLastGoodPos[MAX_PLAYERS][3],
		sLastTick = 0;
	new
		currentTick = GetTickCount(),
		elapse = currentTick - sLastTick;
	for (new i = 0; i < MAX_PROPERTIES; i++)
	{
		new
			flags = YSI_g_sProperties[i][E_PROP_DATA_FLAGS];
		if (flags & _:e_PROP_FLAGS_ACTIVE)
		{
			switch (flags & _:e_PROP_FLAGS_TYPES)
			{
				case e_PROP_FLAGS_TYPE_MONP, e_PROP_FLAGS_TYPE_MONA:
				{
					new
						time = YSI_g_sProperties[i][E_PROP_DATA_DATA_2];
					if (!time) time = YSI_g_sProperties[i][E_PROP_DATA_NAME][0];
					time -= elapse;
					if (time < 0) time = 0;
					YSI_g_sProperties[i][E_PROP_DATA_DATA_2] = time;
				}
				case e_PROP_FLAGS_TYPE_PROP:
				{
					new
						time = YSI_g_sProperties[i][E_PROP_DATA_NAME][MAX_PROP_NAME - 1];
					if (!time) time = YSI_g_sProperties[i][E_PROP_DATA_DATA_1] & 0x000FFFFF;
					time -= elapse;
					if (time <= 0) time = 0;
					YSI_g_sProperties[i][E_PROP_DATA_NAME][MAX_PROP_NAME - 1] = time;
				}
			}
		}
	}
	foreach (Player, i)
	{
		DBGP3("Property_Loop() foreach start");
		new
			money,
			bad;
		for (new j = 0; j < GROUP_PROPERTY_BITS; j++)
		{
			new
				props = _:YSI_g_sPlayerProperties[i][j],
				slot = 1,
				bit;
			while (props)
			{
				if (props & slot)
				{
					new
						prop = (j * 32) + bit,
						flags = YSI_g_sProperties[prop][E_PROP_DATA_FLAGS];
					if (flags & _:e_PROP_FLAGS_ACTIVE)
					{
						switch (flags & _:e_PROP_FLAGS_TYPES)
						{
							case e_PROP_FLAGS_TYPE_MONP, e_PROP_FLAGS_TYPE_MONA:
								if (!YSI_g_sProperties[prop][E_PROP_DATA_DATA_2]) GivePlayerMoney(i, YSI_g_sProperties[prop][E_PROP_DATA_DATA_1]);
							case e_PROP_FLAGS_TYPE_PROP:
							{
								if (((Property_GetOption(2, flags)) ? (_:Bit_GetBit(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS], i)) : (_:(YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] == Bit:i))) && !YSI_g_sProperties[prop][E_PROP_DATA_NAME][MAX_PROP_NAME - 1]) money += YSI_g_sProperties[prop][E_PROP_DATA_DATA_2] & 0x3FFFF;
							}
							case e_PROP_FLAGS_TYPE_RSRC:
							{
								if (Property_GetOption(1, flags))
								{
									SetPlayerPos(i, s_fLastGoodPos[i][0], s_fLastGoodPos[i][1], s_fLastGoodPos[i][2]);
									bad = 1;
								}
								else
								{
									new Float:health;
									GetPlayerHealth(i, health);
									SetPlayerHealth(i, health - YSI_g_sProperties[prop][E_PROP_DATA_DATA_2]);
								}
							}
						}
					}
					props ^= slot;
				}
				slot <<= 1;
				bit++;
			}
		}
		if (money)
		{
			Text_SendFormat(i, "YSI_PROP_EARNT", money);
			GivePlayerMoney(i, money);
		}
		if (!bad) GetPlayerPos(i, s_fLastGoodPos[i][0], s_fLastGoodPos[i][1], s_fLastGoodPos[i][2]);
		DBGP3("Property_Loop() foreach end");
	}
	sLastTick = currentTick;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_IsPlayerProperty
Params:
	flags - Property data to check.
	playerid - Player to check for.
Return:
	-
Notes:
	-
-*----------------------------------------------------------------------------*/

#define Property_IsPlayerProperty(%1,%2) \
	((%1) & e_PROP_FLAGS_ACTIVE && (%1) & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_PROP && Checkpoint_HasPlayerNoWorld(_:((%1) & e_PROP_FLAGS_LINK), (%2)))

/*----------------------------------------------------------------------------*-
Function:
	Property_GetPlayerPropCount
Params:
	playerid - Player to count for.
Return:
	-
Notes:
	Gets the number of properties this player could theoretically own.
-*----------------------------------------------------------------------------*/

stock Property_GetPlayerPropCount(playerid)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			new
				count;
			for (new i = 0; i < MAX_PROPERTIES; i++)
			{
				new
					e_PROP_FLAGS:flags = YSI_g_sProperties[i][E_PROP_DATA_FLAGS];
				if (Property_IsPlayerProperty(flags, playerid)) count++;
			}
			return count;
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", playerid, 0, E_PROP_REMOTE_PPCO);
			return getproperty(0, "LRegProp");
		}
	#endif
}

/*----------------------------------------------------------------------------*-
Function:
	Property_GetPropertyBits
Params:
	playerid - Player to get properties of.
	Bit:properties[] - Array to return properties in.
Return:
	-
Notes:
	Gets the properties currently owned by this player.
-*----------------------------------------------------------------------------*/

stock Property_GetPropertyBits(playerid, Bit:properties[])
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
			for (new i = 0; i < MAX_PROPERTIES; i++)
			{
				new
					e_PROP_FLAGS:flags = YSI_g_sProperties[i][E_PROP_DATA_FLAGS];
				if (flags & e_PROP_FLAGS_ACTIVE && flags & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_PROP && ((Property_GetOption(2, flags)) ? (_:Bit_GetBit(YSI_g_sProperties[i][E_PROP_DATA_PLAYERS], playerid)) : (_:(_:YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][0] == playerid)))) Bit_Set(properties, i, 1, GROUP_PROPERTY_BITS);
			}
			return 1;
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			YSI_g_sTempPropReq = 1;
			CallRemoteFunction("Property_Remote", "iii", playerid, 0, E_PROP_REMOTE_PROBITS);
			YSI_g_sTempPropReq = 0;
			for (new i = 0; i < sizeof (YSI_g_sTempProp); i++) properties[i] = YSI_g_sTempProp[i];
			return 1;
		}
	#endif
}

#if defined _YSI_SETUP_MASTER
/*----------------------------------------------------------------------------*-
Function:
	Property_GetPropertyBitsReceive
Params:
	playerid - Player who's properties are being got.
	Bit:properties[] - Properties owned by the player.
	count - Size of array.
Return:
	-
Notes:
	Receives data requested from the master on properties owned by a player.
-*----------------------------------------------------------------------------*/

	public Property_GetPropertyBitsReceive(playerid, Bit:properties[], count)
	{
		if (!YSI_g_sTempPropReq) return;
		for (new i = 0; i < count && i < sizeof (YSI_g_sTempProp); i++) YSI_g_sTempProp[i] = properties[i];
	}
#endif

/*----------------------------------------------------------------------------*-
Command:
	properties
Parameters:
	<page> - Page of properties to view (optional).
Notes:
	Lista all properties available to a player and who owns them.
-*----------------------------------------------------------------------------*/

public ycmd_properties(playerid, params[], help)
{
	#if defined _YSI_SETUP_MASTER
		if (!YSI_g_sIsMaster) return 1;
	#endif
	if (help)
	{
		Text_Send(playerid, "YSI_LIST_HELP_1");
		Text_Send(playerid, "YSI_LIST_HELP_2");
		Text_Send(playerid, "YSI_LIST_HELP_3");
		return 1;
	}
	new
		props = Property_GetPlayerPropCount(playerid),
		pages = (props + 7) / 8,
		page = strval(params);
	if (props > 8)
	{
		if (page)
		{
			if (page <= pages)
			{
				for (new i = 0, j = 0, k = (page - 1) * 8, n = k + 8; i < MAX_PROPERTIES && j < n; i++)
				{
					new
						e_PROP_FLAGS:flags = YSI_g_sProperties[i][E_PROP_DATA_FLAGS];
					if (Property_IsPlayerProperty(flags, playerid))
					{
						if (j >= k)
						{
							if (Property_GetOption(2, flags)) Text_SendFormat(playerid, "YSI_LIST_MULTI", YSI_g_sProperties[i][E_PROP_DATA_NAME], Bit_GetCount(YSI_g_sProperties[i][E_PROP_DATA_PLAYERS], PLAYER_BIT_ARRAY));
							else Text_SendFormat(playerid, "YSI_LIST_FORM", YSI_g_sProperties[i][E_PROP_DATA_NAME], ReturnPlayerName(_:YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][0]));
						}
						j++;
					}
				}
			}
			else Text_SendFormat(playerid, "YSI_LIST_PAGES", "properties", pages);
		}
		else
		{
			Text_Send(playerid, "YSI_LIST_MORE");
			Text_SendFormat(playerid, "YSI_LIST_PAGES", "properties", pages);
		}
	}
	else if (props)
	{
		for (new j = 0, i = 0; i < props && j < MAX_PROPERTIES; j++)
		{
			new
				e_PROP_FLAGS:flags = YSI_g_sProperties[j][E_PROP_DATA_FLAGS];
			if (Property_IsPlayerProperty(flags, playerid))
			{
				if (Property_GetOption(2, flags)) Text_SendFormat(playerid, "YSI_LIST_MULTI", YSI_g_sProperties[j][E_PROP_DATA_NAME], Bit_GetCount(YSI_g_sProperties[j][E_PROP_DATA_PLAYERS], PLAYER_BIT_ARRAY));
				else Text_SendFormat(playerid, "YSI_LIST_FORM", YSI_g_sProperties[j][E_PROP_DATA_NAME], ReturnPlayerName(_:YSI_g_sProperties[j][E_PROP_DATA_PLAYERS][0]));
				i++;
			}
		}
	}
	else Text_Send(playerid, "YSI_LIST_NONE");
	return 1;
}

/*----------------------------------------------------------------------------*-
Function:
	Property_GetLink
Params:
	property - Property to get link of.
Return:
	-
Notes:
	Returns a reference to the area or checkpoint used by this property or
	NO_PROPERTY on fail.
-*----------------------------------------------------------------------------*/

stock Property_GetLink(property)
{
	#if defined _YSI_SETUP_MASTER
		if (YSI_g_sIsMaster)
		{
	#endif
			if (Property_IsActive(property)) return _:(YSI_g_sProperties[property][E_PROP_DATA_FLAGS] & e_PROP_FLAGS_LINK);
			return NO_PROPERTY;
	#if defined _YSI_SETUP_MASTER
		}
		else
		{
			CallRemoteFunction("Property_Remote", "iii", property, 0, E_PROP_REMOTE_LINK);
			return getproperty(0, "LRegProp");
		}
	#endif
}

#if defined _YSI_SETUP_MASTER
/*----------------------------------------------------------------------------*-
Function:
	Property_Remote
Params:
	ident - Item to do instruction on.
	info - Data to work with.
	instruction - What to do.
Return:
	-
Notes:
	Wraps a load of minor functions for remote calling.
-*----------------------------------------------------------------------------*/

	public Property_Remote(ident, info, instruction)
	{
		if (!YSI_g_sIsMaster) return;
		switch (instruction)
		{
			case E_PROP_REMOTE_LINK:
			{
				if (Property_IsActive(ident)) setproperty(0, "YSIReq", _:(YSI_g_sProperties[ident][E_PROP_DATA_FLAGS] & e_PROP_FLAGS_LINK));
				else setproperty(0, "YSIReq", NO_PROPERTY);
			}
			case E_PROP_REMOTE_PROBITS:
			{
				new
					Bit:properties[GROUP_PROPERTY_BITS];
				if (ident < 0 || ident >= MAX_PLAYERS)
				{
					CallRemoteFunction("Property_GetPropertyBitsReceive", "iai", ident, _:properties, sizeof (properties));
					return;
				}
				for (new i = 0; i < MAX_PROPERTIES; i++)
				{
					new
						e_PROP_FLAGS:flags = YSI_g_sProperties[i][E_PROP_DATA_FLAGS];
					if (flags & e_PROP_FLAGS_ACTIVE && flags & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_PROP && ((Property_GetOption(2, flags)) ? (_:Bit_GetBit(YSI_g_sProperties[i][E_PROP_DATA_PLAYERS], ident)) : (_:(_:YSI_g_sProperties[i][E_PROP_DATA_PLAYERS][0] == ident)))) Bit_Set(properties, i, 1, GROUP_PROPERTY_BITS);
				}
				CallRemoteFunction("Property_GetPropertyBitsReceive", "iai", ident, _:properties, sizeof (properties));
			}
			case E_PROP_REMOTE_PPCO:
			{
				new
					count;
				for (new i = 0; i < MAX_PROPERTIES; i++)
				{
					new
						e_PROP_FLAGS:flags = YSI_g_sProperties[i][E_PROP_DATA_FLAGS];
					if (Property_IsPlayerProperty(flags, ident)) count++;
				}
				setproperty(0, "YSIReq", count);
			}
			case E_PROP_REMOTE_BANK:
			{
				if (IsPlayerInCheckpoint(ident))
				{
					new
						cpid = Checkpoint_Get(ident),
						prop = YSI_g_sCheckpointPointers[cpid];
					if (prop != NO_PROPERTY)
					{
						new
							e_PROP_FLAGS:flag = YSI_g_sProperties[prop][E_PROP_DATA_FLAGS];
						if (flag & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_BANK)
						{
							if ((info > 0) ? (GetPlayerMoney(ident) >= info) : (YSI_g_sMoney[ident] + info >= 0))
							{
								YSI_g_sMoney[ident] += info;
								GivePlayerMoney(ident, -info);
							}
							else
							{
								setproperty(0, "LRegProp", 0);
								return;
							}
						}
						else Text_Send(ident, "YSI_BANK_NOT");
					}
					else Text_Send(ident, "YSI_BANK_NOT");
				}
				else Text_Send(ident, "YSI_BANK_CP");
				setproperty(0, "LRegProp", 1);
			}
			case E_PROP_REMOTE_LBANK:
			{
				YSI_g_sMoney[ident] = info;
			}
			case E_PROP_REMOTE_GBANK:
			{
				setproperty(0, "LRegProp", YSI_g_sMoney[ident]);
			}
			case E_PROP_REMOTE_LWEAP:
			{
				YSI_g_sSpawnWeapons[ident][info >> 16] = info & 0xFFFF;
			}
			case E_PROP_REMOTE_SWEAP:
			{
				new
					str[14];
				for (new i = 0; i < 13; i++)
				{
					str[i] = (YSI_g_sSpawnWeapons[ident][i] << 1) | 0x01;
				}
				str[13] = '\0';
				setproperty(0, "", 110953013, str);
			}
			case E_PROP_REMOTE_GOWEAP:
			{
				setproperty(0, "YSIReq", YSI_g_sSpawnWeapons[ident][info]);
			}
			case E_PROP_REMOTE_SAVEWEAP:
			{
				new
					slot = ident & 0xFFFF,
					playerid = (ident >> 16) & 0xFFFF;
				if ((YSI_g_sSpawnWeapons[playerid][slot] & 0xFF000000) == (info >> 24)) YSI_g_sSpawnWeapons[playerid][slot] += info & 0x00FFFFFF;
				else YSI_g_sSpawnWeapons[playerid][slot] = info;
			}
			case E_PROP_REMOTE_DELETE:
			{
				if (!Property_IsActive(ident)) return;
				new
					e_PROP_FLAGS:flags = YSI_g_sProperties[ident][E_PROP_DATA_FLAGS];
				YSI_g_sProperties[ident][E_PROP_DATA_FLAGS] = e_PROP_FLAGS:0;
				if (flags & e_PROP_FLAGS_TYPES >= e_PROP_FLAGS_TYPE_MONA)
				{
					YSI_g_sAreaPointers[_:(flags & e_PROP_FLAGS_LINK)] = NO_PROPERTY;
					Area_Delete(_:(flags & e_PROP_FLAGS_LINK));
				}
				else
				{
					YSI_g_sCheckpointPointers[_:(flags & e_PROP_FLAGS_LINK)] = NO_PROPERTY;
					DestroyCheckpoint(_:(flags & e_PROP_FLAGS_LINK));
				}
				for (new i = 0; i < MAX_PLAYERS; i++) Bit_Set(YSI_g_sPlayerProperties[i], ident, 0, GROUP_PROPERTY_BITS);
			}
			case E_PROP_REMOTE_TYPE:
			{
				if (!Property_IsActive(ident)) setproperty(0, "YSIReq", 0);
				setproperty(0, "YSIReq", _:(YSI_g_sProperties[ident][E_PROP_DATA_FLAGS] & e_PROP_FLAGS_TYPES));
			}
			case E_PROP_REMOTE_VALID:
			{
				setproperty(0, "YSIReq", Property_IsActive(ident));
			}
			case E_PROP_REMOTE_SET_MAX:
			{
				YSI_g_sMaxPlayerProps = info;
			}
			case E_PROP_REMOTE_SET_HMX:
			{
				YSI_g_sMaxPlayerHouses = info;
			}
			case E_PROP_REMOTE_REBUY:
			{
				YSI_g_sRebuyDelay = info;
			}
		}
	}
#endif

/*----------------------------------------------------------------------------*-
Command:
	enter
Parameters:
	-
Notes:
	Allows you to enter a house you own.
-*----------------------------------------------------------------------------*/

public ycmd_enter(playerid, params[], help)
{
	DBGP2("ycmd_enter() start");
	#if defined _YSI_SETUP_MASTER
		if (!YSI_g_sIsMaster) return 1;
	#endif
	if (help)
	{
		Text_Send(playerid, "YSI_ENTER_HELP_1");
		Text_Send(playerid, "YSI_ENTER_HELP_2");
	}
	else
	{
		DBGP3("ycmd_enter() Not help");
		new
			cpid,
			prop = NO_PROPERTY;
		if (IsPlayerInCheckpoint(playerid))
		{
			DBGP4("ycmd_enter() Checkpoint");
			cpid = Checkpoint_Get(playerid);
			if (cpid != NO_CHECKPOINT)
			{
				prop = YSI_g_sCheckpointPointers[cpid];
			}
		}
		#if defined _YSI_VISUAL_PICKUPS
			#pragma tabsize 0
			else if (YSI_g_sPickupTimer[playerid] != -1)
			{
				cpid = YSI_g_sPlayerPickup[playerid];
				if (cpid != NO_PICKUP)
				{
					prop = YSI_g_sPickupPointers[cpid];
				}
				DBGP4("ycmd_enter() Pickup %d", cpid);
			}
		#endif
		#pragma tabsize 4
		DBGP4("ycmd_enter() Prop %d", prop);
		if (prop != NO_PROPERTY)
		{
			new
				e_PROP_FLAGS:flag = YSI_g_sProperties[prop][E_PROP_DATA_FLAGS];
			if (flag & e_PROP_FLAGS_TYPES == e_PROP_FLAGS_TYPE_HOUS)
			{
				if (_:YSI_g_sProperties[prop][E_PROP_DATA_PLAYERS][0] == playerid)
				{
					SetPlayerInterior(playerid, YSI_g_sProperties[prop][E_PROP_DATA_DATA_1]);
					SetPlayerVirtualWorld(playerid, YSI_g_sProperties[prop][E_PROP_DATA_DATA_2]);
					SetPlayerPos(playerid, Float:YSI_g_sProperties[prop][E_PROP_DATA_NAME][3], Float:YSI_g_sProperties[prop][E_PROP_DATA_NAME][4], Float:YSI_g_sProperties[prop][E_PROP_DATA_NAME][5]);
					YSI_g_sCurrentHouse[playerid] = prop;
				}
				else Text_Send(playerid, "YSI_ENTER_NOT_YOURS");
			}
			else Text_Send(playerid, "YSI_ENTER_NO_HOUSE");
		}
		else Text_Send(playerid, "YSI_ENTER_NO_HOUSE");
	}
	return 1;
	#pragma unused params
}

/*----------------------------------------------------------------------------*-
Command:
	exit
Parameters:
	-
Notes:
	Allows you to exit a house you own.
-*----------------------------------------------------------------------------*/

public ycmd_exit(playerid, params[], help)
{
	DBGP2("ycmd_enter() start");
	#if defined _YSI_SETUP_MASTER
		if (!YSI_g_sIsMaster) return 1;
	#endif
	if (help)
	{
		Text_Send(playerid, "YSI_EXIT_HELP_1");
	}
	else
	{
		new
			prop = YSI_g_sCurrentHouse[playerid];
		if (prop != -1)
		{
			if (IsPlayerInRangeOfPoint(playerid, 3.0, Float:YSI_g_sProperties[prop][E_PROP_DATA_NAME][3], Float:YSI_g_sProperties[prop][E_PROP_DATA_NAME][4], Float:YSI_g_sProperties[prop][E_PROP_DATA_NAME][5]))
			{
				YSI_g_sCurrentHouse[playerid] = -1;
				SetPlayerInterior(playerid, 0);
				SetPlayerVirtualWorld(playerid, 0);
				SetPlayerPos(playerid, Float:YSI_g_sProperties[prop][E_PROP_DATA_NAME][0], Float:YSI_g_sProperties[prop][E_PROP_DATA_NAME][1], Float:YSI_g_sProperties[prop][E_PROP_DATA_NAME][2]);
			}
			else Text_Send(playerid, "YSI_EXIT_NEAR");
		}
		else Text_Send(playerid, "YSI_EXIT_NOT_IN");
	}
	return 1;
}
