//  Agent! - The Dudes From The Matrix

/* CVARS - copy and paste to shconfig.cfg

//Agent
agent_level 4
agent_cooldown 10			//# of seconds before Agent can teleport again.
agent_teleportnum 3			//# of times Agent can teleport in a round
agent_spawndelay 15			//# of seconds player must wait at new round before teleporting

*/


#include <amxmodx>
#include <fakemeta>
#include <superheromod>

// GLOBAL VARIABLES
new gHeroName[]="Agent (Matrix)"
new bool:SpawnDelay = false
new gTeleCounter[SH_MAXSLOTS+1]
new bool:gHasAgent[SH_MAXSLOTS+1]
new gSavedOrigin[SH_MAXSLOTS+1][3]
new gLastPosition[SH_MAXSLOTS+1][3]	   // Variable to help with position checking
new gPcvarCooldown, gPcvarTeleportNum, gPcvarSpawnDelay
//----------------------------------------------------------------------------------------------
public plugin_init()
{
	// Plugin Info
	register_plugin("SUPERHERO Agent", "1.3", "AssKicR & -|-LoA-|-Bass")

	// DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
	register_cvar("agent_level", "4")
	gPcvarCooldown = register_cvar("agent_cooldown", "10")
	gPcvarTeleportNum = register_cvar("agent_teleportnum", "3")
	gPcvarSpawnDelay = register_cvar("agent_spawndelay", "15")

	// FIRE THE EVENT TO CREATE THIS SUPERHERO!
	shCreateHero(gHeroName, "TelePort Menu", "TelePort Menu and Unlimited Desert Eagle Ammo", true, "agent_level")

	// REGISTER EVENTS THIS HERO WILL RESPOND TO! (AND SERVER COMMANDS)
	// INIT
	register_srvcmd("agent_init", "agent_init")
	shRegHeroInit(gHeroName, "agent_init")

	// KEY DOWN
	register_srvcmd("agent_kd", "agent_kd")
	shRegKeyDown(gHeroName, "agent_kd")

	// Weapon Change
	register_event("CurWeapon", "changeWeapon","be", "1=1")

	register_event("ResetHUD", "new_spawn", "b")
	register_logevent("round_start", 2, "1=Round_Start")

	// REGISTER MENU
	register_menucmd(register_menuid("[SH](Agent)"), (MENU_KEY_1|MENU_KEY_2|MENU_KEY_0), "TeleMenuAction")
}
//----------------------------------------------------------------------------------------------
public agent_init()
{
	// First Argument is an id
	new temp[6]
	read_argv(1, temp, 5)
	new id = str_to_num(temp)

	// 2nd Argument is 0 or 1 depending on whether the id has Agent powers
	read_argv(2, temp, 5)
	new hasPowers = str_to_num(temp)
	gHasAgent[id] = (hasPowers != 0)

	if ( gHasAgent[id] ) {
		agent_deagle(id)
	}
	else {
		engclient_cmd(id, "drop", "weapon_deagle")
	}
}
//----------------------------------------------------------------------------------------------
public new_spawn(id)
{
	gTeleCounter[id] = get_pcvar_num(gPcvarTeleportNum)
	if ( gHasAgent[id]  ) {
		set_task(0.1, "agent_deagle",id)
	}
}
//----------------------------------------------------------------------------------------------
public round_start()
{
	new Float:delay = get_pcvar_float(gPcvarSpawnDelay)
	if (delay > 0.0) {
		SpawnDelay = true
		set_task(delay, "roundstart_delay")
	}
}
//----------------------------------------------------------------------------------------------
public roundstart_delay()
{
	SpawnDelay = false
}
//----------------------------------------------------------------------------------------------
public client_connect(id)
{
	gSavedOrigin[id][0] = -999999
	gSavedOrigin[id][1] = -999999
	gSavedOrigin[id][2] = -999999
}
//----------------------------------------------------------------------------------------------
public agent_kd()
{
	// First Argument is an id with agent Powers!
	new temp[6]
	read_argv(1, temp, 5)
	new id = str_to_num(temp)

	if ( !is_user_alive(id) || !gHasAgent[id] ) return PLUGIN_HANDLED

	// Let them know they already used their ultimate if they have
	if ( gPlayerUltimateUsed[id] ) {
		playSoundDenySelect(id)
		return PLUGIN_HANDLED
	}

	showMenu(id)

	return PLUGIN_HANDLED
}
//----------------------------------------------------------------------------------------------
public showMenu(id)
{
	new menuBody[512]
	new len = format(menuBody, 511, "\y[SH](Agent) Teleport Menu:^n^n\w")
	len += format(menuBody[len], 511-len, "1. Save Coordinates^n2. Teleport^n^n0. Exit")
	show_menu(id, (MENU_KEY_1|MENU_KEY_2|MENU_KEY_0), menuBody)
	return PLUGIN_HANDLED
}
//----------------------------------------------------------------------------------------------
public TeleMenuAction(id,key)
{
	switch(key) {
		case 0: {
			agent_saveOrigin(id)
		}
		case 1: {
			if ( !hasRoundStarted() || SpawnDelay ) {
				if (SpawnDelay) client_print(id,print_chat,"[SH](Agent) You must wait %d seconds after round start before teleporting",get_pcvar_num(gPcvarSpawnDelay))
				showMenu(id)
				return PLUGIN_HANDLED
			}

			if ( gSavedOrigin[id][0] == -999999 && gSavedOrigin[id][1] == -999999 && gSavedOrigin[id][2] == -999999 ) {
				client_print(id,print_chat,"[SH](Agent) You must save coordinates before teleporting")
				showMenu(id)
				return PLUGIN_HANDLED
			}

			if ( gTeleCounter[id] > 0 ) {
				gTeleCounter[id]--
				new message[128]
				format(message, 127, "[SH](Agent) You Have %d Teleportations Left",gTeleCounter[id])
				set_hudmessage(255,0,0,-1.0,0.3,0,0.25,1.0,0.0,0.0,26)
				show_hudmessage(id, message)
				ultimateTimer(id, get_pcvar_float(gPcvarCooldown))
				agent_teleport(id)
			}
			else if ( gTeleCounter[id] <= 0 ) {
				set_hudmessage(255,0,0,-1.0,0.3,0,0.25,1.0,0.0,0.0,26)
				show_hudmessage(id, "[SH](Agent) You Have No Teleportations Left")
				gPlayerUltimateUsed[id] = true
			}
		}
		default: return PLUGIN_HANDLED
	}
	return PLUGIN_HANDLED
}
//----------------------------------------------------------------------------------------------
public agent_saveOrigin(id)
{
	get_user_origin(id, gSavedOrigin[id])
	client_print(id, print_chat, "[SH](Agent) Your Saved Coordinates Are: %i %i %i", gSavedOrigin[id][0], gSavedOrigin[id][1], gSavedOrigin[id][2])
	gSavedOrigin[id][2] += 8
}
//----------------------------------------------------------------------------------------------
public agent_teleport(id)
{
	new Origin[3]
	get_user_origin(id, Origin)

	//TE_TELEPORT Effects
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(11)
	write_coord(Origin[0])
	write_coord(Origin[1])
	write_coord(Origin[2])
	message_end()

	//Teleport the player
	set_user_origin(id, gSavedOrigin[id])

	//TE_TELEPORT Effects
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(11)
	write_coord(gSavedOrigin[id][0])
	write_coord(gSavedOrigin[id][1])
	write_coord(gSavedOrigin[id][2])
	message_end()

	positionChangeTimer(id)
}
//----------------------------------------------------------------------------------------------
public positionChangeTimer(id)
{
	if ( !is_user_alive(id) ) return

	get_user_origin(id, gLastPosition[id], 0)

	new Float:velocity[3]
	pev(id, pev_velocity, velocity)

	if ( velocity[0]==0.0 && velocity[1]==0.0 ) {
		// Force a Move (small jump)
		velocity[0] += 20.0
		velocity[2] += 100.0
		set_pev(id, pev_velocity, velocity)
	}

	set_task(0.4, "positionChangeCheck", id)
}
//----------------------------------------------------------------------------------------------
public positionChangeCheck(id)
{
	new origin[3]

	if (!is_user_alive(id) ) return

	get_user_origin(id, origin, 0)
	// Kill this player if Stuck in Wall!
	if ( gLastPosition[id][0] == origin[0] && gLastPosition[id][1] == origin[1] && gLastPosition[id][2] == origin[2] && is_user_alive(id) ) {
		user_kill(id)
		client_print(id,print_chat,"[SH](Agent) You were killed for getting stuck in a wall")
	}
}
//----------------------------------------------------------------------------------------------
public changeWeapon(id)
{
	if ( !gHasAgent[id] || !shModActive() ) return

	new wpnid = read_data(2)
	new clip = read_data(3)

	// Never Run Out of Ammo!
	if ( wpnid == CSW_DEAGLE && clip == 0 ) {
		shReloadAmmo(id)
	}
}
//----------------------------------------------------------------------------------------------
public agent_deagle(id)
{
	shGiveWeapon(id,"weapon_deagle")
}
//----------------------------------------------------------------------------------------------