#include <amxmodx>
#include <amxmisc>
#include <cstrike>
#include <fakemeta>

#include <nst_zombie>
#include <nst_wpn>

new const SETTING_FILE[] = "nst_player.ini"
const MAX_PLAYER = 50
new g_player_name[MAX_PLAYER][32]
new g_player_model[MAX_PLAYER][32]
new g_player_model_index[MAX_PLAYER]
new g_player_sex[MAX_PLAYER]
new g_player_hand[MAX_PLAYER]
new g_player_team[MAX_PLAYER]

new g_set_model_index, g_modelindex_default, g_player_total, g_sex[33], g_idplayer[33], g_team[33], g_hand[33]
new cvar_random_model
new g_dir_model[64] = "models/player/%s/%s.mdl"
new autoselect[] = "autoselect"

// Task offsets
enum (+= 100)
{
	TASK_WELLCOME = 2000
}
// CS Teams
enum
{
	FM_CS_TEAM_UNASSIGNED = 0,
	FM_CS_TEAM_T,
	FM_CS_TEAM_CT,
	FM_CS_TEAM_SPECTATOR
}
// sound female
new const SOUND_F_BHIT[3][] = { "nst_player/f_bhit_flesh-1.wav",
			"nst_player/f_bhit_flesh-2.wav",
			"nst_player/f_bhit_flesh-3.wav"}
new const SOUND_F_DIE[3][] = { "nst_player/f_die1.wav",
			"nst_player/f_die2.wav",
			"nst_player/f_die3.wav"}
new const SOUND_F_HS[3][] = { "nst_player/f_headshot1.wav",
			"nst_player/f_headshot2.wav",
			"nst_player/f_headshot3.wav"}

enum
{
	SECTION_NAME = 0,
	SECTION_MODEL,
	SECTION_TEAM,
	SECTION_SEX,
	SECTION_HAND
}
const OFFSET_LINUX = 5
const OFFSET_MODELINDEX = 491


// ######################## REGISTER PLUGIN ########################
public plugin_natives()
{	
	register_native("nst_set_user_model", "natives_set_user_model", 1)
	register_native("nst_set_user_model_index", "natives_set_user_model_index", 1)
	register_native("nst_reset_user_model", "natives_reset_user_model", 1)
	register_native("nst_reset_user_model_index", "natives_reset_user_model_index", 1)
	register_native("nst_get_user_sex", "natives_get_user_sex", 1)
	register_native("nst_set_user_sex", "natives_set_user_sex", 1)
	register_native("nst_get_user_team", "natives_get_user_team", 1)
	register_native("nst_get_user_hand", "natives_get_user_hand", 1)
	register_native("nst_set_user_hand", "natives_set_user_hand", 1)
	register_native("nst_create_user_sound_bhit", "natives_create_user_sound_bhit", 1)
	
}
public plugin_init()
{
	register_plugin("NST Add Player", "1.0", "NST")
	
	// Language files
	register_dictionary("nst_player.txt")
	
	// register
	register_event("HLTV", "event_round_start", "a", "1=0", "2=0")
	register_forward(FM_EmitSound, "fw_EmitSound")
	
	// cvar
	cvar_random_model = register_cvar("nst_player_random_model", "0")
	
	// client cmd
	register_clcmd("nst_choose_player", "cmd_choose_player")
	register_clcmd("nst_player", "cmd_menu_main")
	//register_concmd("ww", "ww")
	
}
public ww(id)
{
	client_print(id, print_chat, "[%s]", g_player_name[get_random_class(get_user_team(id))])
}
public plugin_precache()
{
	load_config()
	for (new i = 0; i <= 2; i++)
	{
		engfunc(EngFunc_PrecacheSound, SOUND_F_BHIT[i])
		engfunc(EngFunc_PrecacheSound, SOUND_F_DIE[i])
		engfunc(EngFunc_PrecacheSound, SOUND_F_HS[i])
	}
	g_modelindex_default = engfunc(EngFunc_PrecacheModel, "models/player/leet/leet.mdl")
}


// ################################ LOAD CONFIG ################################
new data_name[64], data_model[64], data_team, data_sex, data_hand

