// HUMAN TORCH! - BASED ON FlameThrower by Ludwig

/* CVARS - copy and paste to shconfig.cfg

//Human Torch
htorch_level 0
htorch_armorcost 15			//How much amour each flame uses
htorch_numburns 5			//How many time to burn the victim
htorch_burndamage 10		//How much damage each burn does

*/

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

// GLOBAL VARIABLES
new gHeroName[]="Human Torch"
new bool:gHasHTorchPower[SH_MAXSLOTS+1]
new gIsBurning[SH_MAXSLOTS+1]
new gSpriteSmoke, gSpriteFire, gSpriteBurning
//----------------------------------------------------------------------------------------------
public plugin_init()
{
	// Plugin Info
	register_plugin("SUPERHERO Human Torch","1.18","{HOJ} Batman/JTP10181")

	// DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
	register_cvar("htorch_level", "0" )
	register_cvar("htorch_armorcost", "15" )
	register_cvar("htorch_numburns", "5" )
	register_cvar("htorch_burndamage", "10" )

	// FIRE THE EVENT TO CREATE THIS SUPERHERO!
	shCreateHero(gHeroName, "Flame Thrower", "Get a Flame Thrower to use on enemies", true, "htorch_level" )

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

	register_srvcmd("htorch_kd", "htorch_kd")
	shRegKeyDown(gHeroName, "htorch_kd")

	register_event("ResetHUD","newRound","b")
}
//----------------------------------------------------------------------------------------------
public plugin_precache()
{
	gSpriteSmoke   = precache_model("sprites/steam1.spr")
	gSpriteFire    = precache_model("sprites/explode1.spr")
	gSpriteBurning = precache_model("sprites/xfire.spr")
	precache_sound("ambience/burning1.wav")
	precache_sound("ambience/flameburst1.wav")
	precache_sound("scientist/c1a0_sci_catscream.wav")
	precache_sound("vox/_period.wav")
}
//----------------------------------------------------------------------------------------------
public htorch_init()
{
	// First Argument is an id
	new temp[6]
	read_argv(1,temp,5)
	new id=str_to_num(temp)
	read_argv(2,temp,5)
	new hasPowers = str_to_num(temp)  // !0 = has human torch power

	gHasHTorchPower[id] = (hasPowers!=0)
}
//----------------------------------------------------------------------------------------------
public newRound(id)
{
	gIsBurning[id] = 0
	stopFireSound(id)
}
//----------------------------------------------------------------------------------------------
// Ludwigs flame thrower
public htorch_kd()
{
	if ( !hasRoundStarted() ) return PLUGIN_HANDLED

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

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

	if( Entvars_Get_Int( id, EV_INT_waterlevel ) == 3 ) {
		client_print(id,print_chat,"[SH] You cannot use the Flame Thrower while underwater")
		playSoundDenySelect(id)
		return PLUGIN_HANDLED
	}

	new fl_cost = get_cvar_num("htorch_armorcost")
	new armr = get_user_armor(id)

	if(armr < fl_cost) {
		client_print(id,print_chat,"%s blasts cost %d armor points each", gHeroName, fl_cost)
		playSoundDenySelect(id)
		return PLUGIN_HANDLED
	}

	set_user_armor(id,armr - fl_cost)

	emit_sound(id, CHAN_WEAPON, "ambience/flameburst1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
	new vec[3]
	new aimvec[3]
	new velocityvec[3]
	new length
	new speed = 10
	get_user_origin(id,vec)
	get_user_origin(id,aimvec,2)
	new dist = get_distance(vec,aimvec)

	new speed1 = 160
	new speed2 = 350
	new radius = 105

	if(dist < 50) {
		radius = 0
		speed = 5
	}
	else if(dist < 150) {
		speed1 = speed2 = 1
		speed = 5
		radius = 50
	}
	else if(dist < 200) {
		speed1 = speed2 = 1
		speed = 5
		radius = 90
	}
	else if(dist < 250) {
		speed1 = speed2 = 90
		speed = 6
		radius = 90
	}
	else if(dist < 300) {
		speed1 = speed2 = 140
		speed = 7
	}
	else if(dist < 350) {
		speed1 = speed2 = 190
		speed = 7
	}
	else if(dist < 400) {
		speed1 = 150
		speed2 = 240
		speed = 8
	}
	else if(dist < 450) {
		speed1 = 150
		speed2 = 290
		speed = 8
	}
	else if(dist < 500) {
		speed1 = 180
		speed2 = 340
		speed = 9
	}

	velocityvec[0]=aimvec[0]-vec[0]
	velocityvec[1]=aimvec[1]-vec[1]
	velocityvec[2]=aimvec[2]-vec[2]
	length = sqrt(velocityvec[0]*velocityvec[0]+velocityvec[1]*velocityvec[1]+velocityvec[2]*velocityvec[2])
	velocityvec[0]=velocityvec[0]*speed/length
	velocityvec[1]=velocityvec[1]*speed/length
	velocityvec[2]=velocityvec[2]*speed/length

	new args[8]
	args[0] = vec[0]
	args[1] = vec[1]
	args[2] = vec[2]
	args[3] = velocityvec[0]
	args[4] = velocityvec[1]
	args[5] = velocityvec[2]
	set_task(0.1,"te_spray",0,args,8,"a",2)
	check_burnzone(id,vec,aimvec,speed1,speed2,radius)

	return PLUGIN_HANDLED
}
//----------------------------------------------------------------------------------------------
public te_spray(args[]){

	//TE_SPRAY
	message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
	write_byte (120) // Throws a shower of sprites or models
	write_coord(args[0]) // start pos
	write_coord(args[1])
	write_coord(args[2])
	write_coord(args[3]) // velocity
	write_coord(args[4])
	write_coord(args[5])
	write_short (gSpriteFire) // spr
	write_byte (8) // count
	write_byte (70) // speed
	write_byte (100) //(noise)
	write_byte (5) // (rendermode)
	message_end()
}
//----------------------------------------------------------------------------------------------
check_burnzone(id,vec[],aimvec[],speed1,speed2,radius)
{
	new tbody,tid
	get_user_aiming(id,tid,tbody,550)

	if (tid <= 0 || tid > SH_MAXSLOTS) return

	if (get_cvar_num("mp_friendlyfire") == 1) {
		burn_victim(tid,id)
	}
	else if (get_user_team(id) != get_user_team(tid)) {
		burn_victim(tid,id)
	}
	new burnvec1[3],burnvec2[3],length1

	burnvec1[0]=aimvec[0]-vec[0]
	burnvec1[1]=aimvec[1]-vec[1]
	burnvec1[2]=aimvec[2]-vec[2]

	length1=sqrt(burnvec1[0]*burnvec1[0]+burnvec1[1]*burnvec1[1]+burnvec1[2]*burnvec1[2])
	burnvec2[0]=burnvec1[0]*speed2/length1
	burnvec2[1]=burnvec1[1]*speed2/length1
	burnvec2[2]=burnvec1[2]*speed2/length1
	burnvec1[0]=burnvec1[0]*speed1/length1
	burnvec1[1]=burnvec1[1]*speed1/length1
	burnvec1[2]=burnvec1[2]*speed1/length1
	burnvec1[0] += vec[0]
	burnvec1[1] += vec[1]
	burnvec1[2] += vec[2]
	burnvec2[0] += vec[0]
	burnvec2[1] += vec[1]
	burnvec2[2] += vec[2]

	new origin[3]
	for (new i=1; i <= SH_MAXSLOTS; i++) {
		if( is_user_alive(i) && i != id && ( get_cvar_num("mp_friendly_fire") || get_user_team(id) != get_user_team(i) ) ) {
			get_user_origin(i,origin)
			if(get_distance(origin,burnvec1) < radius) {
				burn_victim(i,id)
			}
			else if(get_distance(origin,burnvec2) < radius) {
				burn_victim(i,id)
			}

		}
	}
}
//----------------------------------------------------------------------------------------------
public burn_victim(id,killer)
{
	if( Entvars_Get_Int( id, EV_INT_waterlevel ) == 3 ) return
	if(gIsBurning[id] == 1) return

	gIsBurning[id] = 1

	emit_sound(id, CHAN_ITEM, "ambience/burning1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)

	new args[3]
	args[0] = id
	args[1] = killer
	set_task(0.3,"on_fire",451,args,3,"a", get_cvar_num("htorch_numburns") )
	set_task(0.7,"fire_scream",0,args,3)
	set_task(5.5,"stopFireSound",id)

}
//----------------------------------------------------------------------------------------------
public on_fire(args[])
{
	new id = args[0]
	new killer = args[1]

	if( !is_user_connected(id) || !is_user_alive(id) ) {
		gIsBurning[id] = 0
		return
	}
	if( Entvars_Get_Int( id, EV_INT_waterlevel ) == 3 ) {
		gIsBurning[id] = 0
		return
	}
	if (!gIsBurning[id]) return

	new rx,ry,rz,forigin[3]
	rx = random_num(-30,30)
	ry = random_num(-30,30)
	rz = random_num(-30,30)
	get_user_origin(id,forigin)

	//TE_SPRITE - additive sprite, plays 1 cycle
	message_begin( MSG_BROADCAST,SVC_TEMPENTITY)
	write_byte( 17 )
	write_coord(forigin[0]+rx) // coord, coord, coord (position)
	write_coord(forigin[1]+ry)
	write_coord(forigin[2]+10+rz)
	write_short( gSpriteBurning ) // short (sprite index)
	write_byte( 30 ) // byte (scale in 0.1's)
	write_byte( 200 ) // byte (brightness)
	message_end()

	//Smoke
	message_begin( MSG_BROADCAST,SVC_TEMPENTITY)
	write_byte( 5 )
	write_coord(forigin[0]+(rx*2)) // coord, coord, coord (position)
	write_coord(forigin[1]+(ry*2))
	write_coord(forigin[2]+100+(rz*2))
	write_short( gSpriteSmoke )// short (sprite index)
	write_byte( 60 ) // byte (scale in 0.1's)
	write_byte( 15 ) // byte (framerate)
	message_end()

	new health = get_user_health(id)
	new damage = get_cvar_num("htorch_burndamage")

	//Prevents the shExtraDamage from saying you attacked a teammate for every cycle of the loop
	if(health - damage  <= 0) {
		shExtraDamage(id, killer, damage, "Human Torch" )
	}
	else {
		set_user_health(id,health - damage)
	}
}
//----------------------------------------------------------------------------------------------
public fire_scream(args[])
{
	emit_sound(args[0], CHAN_AUTO, "scientist/c1a0_sci_catscream.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
	return PLUGIN_CONTINUE
}
//----------------------------------------------------------------------------------------------
public stopFireSound(id)
{
	new sndStop = (1<<5)
	gIsBurning[id] = 0
	emit_sound(id, CHAN_ITEM, "ambience/burning1.wav", 1.0, ATTN_NORM, sndStop, PITCH_NORM)
}
//----------------------------------------------------------------------------------------------
public client_connect(id)
{
	gHasHTorchPower[id] = false
}
//----------------------------------------------------------------------------------------------