// CHUCKY! - From the Child's Play movie series. "Hi. I'm Chucky. Wanna play?"

/* CVARS copy and paste to shconfig.cfg

//Chucky
chucky_level 10
chucky_cooldown 600      //Amount of time before next available respawn
chucky_knifemult 2.50    //Amount mutiplied to damage when knifing
chucky_knifespeed 720    //User speed when knife is out

*/

/*
* v1.4 - vittu - 6/27/06
*      - Updated to amxmodx only, requires amxx 1.70 or higher.
*      - Minor code clean up.
*      - Fixed possible issue with first connect, no respawn possiblity.
*      - vittu - 12/27/06
*      - Added check when respawning if pb_autokill is set to 1.
*      - Added optional model define for those who don't want the model.
*
* v1.3 - vittu - 6/14/05
*      - Minor code clean up.
*      - Cleaned up Respawn blocks and fixed possible bug with
*          no respawn on first connect.
*
* v1.2 - vittu - 3/8/05
*      - fixed small bug I introduced, with team change checking.
*      - optimized some of the code.
*
* v1.1 - vittu - 2/18/05
*      - removed useless code.
*      - removed useless model, found p_ model but wasn't worth adding.
*      - added self contained cooldown to avoid being reset by other
*         respawning heroes for next version of sh mod.
*      - added extra sound.
*      - added lots and lots and lots of checks against exploits.
*
*   Hero Created by LiToViEtBoI
*   Weapon model by TriggerJunky
*/

//---------- User Changeable Defines --------//


// Note: If you change anything from default setting you must recompile the plugin

// 0 = don't use custom KNIFE model, 1 = use custom KNIFE model [Default 1]
#define USE_MODEL 1


//------- Do not edit below this point ------//


#include <amxmodx>
#include <cstrike>
#include <csx>
#include <superheromod>

#if USE_MODEL
	#include <fakemeta>
#endif