load_config()
{
	// Build customization file path
	new path[64]
	get_configsdir(path, charsmax(path))
	format(path, charsmax(path), "%s/%s", path, SETTING_FILE)
	
	// File not present
	if (!file_exists(path))
	{
		new error[100]
		formatex(error, charsmax(error), "Cannot load customization file %s!", path)
		set_fail_state(error)
		return;
	}
	
	// Set up some vars to hold parsing info
	new linedata[1024], key[64], value[960], key2[64], value2[960]
	
	// Open customization file for reading
	new file = fopen(path, "rt")
	new idplayer = 1
	while (file && !feof(file))
	{
		// Read one line at a time
		fgets(file, linedata, charsmax(linedata))
		
		// Replace newlines with a null character to prevent headaches
		replace(linedata, charsmax(linedata), "^n", "")
		
		// Blank line or comment
		if (!linedata[0] || linedata[0] == ';') continue;
		
		strtok(linedata, key2, charsmax(key2), value2, charsmax(value2), '=')
		trim(key2)
		trim(value2)
		
		// set model index
		if (equal(key2, "SET_MODEL_INDEX"))
		{
			g_set_model_index = str_to_num(value2)
			continue;
		}
		
		// Replace
		replace(linedata, charsmax(linedata), ",", "")
		replace(linedata, charsmax(linedata), "[name]", ",")
		replace(linedata, charsmax(linedata), "[model]", ",")
		replace(linedata, charsmax(linedata), "[team]", ",")
		replace(linedata, charsmax(linedata), "[sex]", ",")
		replace(linedata, charsmax(linedata), "[hand]", ",")

		// Get value
		strtok(linedata, key, charsmax(key), value, charsmax(value), ',')
		new i
		while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
		{
			switch (i)
			{
				case SECTION_NAME: format(data_name, charsmax(data_name), "%s", key)
				case SECTION_MODEL: format(data_model, charsmax(data_model), "%s", key)
				case SECTION_TEAM: data_team = str_to_num(key)
				case SECTION_SEX: data_sex = str_to_num(key)
				case SECTION_HAND: data_hand = str_to_num(key)
			}
			//client_print(0, print_chat, "STT[%i]", hand)
			i++
		}
		
		// Set Value
		new modelurl[64]
		format(g_player_name[idplayer], 31, "%s", data_name)
		format(g_player_model[idplayer], 31, "%s", data_model)
		format(modelurl, charsmax(modelurl), g_dir_model, data_model, data_model)
		g_player_model_index[idplayer] = precache_model(modelurl)
		g_player_team[idplayer] = data_team
		g_player_sex[idplayer] = data_sex
		g_player_hand[idplayer] = data_hand
		
		g_player_total = idplayer
		idplayer++
		//client_print(0, print_chat, "==[%i][%s]", idwpn, linedata)
	}
}

// ######################## MAIN PUBLIC FUNCTION ########################
// event round start
public event_round_start()
{
	// wellcome
	remove_task(TASK_WELLCOME)
	set_task(7.0, "wellcome", TASK_WELLCOME)
	
	// set model in new round
	set_model_new_round()
}

// msg wellcome
public wellcome()
{
	// set & show msg
	new message[64]
	format(message, charsmax(message), "^x04[NST Player]^x01 %L", LANG_PLAYER, "NOTICE_HELP_CHOOSE")
	color_saytext(0, message)

	// set task
	//remove_task(TASK_WELLCOME)
	//set_task(60.0, "wellcome", TASK_WELLCOME)
}
public client_putinserver(id)
{
	reset_value(id)
}
public fw_ClientDisconnect(id)
{
	reset_value(id)
}

// Emit Sound Forward
public fw_EmitSound(id, channel, const sample[], Float:volume, Float:attn, flags, pitch)
{
	if (!is_user_connected(id))
		return FMRES_IGNORED;
	
	// change sound Female
	if (g_sex[id] != 2) return FMRES_IGNORED;
	new sound[101]
	for (new i = 0; i <= 2; i++)
	{
		// Hit
		format(sound, charsmax(sound), "%s", SOUND_F_BHIT[i])
		replace(sound, charsmax(sound), "nst_player/f_", "player/")
		if (equal(sample, sound))
		{
			emit_sound(id, channel, SOUND_F_BHIT[i], volume, attn, flags, pitch)
			return FMRES_SUPERCEDE;
		}
		// Die
		format(sound, charsmax(sound), "%s", SOUND_F_DIE[i])
		replace(sound, charsmax(sound), "nst_player/f_", "player/")
		if (equal(sample, sound))
		{
			emit_sound(id, channel, SOUND_F_DIE[i], volume, attn, flags, pitch)
			return FMRES_SUPERCEDE;
		}
		// Headshot
		format(sound, charsmax(sound), "%s", SOUND_F_HS[i])
		replace(sound, charsmax(sound), "nst_player/f_", "player/")
		if (equal(sample, sound))
		{
			emit_sound(id, channel, SOUND_F_HS[i], volume, attn, flags, pitch)
			return FMRES_SUPERCEDE;
		}
	}
	
	//client_print(id, print_chat, "[%s]", sample)
	return FMRES_IGNORED;
}

