new PLUGIN_VERSION[] 	= "1.0.2"

// Based experience ; this are times by the players level 
#define Kill_Experience		15	
#define Hos_Experience		5
#define Obj_Experience		10
#define MIN_PLAYERS		6 //Minimum players that are connected to get objective xp

#define Max_Level		16
// Max level for each passive upgrades
#define MaxLevel_Health		3
#define MaxLevel_Armor		3
#define MaxLevel_Speed		3
#define MaxLevel_Gravity	3
#define MaxLevel_Stealth	3

// How much you get per level
#define Health_PerLevel		15
#define Armor_PerLevel		20
#define Speed_PerLevel		30		
#define Gravity_PerLevel	0.2 // 20%
#define Stealth_PerLevel	60

// Max items players can carry
#define Max_PlayerItems		3

#define Item_Money		1 // 0 = Experience; 1 = dollars	
#define Item_Death		1 // Player lose item on death

// Item plugins configs
#define MAX_ITEMS		100
#define MAX_MAPITEMS		100
#define MAX_ITEM_NAME_SIZE	64
#define MAX_ITEM_DESC_SIZE	128


new LevelUpSound[] 	= { "events/task_complete.wav" }
new DeniedSound[] 	= { "buttons/blip1.wav"}
new UpgradedSound[] 	= { "items/tr_kevlar.wav" }
new BoughtItemSound[] 	= { "items/ammopickup1.wav" }
new PickUpItemSound[] 	= { "items/ammopickup2.wav" }
new DropItemSound[]	= { "events/enemy_died.wav" }
new ItemModel[] 	= { "models/w_gaussammo.mdl" }

new LEVELS[Max_Level] =
{ 
	50, 	//0
	100, 	//1
	200,	//2
	400,	//3
	800,	//4
	1600,	//5
	3200,	//6
	6400,	//7
	12800,	//8
	25600,	//9
	51200,	//10
	102400,	//11
	204800,	//12
	409600,	//13
	819200,	//14
	1638400	//15
}

/* DO NOT EDIT BEYOND THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING */

#include <amxmodx>
#include <amxmisc>
#include <cstrike>
#include <engine>
#include <vault>
#include <fun>

new g_HealthLevel[33]
new g_ArmorLevel[33]
new g_SpeedLevel[33]
new g_GravityLevel[33]
new g_StealthLevel[33]
new bool:g_PlayerReseted[33]

new PlayerXp[33] 
new PlayerLevel[33]
new PlayerPoints[33]

new g_MapItemNum
new bool:ftimeover
new bool:g_DirExist
new g_ConfigsDir[64]
new g_ItemOriginDir[64]
new g_MapItemOrgins[MAX_MAPITEMS+1][3]

new g_numberofitems
new g_menuPosition[33]
new g_itemindex[MAX_ITEMS+1]
new g_itemcost[MAX_ITEMS+1]
new g_itemname[MAX_ITEMS+1][MAX_ITEM_NAME_SIZE+1]
new g_itemdesc[MAX_ITEMS+1][MAX_ITEM_DESC_SIZE+1]
new bool:g_iPlayerItem[33][MAX_ITEMS+1]
new g_PlayerNumItems[33]



new PLUGIN_NAME[] 	= "Upgrades Mod 2.0"
new PLUGIN_AUTHOR[] 	= "Cheap_Suit"

public plugin_init() 
{
	register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)
	register_cvar("um_enable", "1") 
	register_cvar("um_autosavexp", "1")
	register_cvar("um_itemsremoved", "1")
	
	if(get_cvar_num("um_enable"))
	{
		register_clcmd("um_addxp", "cmd_AddXP", ADMIN_IMMUNITY, "<@all/t/ct>/<name><xp> - give users xp eg. um_addxp cheap_suit 100")
		register_clcmd("um_setlevel", "cmd_SetLevel", ADMIN_IMMUNITY, "<name><level> - give users xp eg. um_setlevel cheap_suit 5")
		register_clcmd("um_mapitems", "Open_MapItemConfig", ADMIN_IMMUNITY, "- Open's Map item configs")
		register_clcmd("say /ummenu", 	"open_MainMenu")
		register_clcmd("say /upgrade", 	"open_PassiveUpgrades")
		register_clcmd("say /itemshop", "open_ItemUpgrades")
		register_clcmd("say /itemlist", "display_itemlist")
		register_clcmd("say /umhelp", 	"display_help")
		register_clcmd("say /myitems", 	"display_myitems")
		register_clcmd("say /dropitems","cmd_DropItems")
		register_concmd("ummenu", 	"open_MainMenu")
		register_concmd("upgrade", 	"open_PassiveUpgrades")
		register_concmd("itemshop", 	"open_ItemUpgrades")
		register_concmd("itemlist", 	"display_itemlist")
		register_concmd("umhelp", 	"display_help")
		register_concmd("myitems", 	"display_myitems")
		register_concmd("dropitems", 	"cmd_DropItems")
		
		register_touch("UmItem", "player", "Pickup_Items")
		register_directory()
		
		register_event("DeathMsg", "Event_DeathMsg", "a")
		register_event("ResetHUD", "Event_ResetHUD", "be")
		register_event("CurWeapon", "Event_CurWeapon", "be", "1=1")
		register_event("Damage", "Event_Damage", "bd", "2>0")
		register_event("StatusValue", "Event_StatusValue", "bd", "1=2")
	
		register_event("TextMsg", "Event_GameRestart", "a", "2=#Game_will_restart_in", "2&#Game_C") 
		register_event("SendAudio", "Event_RoundEnd", "a", "2=%!MRAD_terwin", "2=%!MRAD_ctwin", "2=%!MRAD_rounddraw") 	
	
		register_logevent("LogEvent_Objectives", 3, "1=triggered")
		register_logevent("LogEvent_RoundStart", 2, "0=World triggered", "1=Round_Start")
		
		register_menucmd(register_menuid("Main Upgrades Menu"), 1023, "Action_MainMenu")
		register_menucmd(register_menuid("Passive Upgrades"), 1023, "Action_PassiveUpgrades")
		register_menucmd(register_menuid("MI Config Menu"), 1023, "Action_MapItemConfig")
		register_menucmd(register_menuid("Item Shop"), 1023, "Action_ItemUpgrades")
		
	
		//Advertise the command to the dead people
		set_task(random_float(50.0, 90.0), "display_Advertisements", _, _, _, "b")
		set_task(0.1, "client_experience", 12, _, _, "b")
	}
	set_task(0.1, "check_cvar", 34, _, _, "b")
}