// GLOBAL VARIABLES
new HeroName[] = "Chucky"
new bool:HasChucky[SH_MAXSLOTS+1]
new bool:ChuckyPowerUsed[SH_MAXSLOTS+1]
new CsTeams:UserTeam[SH_MAXSLOTS+1]
new bool:BetweenRounds
new bool:BombPlanted
new CvarCooldown, CvarKnifeMult
//----------------------------------------------------------------------------------------------
public plugin_init()
{
	// Plugin Info
	register_plugin("SUPERHERO Chucky", "1.4", "LiToViEtBoI/vittu")

	// DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
	register_cvar("chucky_level", "10")
	register_cvar("chucky_knifespeed", "720")
	CvarKnifeMult = register_cvar("chucky_knifemult", "2.5")
	CvarCooldown = register_cvar("chucky_cooldown", "600")

	// FIRE THE EVENT TO CREATE THIS SUPERHERO!
	shCreateHero(HeroName, "Voodoo Powers", "Rise again from the dead. Get a Bloody Knife that does more damage, which you are faster with.", false, "chucky_level")

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

	// EVENTS
	#if USE_MODEL
		register_event("CurWeapon", "weapon_change", "be", "1=1")
	#endif
	register_event("Damage", "chucky_damage", "b", "2!0")
	register_event("DeathMsg", "chucky_death", "a")

	// LOG 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_")

	// Let Server know about Chucky's Variables
	shSetMaxSpeed(HeroName, "chucky_knifespeed", "[29]")
}
//----------------------------------------------------------------------------------------------
public plugin_precache()
{
	#if USE_MODEL
		precache_model("models/shmod/chucky_knife.mdl")
	#endif

	precache_sound("nihilanth/nil_comes.wav")
	precache_sound("ambience/port_suckin1.wav")
}
//----------------------------------------------------------------------------------------------
public chucky_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)

	switch(hasPowers)
	{
		case true:
		{
			HasChucky[id] = true

			#if USE_MODEL
				switch_model(id)
			#endif
		}

		case false:
		{
			// This gets run if they had the power but don't anymore
			if ( is_user_alive(id) && HasChucky[id] )
				shRemSpeedPower(id)

			HasChucky[id] = false
		}
	}
}
//----------------------------------------------------------------------------------------------
#if USE_MODEL
public weapon_change(id)
{
	if ( !shModActive() || !HasChucky[id] )
		return

	new wpnid = read_data(2)

	if ( wpnid == CSW_KNIFE )
		switch_model(id)
}
//----------------------------------------------------------------------------------------------
switch_model(id)
{
	if ( !shModActive() || !is_user_alive(id) || !HasChucky[id] )
		return

	// If user is holding a shield do not change model, since we don't have one with a shield
	new viewModel[32]
	pev(id, pev_viewmodel, viewModel, 31)
	if ( containi(viewModel, "v_shield_") != -1 )
		return

	new clip, ammo, wpnid = get_user_weapon(id, clip, ammo)

	// Weapon Model change thanks to [CCC]Taz-Devil
	if ( wpnid == CSW_KNIFE )
		set_pev(id, pev_viewmodel2, "models/shmod/chucky_knife.mdl")
}
#endif
//----------------------------------------------------------------------------------------------
public chucky_damage(id)
{
	if ( !shModActive() || !is_user_alive(id) )
		return

	new weapon, bodypart, attacker = get_user_attacker(id, weapon, bodypart)

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

	if ( HasChucky[attacker] && weapon == CSW_KNIFE && is_user_alive(id) )
	{
		new damage = read_data(2)
		new headshot = bodypart == 1 ? 1 : 0

		// Do extra damage
		new extraDamage = floatround(damage * get_pcvar_float(CvarKnifeMult) - damage)
		if ( extraDamage > 0 )
			shExtraDamage(id, attacker, extraDamage, "knife", headshot)
	}
}
//----------------------------------------------------------------------------------------------
public chucky_death()
{
	new id = read_data(2)

	if ( !shModActive() || BetweenRounds || !is_user_connected(id) || !HasChucky[id] )
		return

	// What is the users team when he dies?
	UserTeam[id] = cs_get_user_team(id)

	// Look for self to raise from dead
	if ( !is_user_alive(id) && !ChuckyPowerUsed[id] )
	{
		// Chucky will raise self from dead
		new parm[1]
		parm[0] = id
		// Respawn him 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.5, "chucky_respawn", 0, parm, 1)
	}
}
//----------------------------------------------------------------------------------------------
public chucky_respawn(parm[])
{
	new id = parm[0]

	if ( !shModActive() || !is_user_connected(id) || is_user_alive(id) ) return
	if ( ChuckyPowerUsed[id] || BetweenRounds ) return

	// Check prevents respawning spectators, cs_get_user_team prevents team change respawning
	if ( UserTeam[id] != cs_get_user_team(id) ) return

	// Prevent respawn if Pod-Bot kills all bots when no players are alive and bomb has not been planted
	if ( get_cvar_num("pb_autokill") && !BombPlanted )
	{
		new players[SH_MAXSLOTS], pnum

		// Check for any alive non-bots 
		get_players(players, pnum, "ac")

		// if no alive non-bots do not respawn
		if ( !pnum )
			return
	}

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

	client_print(id, print_chat, "[SH](%s) You used %s's Voodoo power to come back to life!", HeroName, HeroName)

	// Double spawn prevents the no HUD glitch
	// This should eventually be changed to use a better method
	spawn(id)
	spawn(id)

	// Respawned by Chucky, it's ok to set cooldown now.
	new Float:chuckyCooldown = get_pcvar_float(CvarCooldown)
	if ( chuckyCooldown > 0.0 )
	{
		set_task(chuckyCooldown, "enable_chucky", id)
		ChuckyPowerUsed[id] = true
	}

	emit_sound(id, CHAN_STATIC, "nihilanth/nil_comes.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)

	shGlow(id, 75, 75, 255)
	set_task(3.0, "chucky_unglow", 0, parm, 1)
	set_task(1.0, "chucky_teamcheck", 0, parm, 1)
}
//----------------------------------------------------------------------------------------------
public chucky_unglow(parm[])
{
	new id = parm[0]
	
	if ( !is_user_connected(id) )
		return

	shUnglow(id)
}
//----------------------------------------------------------------------------------------------
// This function should now be useless because of using cs_get_user_team rather than get_user_team
public chucky_teamcheck(parm[])
{
	new id = parm[0]

	if ( !is_user_connected(id) )
		return

	if ( UserTeam[id] != cs_get_user_team(id) )
	{
		client_print(id, print_chat, "[SH](%s) You changed teams and used %s Respawn, now you shall die", HeroName, HeroName)

		user_kill(id, 1)

		// Stop Chucky from respawning until round ends
		remove_task(id)
		ChuckyPowerUsed[id] = true
	}
}
//----------------------------------------------------------------------------------------------
public bomb_planted(id)
{
	BombPlanted = true
}
//----------------------------------------------------------------------------------------------
public round_start()
{
	BetweenRounds = false
	BombPlanted = false
}
//----------------------------------------------------------------------------------------------
public round_end()
{
	BetweenRounds = true
	BombPlanted = false

	if ( !shModActive() )
		return

	// Reset the cooldown on round end, to start fresh for a new round
	for ( new id = 1; id <= SH_MAXSLOTS; id++ )
	{
		if ( HasChucky[id] )
		{
			remove_task(id)
			ChuckyPowerUsed[id] = false
		}
	}
}
//----------------------------------------------------------------------------------------------
public enable_chucky(id)
{
	ChuckyPowerUsed[id] = false
}
//----------------------------------------------------------------------------------------------
public client_connect(id)
{
	// Yeah don't want any left over residuals
	remove_task(id)

	// Incase variables are stale reset them
	HasChucky[id] = false
	ChuckyPowerUsed[id] = false
}
//----------------------------------------------------------------------------------------------