// FARTMAN! - superhero from The Howard Stern show.

/* CVARS - copy and paste to shconfig.cfg

//Fartman
fartman_level 7
fartman_gasdmg 10		//Amount of damage caused (Default 10)
fartman_gasradius 200		//Damage radius from smoke grenade to player, 200-250 is the normal smoke radius (Default 200)
fartman_gasfreq 2.0		//Every # of seconds gas damage is caused again (Default 2.0)
fartman_grenadetimer 10.0	//# of seconds until new smoke grenade is given (Default 10.0)

*/

/*
* v1.5 - vittu - 9/26/06
*      - Updated to amxmodx only, requires fakemeta and amxx 1.70 or higher.
*      - Changed sound of smoke nade going off.
*      - Seperated out gasing by nade starting from smoke release.
*      - Changed timer cvar name to represent frequencey and default lowered.
*      - Improved fart sound a little.
*
* v1.4 - vittu - 7/3/05
*      - Fixed crash to AMX caused by the previous update, since
*          AMX can't register a MSG_ONE_UNRELIABLE message.
*
* v1.3 - vittu - 6/27/05
*      - Minor update for FF servers, prevents the shExtraDamage
*          from saying you attacked a teammate for every cycle.
*
* v1.2 - vittu - 6/19/05
*      - Minor code clean up.
*      - Stopped sound from playing on a ResetHud event.
*      - Fixed give grenade timer to only set when nade is thrown.
*
* v1.1 - vittu - 3/28/05
*      - Fixed giving new genades using more reliable event.
*      - Changed how smoke grenade ids are found, actually finds all gas nades now.
*      - Added radius cvar for gas.
*      - Added fart sound to gas grenade throw.
*      - Added gas mask hud icon when damaged by a gas grenade.
*
*   Hero Created by RichoDemus & AssKicR
*/

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

#define AMMOX_SMOKEGRENADE 13

