#include <amxmodx>
#include <amxmisc>
#include <cstrike>
#include <fakemeta_util>
#include <sqlx>
#include <hamsandwich>
#include <zombieplague>
#include <dhudmessage>

#define INI "zp_buymenu.ini"
#define CFG "zp_buymenu.cfg"
#define TXT "zp_buymenu.txt"
#define WAV "items/9mmclip1.wav"

#define FLAG_A (1<<0)
#define FLAG_B (1<<1)
#define FLAG_C (1<<2)
#define FLAG_D (1<<3)
#define FLAG_E (1<<4)
#define FLAG_F (1<<5)
#define FLAG_G (1<<6)
#define FLAG_H (1<<7)
#define FLAG_I (1<<8)
#define FLAG_J (1<<9)
#define FLAG_K (1<<10)

#define MENU 8

new g_money[33], g_menu[MENU], g_maxplayers, g_gamemode, g_count[7],
g_msg_BuyClose, g_msg_StatusIcon, g_msg_Money, g_msg_BlinkAcct, bool:g_limit[128][33],
bool:g_limit_round[128][33], cvar_no_one_win, cvar_zombies_win, cvar_zombies_loose, cvar_zombies_kill,
cvar_humans_win, cvar_humans_loose, cvar_humans_kill, cvar_show_equipments, cvar_ammo_give,
cvar_money_max, cvar_money_save, Array:g_pistols, Array:g_shotguns, Array:g_submachineguns,
Array:g_rifles, Array:g_machineguns, Array:g_equipments_h, Array:g_equipments_z, Handle:SQL_Connection,
Handle:SQL_Tuple, bool:g_connected

enum
{
	SECTION_NONE = 0,
	SECTION_PISTOLS,
	SECTION_SHOTGUNS,
	SECTION_SUBMACHINEGUNS,
	SECTION_RIFLES,
	SECTION_MACHINEGUNS,
	SECTION_EQUIPMENTS_H,
	SECTION_EQUIPMENTS_Z
}

