// CASPER! - the Friendly Ghost! 

/* CVARS - copy and paste to shconfig.cfg

//Casper
casper_level 8
casper_health 50		//Max amount of Health when in Ghost mode (Default 50)
casper_armor 25		//Max amount of Armor when in Ghost mode (Default 25)
casper_stuckcheck 1		//Kill user if stuck in wall/ground after noclip, 0=no 1=yes (Default 1)

*/

/*
* v1.1 - vittu - 6/13/05
*      - Made HP/AP settings as a Max for when in Ghost mode, otherwise
*          they were pretty much useless.
*      - Removed useless code and made invisibility loop itself incase
*          user is made to glow.
*      - Added option to kill a stuck user when leaving no clip.
*
*   Hero Created by BLU3 V1Z10N & maybe
*/

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

// GLOBAL VARIABLES
new gHeroName[]="Casper"
new bool:gHasCasperPower[SH_MAXSLOTS+1]
new bool:gInGhostMode[SH_MAXSLOTS+1]
new gUserHealth[SH_MAXSLOTS+1]
new gUserArmor[SH_MAXSLOTS+1]
new gGhostHealth[SH_MAXSLOTS+1]
new gGhostArmor[SH_MAXSLOTS+1]
new g_lastPosition[SH_MAXSLOTS+1][3]
new gCasperHealth, gCasperArmor
//-------------------------------------------------------------------------------------------------
public plugin_init()
{
	// Plugin Info
	register_plugin("SUPERHERO Casper", "1.1", "BLU3 V1Z10N / maybe / vittu")

	// DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
	register_cvar("casper_level", "8")
	register_cvar("casper_health", "50")
	register_cvar("casper_armor", "25")
	register_cvar("casper_stuckcheck", "1")

	// FIRE THE EVENT TO CREATE THIS SUPERHERO!
	shCreateHero(gHeroName, "Ghost Mode", "Hold power key down for 95 percent invisibility with noclip! Low HP/AP while in Ghost Mode.", true, "casper_level")
	// INIT
	shRegHeroInit(gHeroName, "casper_init")
	register_srvcmd("casper_init", "casper_init")

	// KEYDOWN
	register_srvcmd("casper_kd", "casper_kd")
	shRegKeyDown(gHeroName, "casper_kd")

	// KEYUP
	register_srvcmd("casper_ku", "casper_ku")
	shRegKeyUp(gHeroName, "casper_ku")

	register_event("ResetHUD", "newSpawn", "b")
	register_event("DeathMsg", "casper_death", "a")
}
//---------------------------------------------------------------------------------------------
public casper_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)

	if ( hasPowers && is_user_alive(id) ) {
		gGhostHealth[id] = get_cvar_num("casper_health")
		gGhostArmor[id] = get_cvar_num("casper_armor")
	}
	else if ( !hasPowers && gHasCasperPower[id] && is_user_alive(id) && gInGhostMode[id] ) {
		casper_removeghost(id)
	}

	//Sets this variable to the current status
	gHasCasperPower[id] = (hasPowers != 0)
}
//----------------------------------------------------------------------------------------------
public plugin_cfg()
{
	loadCVARS()
}
//----------------------------------------------------------------------------------------------
public loadCVARS()
{
	// These cvars are checked very often
	gCasperHealth = get_cvar_num("casper_health")
	gCasperArmor = get_cvar_num("casper_armor")
}
//----------------------------------------------------------------------------------------------
public newSpawn(id)
{
	if ( shModActive() && gHasCasperPower[id] && is_user_alive(id) ) {
		if ( gInGhostMode[id] ) {
			casper_removeghost(id)
		}

		// reset varibles
		gGhostHealth[id] = gCasperHealth
		gGhostArmor[id] = gCasperArmor
	}
}
//-----------------------------------------------------------------------------------------------
public casper_kd()
{
	if ( !hasRoundStarted() ) return

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

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

	// Reload CVARS to make sure the variables are current
	loadCVARS()

	//If the user already has noclip (prob from another hero) cancel this keydown
	if ( get_user_noclip(id) == 1 || gInGhostMode[id] ) {
		client_print(id, print_chat, "[SH](Casper) You are already using noclip")
		playSoundDenySelect(id)
		return
	}

	casper_setghost(id)
}
//---------------------------------------------------------------------------------------------
public casper_setghost(id)
{
	if ( !gHasCasperPower[id] || !is_user_alive(id) ) return

	gInGhostMode[id] = true

	set_user_noclip(id, 1)

	// Set invisible first then loop it
	set_user_rendering(id, kRenderFxGlowShell, 8, 8, 8, kRenderTransAlpha, 12)
	set_task(1.0, "casper_loop", id, "", 0, "b")

	// Save users current hp/ap to be set back when exiting ghost mode
	// and only change hp/ap if they have more then max for ghost mode
	gUserHealth[id] = get_user_health(id)
	if ( gUserHealth[id] > gGhostHealth[id] ) {
		set_user_health(id, gGhostHealth[id])
	}

	gUserArmor[id] = get_user_armor(id)
	if ( gUserArmor[id] > gGhostArmor[id] ) {
		set_user_armor(id, gGhostArmor[id])
	}
	else if ( gUserArmor[id] <= 0 ) {
		// IF they have no armor give them some
		give_item(id, "item_assaultsuit")
		set_user_armor(id, gGhostArmor[id])
		gUserArmor[id] = gGhostArmor[id]
	}

	// Let them know they are in Ghost Mode
	new message[128]
	if ( get_cvar_num("casper_stuckcheck") == 1) {
		format(message, 127, "Casper - You have entered Ghost Mode!^nDon't get Stuck or you will die")
	}
	else {
		format(message, 127, "Casper - You have entered Ghost Mode!")
	}
	set_hudmessage(200, 200, 200, -1.0, 0.3, 0, 0.25, 2.0, 0.0, 0.0, 17)
	show_hudmessage(id, message)
}
//---------------------------------------------------------------------------------------------
public casper_loop(id)
{
	if ( !shModActive() || !gHasCasperPower[id] || !is_user_alive(id) || !gInGhostMode[id] ) return

	set_user_rendering(id, kRenderFxGlowShell, 8, 8, 8, kRenderTransAlpha, 12)

	// Preven regen past cvar HP in Ghost Mode
	if ( get_user_health(id) > gCasperHealth ) {
		set_user_health(id, gCasperHealth)
	}

	// Preven regen past cvar AP in Ghost Mode
	if ( get_user_armor(id) > gCasperArmor ) {
		set_user_armor(id, gCasperArmor)
	}
}
//------------------------------------------------------------------------------------------------
public casper_ku()
{
	if ( !hasRoundStarted() ) return

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

	if ( !gHasCasperPower[id] || !is_user_alive(id) || !gInGhostMode[id] ) return

	casper_removeghost(id)
}
//---------------------------------------------------------------------------------------------
public casper_removeghost(id)
{
	remove_task(id)

	if ( !is_user_connected(id) ) return

	if ( get_user_noclip(id) == 1) {
		set_user_noclip(id, 0)
		if ( get_cvar_num("casper_stuckcheck") == 1) {
			positionChangeTimer(id)
		}
	}

	set_user_rendering(id)

	if ( is_user_alive(id) && gInGhostMode[id] && hasRoundStarted() ) {

		// reset users HP and Ghost Mode mode HP
		if ( gUserHealth[id] > gGhostHealth[id] ) {
			gGhostHealth[id] = get_user_health(id)
			// If they are regened HP higher then cvar got to set it back down
			if ( gGhostHealth[id] > gCasperHealth ) {
				gGhostHealth[id] = gCasperHealth
			}
			set_user_health(id, gUserHealth[id])
		}

		// reset users AP and save Ghost Mode AP
		if ( gUserArmor[id] > gGhostArmor[id] ) {
			gGhostArmor[id] = get_user_armor(id)
			// If they are regened AP higher then cvar got to set it back down
			if ( gGhostArmor[id] > gCasperArmor ) {
				gGhostArmor[id] = gCasperArmor
			}
			set_user_armor(id, gUserArmor[id])
		}

		// Let them know they are no longer in Ghost Mode
		new message[128]
		format(message, 127, "Casper - You have left Ghost Mode!" )
		set_hudmessage(200, 200, 200, -1.0, 0.3, 0, 0.25, 2.0, 0.0, 0.0,17)
		show_hudmessage(id, message)
	}

	gInGhostMode[id] = false
}
//---------------------------------------------------------------------------------------------
public positionChangeTimer(id)
{
	if ( !is_user_alive(id) ) return

	get_user_origin(id, g_lastPosition[id])

	new Float:velocity[3]
	Entvars_Get_Vector(id, EV_VEC_velocity, velocity)

	if ( velocity[0]==0.0 && velocity[1]==0.0 ) {
		// Force a Move (small jump)
		velocity[0] += 20.0
		velocity[2] += 100.0
		Entvars_Set_Vector(id, EV_VEC_velocity, velocity)
	}

	set_task(0.4, "positionChangeCheck", id)
}
//----------------------------------------------------------------------------------------------
public positionChangeCheck(id)
{
	if ( !is_user_alive(id) ) return

	new origin[3]
	get_user_origin(id, origin)

	if ( g_lastPosition[id][0] == origin[0] && g_lastPosition[id][1] == origin[1] && g_lastPosition[id][2] == origin[2] && is_user_alive(id) ) {
		// Kill this player - Stuck in wall!
		user_kill(id)
		client_print(id, print_chat, "[SH](Casper) You died from being stuck when leaving Ghost Mode")
	}
}
//----------------------------------------------------------------------------------------------
public casper_death()
{
	new id = read_data(2)

	if ( !gHasCasperPower[id] ) return

	casper_removeghost(id)
}
//---------------------------------------------------------------------------------------------
public client_disconnect(id)
{
	if ( !gHasCasperPower[id] ) return

	remove_task(id)
	gInGhostMode[id] = false
}
//---------------------------------------------------------------------------------------------