#include <amxmodx>
#include <cstrike>
#include <dhudmessage>
#include <engine>
#include <fakemeta>
#include <fun>
#include <hamsandwich>
#include <zombieplague>

#define MAX_SAVE			1024

#define SOUND_HP		"level_sys/hp.wav"
#define SOUND_LV			"level_sys/lv.wav"

#define LINUXDIFF			5

#define m_LastHitGroup		75

#define MONEY_HEAD			random_num(100, 110)
#define MONEY_CHEST			random_num(60, 70)
#define MONEY_STOMACH		50
#define MONEY_ARM			random_num(30, 35)
#define MONEY_LEG			random_num(15, 20)
#define MONEY_KILL			1000

#define COST_HP				12000
#define COST_LV				20000

#define FLAG_FLASH			(1 << 0)
#define FLAG_NONE			0

#define IMPULSE_AUTOBUY		98
#define IMPULSE_REBUY		145

#define MAX_MONEY			32000

#define UNIT_SECOND			(1 << 12)

#define FFADE_IN			0x0000
#define FFADE_HP_COLOR		{243, 127, 1}
#define FFADE_LV_COLOR		{0, 255, 0}
#define FFADE_HP_ALPHA		100
#define FFADE_LV_ALPHA		100

new m_pszLevelHP[33 char]
new m_pszLevelLV[33 char]
new m_pszMaps[33 char]
new m_iSysMoney[33]
new m_arraySaveAuthID[MAX_SAVE][32]
new m_arraySaveMoney[MAX_SAVE]
new m_arraySaveLevelHP[MAX_SAVE]
new m_arraySaveLevelLV[MAX_SAVE]
new m_arraySaveMaps[MAX_SAVE]
new m_iSaveTotal
new m_iMaxPlayers

new MSGID_BlinkAcct
new MSGID_HideWeapon
new MSGID_Money
new MSGID_ScreenFade

public plugin_precache()
{
	register_srvcmd("load_money", "SRVCMD__load_money")
	
	server_cmd("exec addons/amxmodx/configs/cso_level_sys_saved_money.cfg")
	server_exec()
	
	precache_sound(SOUND_HP)
	precache_sound(SOUND_LV)
}

public SRVCMD__load_money()
{
	if (m_iSaveTotal == MAX_SAVE) return
	
	new data[5][32]
	
	read_argv(1, data[0], 31)
	read_argv(2, data[1], 31)
	read_argv(3, data[2], 31)
	read_argv(4, data[3], 31)
	read_argv(5, data[4], 31)
	
	remove_quotes(data[0])
	remove_quotes(data[1])
	remove_quotes(data[2])
	remove_quotes(data[3])
	remove_quotes(data[4])
	
	formatex(m_arraySaveAuthID[m_iSaveTotal], 31, data[0])
	m_arraySaveMoney[m_iSaveTotal] = str_to_num(data[1])
	
	new maps = str_to_num(data[4])
	
	if (maps)
	{
		m_arraySaveLevelHP[m_iSaveTotal] = str_to_num(data[2])
		m_arraySaveLevelLV[m_iSaveTotal] = str_to_num(data[3])
		m_arraySaveMaps[m_iSaveTotal] = --maps
	}
	else m_arraySaveMaps[m_iSaveTotal] = 2
	
	m_iSaveTotal++
}

public plugin_init()
{
	register_plugin("CSO Level System", "Delta", "WPMG Team")
	
	RegisterHam(Ham_Spawn, "player", "CPlayer__Spawn_Post", 1)
	RegisterHam(Ham_Killed, "player", "CPlayer__Killed")
	RegisterHam(Ham_Killed, "player", "CPlayer__Killed_Post", 1)
	RegisterHam(Ham_TakeDamage, "player", "CPlayer__TakeDamage")
	
	MSGID_BlinkAcct = get_user_msgid("BlinkAcct")
	MSGID_HideWeapon = get_user_msgid("HideWeapon")
	MSGID_Money = get_user_msgid("Money")
	MSGID_ScreenFade = get_user_msgid("ScreenFade")
	
	register_message(MSGID_Money, "MSG_Money")
	
	register_impulse(IMPULSE_AUTOBUY, "IMPULSE__autobuy")
	register_impulse(IMPULSE_REBUY, "IMPULSE__rebuy")
	
	m_iMaxPlayers = get_maxplayers()
	
	set_task(1.0, "TASK__ShowHUD", 992121, _, _, "b")
}