// Cmd Chose Player
public cmd_choose_player(id)
{
	if (!is_user_connected(id) || nst_zb_get_user_zombie(id)) return PLUGIN_HANDLED
	
	new models[64]
	read_argv(1, models, 63)
	
	for(new i=1; i<=g_player_total; i++)
	{
		if (g_player_sex[i]>0)
		{
			if (equali(g_player_model[i], models))
			{
				set_player_class(id, i)
				return PLUGIN_HANDLED
			}
		}
	}

	// auto select class
	if (equali(models, autoselect))
	{
		new idplayer = get_random_class(get_user_team(id))
		if (idplayer) set_player_class(id, idplayer)
	}

	
	return PLUGIN_HANDLED
}


// Menu Main
public cmd_menu_main(id)
{	
	if (!is_user_alive(id) || nst_zb_get_user_zombie(id) || nst_zb_get_user_hero(id)) return PLUGIN_HANDLED
	
	// create value
	new menu_title[64], item_1[64], item_2[64]
	format(menu_title, charsmax(menu_title), "[NST Player] %L:", LANG_PLAYER, "MENUTEAM_TITLE")
	format(item_1, charsmax(item_1), "%L", LANG_PLAYER, "MENUTEAM_ITEM_TE")
	format(item_2, charsmax(item_2), "%L", LANG_PLAYER, "MENUTEAM_ITEM_CT")

	// create menu
	new mHandleID = menu_create(menu_title, "menu_main_handler")
	menu_additem(mHandleID, item_1, "1", 0)
	menu_additem(mHandleID, item_2, "2", 0)
	menu_display(id, mHandleID, 0) 
	
	
	return PLUGIN_HANDLED
}
public menu_main_handler(id, menu, item)
{
	if (item == MENU_EXIT)
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED
	}
	
	if (item == 0) menu_class(id, FM_CS_TEAM_T)
	else if (item == 1) menu_class(id, FM_CS_TEAM_CT)
	
	menu_destroy(menu)
	return PLUGIN_HANDLED
}