const PRIMARY_WEAPONS_BIT_SUM = (1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
const SECONDARY_WEAPONS_BIT_SUM = (1<<CSW_P228)|(1<<CSW_ELITE)|(1<<CSW_FIVESEVEN)|(1<<CSW_USP)|(1<<CSW_GLOCK18)|(1<<CSW_DEAGLE)

enum
{
	DROP_PRIMARY = 1,
	DROP_SECONDARY
}

new const MAXAMMO[] =
{
	-1,
	52, // P228 Compact
	-1,
	90, // Schmidt Scout
	1,
	32, // XM1014 M4
	1,
	100, // Ingram MAC-10
	90, // Steyr AUG A1
	1,
	120, // Dual Elite Berettas
	100, // FiveseveN
	100, // UMP 45
	90, // SG-550 Auto-Sniper
	90, // IMI Galil
	90, // Famas
	100, // USP .45 ACP Tactical
	120, // Glock 18C
	30, // AWP Magnum Sniper
	120, // MP5 Navy
	200, // M249 Para Machinegun
	32, // M3 Super 90
	90, // M4A1 Carbine
	120, // Schmidt TMP
	90, // G3SG1 Auto-Sniper
	2,
	35, // Desert Eagle .50 AE
	90, // SG-552 Commando
	90, // AK-47 Kalashnikov
	-1,
	100 // ES P90
}

new const BUYAMMO[] =
{
	-1,
	13, // P228 Compact
	-1,
	30, // Schmidt Scout
	-1,
	8, // XM1014 M4
	-1,
	12, // Ingram MAC-10
	30, // Steyr AUG A1
	-1,
	30, // Dual Elite Berettas
	50, // FiveseveN
	12, // UMP 45
	30, // SG-550 Auto-Sniper
	30, // IMI Galil
	30, // Famas
	12, // USP .45 ACP Tactical
	30, // Glock 18C
	10, // AWP Magnum Sniper
	30, // MP5 Navy
	30, // M249 Para Machinegun
	8, // M3 Super 90
	30, // M4A1 Carbine
	30, // Schmidt TMP
	30, // G3SG1 Auto-Sniper
	-1,
	7, // Desert Eagle .50 AE
	30, // SG-552 Commando
	30, // AK-47 Kalashnikov
	-1,
	50 // ES P90
}

new const TYPEAMMO[][] =
{
	"",
	"357sig", // P228 Compact
	"",
	"762nato", // Schmidt Scout
	"",
	"buckshot", // XM1014 M4
	"",
	"45acp", // Ingram MAC-10
	"556nato", // Steyr AUG A1
	"",
	"9mm", // Dual Elite Berettas
	"57mm", // FiveseveN
	"45acp", // UMP 45
	"556nato", // SG-550 Auto-Sniper
	"556nato", // IMI Galil
	"556nato", // Famas
	"45acp", // USP .45 ACP Tactical
	"9mm", // Glock 18C
	"338magnum", // AWP Magnum Sniper
	"9mm", // MP5 Navy
	"556natobox", // M249 Para Machinegun
	"buckshot", // M3 Super 90
	"556nato", // M4A1 Carbine
	"9mm", // Schmidt TMP
	"762nato", // G3SG1 Auto-Sniper
	"",
	"50ae", // Desert Eagle .50 AE
	"556nato", // SG-552 Commando
	"762nato", // AK-47 Kalashnikov
	"",
	"57mm" // ES P90
}

new const COSTAMMO[] =
{
	-1,
	2, // P228 Compact
	-1,
	4, // Schmidt Scout
	-1,
	6, // XM1014 M4
	-1,
	8, // Ingram MAC-10
	9, // Steyr AUG A1
	-1,
	11, // Dual Elite Berettas
	12, // FiveseveN
	13, // UMP 45
	14, // SG-550 Auto-Sniper
	15, // IMI Galil
	16, // Famas
	17, // USP .45 ACP Tactical
	18, // Glock 18C
	19, // AWP Magnum Sniper
	20, // MP5 Navy
	21, // M249 Para Machinegun
	22, // M3 Super 90
	23, // M4A1 Carbine
	24, // Schmidt TMP
	25, // G3SG1 Auto-Sniper
	-1,
	27, // Desert Eagle .50 AE
	28, // SG-552 Commando
	29, // AK-47 Kalashnikov
	-1,
	31, // ES P90
}

new const g_buy_commands[][] = 
{
	"usp", "glock", "deagle", "p228", "elites",
	"fn57", "m3", "xm1014", "mp5", "tmp",
	"p90", "mac10", "ump45", "ak47", "galil",
	"famas", "sg552", "m4a1", "aug", "scout",
	"awp", "g3sg1", "sg550", "m249", "vest",
	"vesthelm", "flash", "hegren", "sgren", "defuser",
	"nvgs", "shield", "primammo", "secammo", "km45",
	"9x19mm", "nighthawk", "228compact", "fiveseven", "12gauge",
	"autoshotgun", "mp", "c90", "cv47", "defender",
	"clarion", "krieg552", "bullpup", "magnum", "d3au1",
	"krieg550", "buy", "buyequip", "cl_autobuy", "cl_rebuy",
	"cl_setautobuy", "cl_setrebuy", "client_buy_open"
}

public plugin_init()
{
	register_plugin("[ZP] Addon: Buy Menu", "25.06.2015", "ErolD")
	register_dictionary(TXT)
	
	cvar_no_one_win = register_cvar("bm_no_one_win_reward", "1000")
	cvar_zombies_win = register_cvar("bm_zombies_win_reward", "2500")
	cvar_zombies_loose = register_cvar("bm_zombies_loose_reward", "500")
	cvar_zombies_kill = register_cvar("bm_zombies_kill_reward", "500")
	cvar_humans_win = register_cvar("bm_humans_win_reward", "2500")
	cvar_humans_loose = register_cvar("bm_humans_loose_reward", "500")
	cvar_humans_kill = register_cvar("bm_humans_kill_reward", "500")
	cvar_show_equipments = register_cvar("bm_show_equipments", "1")
	cvar_ammo_give = register_cvar("bm_ammo_give", "1")
	cvar_money_max = register_cvar("bm_money_max", "100000")
	cvar_money_save = register_cvar("bm_money_save", "2")
	register_cvar("bm_sql_host", "localhost")
	register_cvar("bm_sql_user", "user")
	register_cvar("bm_sql_password", "password")
	register_cvar("bm_sql_db", "db")	
	register_cvar("zp_remove_money", "0")
	
	register_event("HLTV", "Event_RoundStart", "a", "1=0", "2=0")
	RegisterHam(Ham_Player_PreThink, "player", "Ham_Player_PreThink_Pre")
	RegisterHam(Ham_TakeDamage, "player", "Ham_TakeDamage_Pre")
	RegisterHam(Ham_Spawn, "player", "Ham_Spawn_Post", 1)
	RegisterHam(Ham_Killed, "player", "Ham_Killed_Pre")
	
	new i, callback, buffer[128], name[64], cost[64], buy_commands = sizeof(g_buy_commands)
	
	callback = menu_makecallback("menu_callback")
	
	for(i = 0; i < MENU; i++)
		g_menu[i] = menu_create("BM_MENU", "menu_handler")
	
	for(i = 2; i < MENU; i++)
	{
		if(i == 7)
			menu_addblank(g_menu[0], 0)
		
		menu_additem(g_menu[0], "BM_ITEM", _, _, callback)
	}
	
	for(i = 0; i < ArraySize(g_pistols); i++)
	{
		ArrayGetString(g_pistols, i, buffer, charsmax(buffer))
		parse(buffer, name, charsmax(name), buffer, charsmax(buffer), cost, charsmax(cost))
		formatex(buffer, charsmax(buffer), "%s \y[%d$]", name, str_to_num(cost))
		menu_additem(g_menu[1], buffer, _, _, callback)
	}
	
	for(i = 0; i < ArraySize(g_shotguns); i++)
	{
		ArrayGetString(g_shotguns, i, buffer, charsmax(buffer))
		parse(buffer, name, charsmax(name), buffer, charsmax(buffer), cost, charsmax(cost))
		formatex(buffer, charsmax(buffer), "%s \y[%d$]", name, str_to_num(cost))
		menu_additem(g_menu[2], buffer, _, _, callback)
	}
	
	for(i = 0; i < ArraySize(g_submachineguns); i++)
	{
		ArrayGetString(g_submachineguns, i, buffer, charsmax(buffer))
		parse(buffer, name, charsmax(name), buffer, charsmax(buffer), cost, charsmax(cost))
		formatex(buffer, charsmax(buffer), "%s \y[%d$]", name, str_to_num(cost))
		menu_additem(g_menu[3], buffer, _, _, callback)
	}
	
	for(i = 0; i < ArraySize(g_rifles); i++)
	{
		ArrayGetString(g_rifles, i, buffer, charsmax(buffer))
		parse(buffer, name, charsmax(name), buffer, charsmax(buffer), cost, charsmax(cost))
		formatex(buffer, charsmax(buffer), "%s \y[%d$]", name, str_to_num(cost))
		menu_additem(g_menu[4], buffer, _, _, callback)
	}
	
	for(i = 0; i < ArraySize(g_machineguns); i++)
	{
		ArrayGetString(g_machineguns, i, buffer, charsmax(buffer))
		parse(buffer, name, charsmax(name), buffer, charsmax(buffer), cost, charsmax(cost))
		formatex(buffer, charsmax(buffer), "%s \y[%d$]", name, str_to_num(cost))
		menu_additem(g_menu[5], buffer, _, _, callback)
	}
	
	for(i = 0; i < ArraySize(g_equipments_h); i++)
	{
		ArrayGetString(g_equipments_h, i, buffer, charsmax(buffer))
		parse(buffer, name, charsmax(name), buffer, charsmax(buffer), cost, charsmax(cost))
		formatex(buffer, charsmax(buffer), "%s \y[%d$]", name, str_to_num(cost))
		menu_additem(g_menu[6], buffer, _, _, callback)
	}
	
	for(i = 0; i < ArraySize(g_equipments_z); i++)
	{
		ArrayGetString(g_equipments_z, i, buffer, charsmax(buffer))
		parse(buffer, name, charsmax(name), buffer, charsmax(buffer), cost, charsmax(cost))
		formatex(buffer, charsmax(buffer), "%s \y[%d$]", name, str_to_num(cost))
		menu_additem(g_menu[7], buffer, _, _, callback)
	}
	
	for(i = 0; i < buy_commands; i++)
		register_clcmd(g_buy_commands[i], "clcmd_menu")
	
	register_clcmd("buyammo1", "clcmd_buyammo")
	register_clcmd("buyammo2", "clcmd_buyammo")
	
	g_msg_BuyClose = get_user_msgid("BuyClose")
	g_msg_StatusIcon = get_user_msgid("StatusIcon")
	g_msg_Money = get_user_msgid("Money")
	g_msg_BlinkAcct = get_user_msgid("BlinkAcct")
	
	g_maxplayers = get_maxplayers()
}

public plugin_precache()
{
	g_pistols = ArrayCreate(128, 1)
	g_shotguns = ArrayCreate(128, 1)
	g_submachineguns = ArrayCreate(128, 1)
	g_rifles = ArrayCreate(128, 1)
	g_machineguns = ArrayCreate(128, 1)
	g_equipments_h = ArrayCreate(128, 1)
	g_equipments_z = ArrayCreate(128, 1)
	
	new configsdir[64], line[1024], buffer[128], name[64], name2[64], cost[64], flags[64], players[64], section
	
	get_configsdir(configsdir, charsmax(configsdir))
	format(configsdir, charsmax(configsdir), "%s/%s", configsdir, INI)
	
	if(!file_exists(configsdir))
	{
		log_to_file("zp_buymenu.log", "%s not loaded", INI)
		return;
	}
	
	new file = fopen(configsdir, "rt")
	
	while(file && !feof(file))
	{
		fgets(file, line, charsmax(line))
		
		replace(line, charsmax(line), "^n", "")
		
		if(!line[0] || line[0] == ';')
		{
			continue;
		}
		else if(line[0] == '[')
		{
			section++
			continue;
		}
		else if(line[0] == '"')
		{
			switch(section)
			{
				case SECTION_PISTOLS:
				{
					parse(line, name, charsmax(name), name2, charsmax(name2), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
					formatex(buffer, charsmax(buffer), "^"%s^" ^"%s^" ^"%s^" ^"%s^" ^"%s^"", name, name2, cost, flags, players)
					ArrayPushString(g_pistols, buffer)
					g_count[0]++
				}
				case SECTION_SHOTGUNS:
				{
					parse(line, name, charsmax(name), name2, charsmax(name2), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
					formatex(buffer, charsmax(buffer), "^"%s^" ^"%s^" ^"%s^" ^"%s^" ^"%s^"", name, name2, cost, flags, players)
					ArrayPushString(g_shotguns, buffer)
					g_count[1]++
				}
				case SECTION_SUBMACHINEGUNS:
				{
					parse(line, name, charsmax(name), name2, charsmax(name2), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
					formatex(buffer, charsmax(buffer), "^"%s^" ^"%s^" ^"%s^" ^"%s^" ^"%s^"", name, name2, cost, flags, players)
					ArrayPushString(g_submachineguns, buffer)
					g_count[2]++
				}
				case SECTION_RIFLES:
				{
					parse(line, name, charsmax(name), name2, charsmax(name2), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
					formatex(buffer, charsmax(buffer), "^"%s^" ^"%s^" ^"%s^" ^"%s^" ^"%s^"", name, name2, cost, flags, players)
					ArrayPushString(g_rifles, buffer)
					g_count[3]++
				}
				case SECTION_MACHINEGUNS:
				{
					parse(line, name, charsmax(name), name2, charsmax(name2), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
					formatex(buffer, charsmax(buffer), "^"%s^" ^"%s^" ^"%s^" ^"%s^" ^"%s^"", name, name2, cost, flags, players)
					ArrayPushString(g_machineguns, buffer)
					g_count[4]++
				}
				case SECTION_EQUIPMENTS_H:
				{
					parse(line, name, charsmax(name), name2, charsmax(name2), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
					formatex(buffer, charsmax(buffer), "^"%s^" ^"%s^" ^"%s^" ^"%s^" ^"%s^"", name, name2, cost, flags, players)
					ArrayPushString(g_equipments_h, buffer)
					g_count[5]++
				}
				case SECTION_EQUIPMENTS_Z:
				{
					parse(line, name, charsmax(name), name2, charsmax(name2), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
					formatex(buffer, charsmax(buffer), "^"%s^" ^"%s^" ^"%s^" ^"%s^" ^"%s^"", name, name2, cost, flags, players)
					ArrayPushString(g_equipments_z, buffer)
					g_count[6]++
				}
			}
		}
	}
	
	if(file)
		fclose(file)
}

public plugin_natives()
{
	register_native("zp_cs_get_user_money", "native_get_user_money", 1)
	register_native("zp_cs_set_user_money", "native_set_user_money", 1)
}

public plugin_cfg()
{
	new configsdir[32], errnum, error[128], Handle:query, host[32], user[32], password[32], db[32]
	
	get_configsdir(configsdir, charsmax(configsdir))
	server_cmd("exec %s/%s", configsdir, CFG)
	
	if(!get_pcvar_num(cvar_money_save))
		return;
	
	get_cvar_string("bm_sql_host", host, charsmax(host))
	get_cvar_string("bm_sql_user", user, charsmax(user))
	get_cvar_string("bm_sql_password", password, charsmax(password))
	get_cvar_string("bm_sql_db", db, charsmax(db))
	
	SQL_Tuple = SQL_MakeDbTuple(host, user, password, db)
	SQL_Connection = SQL_Connect(SQL_Tuple, errnum, error, charsmax(error))
	
	if(SQL_Connection == Empty_Handle)
	{
		server_print("ERROR #%d: %s", errnum, error)
		g_connected = false
	}
	else
	{
		query = SQL_PrepareQuery(SQL_Connection, "CREATE TABLE IF NOT EXISTS `zp_buymenu`(`player` VARCHAR(32) NOT NULL PRIMARY KEY, `money` INTEGER NOT NULL)")
		SQL_Execute(query)
		SQL_FreeHandle(query)
		g_connected = true
	}
}

public client_connect(id)
{
	client_cmd(id, "setinfo _vgui_menus 0")
	
	if(g_connected)
	{
		static player[32], Handle:query
		
		switch(get_pcvar_num(cvar_money_save))
		{
			case 1: get_user_name(id, player, charsmax(player))
			case 2: get_user_authid(id, player, charsmax(player))
			case 3: get_user_ip(id, player, charsmax(player))
		}
		
		query = SQL_PrepareQuery(SQL_Connection, "SELECT * FROM `zp_buymenu` WHERE `player`='%s'", player)
		SQL_Execute(query)
		g_money[id] = SQL_ReadResult(query, 1)
		SQL_FreeHandle(query)
	}
}

public client_disconnect(id)
{
	if(g_connected)
	{
		static player[32], Handle:query
		
		switch(get_pcvar_num(cvar_money_save))
		{
			case 1: get_user_name(id, player, charsmax(player))
			case 2: get_user_authid(id, player, charsmax(player))
			case 3: get_user_ip(id, player, charsmax(player))
		}
		
		query = SQL_PrepareQuery(SQL_Connection, "REPLACE INTO `zp_buymenu`(`player`, `money`) VALUES ('%s', '%d')", player, g_money[id])
		SQL_Execute(query)
		SQL_FreeHandle(query)
	}
}

public plugin_end()
{
	if(g_connected)
	{
		SQL_FreeHandle(SQL_Connection)
		SQL_FreeHandle(SQL_Tuple)
	}
}

public clcmd_menu(id)
{
	if(!is_user_alive(id))
		return PLUGIN_HANDLED;
	
	message_begin(MSG_ONE, g_msg_BuyClose, _, id)
	message_end()
	
	static buffer[128]
	
	formatex(buffer, charsmax(buffer), "%L", LANG_PLAYER, "BM_TITLE")
	menu_setprop(g_menu[0], MPROP_TITLE, buffer)
	
	formatex(buffer, charsmax(buffer), "%L", LANG_PLAYER, "BM_PISTOLS")
	menu_item_setname(g_menu[0], 0, buffer)
	menu_setprop(g_menu[1], MPROP_TITLE, buffer)
	
	formatex(buffer, charsmax(buffer), "%L", LANG_PLAYER, "BM_SHOTGUNS")
	menu_item_setname(g_menu[0], 1, buffer)
	menu_setprop(g_menu[2], MPROP_TITLE, buffer)
	
	formatex(buffer, charsmax(buffer), "%L", LANG_PLAYER, "BM_SUBMACHINEGUNS")
	menu_item_setname(g_menu[0], 2, buffer)
	menu_setprop(g_menu[3], MPROP_TITLE, buffer)
	
	formatex(buffer, charsmax(buffer), "%L", LANG_PLAYER, "BM_RIFLES")
	menu_item_setname(g_menu[0], 3, buffer)
	menu_setprop(g_menu[4], MPROP_TITLE, buffer)
	
	formatex(buffer, charsmax(buffer), "%L", LANG_PLAYER, "BM_MACHINEGUNS")
	menu_item_setname(g_menu[0], 4, buffer)
	menu_setprop(g_menu[5], MPROP_TITLE, buffer)
	
	if(zp_get_user_zombie(id))
	{
		formatex(buffer, charsmax(buffer), "%L", LANG_PLAYER, "BM_EQUIPMENTS_ZOMBIES")
		menu_item_setname(g_menu[0], 5, buffer)
		menu_setprop(g_menu[7], MPROP_TITLE, buffer)
		
		if(get_pcvar_num(cvar_show_equipments))
			menu_display(id, g_menu[7])
		else
			menu_display(id, g_menu[0])
	}
	else
	{
		formatex(buffer, charsmax(buffer), "%L", LANG_PLAYER, "BM_EQUIPMENTS_HUMANS")
		menu_item_setname(g_menu[0], 5, buffer)
		menu_setprop(g_menu[6], MPROP_TITLE, buffer)
		
		menu_display(id, g_menu[0])
	}
	
	return PLUGIN_HANDLED;
}

public clcmd_buyammo(id)
{
	if(!is_user_alive(id) || zp_get_user_zombie(id))
		return PLUGIN_HANDLED;
	
	static ammo, weapon
	
	weapon = get_user_weapon(id, _, ammo)
	
	if(g_money[id] < COSTAMMO[weapon])
	{
		message_begin(MSG_ONE_UNRELIABLE, g_msg_BlinkAcct, _, id)
		write_byte(5)
		message_end()
	}
	else if(ammo < MAXAMMO[weapon])
	{
		ExecuteHam(Ham_GiveAmmo, id, BUYAMMO[weapon], TYPEAMMO[weapon], MAXAMMO[weapon])
		set_user_money(id, g_money[id] - COSTAMMO[weapon])
		emit_sound(id, CHAN_ITEM, WAV, 1.0, ATTN_NORM, 0, PITCH_NORM)
	}
	
	return PLUGIN_HANDLED;
}

public menu_handler(id, menu, item)
{
	static buffer[128], name2[64], cost[64], weaponid
	
	if(item == MENU_EXIT)
		return;
	
	switch(menu)
	{
		case 0:
		{
			switch(item)
			{
				case 5:
				{
					if(zp_get_user_zombie(id))
						menu_display(id, g_menu[7], 0)
					else
						menu_display(id, g_menu[6], 0)
				}
				default: menu_display(id, g_menu[item + 1], 0)
			}
		}
 		case 1:
		{
			ArrayGetString(g_pistols, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), name2, charsmax(name2), cost, charsmax(cost))
			
			weaponid = get_weaponid(name2)
			
			if(equal(name2, "weapon_", 7))
			{
				drop_weapons(id, DROP_SECONDARY)
				fm_give_item(id, name2)
				
				if(get_pcvar_num(cvar_ammo_give))
					ExecuteHam(Ham_GiveAmmo, id, MAXAMMO[weaponid], TYPEAMMO[weaponid], MAXAMMO[weaponid])
			}
			else
			{
				zp_force_buy_extra_item(id, zp_get_extra_item_id(name2), 1)
			}
			
			set_user_money(id, g_money[id] - str_to_num(cost))
			g_limit_round[item][id] = g_limit[item][id] = true
		}
		case 2:
		{
			ArrayGetString(g_shotguns, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), name2, charsmax(name2), cost, charsmax(cost))
			
			weaponid = get_weaponid(name2)
			
			if(equal(name2, "weapon_", 7))
			{
				drop_weapons(id, DROP_PRIMARY)
				fm_give_item(id, name2)
				
				if(get_pcvar_num(cvar_ammo_give))
					ExecuteHam(Ham_GiveAmmo, id, MAXAMMO[weaponid], TYPEAMMO[weaponid], MAXAMMO[weaponid])
			}
			else
			{
				zp_force_buy_extra_item(id, zp_get_extra_item_id(name2), 1)
			}
			
			set_user_money(id, g_money[id] - str_to_num(cost))
			g_limit_round[item][id] = g_limit[item][id] = true
		}
		case 3:
		{
			ArrayGetString(g_submachineguns, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), name2, charsmax(name2), cost, charsmax(cost))
			
			weaponid = get_weaponid(name2)
			
			if(equal(name2, "weapon_", 7))
			{
				drop_weapons(id, DROP_PRIMARY)
				fm_give_item(id, name2)
				
				if(get_pcvar_num(cvar_ammo_give))
					ExecuteHam(Ham_GiveAmmo, id, MAXAMMO[weaponid], TYPEAMMO[weaponid], MAXAMMO[weaponid])
			}
			else
			{
				zp_force_buy_extra_item(id, zp_get_extra_item_id(name2), 1)
			}
			
			set_user_money(id, g_money[id] - str_to_num(cost))
			g_limit_round[item][id] = g_limit[item][id] = true
		}
		case 4:
		{
			ArrayGetString(g_rifles, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), name2, charsmax(name2), cost, charsmax(cost))
			
			weaponid = get_weaponid(name2)
			
			if(equal(name2, "weapon_", 7))
			{
				drop_weapons(id, DROP_PRIMARY)
				fm_give_item(id, name2)
				
				if(get_pcvar_num(cvar_ammo_give))
					ExecuteHam(Ham_GiveAmmo, id, MAXAMMO[weaponid], TYPEAMMO[weaponid], MAXAMMO[weaponid])
			}
			else
			{
				zp_force_buy_extra_item(id, zp_get_extra_item_id(name2), 1)
			}
			
			set_user_money(id, g_money[id] - str_to_num(cost))
			g_limit_round[item][id] = g_limit[item][id] = true
		}
		case 5:
		{
			ArrayGetString(g_machineguns, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), name2, charsmax(name2), cost, charsmax(cost))
			
			weaponid = get_weaponid(name2)
			
			if(equal(name2, "weapon_", 7))
			{
				drop_weapons(id, DROP_PRIMARY)
				fm_give_item(id, name2)
				
				if(get_pcvar_num(cvar_ammo_give))
					ExecuteHam(Ham_GiveAmmo, id, MAXAMMO[weaponid], TYPEAMMO[weaponid], MAXAMMO[weaponid])
			}
			else
			{
				zp_force_buy_extra_item(id, zp_get_extra_item_id(name2), 1)
			}
			
			set_user_money(id, g_money[id] - str_to_num(cost))
			g_limit_round[item][id] = g_limit[item][id] = true
		}
		case 6:
		{
			ArrayGetString(g_equipments_h, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), name2, charsmax(name2), cost, charsmax(cost))
			
			if(equal(name2, "weapon_", 7))
				fm_give_item(id, name2)
			else
				zp_force_buy_extra_item(id, zp_get_extra_item_id(name2), 1)
			
			set_user_money(id, g_money[id] - str_to_num(cost))
			g_limit_round[item][id] = g_limit[item][id] = true
		}
		case 7:
		{
			ArrayGetString(g_equipments_z, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), name2, charsmax(name2), cost, charsmax(cost))
			
			if(equal(name2, "weapon_", 7))
				fm_give_item(id, name2)
			else
				zp_force_buy_extra_item(id, zp_get_extra_item_id(name2), 1)
			
			set_user_money(id, g_money[id] - str_to_num(cost))
			g_limit_round[item][id] = g_limit[item][id] = true
		}
	}
}

public menu_callback(id, menu, item)
{
	static buffer[128], name2[64], cost[64], flags[64], players[64], flag
	
	switch(menu)
	{
		case 0:
		{
			switch(item)
			{
				case 5: return ITEM_ENABLED;
				default:
				{
					if(zp_get_user_zombie(id) || !g_count[item])
						return ITEM_DISABLED;
				}
			}
		}
		case 1:
		{
			ArrayGetString(g_pistols, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), buffer, charsmax(buffer), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
			flag = read_flags(flags)
			
			if(zp_get_user_zombie(id) || g_money[id] < str_to_num(cost) || (!g_gamemode && flag & FLAG_A) || (g_gamemode && flag & FLAG_B) || (zp_get_user_last_zombie(id) && flag & FLAG_C) || (zp_get_user_last_human(id) && flag & FLAG_D) || (g_gamemode == MODE_NEMESIS && flag & FLAG_E)
			|| (g_gamemode == MODE_SURVIVOR && flag & FLAG_F) || (g_gamemode == MODE_SWARM && flag & FLAG_G) || (g_gamemode == MODE_PLAGUE && flag & FLAG_H) || (!(get_user_flags(id) & ADMIN_BAN) && flag & FLAG_I) || ((g_limit_round[item][id]) && flag & FLAG_J) || ((g_limit[item][id]) && flag & FLAG_K) || get_playersnum() < str_to_num(players))
				return ITEM_DISABLED;
		}
		case 2:
		{
			ArrayGetString(g_shotguns, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), buffer, charsmax(buffer), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
			flag = read_flags(flags)
			
			if(zp_get_user_zombie(id) || g_money[id] < str_to_num(cost) || (!g_gamemode && flag & FLAG_A) || (g_gamemode && flag & FLAG_B) || (zp_get_user_last_zombie(id) && flag & FLAG_C) || (zp_get_user_last_human(id) && flag & FLAG_D) || (g_gamemode == MODE_NEMESIS && flag & FLAG_E)
			|| (g_gamemode == MODE_SURVIVOR && flag & FLAG_F) || (g_gamemode == MODE_SWARM && flag & FLAG_G) || (g_gamemode == MODE_PLAGUE && flag & FLAG_H) || (!(get_user_flags(id) & ADMIN_BAN) && flag & FLAG_I) || ((g_limit_round[item][id]) && flag & FLAG_J) || ((g_limit[item][id]) && flag & FLAG_K) || get_playersnum() < str_to_num(players))
				return ITEM_DISABLED;
		}
		case 3:
		{
			ArrayGetString(g_submachineguns, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), buffer, charsmax(buffer), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
			flag = read_flags(flags)
			
			if(zp_get_user_zombie(id) || g_money[id] < str_to_num(cost) || (!g_gamemode && flag & FLAG_A) || (g_gamemode && flag & FLAG_B) || (zp_get_user_last_zombie(id) && flag & FLAG_C) || (zp_get_user_last_human(id) && flag & FLAG_D) || (g_gamemode == MODE_NEMESIS && flag & FLAG_E)
			|| (g_gamemode == MODE_SURVIVOR && flag & FLAG_F) || (g_gamemode == MODE_SWARM && flag & FLAG_G) || (g_gamemode == MODE_PLAGUE && flag & FLAG_H) || (!(get_user_flags(id) & ADMIN_BAN) && flag & FLAG_I) || ((g_limit_round[item][id]) && flag & FLAG_J) || ((g_limit[item][id]) && flag & FLAG_K) || get_playersnum() < str_to_num(players))
				return ITEM_DISABLED;
		}
		case 4:
		{
			ArrayGetString(g_rifles, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), buffer, charsmax(buffer), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
			flag = read_flags(flags)
			
			if(zp_get_user_zombie(id) || g_money[id] < str_to_num(cost) || (!g_gamemode && flag & FLAG_A) || (g_gamemode && flag & FLAG_B) || (zp_get_user_last_zombie(id) && flag & FLAG_C) || (zp_get_user_last_human(id) && flag & FLAG_D) || (g_gamemode == MODE_NEMESIS && flag & FLAG_E)
			|| (g_gamemode == MODE_SURVIVOR && flag & FLAG_F) || (g_gamemode == MODE_SWARM && flag & FLAG_G) || (g_gamemode == MODE_PLAGUE && flag & FLAG_H) || (!(get_user_flags(id) & ADMIN_BAN) && flag & FLAG_I) || ((g_limit_round[item][id]) && flag & FLAG_J) || ((g_limit[item][id]) && flag & FLAG_K) || get_playersnum() < str_to_num(players))
				return ITEM_DISABLED;
		}
		case 5:
		{
			ArrayGetString(g_machineguns, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), buffer, charsmax(buffer), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
			flag = read_flags(flags)
			
			if(zp_get_user_zombie(id) || g_money[id] < str_to_num(cost) || (!g_gamemode && flag & FLAG_A) || (g_gamemode && flag & FLAG_B) || (zp_get_user_last_zombie(id) && flag & FLAG_C) || (zp_get_user_last_human(id) && flag & FLAG_D) || (g_gamemode == MODE_NEMESIS && flag & FLAG_E)
			|| (g_gamemode == MODE_SURVIVOR && flag & FLAG_F) || (g_gamemode == MODE_SWARM && flag & FLAG_G) || (g_gamemode == MODE_PLAGUE && flag & FLAG_H) || (!(get_user_flags(id) & ADMIN_BAN) && flag & FLAG_I) || ((g_limit_round[item][id]) && flag & FLAG_J) || ((g_limit[item][id]) && flag & FLAG_K) || get_playersnum() < str_to_num(players))
				return ITEM_DISABLED;
		}
		case 6:
		{
			ArrayGetString(g_equipments_h, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), name2, charsmax(name2), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
			flag = read_flags(flags)
			
			if(zp_get_user_zombie(id) || g_money[id] < str_to_num(cost) || (!g_gamemode && flag & FLAG_A) || (g_gamemode && flag & FLAG_B) || (zp_get_user_last_zombie(id) && flag & FLAG_C) || (zp_get_user_last_human(id) && flag & FLAG_D) || (g_gamemode == MODE_NEMESIS && flag & FLAG_E)
			|| (g_gamemode == MODE_SURVIVOR && flag & FLAG_F) || (g_gamemode == MODE_SWARM && flag & FLAG_G) || (g_gamemode == MODE_PLAGUE && flag & FLAG_H) || (!(get_user_flags(id) & ADMIN_BAN) && flag & FLAG_I) || ((g_limit_round[item][id]) && flag & FLAG_J) || ((g_limit[item][id]) && flag & FLAG_K)
			|| get_playersnum() < str_to_num(players) || (equal(name2, "weapon_hegrenade") && cs_get_user_bpammo(id, CSW_HEGRENADE) >= 1) || (equal(name2, "weapon_flashbang") && cs_get_user_bpammo(id, CSW_FLASHBANG) >= 2) || (equal(name2, "weapon_smokegrenade") && cs_get_user_bpammo(id, CSW_SMOKEGRENADE) >= 1))
				return ITEM_DISABLED;
		}
		case 7:
		{
			ArrayGetString(g_equipments_z, item, buffer, charsmax(buffer))
			parse(buffer, buffer, charsmax(buffer), buffer, charsmax(buffer), cost, charsmax(cost), flags, charsmax(flags), players, charsmax(players))
			flag = read_flags(flags)
			
			if(g_money[id] < str_to_num(cost) || (!g_gamemode && flag & FLAG_A) || (g_gamemode && flag & FLAG_B) || (zp_get_user_last_zombie(id) && flag & FLAG_C) || (zp_get_user_last_human(id) && flag & FLAG_D) || (g_gamemode == MODE_NEMESIS && flag & FLAG_E)
			|| (g_gamemode == MODE_SURVIVOR && flag & FLAG_F) || (g_gamemode == MODE_SWARM && flag & FLAG_G) || (g_gamemode == MODE_PLAGUE && flag & FLAG_H) || (!(get_user_flags(id) & ADMIN_BAN) && flag & FLAG_I) || ((g_limit_round[item][id]) && flag & FLAG_J) || ((g_limit[item][id]) && flag & FLAG_K) || get_playersnum() < str_to_num(players))
				return ITEM_DISABLED;
		}
	}
	
	return ITEM_ENABLED;
}

public zp_round_started(gamemode)
	g_gamemode = gamemode

public zp_round_ended(winteam)
{
	new id
	
	for(id = 1; id <= g_maxplayers; id++)
	{
		if(!is_user_connected(id))
			continue;
		
		switch(winteam)
		{
			case WIN_NO_ONE:
			{
				set_user_money(id, g_money[id] + get_pcvar_num(cvar_no_one_win))
				
				set_dhudmessage(0, 125, 0, 0.08, 0.5, 0, 0.0, 1.0, 3.0, 1.0, false)
				show_dhudmessage(id, "%L", LANG_PLAYER, "BM_WIN_NO_ONE", get_pcvar_num(cvar_no_one_win))
			}
			case WIN_ZOMBIES:
			{
				switch(zp_get_user_zombie(id))
				{
					case 0:
					{
						set_user_money(id, g_money[id] + get_pcvar_num(cvar_humans_loose))
						
						set_dhudmessage(200, 0, 0, 0.08, 0.5, 0, 0.0, 1.0, 3.0, 1.0, false)
						show_dhudmessage(id, "%L", LANG_PLAYER, "BM_LOOSE_HUMANS", get_pcvar_num(cvar_humans_loose))
					}
					case 1:
					{
						set_user_money(id, g_money[id] + get_pcvar_num(cvar_zombies_win))
						
						set_dhudmessage(200, 0, 0, 0.08, 0.5, 0, 0.0, 1.0, 3.0, 1.0, false)
						show_dhudmessage(id, "%L", LANG_PLAYER, "BM_WIN_ZOMBIES", get_pcvar_num(cvar_zombies_win))
					}
				}
			}
			case WIN_HUMANS:
			{
				switch(zp_get_user_zombie(id))
				{
					case 0:
					{
						set_user_money(id, g_money[id] + get_pcvar_num(cvar_humans_win))
						
						set_dhudmessage(0, 0, 200, 0.08, 0.5, 0, 0.0, 1.0, 3.0, 1.0, false)
						show_dhudmessage(id, "%L", LANG_PLAYER, "BM_WIN_HUMANS", get_pcvar_num(cvar_humans_win))
					}
					case 1:
					{
						set_user_money(id, g_money[id] + get_pcvar_num(cvar_zombies_loose))
						
						set_dhudmessage(0, 0, 200, 0.08, 0.5, 0, 0.0, 1.0, 3.0, 1.0, false)
						show_dhudmessage(id, "%L", LANG_PLAYER, "BM_LOOSE_ZOMBIES", get_pcvar_num(cvar_zombies_loose))
					}
				}
			}
		}
	}
}

public Event_RoundStart()
{
	new id, item, limit_round = sizeof(g_limit_round)
	
	for(id = 1; id <= g_maxplayers; id++)
	{
		for(item = 0; item < limit_round; item++)
			g_limit_round[item][id] = false
	}
}

public Ham_Player_PreThink_Pre(id)
{
	if(!is_user_alive(id))
		return HAM_IGNORED;
	
	message_begin(MSG_ONE, g_msg_StatusIcon, _, id)
	write_byte(1)
	write_string("buyzone")
	write_byte(0)
	write_byte(0)
	write_byte(0)
	message_end()
	
	return HAM_IGNORED;
}

public Ham_TakeDamage_Pre(victim, inflictor, attacker, Float:damage, damage_type)
{
	if(victim == attacker || !is_user_connected(attacker))
		return HAM_IGNORED;
	
	set_user_money(attacker, g_money[attacker] + floatround(damage))
	
	return HAM_IGNORED;
}

public Ham_Spawn_Post(id)
{
	set_user_money(id, g_money[id], 0)
	
	set_dhudmessage(0, 125, 0, -1.0, 0.75, 0, 0.0, 3.0, 2.0, 1.0, false)
	show_dhudmessage(id, "%L", LANG_PLAYER, "BM_HUD_INFO")
}

public Ham_Killed_Pre(victim, attacker, shouldgib)
{
	if(victim == attacker || !is_user_connected(attacker))
		return HAM_IGNORED;
	
	if(zp_get_user_zombie(attacker))
		set_user_money(attacker, g_money[attacker] + get_pcvar_num(cvar_zombies_kill))
	else
		set_user_money(attacker, g_money[attacker] + get_pcvar_num(cvar_humans_kill))
	
	return HAM_IGNORED;
}

public native_get_user_money(id)
	return g_money[id];

public native_set_user_money(id, money)
	set_user_money(id, money)

stock set_user_money(id, money, flash=1)
{
	if(!is_user_connected(id))
		return;
	
	if(money > get_pcvar_num(cvar_money_max))
		money = get_pcvar_num(cvar_money_max)
	
	g_money[id] = money
	
	if(!is_user_alive(id))
		return;
	
	message_begin(MSG_ONE_UNRELIABLE, g_msg_Money, _, id)
	write_long(money)
	write_byte(flash)
	message_end()
}

stock drop_weapons(id, slot)
{
	static i, weaponname[32]
	
	for(i = CSW_P228; i < CSW_P90; i++)
	{
		switch(slot)
		{
			case DROP_PRIMARY:
			{
				if((1<<i) & PRIMARY_WEAPONS_BIT_SUM)
				{
					get_weaponname(i, weaponname, charsmax(weaponname))
					engclient_cmd(id, "drop", weaponname)
				}
			}
			case DROP_SECONDARY:
			{
				if((1<<i) & SECONDARY_WEAPONS_BIT_SUM)
				{
					get_weaponname(i, weaponname, charsmax(weaponname))
					engclient_cmd(id, "drop", weaponname)
				}
			}
		}
	}
}