/* AMX Mod X Plugin 
* 
* (c) Copyright 2008, ConnorMcLeod 
* This file is provided as is (no warranties). 
* 
*/

/*
* v0.4c (2008feb05)
* fixed bad colored text in czero
*
* v0.4b (2008feb02)
* fixed event Location, first argument have to be equal to player id
*
* v0.4 (2008feb01)
* now supports czero located radio messages
* can run safely with realradio plugin (changed TextMsg emessage_begin -> message_begin)
*
* v0.3 (2008jan14)
* supports ML
* added ML radio chat messages
* chat messages can be disabled
* supports funradio plugin by VEN
* added realradio feature
*
* v0.2
* amxx port
*
* v0.1 (2007apr07)
* First amx release http://djeyl.net/forum/index.php?showtopic=54146
*/

#include <amxmodx>

new const VERSION[] = "0.4c"

#define MAX_PLAYERS	32

#define MAX_MENU_NUM 4
#define MAX_ACTIONS 36
#define MAX_ALIASES	27

#define KEYS ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9))

#define RADIO_COOLDOWN	1.5
#define PRINT_RADIO		5
#define PITCH_RADIO	100  // have to be 100 for funradio plugin compatibility
#define CVAR_FUNRADIO  "amx_funradio_playspeed"

new Float:g_fCanRadioTime[MAX_PLAYERS+1]
new g_iMenuId[MAX_PLAYERS+1]
new bool:g_bFunRadio, bool:g_bRealRadio
new bool:g_Location = false
new g_szLocation[MAX_PLAYERS+1][32]
new g_msgidSendAudio, g_msgidTextMsg
new g_pcvarRadioReplacement, g_pcvarRadioNoChat, g_pcvarRealRadio, g_pcvarFunRadio

new const g_soundNames[MAX_ACTIONS][] = {
	"ct_coverme", "takepoint", "position", "regroup", "followme", "fireassis", "letsgo", "matedown", "flankthem",
	"com_go", "fallback", "sticktog", "com_getinpos", "stormfront", "com_reportin", "getout", "elim", "roger",
	"ct_affirm", "ct_enemys", "ct_backup", "clear", "ct_inpos", "ct_reportingin", "blow", "negative", "enemydown",
	"ct_point", "com_followcom",  "meetme",  "moveout",  "hosdown",  "ct_imhit",  "hitassist",  "circleback",  "locknload"
}

new const g_szChatRadioMsgs[MAX_ACTIONS][] = {
	"RR_MSG_COVERME", "RR_MSG_TAKEPOS", "RR_MSG_HOLDPOS", "RR_MSG_REGROUP", "RR_MSG_FOLLOWME",
		"RR_MSG_TAKINGFIRE", "RR_MSG_LETSGO", "RR_MSG_MATEDOWN", "RR_MSG_FLANKTHEM",
	"RR_MSG_GOGOGO", "RR_MSG_FALLBACK", "RR_MSG_STICKTOG", "RR_MSG_GETINPOS", "RR_MSG_STORMFRONT",
		"RR_MSG_REPORT", "RR_MSG_GETOUT", "RR_MSG_ELIMIN", "RR_MSG_ROGER",
	"RR_MSG_AFFIRM", "RR_MSG_ENEMYSPOTTED", "RR_MSG_NEEDBACKUP", "RR_MSG_SECTORCLEAR", "RR_MSG_INPOSITION",
		"RR_MSG_REPORTING", "RR_MSG_GETOUTBLOW", "RR_MSG_NEGATIVE", "RR_MSG_ENEMYDOWN",
	"RR_MSG_ITAKEPOINT", "RR_MSG_FOLLOWCOM", "RR_MSG_RENDEZVOUS", "RR_MSG_MOUVEOUT", "RR_MSG_HOSDOWN",
		"RR_MSG_IMHIT", "RR_MSG_HITASSIST", "RR_MSG_CIRCLEBACK", "RR_MSG_LOCKNLOAD"	
}

new const g_aliases[MAX_ALIASES][] = {
	"coverme", "takepoint", "holdpos", "regroup", "followme", "takingfire", "", "", "",
	"go", "fallback", "sticktog", "getinpos", "stormfront", "report", "", "", "",
	"roger", "enemyspot", "needbackup", "sectorclear", "inposition", "reportingin", "getout", "negative", "enemydown"
}

new const g_cmdMenuName[MAX_MENU_NUM][] = {
	"RR_RADIO_1", "RR_RADIO_2", "RR_RADIO_3", "RR_RADIO_4"
}

new const g_cmdMenuCmd[MAX_MENU_NUM][] = {
	"radio1", "radio2", "radio3", "radio4"
}

public plugin_precache() {
	g_pcvarRealRadio = register_cvar("amx_radio_real", "0")

	if(!get_pcvar_num(g_pcvarRealRadio))
		return

	g_bRealRadio = true

	new szSound[32]
	for(new i; i<MAX_ACTIONS; i++)
	{
		formatex(szSound, 31, "radio/%s.wav", g_soundNames[i])
		precache_sound(szSound)
	}
}

