// PHOENIX! - The fiery bird from Mythology. Rebirth from the ashes of it's burning death.

/* CVARS copy and paste to shconfig.cfg

//Phoenix
phoenix_level 8
phoenix_cooldown 120	//Ammount of time before next available respawn (Default 120)
phoenix_radius 375		//Radius of people affected by blast (Default 375)
phoenix_maxdamage 90	//Maximum damage dealt spread over radius (Default 90)

*/

/*
* v1.1 - vittu - 12/31/05
*      - Code cleaned up.
*      - Fixed respawn issues.
*      - Changed damage to be an actual radius damage.
*      - Added extra sound.
*
*   Hero based on Chucky for respawn, Agent for teleport, and Kamikaze for blowing up.
*/


#include <amxmod>
#include <Vexd_Utilities>
#include <superheromod>

new g_heroName[]="Phoenix"
new bool:g_hasPhoenix[SH_MAXSLOTS+1]
new bool:g_phoenixPowerUsed[SH_MAXSLOTS+1]
new bool:g_betweenRounds
new g_userTeam[SH_MAXSLOTS+1]
new g_savedOrigin[SH_MAXSLOTS+1][3]
new g_lastPosition[SH_MAXSLOTS+1][3]
new g_spriteSmoke, g_spriteRing, g_spriteExplosion
//----------------------------------------------------------------------------------------------
public plugin_init()
{
	// Plugin Info
	register_plugin("SUPERHERO Phoenix", "1.1", "[FTW]-S.W.A.T / vittu")

	// DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
	register_cvar("phoenix_level", "8")
	register_cvar("phoenix_cooldown", "120")
	register_cvar("phoenix_radius", "375")
	register_cvar("phoenix_maxdamage", "90")

	// FIRE THE EVENT TO CREATE THIS SUPERHERO!
	shCreateHero(g_heroName, "Re-Birth", "As the Phoenix you shall Rise Again from your Burning Ashes.", false, "phoenix_level")

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

	// DEATH EVENT
	register_event("DeathMsg", "phoenix_death", "a")

	// ROUND EVENTS
	register_logevent("round_start", 2, "1=Round_Start")
	register_logevent("round_end", 2, "1=Round_End")
	register_logevent("round_end", 2, "1&Restart_Round_")
}
//----------------------------------------------------------------------------------------------
public plugin_precache()
{
	g_spriteSmoke = precache_model("sprites/steam1.spr")
	g_spriteRing = precache_model("sprites/white.spr")
	g_spriteExplosion = precache_model("sprites/explode1.spr")
	precache_sound("ambience/port_suckin1.wav")
	precache_sound("ambience/3dmeagle.wav")
}
//----------------------------------------------------------------------------------------------
public phoenix_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 the hero
	read_argv(2,temp,5)
	new hasPowers = str_to_num(temp)

	g_hasPhoenix[id] = (hasPowers != 0)
}
//----------------------------------------------------------------------------------------------
public phoenix_death()
{
	if ( !shModActive() || g_betweenRounds ) return

	new id = read_data(2)

	if ( !is_user_connected(id) || !g_hasPhoenix[id] ) return

	g_userTeam[id] = get_user_team(id)

	// Save users origin on death
	get_user_origin(id, g_savedOrigin[id])
	g_savedOrigin[id][2] += 8

	// Look for self to raise from dead
	if ( !is_user_alive(id) && !g_phoenixPowerUsed[id] ) {
		new parm[1]
		parm[0] = id
		// Respawn it faster then Zues, let this power be used before Zues's
		// never set higher then 1.9 or lower then 0.5
		set_task(0.6, "phoenix_respawn", 0, parm, 1)
	}
}
//----------------------------------------------------------------------------------------------
public phoenix_respawn(parm[])
{
	new id = parm[0]

	if ( !is_user_connected(id) || is_user_alive(id) ) return
	if ( g_phoenixPowerUsed[id] || g_betweenRounds ) return
	if ( g_userTeam[id] != get_user_team(id) ) return //prevents respawning spectators

	emit_sound(id, CHAN_STATIC, "ambience/port_suckin1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)

	client_print(id, print_chat, "[SH](Phoenix) You used the Phoenix power to Rise Again from the Ashes!")

	// Double spawn prevents the no HUD glitch
	user_spawn(id)
	user_spawn(id)

	// Respawned by Phoenix, it's ok to set cooldown now.
	new Float:phoenixCooldown = get_cvar_float("phoenix_cooldown")
	if ( phoenixCooldown > 0.0 ) {
		set_task(phoenixCooldown, "enable_phoenix", id)
		g_phoenixPowerUsed[id] = true
	}

	emit_sound(id, CHAN_STATIC, "ambience/3dmeagle.wav", 0.6, ATTN_NORM, 0, PITCH_NORM)

	shGlow(id, 248, 20, 25)
	set_task(3.0, "phoenix_unglow", 0, parm, 1)
	set_task(1.0, "phoenix_teamcheck", 0, parm, 1)

	set_user_health(id, 75)
	phoenix_teleport(id)
}
//----------------------------------------------------------------------------------------------
public phoenix_unglow(parm[])
{
	new id = parm[0]
	shUnglow(id)
}
//----------------------------------------------------------------------------------------------
public phoenix_teamcheck(parm[])
{
	new id = parm[0]

	if ( g_userTeam[id] != get_user_team(id) ) {
		client_print(id, print_chat, "[SH](Phoenix) You changed teams and used Phoenix Respawn, now you shall die")

		user_kill(id, 1)

		// Stop Phoenix from respawning until round ends
		remove_task(id)
		g_phoenixPowerUsed[id] = false
	}
}
//----------------------------------------------------------------------------------------------
public round_start()
{
	g_betweenRounds = false
}
//----------------------------------------------------------------------------------------------
public round_end()
{
	if ( !shModActive() ) return

	g_betweenRounds = true

	// Reset the cooldown on round end, to start fresh for a new round
	for (new id = 1; id <= SH_MAXSLOTS; id++) {
		if ( g_hasPhoenix[id] ) {
			// Reset the cooldown on round end, to start fresh for a new round
			remove_task(id)
			g_phoenixPowerUsed[id] = false
		}
	}
}
//----------------------------------------------------------------------------------------------
public enable_phoenix(id)
{
	g_phoenixPowerUsed[id] = false
}
//----------------------------------------------------------------------------------------------
public phoenix_teleport(id)
{
	// Teleport the player
	set_user_origin(id, g_savedOrigin[id])

	// Teleport Effects
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(11)					// TE_TELEPORT
	write_coord(g_savedOrigin[id][0])	// start position
	write_coord(g_savedOrigin[id][1])
	write_coord(g_savedOrigin[id][2])
	message_end()

	positionChangeTimer(id)

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

	get_user_origin(id, g_lastPosition[id])

	new Float:velocity[3]
	Entvars_Get_Vector(id, EV_VEC_velocity, velocity)

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

	set_task(0.4, "positionChangeCheck", id+100)
}
//----------------------------------------------------------------------------------------------
public positionChangeCheck(id)
{
	id -= 100

	if ( !is_user_alive(id) ) return

	new origin[3]
	get_user_origin(id, origin)

	// Kill this player if Stuck in Wall!
	if ( g_lastPosition[id][0] == origin[0] && g_lastPosition[id][1] == origin[1] && g_lastPosition[id][2] == origin[2] && is_user_alive(id) ) {
		user_kill(id, 1)
		client_print(id, print_chat, "[SH](Phoenix) You were killed for being stuck in a wall")
	}
}
//----------------------------------------------------------------------------------------------
public BlowUp(id)
{
	new Float:dRatio, damage, distanceBetween
	new origin[3], origin1[3], name[32]
	new dmgRadius = get_cvar_num("phoenix_radius")
	new maxDamage = get_cvar_num("phoenix_maxdamage")
	new FFOn = get_cvar_num("mp_friendlyfire")

	get_user_origin(id, origin)

	get_user_name(id, name, 31)

	// blowup even if dead
	explode_effect(origin, dmgRadius)

	for (new a = 1; a <= SH_MAXSLOTS; a++) {
		if ( is_user_alive(a) && a != id && (get_user_team(id) != get_user_team(a) || FFOn) ) {

			get_user_origin(a, origin1)

			distanceBetween = get_distance(origin, origin1)

			if ( distanceBetween < dmgRadius ) {
				set_hudmessage(248, 20, 25, 0.05, 0.65, 2, 0.02, 3.0, 0.01, 0.1, 85)
				show_hudmessage(a, "%s was Re-Born using the power of the Phoenix!", name)

				dRatio = float(distanceBetween) / float(dmgRadius)
				damage = maxDamage - floatround(maxDamage * dRatio)
				shExtraDamage(a, id, damage, "Phoenix Re-Birth")
			}
		}
	}
}
//----------------------------------------------------------------------------------------------
public explode_effect(vec1[3], dmgRadius)
{
	// Ring
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY, vec1)
	write_byte(21)				// TE_BEAMCYLINDER
	write_coord(vec1[0])		// center position
	write_coord(vec1[1])
	write_coord(vec1[2] + 10)
	write_coord(vec1[0])		// axis and radius
	write_coord(vec1[1])
	write_coord(vec1[2] + floatround(dmgRadius*3.5))
	write_short(g_spriteRing)	// sprite index
	write_byte(0)		// starting frame
	write_byte(0)		// frame rate in 0.1's
	write_byte(2)		// life in 0.1's
	write_byte(20)		// line width in 0.1's
	write_byte(0)		// noise amplitude in 0.01's
	write_byte(248)	//colour
	write_byte(20)
	write_byte(25)
	write_byte(255)	// brightness
	write_byte(0)		// scroll speed in 0.1's
	message_end()

	// Explosion2
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(12)			// TE_EXPLOSION2
	write_coord(vec1[0])	// start position
	write_coord(vec1[1])
	write_coord(vec1[2])
	write_byte(188)	// starting color
	write_byte(10)		// num colors
	message_end()

	// Explosion
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY, vec1)
	write_byte(3)			// TE_EXPLOSION
	write_coord(vec1[0])	// start position 
	write_coord(vec1[1])
	write_coord(vec1[2])
	write_short(g_spriteExplosion)	// sprite index
	write_byte(dmgRadius/9)	// scale in 0.1's 
	write_byte(10)			// framerate
	write_byte(0)			// flags
	message_end()

	// Smoke
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY, vec1)
	write_byte(5)			// TE_SMOKE
	write_coord(vec1[0])	// start position
	write_coord(vec1[1])
	write_coord(vec1[2])
	write_short(g_spriteSmoke)	// sprite index
	write_byte(dmgRadius/14)	// scale in 0.1's
	write_byte(10)			// framerate
	message_end()
}
//----------------------------------------------------------------------------------------------