// MASTER CHIEF! - Master Chief Petty Officer John-117 from the game Halo.

/* CVARS - copy and paste to shconfig.cfg

//Master Chief
masterchief_level 0
masterchief_health 100		//Default 100 (no extra health)
masterchief_armor 150		//Default 150
masterchief_gravity 1.0		//Default 1.0 = no extra gravity (0.50 is 50% of normal gravity, ect.)
masterchief_speed -1		//Default -1 = no extra speed, this cvar is for all weapons (for faster then normal speed set to 261 or higher)
masterchief_p90mult 1.3		//Damage multiplyer for his P90
// Below Only used if PLAYER_MODEL define = 1
masterchief_teamglow 0		//Glow Team Color when player skin in use (0=no 1=yes)

*/

/*
* v1.6 - vittu - 11/19/07
*      - Added use of const requires amxx 1.76d or higher
*      - Added define options for more customization.
*      - Team colored models can be set with define now.
*      - Now verifies models are loaded else does not use them.
*
* v1.5 - vittu - 6/3/06
*      - Updated to amxmodx only, requires amxx 1.75 or higher.
*      - Removed engine for fakemeta only support.
*      - Changed 2 default cvar values.
*      - Added excessive checking plus other minor code changes.
*      - Fixed rare issue with stale varible giving users the hero that shouldn't have it.
*
* v1.4 - vittu - 6/14/05
*      - Minor code clean up.
*      - Lowered glow value so it's not so bright.
*
* v1.3 - vittu - 1/3/05
*      - Fixed up task set for team glow, so as not to interfere
*         with other tasks when it's removed.
*      - This should be the final version for now.
*
* v1.2 - vittu - 12/26/04
*      - Changed 2 default cvars, gravity and speed to avoid bugs.
*      - Changed give weapon time on ResetHUD, to avoid bugs.
*
* v1.1 - vittu - 12/21/04
*      - set a delay to change player model, better for servers with
*         sh_loadimmediate 0.
*
* v1.0 - vittu - 12/20/04
*      - Complete rework of entire code, started from scratch.
*      - Changed player model to automatic rather than a keydown.
*      - Added p_ weapon model (for 3rd person view).
*
*   Concept by Spartan-117 and JASerrano
*   Player and Weapon models by Strykerwolf (aka Alex Wright) & Grenappels
*/


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


// 0-no player model
// 1-green master chief model + glow cvar option [Default]
// 2-team colored master chief models t=red ct=blue (Note:Requires models from optional zip)
#define PLAYER_MODEL 1

// 0-continuous shooting, no reload [Default]
// 1-drop weapon and get a new one with full clip
// 4-normal cs, no reload mode
#define AMMO_MODE 0

// Comment out to not use the P90 model
#define USE_WPN_MODEL

// Comment out to not give a free P90
#define GIVE_WEAPON


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


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

// GLOBAL VARIABLES
new HeroName[] = "Master Chief"
new bool:HasMasterChief[SH_MAXSLOTS+1]
new CvarP90DmgMult

#if PLAYER_MODEL > 0
	new bool:ModelPlayerSet[SH_MAXSLOTS+1]
	new bool:ModelPlayerLoaded
	new const MasterChiefSound[] = "items/suitchargeno1.wav"

	#if PLAYER_MODEL == 1
		new const Model_Player[] = "models/player/masterchief/masterchief.mdl"
		new const Model_Player_Name[] = "masterchief"
		new CvarTeamGlow
	//#elseif does not work right
	#else
		#if PLAYER_MODEL == 2
			new const Model_Player_T[] = "models/player/masterchief_t/masterchief_t.mdl"
			new const Model_Player_CT[] = "models/player/masterchief_ct/masterchief_ct.mdl"
			new const Model_Player_Name[2][] = {
				"masterchief_t",
				"masterchief_ct"
			}
		#endif
	#endif
#endif

#if defined USE_WPN_MODEL
	new const Model_V_P90[] = "models/shmod/masterchief_v_p90.mdl"
	new const Model_P_P90[] = "models/shmod/masterchief_p_p90.mdl"
	new bool:ModelWeaponLoaded
