//GOTEN! - from Dragonball Z/GT. 2nd son of Gohan, he mispronounces Kamehameha as Kamekameha.

/* CVARS - copy and paste to shconfig.cfg

//Goten
goten_level 6
goten_health 400			//Default HP 400
goten_armor 100			//Default AP 100
goten_cooldown 30			//Cooldown timer between shots in seconds
goten_maxdamage 75			//Max Damage from blast
goten_radius 100			//Radius of blast
goten_blast_decals 1 		//Show the burn decals on the walls

*/

/*
* v1.3 - vittu - 6/19/05
*      - Minor code clean up.
*      - Renamed extra sprites for future use in other heroes.
*
* v1.2 - vittu - 3/5/05
*      - removed 2 lines of unused code, left over from testing
*      - fixed bug that caused weapon change on key up when in
*         cooldown if different weapon in hand then one during power use
*
* v1.1 - vittu - 2/23/05
*      - removed unused and useless code, and an overall clean up
*      - made user switch to knife so they cannot shoot while using power
*      - changed damage radius calculation to get proper damage
*      - changed damage taken by self to be reduced to half the ammout
*      - overall improvement to effects, new sprites added
*      - added other small checks
*
*   Extra sprites used from Earth's Special Forces a HL mod - http://www.esforces.com/
*/

#include <amxmod>
#include <superheromod>

