#include <amxmodx>
#include <amxmisc>
#include <nrs_main>
#include <nvault>
#include <cstrike>
#include <fakemeta>
#include <fun>

#define TASK_SHOWHUD 100

new g_MsgSync

const PEV_SPEC_TARGET = pev_iuser2

new g_PlayerXp[33]
new g_PlayerLevel[33]

enum _:TOTAL_FORWARDS
{
	FW_USER_LEVEL_GET = 0, /**Момент получения уровня**/
	FW_USER_EXP_GET /**Момент получения опыта**/
}

new g_ForwardResult
new g_Forwards[TOTAL_FORWARDS]

const MAX_LVL = 10
new g_LevelExp[MAX_LVL] = 
{
	1,
	25,
	50,
	75,
	100,
	130,
	160,
	290,
	350,
	400
}

/**Получение опыта(Настройки)**/
const g_TankExp = 5
const g_ShamanExp = 5
const g_GhostExp = 5
const g_PsycoExp = 5
const g_DioneExp = 15
const g_JuggernautExp = 10
const g_ZombieExp = 3

new g_vault

public plugin_init()
{
	register_plugin("[NRS]Level system", "1.0", "Joker")
	
	g_Forwards[FW_USER_LEVEL_GET] = CreateMultiForward("nrs_fw_take_level", ET_IGNORE, FP_CELL)
	g_Forwards[FW_USER_EXP_GET] = CreateMultiForward("nrs_fw_take_exp", ET_IGNORE, FP_CELL)
	
	g_vault = nvault_open("NrsLevels")
	
	g_MsgSync = CreateHudSyncObj()
}

public client_putinserver(id)
{
	if (!is_user_bot(id))
	{
		set_task(1.0, "ShowInfo", id+TASK_SHOWHUD, _, _, "b")
	}
}

public event_npc_death(victim, attacker)
{
	if ( !is_user_connected(attacker) )
		return
	
	new RewardExp 
	
	if(get_npc_id(victim) == get_npc_classname_id("npc_dione"))
		RewardExp = g_DioneExp
	
	else if(get_npc_id(victim) == get_npc_classname_id("npc_cso_juggernaut"))
		RewardExp = g_JuggernautExp
	
	else if(get_npc_id(victim) == get_npc_classname_id("npc_cso_zm_pc"))
		RewardExp = g_PsycoExp
	
	else if(get_npc_id(victim) == get_npc_classname_id("npc_cso_zm7"))
		RewardExp = g_ShamanExp
	
	else if(get_npc_id(victim) == get_npc_classname_id("npc_cso_zm5"))
		RewardExp = g_GhostExp
	
	else if(get_npc_id(victim) == get_npc_classname_id("npc_cso_zm6"))
		RewardExp = g_TankExp
	
	else //if((get_npc_id(victim) == get_npc_classname_id("npc_cso_zm4")) || (get_npc_id(i) == get_npc_classname_id("npc_cso_zm2")) || (get_npc_id(i) == get_npc_classname_id("npc_cso_zm3")))
		RewardExp = g_ZombieExp
	
	g_PlayerXp[attacker] += RewardExp
	
	ExecuteForward(g_Forwards[FW_USER_EXP_GET], g_ForwardResult, attacker)
	
	if ( g_PlayerLevel[attacker] < MAX_LVL )
	if(g_PlayerXp[attacker] >= g_LevelExp[ g_PlayerLevel[attacker]])
	{
		if ( g_PlayerLevel[attacker] < MAX_LVL ) g_PlayerLevel[attacker]++
		g_PlayerXp[attacker] = 0
		
		ExecuteForward(g_Forwards[FW_USER_LEVEL_GET], g_ForwardResult, attacker)
	}
}

public plugin_natives()
{
	register_native("nrs_get_user_level", "get_level")
	register_native("nrs_set_user_level", "set_level")
	register_native("nrs_get_user_exp", "get_exp")
	register_native("nrs_set_user_exp", "set_exp")
}

public get_level(id)
{
	return g_PlayerLevel[id]
}

public set_level(id, value)
{
	value = value > MAX_LVL ? MAX_LVL : value
	g_PlayerLevel[id] = value
}

public get_exp(id)
{
	return g_PlayerXp[id]
}

public set_exp(id, value)
{
	g_PlayerXp[id] = value
}
	
public client_connect(id)
{
	LoadData(id)
	if(g_PlayerLevel[id] == 0)
		g_PlayerLevel[id] = 1
}

public client_disconnect(id)
{
	SaveData(id)
	
	remove_task(id+TASK_SHOWHUD)
}

public SaveData(id) 
{ 
	new AuthID[35] 
	
	get_user_authid(id, AuthID, 34) 
	
	new vaultkey[64],vaultdata[256]  
	format(vaultkey,63,"%s-Mod",AuthID) 
	format(vaultdata,255,"%i#%i#",g_PlayerXp[id],g_PlayerLevel[id]) 
	nvault_set(g_vault,vaultkey,vaultdata) 
	
	return PLUGIN_CONTINUE 
}  

public LoadData(id) 
{ 
	new AuthID[35] 
	
	get_user_authid(id, AuthID, 34) 
	
	new vaultkey[64],vaultdata[256] 
	format(vaultkey,63,"%s-Mod",AuthID) 
	format(vaultdata,255,"%i#%i#",g_PlayerXp[id],g_PlayerLevel[id]) 
	nvault_get(g_vault,vaultkey,vaultdata,255) 
	replace_all(vaultdata, 255, "#", " ") 
	new playerxp[32], playerlevel[32] 
	parse(vaultdata, playerxp, 31, playerlevel, 31) 
	g_PlayerXp[id] = str_to_num(playerxp) 
	g_PlayerLevel[id] = str_to_num(playerlevel)
	
	g_PlayerLevel[id] = g_PlayerLevel[id] > MAX_LVL ? MAX_LVL : g_PlayerLevel[id]
	
	return PLUGIN_CONTINUE 
}  

public ShowInfo(taskid)
{
	new player = (taskid - TASK_SHOWHUD)
	
	if (!is_user_alive(player))
	{
		player = pev(player, PEV_SPEC_TARGET)
		
		if (!is_user_alive(player))
			return;
	}
	
	new progress = 100
	
	if ( g_PlayerLevel[player]+1 < MAX_LVL )
	{
		progress = (g_LevelExp[g_PlayerLevel[player]+1]/100)
		progress = progress > 0 ? (g_PlayerXp[player]/progress) : 0
	}
	
	
	if (player != (taskid - TASK_SHOWHUD))
	{
		new player_name[32]
		get_user_name(player, player_name, charsmax(player_name))
		
		set_hudmessage(200, 250, 0, 0.6, 0.8, 0, 6.0, 1.1, 0.0, 0.0, -1)
		ShowSyncHudMsg((taskid - TASK_SHOWHUD), g_MsgSync, "[ %s ] [ Health : %d ] [ Level : %d ] [ Money : %d ]", player_name, get_user_health(player), g_PlayerLevel[player], cs_get_user_money(player))
	}
	else
	{
		set_hudmessage(200, 250, 0, 0.02, 0.9, 0, 6.0, 1.1, 0.0, 0.0, -1)
		ShowSyncHudMsg((taskid - TASK_SHOWHUD), g_MsgSync, "[ Health : %d ] [ Level : %d ] [ Progress : %i^%% ]", get_user_health((taskid - TASK_SHOWHUD)), g_PlayerLevel[(taskid - TASK_SHOWHUD)], progress)
	}
}