public plugin_init()
{
	register_plugin("Radio Replacement", VERSION, "ConnorMcLeod")
	register_dictionary("radio_replacement.txt")

	g_pcvarRadioReplacement = register_cvar("amx_radio_replacement", "1")
	g_pcvarRadioNoChat = register_cvar("amx_radio_nochat", "0")

	new a
	for(a = 0; a < MAX_MENU_NUM; ++a)
	{
		register_menucmd(register_menuid(g_cmdMenuName[a]), KEYS ,"actionRadio")
		register_clcmd(g_cmdMenuCmd[a],"cmdCmdMenu")
	}
	for(a = 0; a < MAX_ALIASES; ++a)
	{
		if(g_aliases[a][0])
		{
			register_clcmd(g_aliases[a],"Hook_RadioAliases")
		}
	}
}

public plugin_cfg()
{
	g_msgidSendAudio = get_user_msgid("SendAudio")
	g_msgidTextMsg = get_user_msgid("TextMsg")
	if(cvar_exists(CVAR_FUNRADIO))
	{
		g_pcvarFunRadio = get_cvar_pointer(CVAR_FUNRADIO)
		g_bFunRadio = true
	}
	new szModName[6]
	get_modname(szModName, 5)
	if(equal(szModName, "czero"))
	{
		register_event("Location", "eLocation", "be")
	}
}

public eLocation(id)
{
	if(!g_Location)
	{
		g_Location = true
	}

	if(read_data(1) != id)
		return

	read_data(2, g_szLocation[id], 31)
}

public Hook_RadioAliases(id)
{
	if(!get_pcvar_num(g_pcvarRadioReplacement))
		return PLUGIN_CONTINUE

	if(!is_user_alive(id))
		return PLUGIN_CONTINUE

	new Float:fTime = get_gametime()
	if(g_fCanRadioTime[id] > fTime)
		return PLUGIN_HANDLED

	new szAlias[16]
	read_argv(0, szAlias, 15)
	for(new i = 0; i < MAX_ALIASES - 1; i++)
	{
		if(equal(g_aliases[i],szAlias))
		{
			g_fCanRadioTime[id] = fTime + RADIO_COOLDOWN
			do_radio(id, i)
			return PLUGIN_HANDLED
		}
	}
	return PLUGIN_CONTINUE
}

public cmdCmdMenu(id)
{
	if(!get_pcvar_num(g_pcvarRadioReplacement))
		return PLUGIN_CONTINUE
	if(!is_user_alive(id))
		return PLUGIN_HANDLED

	new szArg[7]
	read_argv(0, szArg, 6)

	g_iMenuId[id] = str_to_num(szArg[5]) - 1
	
	displayMenu(id)
	return PLUGIN_HANDLED
}

displayMenu(id)
{
	static szMenu[1024], ML_MENU[10], iMenuPos
	iMenuPos = g_iMenuId[id]
	formatex(ML_MENU, 9, "RR_MENU_%i", iMenuPos + 1)
	formatex(szMenu, 1023, "%L", id, ML_MENU)

	show_menu(id, KEYS, szMenu, -1, g_cmdMenuName[iMenuPos])
	
	return PLUGIN_HANDLED
}

public actionRadio(id, key)
{
	new Float:fTime = get_gametime()
	if(g_fCanRadioTime[id] > fTime || !is_user_alive(id) || key == 9)
		return PLUGIN_HANDLED
	
	g_fCanRadioTime[id] = fTime + RADIO_COOLDOWN

	new iWitchOne = key + g_iMenuId[id] * 9
	do_radio(id, iWitchOne)
	return PLUGIN_HANDLED
}

do_radio(id, iWitchOne)
{
	new iPlayers[MAX_PLAYERS], iNum, szTeam[10], iPlayer
	get_user_team(id, szTeam, 9)
	get_players(iPlayers, iNum, "ce", szTeam)

	static szSample[32], szName[32]
	formatex(szSample, 31, "radio/%s.wav", g_soundNames[iWitchOne])
	get_user_name(id, szName, 31)

	static const szGameRadio[] = "#Game_radio"
	static const szGameRadioLoc[] = "#Game_radio_location"
	static szId[3], szMessage[64]
	new bool:bChat = !get_pcvar_num(g_pcvarRadioNoChat)

	if(bChat)
		num_to_str(id, szId, 2)

	for(new i=0; i<iNum; i++)
	{
		iPlayer = iPlayers[i]
		if(!is_user_alive(iPlayer))
			continue

		if(bChat)
		{
			formatex(szMessage, 63, "%L", iPlayer, g_szChatRadioMsgs[iWitchOne])

			message_begin(MSG_ONE, g_msgidTextMsg, _, iPlayer)
			write_byte(PRINT_RADIO)
			write_string(szId)
			if(g_Location)
			{
				write_string(szGameRadioLoc)
				write_string(szName)
				write_string(g_szLocation[id][1])
			}
			else
			{
				write_string(szGameRadio)
				write_string(szName)
			}
			write_string(szMessage)
			message_end()
		}

		if(g_bRealRadio && iPlayer == id)
			continue

		emessage_begin(MSG_ONE, g_msgidSendAudio, _, iPlayer)
		ewrite_byte(id)
		ewrite_string(szSample)
		ewrite_short(PITCH_RADIO)
		emessage_end()
	}

	if(g_bRealRadio)
	{
		emit_sound(id, CHAN_VOICE, szSample, VOL_NORM, ATTN_STATIC, 0, g_bFunRadio ? get_pcvar_num(g_pcvarFunRadio) : PITCH_RADIO)
	}
}