new gHeroName[]="Goten"
new bool:gHasGotenPower[SH_MAXSLOTS+1]
new bool:gBlockKeyup[SH_MAXSLOTS+1]
new gLastWeapon[SH_MAXSLOTS+1]
new Beam, Explosion, Smoke
static const burn_decal[3] = {28, 29, 30}
static const burn_decal_big[3] = {46, 47, 48}
//----------------------------------------------------------------------------------------------
public plugin_init()
{
	// Plugin Info
	register_plugin("SUPERHERO Goten", "1.3", "buttface / vittu")

	// DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
	register_cvar("goten_level", "6")
	register_cvar("goten_health", "400")
	register_cvar("goten_armor", "100")
	register_cvar("goten_cooldown", "30")
	register_cvar("goten_maxdamage", "75")
	register_cvar("goten_radius", "100")
	register_cvar("goten_blast_decals", "1")

	// FIRE THE EVENT TO CREATE THIS SUPERHERO!
	shCreateHero(gHeroName, "Kamekameha!", "Fire Goten's Kamehameha Wave on Keydown.", true, "goten_level")

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

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

	//KEY UP
	register_srvcmd("goten_ku", "goten_ku")
	shRegKeyUp(gHeroName, "goten_ku")

	register_event("ResetHUD", "newSpawn", "b")

	// Let Server know about Goten's Variables
	shSetMaxHealth(gHeroName, "goten_health" )
	shSetMaxArmor(gHeroName, "goten_armor" )
}
//----------------------------------------------------------------------------------------------
public plugin_precache()
{
	Beam = precache_model("sprites/shmod/esf_trail_blue.spr")
	Explosion = precache_model("sprites/shmod/esf_exp_blue.spr")
	Smoke = precache_model("sprites/wall_puff4.spr")
}
//----------------------------------------------------------------------------------------------
public goten_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)

	//This gets run if they had the power but don't anymore
	if ( !hasPowers && gHasGotenPower[id] && is_user_alive(id) ) {
		shRemHealthPower(id)
		shRemArmorPower(id)
	}

	//Sets this variable to the current status
	gHasGotenPower[id] = (hasPowers != 0)
}
//----------------------------------------------------------------------------------------------
public newSpawn(id)
{
	gPlayerUltimateUsed[id] = false
}
//----------------------------------------------------------------------------------------------
// RESPOND TO KEYDOWN
public goten_kd()
{
	if ( !hasRoundStarted() ) return

	// First Argument is an id
	new temp[6]
	read_argv(1,temp,5)
	new id = str_to_num(temp)

	if ( !is_user_alive(id) || !gHasGotenPower[id] ) return

	if ( gPlayerUltimateUsed[id] ) {
		playSoundDenySelect(id)
		gBlockKeyup[id] = true
		return
	}

	gBlockKeyup[id] = false

	// Remember this weapon...
	new clip, ammo, weaponID = get_user_weapon(id, clip, ammo)
	gLastWeapon[id] = weaponID

	// switch to knife
	engclient_cmd(id, "weapon_knife")

	fire_wave(id)

	if (get_cvar_float("goten_cooldown") > 0.0) ultimateTimer(id, get_cvar_float("goten_cooldown"))
}
//----------------------------------------------------------------------------------------------
public goten_ku()
{
	if ( !hasRoundStarted() ) return

	// First Argument is an id
	new temp[6]
	read_argv(1,temp,5)
	new id = str_to_num(temp)

	if ( !is_user_alive(id) || !gHasGotenPower[id] || gBlockKeyup[id] ) return

	// Switch back to previous weapon...
	// Use keyup since if called too fast CurWeapon functions may be bypassed
	if (gLastWeapon[id] != CSW_KNIFE) shSwitchWeaponID(id, gLastWeapon[id])
}
//----------------------------------------------------------------------------------------------
public fire_wave(id)
{
	new aimvec[3]
	new FFOn = get_cvar_num("mp_friendlyfire")

	new Float:dRatio, damage, distanceBetween
	new damradius = get_cvar_num("goten_radius")
	new maxdamage = get_cvar_num("goten_maxdamage")

	if( !is_user_alive(id) ) return

	get_user_origin(id, aimvec, 3)
	beam_effects(id, aimvec, damradius)

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

			new origin[3]
			get_user_origin(vic, origin)
			distanceBetween = get_distance(aimvec, origin)

			if ( distanceBetween < damradius ) {

				dRatio = float(distanceBetween) / float(damradius)
				damage = maxdamage - floatround(maxdamage * dRatio)

				// Lessen damage taken by self
				if (vic == id) damage = floatround(damage / 2.0)

				shExtraDamage(vic, id, damage, "Kamehameha")
			}
		}
	}
}
//----------------------------------------------------------------------------------------------
public beam_effects(id, aimvec[3], damradius)
{
	new decal_id, beamWidth

	//Change sprite size according to blast radius
	new blastSize = floatround(damradius / 12.0)

	//Change burn decal and beam width size according to blast size
	if (blastSize <= 18) {
		decal_id = burn_decal[random_num(0, 2)]
		beamWidth = 50
	}
	else {
		decal_id = burn_decal_big[random_num(0, 2)]
		beamWidth = 75
	}

	//Beam
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(1)			//TE_BEAMENTPOINTS
	write_short(id)		//ent
	write_coord(aimvec[0])	//position
	write_coord(aimvec[1])
	write_coord(aimvec[2])
	write_short(Beam)	// sprite index
	write_byte(0)		// start frame
	write_byte(35)		// framerate
	write_byte(4)		// life
	write_byte(beamWidth)	// width
	write_byte(0)		// noise
	write_byte(255)	// red (rgb color)
	write_byte(255)	// green (rgb color)
	write_byte(255)	// blue (rgb color)
	write_byte(255)	// brightness
	write_byte(20)		// speed
	message_end()

	//Glow Sprite (explosion)
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(23)			//TE_GLOWSPRITE
	write_coord(aimvec[0])	//position
	write_coord(aimvec[1])
	write_coord(aimvec[2])
	write_short(Explosion)	// model
	write_byte(001)		// life 0.x sec (01 min limit?)
	write_byte(blastSize)	// size
	write_byte(255)		// brightness
	message_end()

	//Explosion (smoke, sound/effects)
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(3)			//TE_EXPLOSION
	write_coord(aimvec[0])	//pos
	write_coord(aimvec[1])
	write_coord(aimvec[2])
	write_short(Smoke)		// model
	write_byte(blastSize+5)	// scale in 0.1's
	write_byte(20)			// framerate
	write_byte(10)			// flags
	message_end()

	//Burn Decals
	if(get_cvar_num("goten_blast_decals") == 1) {
		message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
		write_byte(109)		//TE_GUNSHOTDECAL
		write_coord(aimvec[0])	//pos
		write_coord(aimvec[1])
		write_coord(aimvec[2])
		write_short(0)			//?
		write_byte(decal_id)	//decal
		message_end()
	}
}
//----------------------------------------------------------------------------------------------