public check_cvar()
{
	if(!get_cvar_num("um_enable"))
	{
		remove_items()
		remove_task(12)
		remove_task(34)
		
		for(new i = 1; i <= get_maxplayers(); ++i) if(is_user_connected(i)) 
		{
			message_begin(MSG_ONE, get_user_msgid("StatusText"), {0, 0, 0}, i) 
			write_byte(0) 
			write_string("")
			message_end()
		}
		
		for(new i = 0; i < get_pluginsnum(); ++i)
		{
			new temp[2], name[64]
			get_plugin(i, name, 63, temp, 1, temp, 1, temp, 1, temp, 1)
			if(equali(name, "Item_", 5)) {
				server_cmd("amxx pause %s", name)
			}
		}

		server_cmd("amxx pause %s", PLUGIN_NAME)
		server_print("If enabled again, restart server for upgrades mod to work properly")
	}
}

register_directory()
{
	get_configsdir(g_ConfigsDir, 63)
	format(g_ItemOriginDir, 63, "%s/itemorigin", g_ConfigsDir)
	
	if(!dir_exists(g_ItemOriginDir)) 
	{
		log_amx("itemorigin directory does not exist")
		g_DirExist = false
	} 
	else 
	{
		g_DirExist = true
		
		new CurMap[32]
		get_mapname(CurMap, 31)
		Load_Origins(CurMap)
	}
	
}

public client_authorized(id)
{
	g_HealthLevel[id] = 0
	g_ArmorLevel[id] = 0
	g_SpeedLevel[id] = 0
	g_GravityLevel[id] = 0
	g_StealthLevel[id] = 0
		
	PlayerXp[id] = 0 
	PlayerLevel[id] = 0
	PlayerPoints[id] = 0
		
	g_PlayerNumItems[id] = 0
	for(new i = 1; i <= MAX_ITEMS; ++i) {
		g_iPlayerItem[id][MAX_ITEMS] = false
	}
	LoadData(id)
}

public client_disconnect(id) 
{
	if(get_cvar_num("um_autosavexp")) {
		SaveData(id)
	}
}

public client_experience()
{	
	new Players[32], iNum
	get_players(Players, iNum)
	
	for(new i = 0; i < iNum; ++i)
	{
		new id = Players[i]
		if(is_user_alive(id)) 
		{
			new InfoMsg[255] 
			format(InfoMsg, 254, "Level: %d/%d    XP: %d/%d    Points: %d    Items: %d/%d", PlayerLevel[id], Max_Level-1, PlayerXp[id], LEVELS[PlayerLevel[id]], PlayerPoints[id], g_PlayerNumItems[id], Max_PlayerItems)
					    
			message_begin(MSG_ONE, get_user_msgid("StatusText"), {0, 0, 0}, id) 
			write_byte(0) 
			write_string(InfoMsg)
			message_end()
		}
	
		if(PlayerXp[id] >= LEVELS[Max_Level-1] || PlayerLevel[id] >= Max_Level-1) 
		{
			PlayerLevel[id] = Max_Level-1
			PlayerXp[id] = LEVELS[Max_Level-1]
			return PLUGIN_CONTINUE
		}
		
		if(PlayerXp[id] >= LEVELS[PlayerLevel[id]])
		{
			PlayerLevel[id] += 1
			PlayerPoints[id] += 1
			display_PassiveUpgrades(id)
			client_cmd(id, "spk %s", LevelUpSound)
		}
	}
	return PLUGIN_CONTINUE
}

public LogEvent_RoundStart() 
{
	ftimeover = true
	set_task(0.6, "Spawn_Items")
}

public Event_RoundEnd()
{
	ftimeover = false
	if(get_cvar_num("um_itemsremoved")) {
		set_task(2.5, "remove_items")
	}
}

public remove_items()
{
	new items = find_ent_by_class(-1, "UmItem")
	while(items) 
	{
		remove_entity(items)
		items = find_ent_by_class(items, "UmItem")
	}
}

public Event_GameRestart()
{
	new Float:fRestartCvar = get_cvar_float("sv_restart")
	set_task((fRestartCvar - 0.2), "Event_RoundEnd")
}

get_connectedplayers()
{
	new cpl
	for(new i = 1; i <= get_maxplayers(); ++i) if(is_user_connected(i)) {
		cpl += 1
	}
	return cpl
}

public Event_StatusValue(id)
{
	new target = read_data(2)
  	if(target != id && target != 0)
  	{
		new sName[32], szMenuBody[512]
		get_user_name(target, sName, 31)

		new len = format(szMenuBody, 511, "Name: %s^n", sName)
		len += format(szMenuBody[len], 511-len, "Level: %d^n", PlayerLevel[target])
		len += format(szMenuBody[len], 511-len, "Items: %d^n", g_PlayerNumItems[target])
		for(new i = 1; i <= g_numberofitems; ++i) if(g_iPlayerItem[target][i]) {
			len += format(szMenuBody[len], 511-len, "%s^n", g_itemname[i])
		}
		set_hudmessage(255, 255, 255, 0.6, -1.0, 0, 0.0, 6.0, 0.0, 0.0, 1)
		show_hudmessage(id, szMenuBody)
	}
}