#endif
//----------------------------------------------------------------------------------------------
public plugin_init()
{
	// Plugin Info
	register_plugin("SUPERHERO Master Chief", "1.6", "Spartan-117/vittu")

	// DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
	register_cvar("masterchief_level", "0")
	register_cvar("masterchief_health", "100")
	register_cvar("masterchief_armor", "150")
	register_cvar("masterchief_gravity", "1.0")
	register_cvar("masterchief_speed", "-1")
	CvarP90DmgMult = register_cvar("masterchief_p90mult", "1.3")

	#if PLAYER_MODEL == 1
		CvarTeamGlow = register_cvar("masterchief_teamglow", "0")
	#endif

	// FIRE THE EVENT TO CREATE THIS SUPERHERO!
	shCreateHero(HeroName, "SPARTAN project", "Become Master Chief - get a MJOLNIR battlesuit and MA5B Assault Rifle (P90), which does more damage.", false, "masterchief_level")

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

	// EVENTS
	register_event("Damage", "masterchief_damage", "b", "2!0")

	#if PLAYER_MODEL > 0 || defined GIVE_WEAPON
		register_event("ResetHUD", "new_spawn", "b")
	#endif

	#if defined USE_WPN_MODEL || AMMO_MODE < 4
		register_event("CurWeapon", "weapon_change", "be", "1=1")
	#endif

	#if PLAYER_MODEL > 0
		register_event("DeathMsg", "masterchief_death", "a")
	#endif

	// Let Server know about the hero's variables
	shSetMaxHealth(HeroName, "masterchief_health")
	shSetMaxArmor(HeroName, "masterchief_armor")
	shSetMinGravity(HeroName, "masterchief_gravity")
	shSetMaxSpeed(HeroName, "masterchief_speed", "[0]")

	#if defined GIVE_WEAPON
		shSetShieldRestrict(HeroName)
	#endif
}
//----------------------------------------------------------------------------------------------
#if PLAYER_MODEL > 0 || defined USE_WPN_MODEL
public plugin_precache()
{
	#if PLAYER_MODEL > 0
		precache_sound(MasterChiefSound)
		ModelPlayerLoaded = true
		#if PLAYER_MODEL == 1
			if ( file_exists(Model_Player) ) {
				precache_model(Model_Player)
			}
			else {
				log_amx("[SH](%s)Aborted loading ^"%s^", file does not exist on server", HeroName, Model_Player)
				ModelPlayerLoaded = false
			}
		#else
			#if PLAYER_MODEL == 2
				if ( file_exists(Model_Player_T) ) {
					precache_model(Model_Player_T)
				}
				else {
					log_amx("[SH](%s)Aborted loading ^"%s^", file does not exist on server", HeroName, Model_Player_T)
					ModelPlayerLoaded = false
				}

				if ( file_exists(Model_Player_CT) ) {
					precache_model(Model_Player_CT)
				}
				else {
					log_amx("[SH](%s)Aborted loading ^"%s^", file does not exist on server", HeroName, Model_Player_CT)
					ModelPlayerLoaded = false
				}
			#endif
		#endif
	#endif

	#if defined USE_WPN_MODEL
		ModelWeaponLoaded = true
		if ( file_exists(Model_V_P90) ) {
			precache_model(Model_V_P90)
		}
		else {
			log_amx("[SH](%s)Aborted loading ^"%s^", file does not exist on server", HeroName, Model_V_P90)
			ModelWeaponLoaded = false
		}

		if ( file_exists(Model_P_P90) ) {
			precache_model(Model_P_P90)
		}
		else {
			log_amx("[SH](%s)Aborted loading ^"%s^", file does not exist on server", HeroName, Model_P_P90)
			ModelWeaponLoaded = false
		}
	#endif
}
#endif
//----------------------------------------------------------------------------------------------
public masterchief_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)

	// Reset thier shield restrict status
	// Shield restrict MUST be before weapons are given out
	#if defined GIVE_WEAPON
		shResetShield(id)
	#endif

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

			if ( is_user_alive(id) )
			{
				#if defined GIVE_WEAPON
					masterchief_weapons(id)
				#endif

				#if defined USE_WPN_MODEL
					if ( ModelWeaponLoaded )
						switch_model(id)
				#endif

				#if PLAYER_MODEL > 0
					if ( ModelPlayerLoaded )
						masterchief_tasks(id)
				#endif
			}
		}

		case false:
		{
			// Check is needed since this gets run on clearpowers even if user didn't have this hero
			if ( is_user_alive(id) && HasMasterChief[id] )
			{
				// This gets run if they had the power but don't anymore
				#if defined GIVE_WEAPON
					engclient_cmd(id, "drop", "weapon_p90")
				#endif

				#if PLAYER_MODEL > 0
					if ( ModelPlayerLoaded )
						masterchief_unmorph(id)
				#endif

				shRemHealthPower(id)
				shRemArmorPower(id)
				shRemGravityPower(id)
				shRemSpeedPower(id)
			}

			HasMasterChief[id] = false
		}
	}
}
//----------------------------------------------------------------------------------------------
#if PLAYER_MODEL > 0 || defined GIVE_WEAPON
public new_spawn(id)
{
	if ( shModActive() && is_user_alive(id) && HasMasterChief[id] )
	{
		#if defined GIVE_WEAPON
			set_task(0.1, "masterchief_weapons", id)
		#endif

		#if PLAYER_MODEL > 0
			if ( ModelPlayerLoaded )
				masterchief_tasks(id)
		#endif
	}
}
#endif
//----------------------------------------------------------------------------------------------
#if PLAYER_MODEL > 0
masterchief_tasks(id)
{
	set_task(1.0, "masterchief_morph", id)

	#if PLAYER_MODEL == 1
		if ( get_pcvar_num(CvarTeamGlow) )
			set_task(1.0, "masterchief_glow", id+100, _, _, "b")
	#endif
}
#endif
//----------------------------------------------------------------------------------------------
#if defined GIVE_WEAPON
public masterchief_weapons(id)
{
	if ( !shModActive() || !is_user_alive(id) || !HasMasterChief[id] )
		return

	shGiveWeapon(id, "weapon_p90")
}
#endif
//----------------------------------------------------------------------------------------------
#if defined USE_WPN_MODEL
switch_model(id)
{
	if ( !shModActive() || !is_user_alive(id) || !HasMasterChief[id] )
		return

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

	if ( wpnid == CSW_P90 )
	{
		set_pev(id, pev_viewmodel2, Model_V_P90)
		set_pev(id, pev_weaponmodel2, Model_P_P90)
	}
}
#endif
//----------------------------------------------------------------------------------------------
#if defined USE_WPN_MODEL || AMMO_MODE < 4
public weapon_change(id)
{
	if ( !shModActive() || !HasMasterChief[id] )
		return

	//weaponID = read_data(2)
	if ( read_data(2) != CSW_P90 )
		return

	#if defined USE_WPN_MODEL
		if ( ModelWeaponLoaded )
			switch_model(id)
	#endif

	// Never Run Out of Ammo!
	#if AMMO_MODE < 4
		//clip = read_data(3)
		if ( read_data(3) == 0 )
			shReloadAmmo(id, AMMO_MODE)
	#endif
}
#endif
//----------------------------------------------------------------------------------------------
public masterchief_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 ( HasMasterChief[attacker] && weapon == CSW_P90 )
	{
		new damage = read_data(2)
		new headshot = bodypart == 1 ? 1 : 0

		// do extra damage
		new extraDamage = floatround(damage * get_pcvar_float(CvarP90DmgMult) - damage)
		if ( extraDamage > 0 )
			shExtraDamage(id, attacker, extraDamage, "p90", headshot)
	}
}
//----------------------------------------------------------------------------------------------
#if PLAYER_MODEL > 0
masterchief_sound(id)
{
	emit_sound(id, CHAN_AUTO, MasterChiefSound, 0.2, ATTN_NORM, SND_STOP, PITCH_NORM)
	emit_sound(id, CHAN_AUTO, MasterChiefSound, 0.2, ATTN_NORM, 0, PITCH_NORM)
}
//----------------------------------------------------------------------------------------------
public masterchief_morph(id)
{
	if ( ModelPlayerSet[id] || !is_user_alive(id) || !HasMasterChief[id] )
		return

	#if PLAYER_MODEL == 1
		cs_set_user_model(id, Model_Player_Name)
	#else
		#if PLAYER_MODEL == 2
			// Done this way for safety (ie user is spec alive)
			switch(cs_get_user_team(id))
			{
				case CS_TEAM_T: cs_set_user_model(id, Model_Player_Name[0])
				case CS_TEAM_CT: cs_set_user_model(id, Model_Player_Name[1])
				default: return
			}	
		#endif
	#endif

	masterchief_sound(id)

	// Message
	set_hudmessage(50, 205, 50, -1.0, 0.40, 2, 0.02, 4.0, 0.01, 0.1, -1)
	show_hudmessage(id, "%s - Spartan-117 reporting for duty", HeroName)

	ModelPlayerSet[id] = true
}
//----------------------------------------------------------------------------------------------
masterchief_unmorph(id)
{
	if ( ModelPlayerSet[id] && is_user_connected(id) )
	{
		if ( is_user_alive(id) )
		{
			// Message only shows if alive and dropping hero
			set_hudmessage(50, 205, 50, -1.0, 0.40, 2, 0.02, 4.0, 0.01, 0.1, -1)
			show_hudmessage(id, "%s - MODE OFF, you returned to normal self", HeroName)
		}

		cs_reset_user_model(id)

		masterchief_sound(id)

		ModelPlayerSet[id] = false

		#if PLAYER_MODEL == 1
			if ( get_pcvar_num(CvarTeamGlow) )
			{
				remove_task(id+100)
				set_user_rendering(id)
			}
		#endif
	}
}
//----------------------------------------------------------------------------------------------
#if PLAYER_MODEL == 1
public masterchief_glow(id)
{
	id -= 100

	if ( !shModActive() || !is_user_connected(id) )
	{
		//Don't want any left over residuals
		remove_task(id+100)
		return
	}

	if ( HasMasterChief[id] && is_user_alive(id) )
	{
		switch(cs_get_user_team(id))
		{
			case CS_TEAM_T: shGlow(id, 100, 0, 0)
			case CS_TEAM_CT: shGlow(id, 0, 0, 100)
		}
	}
}
#endif
//----------------------------------------------------------------------------------------------
public masterchief_death()
{
	new id = read_data(2)

	if ( !HasMasterChief[id] )
		return

	if ( ModelPlayerLoaded )
		masterchief_unmorph(id)
}
#endif
//----------------------------------------------------------------------------------------------
public client_connect(id)
{
	HasMasterChief[id] = false

	#if PLAYER_MODEL > 0
		ModelPlayerSet[id] = false
	#endif
}
//----------------------------------------------------------------------------------------------