public TASK__ShowHUD()
{
	new num[4], numSec[4], Secnum[4], SecnumSec[4]
	for (new id = 1; id <= m_iMaxPlayers; id++)
	{
		if (!is_user_connected(id)) continue
		
		set_dhudmessage(255, 255, 255, 1.0, 0.8, 0, 0.0, 1.2, 0.0, 0.0, false)
		show_dhudmessage(id, "[F1]-[HP:^t^t^t]^n[F2]-[LV:^t^t^t]")
		
		if (m_pszLevelHP{id} == 10)
		{
			formatex(num, 3, "")
			formatex(Secnum, 3, "MAX")
		}
		else
		{
			formatex(num, 3, "%d%", m_pszLevelHP{id} * 10)
			formatex(Secnum, 3, "")
		}
		
		if (m_pszLevelLV{id} == 10)
		{
			formatex(numSec, 3, "")
			formatex(SecnumSec, 3, "MAX")
		}
		else
		{
			formatex(numSec, 3, "%d%", m_pszLevelLV{id} * 10)
			formatex(SecnumSec, 3, "")
		}
		
		set_dhudmessage(0, 255, 0, 1.0, 0.8, 0, 0.0, 1.2, 0.0, 0.0, false)
		show_dhudmessage(id, "%s ^n%s ", num, numSec)
		
		set_dhudmessage(255, 0, 0, 1.0, 0.8, 0, 0.0, 1.2, 0.0, 0.0, false)
		show_dhudmessage(id, "%s ^n%s ", Secnum, SecnumSec)
	}
}

public client_putinserver(id)
{
	m_iSysMoney[id] = 0
	m_pszLevelHP{id} = 0
	m_pszLevelLV{id} = 0
	m_pszMaps{id} = 2
	
	new authid[32]
	get_user_authid(id, authid, 31)
	
	if (authid[5] != '_' || authid[6] == 'I') get_user_ip(id, authid, 31, 1)
	
	for (new i = 0; i < m_iSaveTotal; i++)
	{
		if (equal(authid, m_arraySaveAuthID[i]))
		{
			m_iSysMoney[id] = m_arraySaveMoney[i]
			m_pszLevelHP{id} = m_arraySaveLevelHP[i]
			m_pszLevelLV{id} = m_arraySaveLevelLV[i]
			m_pszMaps{id} = m_arraySaveMaps[i]
			break
		}
	}
	
	cs_set_user_money(id, m_iSysMoney[id], 0)
	
	set_task(0.3, "TASK__rebind_f1_f2", id)
}

public TASK__rebind_f1_f2(id)
{
	client_cmd(id, "bind F1 ^"autobuy;impulse %d^"", IMPULSE_AUTOBUY)
	client_cmd(id, "bind F2 ^"rebuy;impulse %d^"", IMPULSE_REBUY)
}

public client_disconnect(id)
{
	new authid[32], i
	get_user_authid(id, authid, 31)
	
	if (authid[5] != '_' || authid[6] == 'I') get_user_ip(id, authid, 31, 1)
	
	for (i = 0; i < m_iSaveTotal; i++)
	{
		if (equal(authid, m_arraySaveAuthID[i]))
		{
			m_arraySaveMoney[i] = m_iSysMoney[id]
			m_arraySaveLevelHP[i] = m_pszLevelHP{id}
			m_arraySaveLevelLV[i] = m_pszLevelLV{id}
			m_arraySaveMaps[i] = m_pszMaps{id}
			i = 9999
			break
		}
	}
	
	if (i != 9999)
	{
		if (m_iSaveTotal == MAX_SAVE) return
		
		formatex(m_arraySaveAuthID[m_iSaveTotal], 31, authid)
		m_arraySaveMoney[m_iSaveTotal] = m_iSysMoney[id]
		m_arraySaveLevelHP[m_iSaveTotal] = m_pszLevelHP{id}
		m_arraySaveLevelLV[m_iSaveTotal] = m_pszLevelLV{id}
		m_arraySaveMaps[m_iSaveTotal] = m_pszMaps{id}
		m_iSaveTotal++
	}
	
	delete_file("addons/amxmodx/configs/cso_level_sys_saved_money.cfg")
	
	new file, data[64]
	file = fopen("addons/amxmodx/configs/cso_level_sys_saved_money.cfg", "at")
	
	for (new i = 0; i < m_iSaveTotal; i++)
	{
		formatex(data, 63, "load_money ^"%s^" ^"%d^" ^"%d^" ^"%d^" ^"%d^"^n", m_arraySaveAuthID[i], m_arraySaveMoney[i], m_arraySaveLevelHP[i], m_arraySaveLevelLV[i], m_arraySaveMaps[i])
		fputs(file, data)
	}
	
	fclose(file)
	
	remove_task(id)
}

public CPlayer__Spawn_Post(id)
{
	if (!is_user_alive(id)) return
	if (!_:cs_get_user_team(id)) return
	
	message_begin(MSG_ONE_UNRELIABLE, MSGID_HideWeapon, _, id)
	write_byte(0)
	message_end()
	
	if (zp_get_user_zombie(id) || zp_get_user_survivor(id)) return
	
	set_user_health(id, get_user_health(id) + (m_pszLevelHP{id} * 100))
}

public CPlayer__Killed(id, idattacker, shouldgib) cs_set_user_money(id, m_iSysMoney[id], FLAG_NONE)

public CPlayer__Killed_Post(id, idattacker, shouldgib)
{
	if (id == idattacker) return
	if (!is_user_connected(idattacker)) return
	if (zp_get_user_zombie(idattacker)) return
	
	CPlayer__SetMoney(idattacker, m_iSysMoney[idattacker] + MONEY_KILL, FLAG_FLASH)
}