public LogEvent_Objectives()
{
	if(get_connectedplayers() < MIN_PLAYERS) {
		return PLUGIN_CONTINUE
	}
	
	new sArg[64], sAction[64]
	read_logargv(0, sArg, 64) 
	read_logargv(2, sAction, 64) 
	
	new sName[1], iUserId, iExperienceGain
	parse_loguser(sArg, sName, 0, iUserId)
	new id = find_player("k", iUserId)

	if(equal(sAction,"Planted_The_Bomb") || equal(sAction, "Defused_The_Bomb") || equal(sAction, "Escaped_As_VIP")) 
	{ 
		if(PlayerLevel[id] < 1) {
			iExperienceGain = Obj_Experience
		} else {
			iExperienceGain = Obj_Experience * PlayerLevel[id]
		}
		
		add_experience(id, iExperienceGain)
		client_print(id, print_chat, "+%d objective xp", iExperienceGain)
		client_print(id, print_console, "*** +%d objective xp ***", iExperienceGain)
	}
	else if(equal(sAction, "Rescued_A_Hostage"))
	{
		if(PlayerLevel[id] < 1) {
			iExperienceGain = Hos_Experience
		} else {
			iExperienceGain = Hos_Experience * PlayerLevel[id]
		}	
		
		add_experience(id, iExperienceGain)
		client_print(id, print_chat, "+%d objective xp", iExperienceGain)
		client_print(id, print_console, "*** +%d objective xp ***", iExperienceGain)
	}
	return PLUGIN_CONTINUE
}

public Event_HostagesRescued()
{
	if(get_connectedplayers() < MIN_PLAYERS) {
		return PLUGIN_CONTINUE
	}
	
	new iPlayers[32], iNum, i
	get_players(iPlayers, iNum, "ae", "CT")
	for(i = 0; i <= iNum; i++)
	{
		new id = iPlayers[i]
		
		new iExperienceGain
		if(PlayerLevel[id] < 1) {
			iExperienceGain = Obj_Experience
		} else {
			iExperienceGain = Obj_Experience * PlayerLevel[id]
		}
		
		add_experience(id, iExperienceGain)
		client_print(id, print_chat, "+%d objective xp", iExperienceGain)
		client_print(id, print_console, "*** +%d objective xp ***", iExperienceGain)
	}
	return PLUGIN_CONTINUE
}

public Event_DeathMsg() 
{ 
	new attacker = read_data(1)
	new victim = read_data(2)

	if(!is_user_connected(attacker) || !is_user_connected(victim)) {
		return PLUGIN_CONTINUE
	}
	
	#if(Item_Death)
		Drop_Items(victim)
	#endif
	if(get_user_team(attacker) == get_user_team(victim)) {
		return PLUGIN_CONTINUE
	}

	if(attacker != victim)
	{
		new iExperienceGain 
		if(PlayerLevel[attacker] < 1) {
			iExperienceGain = Kill_Experience
		} else {
			iExperienceGain = Kill_Experience * PlayerLevel[attacker]
		}		
			
		add_experience(attacker, iExperienceGain)
		client_print(attacker, print_center, "+%d kill xp", iExperienceGain)
		client_print(attacker, print_console, "*** +%d kill xp ***", iExperienceGain)
	}
	return PLUGIN_CONTINUE
}

public Event_Damage(id)
{
	if(!is_user_connected(id)) {
		return PLUGIN_CONTINUE
	}
	#if(Item_Death)
		Drop_Items(id)
	#endif
	return PLUGIN_CONTINUE
}

public Event_ResetHUD(id)
{
	if(!is_user_alive(id)) {
		return PLUGIN_CONTINUE
	}

	if(g_HealthLevel[id] > 0) 
	{
		set_user_health(id, 100)
		add_health(id, g_HealthLevel[id] * Health_PerLevel)
	}
	
	if(g_ArmorLevel[id] > 0) 
	{
		cs_set_user_armor(id, 100, CS_ARMOR_KEVLAR) 
		add_armor(id, g_ArmorLevel[id] * Armor_PerLevel)
	}
	
	if(PlayerPoints[id] > 0) {
		display_PassiveUpgrades(id)
	}
	
	if(g_PlayerReseted[id])
	{
		new iPoints =  g_HealthLevel[id] + g_ArmorLevel[id] + g_SpeedLevel[id] + g_GravityLevel[id] + g_StealthLevel[id]
		PlayerPoints[id] += iPoints
		g_HealthLevel[id] = 0
		g_ArmorLevel[id] = 0
		g_SpeedLevel[id] = 0
		g_GravityLevel[id] = 0
		g_StealthLevel[id] = 0
		client_print(id, print_chat, "Your Points has been reseted")
		g_PlayerReseted[id] = false
	}
	if(get_cvar_num("um_autosavexp")) {
		SaveData(id)
	}
	return PLUGIN_CONTINUE
}

public Event_CurWeapon(id)
{
	new Weapon_ID = read_data(2)
	//new Weapon_Clip = read_data(3)
	
	new Float: fGravity = g_GravityLevel[id] * Gravity_PerLevel
	if(get_user_gravity(id) != fGravity) {
		set_gravity(id, fGravity)
	}

	new Float:fSpeed = 240.0 + (g_SpeedLevel[id] * Speed_PerLevel)
	if(get_user_maxspeed(id) != fSpeed && ftimeover) {
		set_user_maxspeed(id, fSpeed)
	}
	
	if(g_StealthLevel[id] > 0)
	{
		new iStealth = g_StealthLevel[id] * MaxLevel_Stealth
		new iKnifeStealth = iStealth + 10
		switch(Weapon_ID)
		{
			case CSW_KNIFE: set_stealth(id, iStealth)
			default:set_stealth(id, iKnifeStealth)
		}
	} else if(g_StealthLevel[id] < 1) {
		set_user_rendering(id, kRenderFxNone, kRenderNormal)
	}
	return PLUGIN_CONTINUE
}