// GLOBAL VARIABLES
new HeroName[]="Fartman"
new bool:HasFartman[SH_MAXSLOTS+1]
new bool:BlockGiveNade[SH_MAXSLOTS+1]
new MsgIcon, MsgDamage
new CvarGasDmg, CvarGasRadius, CvarGasFreq, CvarGrenadeReset
//----------------------------------------------------------------------------------------------
public plugin_init()
{
	// Plugin Info
	register_plugin("SUPERHERO Fartman", "1.5", "RichoDemus / AssKicR / vittu")

	// DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
	register_cvar("fartman_level", "7")
	CvarGasDmg = register_cvar("fartman_gasdmg", "10")
	CvarGasRadius = register_cvar("fartman_gasradius", "200")
	CvarGasFreq = register_cvar("fartman_gasfreq", "2.0")
	CvarGrenadeReset = register_cvar("fartman_grenadetimer", "10.0")

	// FIRE THE EVENT TO CREATE THIS SUPERHERO!
	shCreateHero(HeroName, "Fart Gas Nades", "Your Smoke Grenades are now toxic Fart Gas Grenades.", false, "fartman_level")

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

	// EVENTS
	register_event("ResetHUD", "new_spawn", "b")
	register_event("AmmoX", "on_ammox", "b")

	// FORWARD
	register_forward(FM_EmitSound, "sound_emitted")

	MsgIcon = get_user_msgid("StatusIcon")
	MsgDamage = get_user_msgid("Damage")
}
//----------------------------------------------------------------------------------------------
public plugin_precache()
{
	precache_sound("player/gasp1.wav")
	precache_sound("player/gasp2.wav")
	precache_sound("shmod/fartman_smokegrenade.wav")
}
//----------------------------------------------------------------------------------------------
public fartman_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:
		{
			HasFartman[id] = true

			if ( is_user_alive(id) )
				fartman_weapons(id)
		}

		case false:
			HasFartman[id] = false
	}
}
//----------------------------------------------------------------------------------------------
public new_spawn(id)
{
	if ( shModActive() && HasFartman[id] && is_user_alive(id) )
	{
		// Block Ammox nade give task on spawn, if respawned without smoke nade,
		// since you are given one on spawn.
		BlockGiveNade[id] = true

		set_task(0.1, "fartman_weapons", id)
	}
}
//----------------------------------------------------------------------------------------------
public fartman_weapons(id)
{
	if ( shModActive() && is_user_alive(id) && HasFartman[id] )
		shGiveWeapon(id, "weapon_smokegrenade")
}
//----------------------------------------------------------------------------------------------
public on_ammox(id)
{
	if ( !shModActive() || !is_user_alive(id) || !HasFartman[id] )
		return

	new iAmmoType = read_data(1)
	new iAmmoCount = read_data(2)

	if ( iAmmoType == AMMOX_SMOKEGRENADE )
	{
		if ( iAmmoCount == 0 && !BlockGiveNade[id] )
			set_task(get_pcvar_float(CvarGrenadeReset), "fartman_weapons", id)
		else if ( iAmmoCount > 0 )
		{
			// Either has a smoke nade or was given one on spawn, ok to allow sound and task now
			BlockGiveNade[id] = false

			// Got a new smoke nade remove the timer
			remove_task(id)
		}
	}
}
//----------------------------------------------------------------------------------------------
public sound_emitted(entity, channel, const sample[])
{
	// For debugging purposes
	//client_print(0, print_chat, "entity: %d, channel: %d, sample: %s", entity, channel, sample)

	if ( equal(sample, "weapons/sg_explode.wav") )
	{
		new id = pev(entity, pev_owner)

		if ( is_user_connected(id) && HasFartman[id] )
		{
			// Smoke nade went off, change to fart gas
			emit_sound(entity, CHAN_WEAPON, "shmod/fartman_smokegrenade.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)

			new parm[2]
			parm[0] = id
			parm[1] = entity
			fartman_gas(parm)
	
			return FMRES_SUPERCEDE
		}

		return FMRES_IGNORED
	}

	return FMRES_IGNORED
}
//----------------------------------------------------------------------------------------------
public fartman_gas(parm[])
{
	new id = parm[0]
	new grenadeid = parm[1]

	if ( !pev_valid(grenadeid) || !is_user_connected(id) || !HasFartman[id] )
	{
		remove_task(grenadeid+923)
		return
	}

	new Float:grOrigin[3], Float:vicOrigin[3]
	new FFOn = get_cvar_num("mp_friendlyfire")
	new Float:gasRadius = get_pcvar_float(CvarGasRadius)
	new Float:gasTimer = get_pcvar_float(CvarGasFreq)
	new gasDamage = get_pcvar_num(CvarGasDmg)
	new CsTeams:idTeam = cs_get_user_team(id)

	// Find origin of smoke grenade
	pev(grenadeid, pev_origin, grOrigin)

	new players[SH_MAXSLOTS], pnum, vic
	get_players(players, pnum, "a")

	for ( new i = 0; i < pnum; i++ )
	{
		vic = players[i]

		if ( is_user_alive(vic) && !get_user_godmode(vic) && vic != id && (idTeam != cs_get_user_team(vic) || FFOn) )
		{
			pev(vic, pev_origin, vicOrigin)

			if ( vector_distance(grOrigin, vicOrigin) < gasRadius )
			{
				new bool:playSound = true

				// If gas check is less then 1.0 sec, don't flood the server with gasp sounds
				if ( gasTimer < 1.0 )
				{
					if ( random_num(1, 5) > 3 )
						playSound = false
				}

				if ( playSound )
				{
					new number = random_num(1, 2)
					switch(number)
					{
						case 1: emit_sound(vic, CHAN_VOICE, "player/gasp1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
						case 2: emit_sound(vic, CHAN_VOICE, "player/gasp2.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
					}
				}

				new lessHealth = get_user_health(vic) - gasDamage

				// Prevents the shExtraDamage from saying you attacked a teammate for every cycle of the loop
				if ( lessHealth  <= 0 )
					shExtraDamage(vic, id, gasDamage, "fart gas grenade")
				else
					set_user_health(vic, lessHealth)

				// Gas Mask HUD Icon, Flash to show being gased
				message_begin(MSG_ONE_UNRELIABLE, MsgIcon, {0,0,0}, vic)
				write_byte(1)			// status (0=hide, 1=show, 2=flash)
				write_string("dmg_gas")		// sprite name
				write_byte(0)			// red
				write_byte(125)			// green
				write_byte(0)			// blue
				message_end()

				// Remove gasmask icon
				new parm2[1]
				parm2[0] = vic
				set_task(0.3, "remove_gasicon", 0, parm2, 1)

				// Show damage origin as self, so extradamage doesn't show it from attacker origin
				message_begin(MSG_ONE_UNRELIABLE, MsgDamage, {0,0,0}, vic)
				write_byte(30)			// dmg_save
				write_byte(30)			// dmg_take
				write_long(1<<16)		// visibleDamageBits
				write_coord(floatround(vicOrigin[0]))	// damageOrigin.x
				write_coord(floatround(vicOrigin[1]))	// damageOrigin.y
				write_coord(floatround(vicOrigin[2]))	// damageOrigin.z
				message_end()
			}
		}
	}

	// If the smoke grenade still exists gas them again.
	if ( pev_valid(grenadeid) && gasTimer > 0.0 )
		set_task(gasTimer, "fartman_gas", grenadeid+923, parm, 2)
}
//----------------------------------------------------------------------------------------------
public remove_gasicon(parm2[])
{
	new vic = parm2[0]

	if ( !is_user_connected(vic) )
		return

	// Gas Mask HUD Icon, reset to none
	message_begin(MSG_ONE, MsgIcon, {0,0,0}, vic)
	write_byte(0)			// status (0=hide, 1=show, 2=flash)
	write_string("dmg_gas")		// sprite name
	write_byte(0)			// red
	write_byte(125)			// green
	write_byte(0)			// blue
	message_end()
}
//----------------------------------------------------------------------------------------------