// Menu Chose Class
public menu_class(id, team)
{
	// create value
	new menu_title[64]
	format(menu_title, charsmax(menu_title), "[NST Player] %L:", LANG_PLAYER, "MENUPLAYER_TITLE")

	// create menu
	new mHandleID = menu_create(menu_title, "menu_class_handler")
	
	for (new i=1; i<=g_player_total; i++)
	{
		if (g_player_team[i]==team)
		{
			new idplayer[32], nameplayer[32]
			format(nameplayer, charsmax(nameplayer), "%s", g_player_name[i])
			format(idplayer, charsmax(idplayer), "%i", i)
			menu_additem(mHandleID, nameplayer, idplayer, 0)
		}
	}
	
	menu_display(id, mHandleID, 0)
   
	return PLUGIN_HANDLED
}
public menu_class_handler(id, menu, item)
{
	if (item == MENU_EXIT)
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED
	}
	
	// get idplayer & team
	new idplayer_str[32], nameplayer_str[32], access
	menu_item_getinfo(menu, item, access, idplayer_str, 31, nameplayer_str, 31, access)
	new idplayer = str_to_num(idplayer_str)
	
	// set class player
	set_player_class(id, idplayer)
	//client_print(id, print_chat, "[%i] - [%i]", team, idplayer)
	
	menu_destroy(menu)
	return PLUGIN_HANDLED
}
set_player_class(id, idplayer)
{
	new team = get_user_team(id)
	//if (team!=FM_CS_TEAM_T && team!=FM_CS_TEAM_CT) return;
	
	// check idplayer
	if (!idplayer)
	{
		idplayer = get_random_class(team)
	}
	
	// check team
	else if (team!=g_player_team[idplayer])
	{
		fm_cs_set_user_team(id, g_player_team[idplayer])
		if (is_user_alive(id)) user_kill(id)
	}

	// set class player
	set_player_model(id, idplayer)
	
	// show msg
	new msg[101]
	format(msg, charsmax(msg), "^x04[NST Player]^x01 %L", LANG_PLAYER, "NOTICE_CHOOSE_COMPLETE", g_player_name[idplayer])
	color_saytext(id, msg)
}
set_player_model(id, idplayer)
{
	g_idplayer[id] = idplayer
	g_sex[id] = g_player_sex[idplayer]
	g_hand[id] = g_player_hand[idplayer]
	g_team[id] = g_player_team[idplayer]
	set_user_model(id, g_player_model[idplayer])
	
	if (g_set_model_index) set_user_model_index(id, g_player_model_index[idplayer])
	else
	{
		new mod_runing = nst_get_mod_runing()
		if (mod_runing==NST_MOD_ZB3 || mod_runing==NST_MOD_ZBU || mod_runing==NST_MOD_ZBS)
		{
			set_user_model_index(id, g_modelindex_default)
		}
	}
}
set_user_model(id, model[])
{
	if (!is_user_connected(id)) return;
	
	new model_url[64]
	format(model_url, charsmax(model_url), g_dir_model, model, model)
	cs_set_user_model(id, model)
	set_pev(id, pev_model, model_url)
}
set_user_model_index(id, model_index)
{
	fm_cs_set_user_model_index(id, model_index)
}
reset_user_model(id)
{
	if (!is_user_connected(id)) return;
	
	if (!g_idplayer[id]) g_idplayer[id] = get_random_class(get_user_team(id))
	set_player_model(id, g_idplayer[id])
}
set_model_new_round()
{
	for (new id = 1; id < 33; id++)
	{
		if (!is_user_connected(id)) continue;
		
		// Random model
		if (is_user_bot(id) && get_pcvar_num(cvar_random_model) || !g_idplayer[id]) set_player_class(id, 0)
		else set_player_model(id, g_idplayer[id])
	}
}
get_random_class(team)
{
	new n_player_idplayer[MAX_PLAYER], total, idrandom
	for (new i=1; i<=g_player_total; i++)
	{
		if (g_player_team[i] == team)
		{
			n_player_idplayer[total+1] = i
			total++
		}
	}
	if (total) idrandom = n_player_idplayer[random_num(1, total)]
	
	return idrandom
}
color_saytext(player, const message[], any:...)
{
	new text[301]
	format(text, 300, "%s", message)

	new dest
	if (player) dest = MSG_ONE
	else dest = MSG_ALL
	
	message_begin(dest, get_user_msgid("SayText"), {0,0,0}, player)
	write_byte(1)
	write_string(check_text(text))
	return message_end()
}
check_text(text1[])
{
	new text[301]
	format(text, 300, "%s", text1)
	replace(text, 300, ">x04", "^x04")
	replace(text, 300, ">x03", "^x03")
	replace(text, 300, ">x01", "^x01")
	return text
}
reset_value(id)
{
	g_idplayer[id] = 0
	g_sex[id] = 0
	g_team[id] = 0
	g_hand[id] = 0
}
PlayEmitSound(id, type, const sound[])
{
	emit_sound(id, type, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
}


// ######################## STOCK ########################
// Set a Player's Team
stock fm_cs_set_user_team(id, team)
{
	cs_set_user_team(id, team, 0)
}
stock fm_cs_set_user_model_index(id, value)
{
	if (!value) return;
	set_pdata_int(id, OFFSET_MODELINDEX, value, OFFSET_LINUX)
}


// ######################## NATIVE ########################
public natives_get_user_sex(id)
{
	return g_sex[id];
}
public natives_set_user_sex(id, sex)
{
	g_sex[id] = sex
	return 1;
}
public natives_get_user_team(id)
{
	return g_team[id];
}
public natives_set_user_model(id, model[])
{
	param_convert(2)
	set_user_model(id, model)
	return 1;
}
public natives_reset_user_model(id)
{
	reset_user_model(id)
	return 1;
}
public natives_set_user_model_index(id, modelindex)
{
	set_user_model_index(id, modelindex)
	return 1;
}
public natives_reset_user_model_index(id)
{
	set_user_model_index(id, g_modelindex_default)
	return 1;
}
public natives_get_user_hand(id)
{
	return g_hand[id];
}
public natives_set_user_hand(id, hand)
{
	g_hand[id] = hand
	return 1;
}
public natives_create_user_sound_bhit(id)
{
	new sound[64]
	if (g_sex[id]==2) format(sound, charsmax(sound), "nst_player/f_bhit_flesh-%i.wav", random_num(1, 3))
	else format(sound, charsmax(sound), "player/bhit_flesh-%i.wav", random_num(1, 3))
	PlayEmitSound(id, CHAN_VOICE, sound)
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1034\\ f0\\ fs16 \n\\ par }
*/