public cmd_AddXP(id, level, cid) 
{
	if(!cmd_access(id, level, cid, 3)) {
		return PLUGIN_HANDLED
	}
	
	new Arg1[64], Target
	read_argv(1, Arg1, 63)
	
	new iAddExp[32], Value
	read_argv(2, iAddExp, 31)
	if(iAddExp[0] == '-') 
	{
		console_print(id, "You cant have a - in the value")
		return PLUGIN_HANDLED
	}
	Value = str_to_num(iAddExp)
	
	new AdminName[32]
	get_user_name(id, AdminName, 31)
	
	new TargetTeam
	new Players[32], iNum
	if(Arg1[0] == '@') 
	{
		if(equali(Arg1[1], "all")) 
		{
			TargetTeam = 0
			get_players(Players, iNum)
		} 
		else if(equali(Arg1[1], "t")) 
		{
			TargetTeam = 1
			get_players(Players, iNum, "e" , "terrorist")
		
		} 
		else if(equali(Arg1[1], "ct")) 
		{
			TargetTeam = 2
			get_players(Players, iNum, "e" , "ct")
		}
		
		for(new i = 0; i < iNum; ++i)
		{
			Target = Players[i]
			add_experience(Target, Value)
		}
		
		switch(TargetTeam)
		{
			case 0:
			{
				console_print(id, "You have given %d xp to all", Value)
				client_print(0, print_chat, "Admin: %s has given %d xp to all", AdminName, Value)
			}
			case 1:
			{
				console_print(id, "You have given %d xp to the terrorist team", Value)
				client_print(0, print_chat, "Admin: %s has given %d xp to the terrorist team", AdminName, Value)
			}
			case 2:
			{
				console_print(id, "You have given %d xp to the terrorist team", Value)
				client_print(0, print_chat, "Admin: %s has given %d xp to the ct team", AdminName, Value)
			}	
		}
	}
	else
	{
		Target = cmd_target(id, Arg1, 0)
		if(!is_user_connected(Target)) {
			return PLUGIN_HANDLED
		}
		
		new TargetName[32]
		get_user_name(Target, TargetName, 31)
		
		add_experience(Target, Value)
		
		console_print(id, "You have given %d xp to %s", Value, TargetName)
		client_print(Target, print_chat, "Admin: %s has given you %d xp", AdminName, Value)
	}
	return PLUGIN_HANDLED
}

public cmd_SetLevel(id, level, cid) 
{
	if(!cmd_access(id, level, cid, 3)) {
		return PLUGIN_HANDLED
	}
	
	new Arg1[64], Target
	read_argv(1, Arg1, 63)
	Target = cmd_target(id, Arg1, 0)
	
	new iLevel[32], Value
	read_argv(2, iLevel, 31)
	Value = str_to_num(iLevel)
	
	if(!is_user_connected(Target)) {
		return PLUGIN_HANDLED
	}
	
	if(Value > Max_Level-1)
	{
		console_print(id, "You cant have a more than %d", Max_Level-1)
		return PLUGIN_HANDLED
	}
	
	new AdminName[32]
	get_user_name(id, AdminName, 31)
		
	new TargetName[32]
	get_user_name(Target, TargetName, 31)
	
	PlayerLevel[Target] = Value
	PlayerXp[Target] = LEVELS[PlayerLevel[Target]]

	g_HealthLevel[Target] = 0
	g_ArmorLevel[Target] = 0
	g_SpeedLevel[Target] = 0
	g_GravityLevel[Target] = 0
	g_StealthLevel[Target] = 0
	PlayerPoints[Target] = PlayerLevel[Target]
	
	client_cmd(id, "spk %s", LevelUpSound)
	
	console_print(id, "You have set %s level to %d", TargetName, Value)
	client_print(Target, print_chat, "Admin: %s has set your level to %d", AdminName, Value)

	return PLUGIN_HANDLED
}
	
public display_Advertisements() 
{
	new Players[32], iNum
	get_players(Players, iNum, "b")
	
	for(new i = 0; i < iNum; ++i)
	{
		new id = Players[i]
		client_print(id, print_chat, "This server is running %s Version: %s", PLUGIN_NAME, PLUGIN_VERSION)
		client_print(id, print_chat, "Main Commands: say /umhelp  |  say /ummenu")
	}
}
	
public display_myitems(id)
{
	new szMenuBody[512]
	new len = format(szMenuBody, 511, "Items: %d^n", g_PlayerNumItems[id])
	for(new i = 1; i <= g_numberofitems; ++i) if(g_iPlayerItem[id][i]) {
		len += format(szMenuBody[len], 511-len, "%s^n", g_itemname[i])
	}
	set_hudmessage(255, 255, 255, 0.6, -1.0, 0, 0.0, 10.0, 0.0, 0.0, 4)
	show_hudmessage(id, szMenuBody)
	
	return PLUGIN_HANDLED
}

public open_ItemUpgrades(id)
{
	display_ItemUpgrades(id, g_menuPosition[id] = 0)
	return PLUGIN_HANDLED
}

public open_PassiveUpgrades(id)
{
	display_PassiveUpgrades(id)
	return PLUGIN_HANDLED
}

public display_help(id)
{
	new szMotd[2048], szTitle[64], iPos = 0
	format(szTitle, 63, "%s Version: %s", PLUGIN_NAME, PLUGIN_VERSION)
	iPos += format(szMotd[iPos], 2047-iPos, "<html><head><style type=^"text/css^">pre{color:#FFB000;}body{background:#000000;margin-left:8px;margin-top:0px;}</style></head><pre><body>")
	iPos += format(szMotd[iPos], 2047-iPos, "^n^n<b>%s</b>^n^n", szTitle)
	iPos += format(szMotd[iPos], 2047-iPos, "Client Commands:^n")
	iPos += format(szMotd[iPos], 2047-iPos, "say /ummenu - Main menu^n")
	iPos += format(szMotd[iPos], 2047-iPos, "say /upgrade - Passive upgrades menu^n")
	iPos += format(szMotd[iPos], 2047-iPos, "say /itemshop - Item shop menu^n")
	iPos += format(szMotd[iPos], 2047-iPos, "say /myitem - Displays your items^n")
	iPos += format(szMotd[iPos], 2047-iPos, "say /dropitems - Drop all your items^n")
	iPos += format(szMotd[iPos], 2047-iPos, "say /itemlist - Displays all items with description^n")
	iPos += format(szMotd[iPos], 2047-iPos, "say /umhelp - Displays help^n")
	iPos += format(szMotd[iPos], 2047-iPos, "Can also type in the console without '/'^n")
	iPos += format(szMotd[iPos], 2047-iPos, "Bind example: bind home ummenu^n^n")
	iPos += format(szMotd[iPos], 2047-iPos, "Passive Upgrades:^n")
	iPos += format(szMotd[iPos], 2047-iPos, "Health - Increase Health; HP per level: %d^n", Health_PerLevel)
	iPos += format(szMotd[iPos], 2047-iPos, "Armor - Increase Armor; AP per level: %d^n", Armor_PerLevel)
	iPos += format(szMotd[iPos], 2047-iPos, "Speed - Increases Speed; Speed per level: %d^n", Speed_PerLevel)
	iPos += format(szMotd[iPos], 2047-iPos, "Gravity - Decreases your gravity; -Gravity per level %d^n", floatround((Gravity_PerLevel * 100)))
	iPos += format(szMotd[iPos], 2047-iPos, "Stealth - Descreses Visability; Stealth per level: %d^n", Stealth_PerLevel)
	
	show_motd(id, szMotd, szTitle)
	return PLUGIN_HANDLED
}