public CPlayer__TakeDamage(id, idinflictor, idattacker, Float:damage, damagebits)
{
	if (id == idattacker) return
	if (!is_user_connected(idattacker)) return
	if (zp_get_user_zombie(idattacker)) return
	
	if (!zp_get_user_survivor(idattacker)) SetHamParamFloat(4, damage + (m_pszLevelLV{idattacker} * 10.0))
	
	switch (get_pdata_int(id, m_LastHitGroup, LINUXDIFF))
	{
		case HIT_HEAD: CPlayer__SetMoney(idattacker, m_iSysMoney[idattacker] + MONEY_HEAD, FLAG_FLASH)
		case HIT_CHEST: CPlayer__SetMoney(idattacker, m_iSysMoney[idattacker] + MONEY_CHEST, FLAG_FLASH)
		case HIT_STOMACH: CPlayer__SetMoney(idattacker, m_iSysMoney[idattacker] + MONEY_STOMACH, FLAG_FLASH)
		case HIT_LEFTARM, HIT_RIGHTARM: CPlayer__SetMoney(idattacker, m_iSysMoney[idattacker] + MONEY_ARM, FLAG_FLASH)
		case HIT_LEFTLEG, HIT_RIGHTLEG: CPlayer__SetMoney(idattacker, m_iSysMoney[idattacker] + MONEY_LEG, FLAG_FLASH)
	}
}

public CPlayer__SetMoney(id, amount, flag)
{
	if (amount < 0)
	{
		UTIL_MakeBlinkAcct(id, 2)
		return 0
	}
	
	amount = min(amount, MAX_MONEY)
	
	m_iSysMoney[id] = amount
	
	message_begin(MSG_ONE_UNRELIABLE, MSGID_Money, _, id)
	write_long(amount)
	write_byte(flag)
	message_end()
	
	return 1
}

public MSG_Money(msg_id, msg_dest, msg_entity)
{
	if (get_msg_arg_int(2)) return PLUGIN_HANDLED
	
	set_msg_arg_int(1, ARG_LONG, m_iSysMoney[msg_entity])
	
	return PLUGIN_CONTINUE
}

public IMPULSE__autobuy(id)
{
	if (m_pszLevelHP{id} == 10) return
	if (!CPlayer__SetMoney(id, m_iSysMoney[id] - COST_HP, FLAG_FLASH))
	{
		client_print(id, print_chat, "У тебя нет %d$ чтобы взять HP", COST_HP)
		return
	}
	m_pszLevelHP{id}++
	
	UTIL_MakeBuyEffect(id, 1, UNIT_SECOND * 3, FFADE_IN, FFADE_HP_COLOR, FFADE_HP_ALPHA, SOUND_HP)
	
	if (is_user_alive(id) && !zp_get_user_zombie(id) && !zp_get_user_survivor(id)) set_user_health(id, get_user_health(id) + 100)
}

public IMPULSE__rebuy(id)
{
	if (m_pszLevelLV{id} == 10) return
	if (!CPlayer__SetMoney(id, m_iSysMoney[id] - COST_LV, FLAG_FLASH))
	{
		client_print(id, print_chat, "У тебя нет %d$ чтобы взять LV", COST_LV)
		return
	}
	m_pszLevelLV{id}++
	
	UTIL_MakeBuyEffect(id, 1, UNIT_SECOND * 3, FFADE_IN, FFADE_LV_COLOR, FFADE_LV_ALPHA, SOUND_LV)
}

public zp_user_humanized_post(id, survivor)
{
	message_begin(MSG_ONE_UNRELIABLE, MSGID_HideWeapon, _, id)
	write_byte(0)
	message_end()
	
	if (survivor) return
	
	set_user_health(id, get_user_health(id) + (m_pszLevelHP{id} * 100))
}

UTIL_MakeBlinkAcct(id, BlinkAmt)
{
	message_begin(MSG_ONE_UNRELIABLE, MSGID_BlinkAcct, _, id)
	write_byte(BlinkAmt)
	message_end()
}

UTIL_MakeBuyEffect(id, Duration, HoldTime, Flags, Color[3], Alpha, sound[])
{
	client_cmd(id, "spk %s", sound)
	
	message_begin(MSG_ONE_UNRELIABLE, MSGID_ScreenFade, _, id)
	write_short(Duration)
	write_short(HoldTime)
	write_short(Flags)
	write_byte(Color[0])
	write_byte(Color[1])
	write_byte(Color[2])
	write_byte(Alpha)
	message_end()
	
	for (new i = 1; i < m_iMaxPlayers; i++)
	{
		if (entity_get_int(i, EV_INT_iuser1) != id || i == id) continue
		
		client_cmd(i, "spk %s", sound)
		
		message_begin(MSG_ONE_UNRELIABLE, MSGID_ScreenFade, _, i)
		write_short(Duration)
		write_short(HoldTime)
		write_short(Flags)
		write_byte(Color[0])
		write_byte(Color[1])
		write_byte(Color[2])
		write_byte(Alpha)
		message_end()
	}
}