public display_itemlist(id)
{
	new szMotd[2048], szTitle[64], iPos = 0
	format(szTitle, 63, "Item List")
	iPos += format(szMotd[iPos], 2047-iPos, "<html><head><style type=^"text/css^">pre{color:#FFB000;}body{background:#000000;margin-left:8px;margin-top:0px;}</style></head><pre><body>")
	iPos += format(szMotd[iPos], 2047-iPos, "^n^n<b>%s</b>^n^n", szTitle)
	iPos += format(szMotd[iPos], 2047-iPos, "# Item Name | Item Description | Item Cost^n")
	
	for(new i = 1; i <= g_numberofitems; ++i) {
		iPos += format(szMotd[iPos], 2047-iPos, "(%d)%s   %s   %d^n", i, g_itemname[i], g_itemdesc[i], g_itemcost[i])
	}
	show_motd(id, szMotd, szTitle)
	return PLUGIN_HANDLED
}

public open_MainMenu(id)
{
	new szMenuBody[512]
	new len = format(szMenuBody, 511, "Main Upgrades Menu^n")
	len += format(szMenuBody[len], 511-len, "^n1. Passive Upgrades")
	len += format(szMenuBody[len], 511-len, "^n2  Item Shop")
	len += format(szMenuBody[len], 511-len, "^n3. Item List")
	len += format(szMenuBody[len], 511-len, "^n4. Upgrades Help")
	len += format(szMenuBody[len], 511-len, "^n^n^n8. Save Experience")
	len += format(szMenuBody[len], 511-len, "^n9. Plugin Info")
	len += format(szMenuBody[len], 511-len, "^n0. Cancel")

	new keys = (1<<0|1<<1|1<<2|1<<3|1<<7|1<<8|1<<9)
	show_menu(id, keys, szMenuBody, -1, "Main Upgrades Menu")		
}

public Action_MainMenu(id, key)
{
	switch(key) 
	{
		case 0:	open_PassiveUpgrades(id)
		case 1: open_ItemUpgrades(id)
		case 2: display_itemlist(id)
		case 3: display_help(id)
		case 7:
		{
			SaveData(id)
			client_print(id, print_chat, "Saved experience")
		}
		case 8: client_print(id, print_chat, "%s by %s  Version: %s", PLUGIN_NAME, PLUGIN_AUTHOR, PLUGIN_VERSION)
	}
	return PLUGIN_HANDLED
}

public cmd_DropItems(id)
{
	if(!is_user_alive(id)) {
		return PLUGIN_HANDLED
	}
	
	if(g_PlayerNumItems[id] < 1) 
	{
		client_print(id, print_chat, "You dont have any items")
		return PLUGIN_HANDLED
	}
	Drop_Items(id)
	client_cmd(id, "spk %s", DropItemSound)
	return PLUGIN_HANDLED
}

public Open_MapItemConfig(id, level, cid)
{
	if(!cmd_access(id, level, cid, 1)) {
		return PLUGIN_HANDLED
	}
	
	if(!g_DirExist) 
	{
		console_print(id, "itemconfig directory does not exist")
		return PLUGIN_HANDLED
	}
	display_MapItemConfig(id)
	return PLUGIN_HANDLED
}

display_MapItemConfig(id)
{
	new MenuBody[512]
	new len = format(MenuBody, 511, "Map Item Menu^n")
	len += format(MenuBody[len], 511-len, "^n1. Create Spawn Points")
	len += format(MenuBody[len], 511-len, "^n2  Remove All Spawn Points")
	len += format(MenuBody[len], 511-len, "^n^n0. Cancel")

	new keys = (1<<0|1<<1|1<<9)
	show_menu(id, keys, MenuBody, -1, "MI Config Menu")	
}

public Action_MapItemConfig(id, key)
{
	switch(key) 
	{
		case 0:	
		{
			if(g_MapItemNum >= MAX_MAPITEMS)
			{
				client_print(id, print_chat, "Max map items reached")
				return PLUGIN_HANDLED
			}
			
			new Origin[3]
			get_user_origin(id, Origin, 0)
			
			new MapName[33]
			get_mapname(MapName, 32)
			Save_Origin(MapName, Origin)
			
			Load_Origins(MapName)
			display_MapItemConfig(id)
			client_print(id, print_chat, "item spawn point created")
		}			
		case 1: 
		{
			RemoveMapItems()
			client_print(id, print_chat, "All spawn points removed")
		}
	}
	return PLUGIN_HANDLED
}

display_ItemUpgrades(id, pos)
{
	if(pos < 0) {
		return
	}
	
	new start = pos * 8
  	if(start >= g_numberofitems) {
    		start = pos = g_menuPosition[id]
	}

	new menuBody[512]
  	new len = format(menuBody, 511, "Item Shop^n^n")
	
  	new end = start + 8
  	new keys = MENU_KEY_0

	if(end > g_numberofitems) {
    		end = g_numberofitems
	}
	
	new b = 0
  	for(new a = start; a < end; ++a) 
	{
		new i = a + 1
		keys |= (1<<b)
		new money
		#if(Item_Money)		
			money = cs_get_user_money(id)
		#else
			money = PlayerXp[id]
		#endif
		if(g_iPlayerItem[id][i] ||(money < g_itemcost[i]) || g_PlayerNumItems[id] >= Max_PlayerItems) {
			len += format(menuBody[len], 511-len,"\r%d. %s (%d)\w^n", ++b, g_itemname[i], g_itemcost[i])
		} else {
			len += format(menuBody[len], 511-len,"%d. %s (%d)^n", ++b, g_itemname[i], g_itemcost[i])
		}
  	}

  	if(end != g_numberofitems)
	{
    		format(menuBody[len], 511-len, "^n9. %L...^n0. %L", id, "MORE", id, pos ? "BACK" : "EXIT")
    		keys |= MENU_KEY_9
  	}
  	else
	{
		format(menuBody[len], 511-len, "^n0. %L", id, pos ? "BACK" : "EXIT")
	}
  	show_menu(id, keys, menuBody, -1, "Item Shop")
}

public Action_ItemUpgrades(id, key)
{
	switch(key) 
	{
    		case 8: display_ItemUpgrades(id, ++g_menuPosition[id])
		case 9: display_ItemUpgrades(id, --g_menuPosition[id])
    		default:
		{
			if(!is_user_alive(id)) {
				return PLUGIN_HANDLED
			}
			
			++key
			new money
			new plugin_id = g_itemindex[g_menuPosition[id] * 8 + key]
			new item_id = g_menuPosition[id] * 8 + key
			new func = get_func_id("Enable_Item", plugin_id)
			#if(Item_Money)
				money = cs_get_user_money(id)
			#else
				money = PlayerXp[id]
			#endif
			new cost = g_itemcost[item_id]
			if(g_PlayerNumItems[id] >= Max_PlayerItems) 
			{
				client_print(id, print_chat, "Only %d items", Max_PlayerItems)
				client_cmd(id, "spk %s", DeniedSound)
				display_ItemUpgrades(id, g_menuPosition[id])
				return PLUGIN_HANDLED
			}
		
			if(g_iPlayerItem[id][item_id])
			{
				client_print(id, print_chat, "You already have %s", g_itemname[item_id])
				client_cmd(id, "spk %s", DeniedSound)
				display_ItemUpgrades(id, g_menuPosition[id])
				return PLUGIN_HANDLED
			}
			
			if(money >= cost)
			{
				callfunc_begin_i(func, plugin_id)
				callfunc_push_int(id)
				callfunc_end()

				g_PlayerNumItems[id] += 1
				g_iPlayerItem[id][item_id] = true
				#if(Item_Money)
					cs_set_user_money(id, money - cost, 1)
				#else
					PlayerXp[id] = money - cost
				#endif
				client_cmd(id, "spk %s", BoughtItemSound)
				client_print(id, print_chat, "Item Bought: %s", g_itemname[item_id])
				client_print(id, print_chat, "Item Description: %s", g_itemdesc[item_id])
			
				if(g_PlayerNumItems[id] < Max_PlayerItems) {
					display_ItemUpgrades(id, g_menuPosition[id])
				}
			}
			else
			{
				#if(Item_Money)
					client_print(id, print_chat, "You need $%d to buy %s", g_itemcost[item_id], g_itemname[item_id])
				#else
					client_print(id, print_chat, "You need %d xp to buy %s", g_itemcost[item_id], g_itemname[item_id])
				#endif
				display_ItemUpgrades(id, g_menuPosition[id])
				client_cmd(id, "spk %s", DeniedSound)
			}
		}
	}
	return PLUGIN_HANDLED
}

display_PassiveUpgrades(id)
{
	new szMenuBody[512]
	new len = format(szMenuBody, 511, "Passive Upgrades^n")
	len += format(szMenuBody[len], 511-len, "^n1. Health (%d/%d)", 	g_HealthLevel[id],	MaxLevel_Health)
	len += format(szMenuBody[len], 511-len, "^n2. Armor (%d/%d)", 	g_ArmorLevel[id],	MaxLevel_Armor)
	len += format(szMenuBody[len], 511-len, "^n3. Speed (%d/%d)",	g_SpeedLevel[id], 	MaxLevel_Speed)
	len += format(szMenuBody[len], 511-len, "^n4. Gravity (%d/%d)",	g_GravityLevel[id], 	MaxLevel_Gravity)
	len += format(szMenuBody[len], 511-len, "^n5. Stealth (%d/%d)",	g_StealthLevel[id],	MaxLevel_Stealth)
	len += format(szMenuBody[len], 511-len, "^n^n9. Reset")
	len += format(szMenuBody[len], 511-len, "^n0. Cancel")

	new keys = (1<<0|1<<1|1<<2|1<<3|1<<4|1<<8|1<<9) 
	show_menu(id, keys, szMenuBody, -1, "Passive Upgrades")
}

public Action_PassiveUpgrades(id, key) 
{
	switch(key) 
	{
		case 0: 
		{
			if(g_HealthLevel[id] >= MaxLevel_Health) {
				return PLUGIN_HANDLED
			} else if(!is_user_alive(id)) {
				return PLUGIN_HANDLED
			} else {
				Set_Upgrade(id, 0)
			}
		}
		case 1: 
		{
			if(g_ArmorLevel[id] >= MaxLevel_Armor) {
				return PLUGIN_HANDLED
			} else if(!is_user_alive(id)) {
				return PLUGIN_HANDLED
			} else {
				Set_Upgrade(id, 1)
			}
		}
		case 2: 
		{
			if(g_SpeedLevel[id] >= MaxLevel_Speed) {
				return PLUGIN_HANDLED
			} else if(!is_user_alive(id)) {
				return PLUGIN_HANDLED
			} else {
				Set_Upgrade(id, 2)
			}
		}
		case 3: 
		{
			if(g_GravityLevel[id] >= MaxLevel_Gravity) {
				return PLUGIN_HANDLED
			} else if(!is_user_alive(id)) {
				return PLUGIN_HANDLED
			} else {
				Set_Upgrade(id, 3)
			}
		}
		case 4: 
		{
			if(g_StealthLevel[id] >= MaxLevel_Stealth) {
				return PLUGIN_HANDLED
			} else if(!is_user_alive(id)) {
				return PLUGIN_HANDLED
			} else {
				Set_Upgrade(id, 4)
			}
		}
		case 8: 
		{
			g_PlayerReseted[id] = true
			client_print(id, print_chat, "Your points will be reseted next time you spawn")
		}
	}
	return PLUGIN_HANDLED
}
	
public Set_Upgrade(id, value)
{
	if(PlayerPoints[id] > 0)
	{
		switch(value)
		{
			case 0:
			{
				g_HealthLevel[id] += 1
				add_health(id, Health_PerLevel)
				client_print(id, print_chat, "+%d Health", g_HealthLevel[id] * Health_PerLevel)
			}
			case 1:
			{
				g_ArmorLevel[id]  += 1
				add_armor(id, Armor_PerLevel)
				client_print(id, print_chat, "+%d Armor", g_ArmorLevel[id] * Armor_PerLevel)
			}
			case 2:
			{
				g_SpeedLevel[id]  += 1
				new Float:fSpeed = 240.0 + (g_SpeedLevel[id] * Speed_PerLevel)
				
				if(ftimeover) {
					set_user_maxspeed(id, fSpeed)
				}
				client_print(id, print_chat, "+%d Speed",  g_SpeedLevel[id] * Speed_PerLevel)
			}
			case 3:
			{
				g_GravityLevel[id]  += 1
				new Float: fGravity = g_GravityLevel[id] * Gravity_PerLevel
				set_gravity(id, fGravity)
				client_print(id, print_chat, "-%d Gravity", g_GravityLevel[id] * floatround((Gravity_PerLevel * 100)))
			}
			case 4:
			{
				g_StealthLevel[id]  += 1
				set_stealth(id, Stealth_PerLevel)
				client_print(id, print_chat, "+%d Stealth", g_StealthLevel[id] * Stealth_PerLevel)
			}
		}
		
		PlayerPoints[id] -= 1
		client_cmd(id, "spk %s", UpgradedSound)
		
		if(PlayerPoints[id] > 0) {
			display_PassiveUpgrades(id)
		}
	} else { 
		client_cmd(id, "spk %s", DeniedSound)
	}
}

public register_umitem(item_index, item_name[], item_desc[], item_cost)
{
	if(g_numberofitems == MAX_ITEMS) {
		return -2
	}
	
	g_numberofitems++
	g_itemindex[g_numberofitems] = item_index
	format(g_itemname[g_numberofitems], MAX_ITEM_NAME_SIZE, item_name)
	format(g_itemdesc[g_numberofitems], MAX_ITEM_DESC_SIZE, item_desc)
	g_itemcost[g_numberofitems] = item_cost
	
	return g_numberofitems
}

add_experience(id, value)
{
	if(PlayerLevel[id] <= Max_Level-1) {
		PlayerXp[id] += value
	}
}

add_armor(id, value) 
{
	new CsArmorType:ArmorType 
         new iArmor = cs_get_user_armor(id, ArmorType)
	cs_set_user_armor(id, iArmor + value, ArmorType)
}

add_health(id, value) 
{
	new iHealth = get_user_health(id)
	set_user_health(id, iHealth + value)
}

set_stealth(id, value)
{
	new iMax_Stealth = 20 + (MaxLevel_Stealth * Stealth_PerLevel)
	set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, iMax_Stealth  - value)
}

set_gravity(id, Float:value) {
	set_user_gravity(id, 1.00 - value)
}

SaveData(id)
{ 
	new authid[32]
	get_user_authid(id, authid, 31)
	new vaultkey[64], vaultdata[64]
	
	format(vaultkey, 63, "Account-%s-Level", authid)
	format(vaultdata, 63, "%d", PlayerLevel[id])
	set_vaultdata(vaultkey, vaultdata)
	
	format(vaultkey, 63, "Account-%s-Xp", authid)
	format(vaultdata, 63, "%d", PlayerXp[id])
	set_vaultdata(vaultkey, vaultdata)

	format(vaultkey, 63, "Account-%s-Points", authid)
	format(vaultdata, 63, "%d", PlayerLevel[id])
	set_vaultdata(vaultkey, vaultdata)
}

LoadData(id) 
{ 
	new authid[32] 
	get_user_authid(id,authid,31)
	new vaultkey[64], vaultdata[64]

	format(vaultkey, 63, "Account-%s-Level", authid) 
    	get_vaultdata(vaultkey, vaultdata, 63)
    	PlayerLevel[id] = str_to_num(vaultdata)
	
	format(vaultkey, 63, "Account-%s-Xp", authid)
    	get_vaultdata(vaultkey, vaultdata, 63)
    	PlayerXp[id] = str_to_num(vaultdata)

    	format(vaultkey, 63, "Account-%s-Points", authid)
    	get_vaultdata(vaultkey, vaultdata, 63)
    	PlayerPoints[id] = str_to_num(vaultdata)
}

public Pickup_Items(ptr, ptd)
{
	if(is_user_alive(ptd) && is_valid_ent(ptr)) 
	{ 
		new item_id = entity_get_int(ptr, EV_INT_iuser4)
		new plugin_id = g_itemindex[item_id]
		new func = get_func_id("Enable_Item", plugin_id)
		if(!g_iPlayerItem[ptd][item_id])
		{
			if(g_PlayerNumItems[ptd] < Max_PlayerItems)
			{
				callfunc_begin_i(func, plugin_id)
				callfunc_push_int(ptd)
				callfunc_end()
						
				g_PlayerNumItems[ptd] += 1
				g_iPlayerItem[ptd][item_id] = true
				client_cmd(ptd, "spk %s", PickUpItemSound)
				client_print(ptd, print_chat, "Item Picked: %s", g_itemname[item_id])
					
				remove_entity(ptr)
			}
		}
	}
}

Drop_Items(id)
{
	for(new item_id = 1; item_id <= MAX_ITEMS ; item_id++) 
	{
		if(g_iPlayerItem[id][item_id])
		{
			new Float:fVelocity[3], Float:fOrigin[3], Float:fGlowColors[3] = {100.0, 100.0, 100.0}
			entity_get_vector(id, EV_VEC_origin, fOrigin)
			fOrigin[2] += 75
	
			VelocityByAim(id, 130, fVelocity)
			
			new item_ent = create_entity("info_target")
			if(is_valid_ent(item_ent))
			{
				entity_set_string(item_ent, EV_SZ_classname, "UmItem")
				
				entity_set_int(item_ent, EV_INT_solid, SOLID_TRIGGER)
				entity_set_int(item_ent, EV_ENT_owner, 0)
				entity_set_int(item_ent, EV_INT_movetype, 6)
				entity_set_int(item_ent, EV_INT_iuser4, item_id)
				entity_set_int(item_ent, EV_INT_renderfx, kRenderFxGlowShell)

				entity_set_vector(item_ent, EV_VEC_origin, fOrigin)
				entity_set_vector(item_ent, EV_VEC_velocity, fVelocity)
				entity_set_vector(item_ent, EV_VEC_rendercolor, fGlowColors)
				
				entity_set_model(item_ent, ItemModel)
				entity_set_size(item_ent, Float:{-2.5, -2.5, -1.5}, Float:{2.5, 2.5, 1.5})
				
				new plugin_id = g_itemindex[item_id]
				new func = get_func_id("Disable_Item", plugin_id)

				callfunc_begin_i(func, plugin_id)
				callfunc_push_int(id)
				callfunc_end()
				
				g_iPlayerItem[id][item_id] = false
				g_PlayerNumItems[id] = 0
			}
		}
	}
	return PLUGIN_CONTINUE
}

Save_Origin(CurMap[], Origin[3])
{
	new MapFile[64], Text[64]
	format(MapFile, 63, "%s/%s.cfg", g_ItemOriginDir, CurMap)
	if(!file_exists(MapFile)) 
	{
		new Comments[64]
		format(Comments, 63, "; Map item origins for %s", CurMap)
		write_file(MapFile, Comments, -1)
	}
	
	format(Text, 64, "%i %i %i", Origin[0], Origin[1], Origin[2])
	write_file(MapFile, Text, -1)
}

Load_Origins(CurMap[])
{
	new MapFile[64]
	format(MapFile, 63, "%s/%s.cfg", g_ItemOriginDir, CurMap)
	if(!file_exists(MapFile)) {
		return PLUGIN_CONTINUE
	}

	g_MapItemNum = 0
	for(new i = 1; i <= MAX_MAPITEMS; ++i) 
	{
		g_MapItemOrgins[i][0] = 0
		g_MapItemOrgins[i][1] = 0
		g_MapItemOrgins[i][2] = 0
	}
	
	new Text[64], Line = 0, Len = 0
	while(read_file(MapFile, Line++, Text, 63, Len))
	{
		if((Text[0]==';') || !Len) {
		 	continue
		}
		
		if(g_MapItemNum >= MAX_MAPITEMS) 
		{
			log_amx("Max map items reached, please increase MAX_MAPITEMS")
			break
		}
		
		new iOrigin[3][16]
		parse(Text, iOrigin[0], 15, iOrigin[1], 15, iOrigin[2], 15)
		
		g_MapItemNum++
		g_MapItemOrgins[g_MapItemNum][0] = str_to_num(iOrigin[0])
		g_MapItemOrgins[g_MapItemNum][1] = str_to_num(iOrigin[1])
		g_MapItemOrgins[g_MapItemNum][2] = str_to_num(iOrigin[2])
	}
	return PLUGIN_CONTINUE
}

public Spawn_Items()
{
	for(new i = 1; i <= MAX_MAPITEMS; ++i)
	{
		if((g_MapItemOrgins[i][0] == 0) 
		&& (g_MapItemOrgins[i][1] == 0) 
		&& g_MapItemOrgins[i][2] == 0) { 
				continue
		}
		Create_Items(g_MapItemOrgins[i])
	}
}

RemoveMapItems()
{
	new MapFile[64], CurMap[32]
	get_mapname(CurMap, 31)
	format(MapFile, 63, "%s/%s.cfg", g_ItemOriginDir, CurMap)
	if(file_exists(MapFile)) {
		delete_file(MapFile)
	}

	g_MapItemNum = 0
	for(new i = 1; i <= MAX_MAPITEMS; ++i) 
	{
		g_MapItemOrgins[i][0] = 0
		g_MapItemOrgins[i][1] = 0
		g_MapItemOrgins[i][2] = 0
	}
}

Create_Items(Origin[3])
{
	new Float:flOrigin[3]
	IVecFVec(Origin, flOrigin)
	
	new Float:fGlowColors[3] = {0.0, 100.0, 0.0}
	new item_ent = create_entity("info_target")
	new item_id = random_num(1, g_numberofitems)
	if(is_valid_ent(item_ent))
	{
		entity_set_string(item_ent, EV_SZ_classname, "UmItem")
				
		entity_set_int(item_ent, EV_INT_solid, SOLID_TRIGGER)
		entity_set_int(item_ent, EV_ENT_owner, 0)
		entity_set_int(item_ent, EV_INT_movetype, 6)
		entity_set_int(item_ent, EV_INT_iuser4, item_id)
		entity_set_int(item_ent, EV_INT_renderfx, kRenderFxGlowShell)

		entity_set_vector(item_ent, EV_VEC_origin, flOrigin)
		entity_set_vector(item_ent, EV_VEC_rendercolor, fGlowColors)
		
		drop_to_floor(item_ent)
		entity_set_model(item_ent, ItemModel)
		entity_set_size(item_ent, Float:{-2.5, -2.5, -1.5}, Float:{2.5, 2.5, 1.5})

	}
	return PLUGIN_CONTINUE
}

public plugin_precache() 
{
	precache_model(ItemModel)
	precache_sound(DeniedSound)
	precache_sound(LevelUpSound)
	precache_sound(UpgradedSound)
	precache_sound(PickUpItemSound)
	precache_sound(BoughtItemSound)
}
