/*
		
				[ZP] Extra Item : Parachute
				     ( For Humans ) 
					 by Fry!
				

	Description :

			Now Humans can purchase parachute to fly away from zombies if they are on high buildings.
			This will cost it to You some ammo packs, can change by ( cvars )
			When you will use parachute your screen will be changed to 3rd view screen depends on cvar.
	

	Cvars :
			
			zp_3rd_person_view <1|2>	- set 1 to disable 3rd person view and set 2 to enable 3rd person view
			zp_parachute_fallspeed "100" 	- How fast You gonna fall.
			zp_parachute_detach <1|0> 	- Default is 1.
			zp_parachute_cost "15"		- How much it cost.
			

	Credits :

			KRoTaL/JTP10181 - For his original parachute plugin
			Random1 - Took some stuff from his plugin


	Changelog :

			02/11/2008 - v0.1 - First test
			03/11/2008 - v0.2 - added some stuff
			17/01/2009 - v0.2.2 - removed fun and cstrike module, removed some unnecessary code lines
			15/02/2009 - v0.2.8 - fixed now you will need to buy parachute to use it, remove toggle command, removed admin give options and for admins only too, removed chat command, removed sell option, changed all to fakemeta.
			27/02/2009 - v0.3.0 - removed gravity function cuz it could cause bug with Nemesis gravity, added cvar for person view.
*/

#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <zombieplague>

#define PLUGIN "[ZP] Extra : Parachute"
#define VERSION "0.3"
#define AUTHOR "Fry!"

new const parachute_model[] = "models/parachute.mdl"

new g_item_name[] = "Parachute"
new g_itemid_parachute

new bool:has_parachute[33]
new para_ent[33]
new g_para_3rd_view
new g_ppurchase, g_parachute_FallSpeed, g_parachute_Detach

public plugin_init()
{
	register_plugin(PLUGIN, VERSION , AUTHOR)
	
	register_cvar("zp_extra_parachute",VERSION,FCVAR_SERVER|FCVAR_EXTDLL|FCVAR_UNLOGGED|FCVAR_SPONLY)
	
	g_para_3rd_view = register_cvar("zp_3rd_person_view", "1")
	g_parachute_FallSpeed = register_cvar("zp_parachute_fallspeed", "100")
	g_parachute_Detach = register_cvar("zp_parachute_detach", "1")
	g_ppurchase = register_cvar("zp_parachute_cost", "15")
		
	g_itemid_parachute = zp_register_extra_item(g_item_name, get_pcvar_num(g_ppurchase), 0)

	register_event("ResetHUD", "newSpawn", "be")
	register_event("DeathMsg", "death_event", "a")
	
	register_forward(FM_PlayerPreThink, "fw_PreThink")
}

public plugin_precache()
	engfunc(EngFunc_PrecacheModel, parachute_model)

public client_connect(id)
{
	parachute_reset(id)
	has_parachute[id] = false
}

public client_disconnect(id)
{
	parachute_reset(id)
	has_parachute[id] = false
}

public death_event()
{
	new i = read_data(2)
	
	parachute_reset(i)
	has_parachute[i] = false
	set_view(i, CAMERA_NONE)
}

public zp_extra_item_selected(player, itemid)
{
	if (itemid == g_itemid_parachute)
	{
		has_parachute[player] = true
	}
}

parachute_reset(id)
{
	if (para_ent[id] > 0) 
	{
		if ( pev_valid(para_ent[id]) ) 
			engfunc(EngFunc_RemoveEntity, para_ent[id])
	}

	has_parachute[id] = false
	para_ent[id] = 0
}

public newSpawn(id)
{
	parachute_reset(id)
}

public fw_PreThink(id)
{
	//parachute.mdl animation information
	//0 - deploy - 84 frames
	//1 - idle - 39 frames
	//2 - detach - 29 frames
	
	if (!is_user_alive(id) || !has_parachute[id] && !zp_get_user_zombie(id))
		return

	new Float:fallspeed = get_pcvar_float(g_parachute_FallSpeed) * -1.0
	new Float:frame

	new button = pev(id, pev_button)
	new oldbutton = pev(id, pev_oldbuttons)
	new flags = pev(id, pev_flags)

	if (para_ent[id] > 0 && (flags & FL_ONGROUND)) 
	{
		set_view(id, CAMERA_NONE)
		
		if (get_pcvar_num(g_parachute_Detach)) 
		{
			if ( pev(para_ent[id],pev_sequence) != 2 ) 
			{
				set_pev(para_ent[id], pev_sequence, 2)
				set_pev(para_ent[id], pev_gaitsequence, 1)
				set_pev(para_ent[id], pev_frame, 0.0)
				set_pev(para_ent[id], pev_fuser1, 0.0)
				set_pev(para_ent[id], pev_animtime, 0.0)
				return
			}
			
			pev(para_ent[id],pev_fuser1, frame)
			frame += 2.0
			set_pev(para_ent[id],pev_fuser1,frame)
			set_pev(para_ent[id],pev_frame,frame)
			
			if ( frame > 254.0 )
			{
				engfunc(EngFunc_RemoveEntity, para_ent[id])
				para_ent[id] = 0
			}
		}
		else 
		{
			engfunc(EngFunc_RemoveEntity, para_ent[id])
			para_ent[id] = 0
		}
		return
	}

	if (button & IN_USE) 
	{
		new Float:velocity[3]
		pev(id, pev_velocity, velocity)
		
		if (get_pcvar_num(g_para_3rd_view) == 1)
		{
			set_view(id, CAMERA_NONE)
		}
		if (get_pcvar_num(g_para_3rd_view) == 2)
		{
			set_view(id, CAMERA_3RDPERSON)
		}
		
		if (velocity[2] < 0.0) 
		{
			if(para_ent[id] <= 0) 
			{
				para_ent[id] = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
				
				if(para_ent[id] > 0) 
				{
					set_pev(para_ent[id],pev_classname,"parachute")
					set_pev(para_ent[id], pev_aiment, id)
					set_pev(para_ent[id], pev_owner, id)
					set_pev(para_ent[id], pev_movetype, MOVETYPE_FOLLOW)
					engfunc(EngFunc_SetModel, para_ent[id], parachute_model)
					set_pev(para_ent[id], pev_sequence, 0)
					set_pev(para_ent[id], pev_gaitsequence, 1)
					set_pev(para_ent[id], pev_frame, 0.0)
					set_pev(para_ent[id], pev_fuser1, 0.0)
				}
			}
			
			if (para_ent[id] > 0) 
			{
				set_pev(id, pev_sequence, 3)
				set_pev(id, pev_gaitsequence, 1)
				set_pev(id, pev_frame, 1.0)
				set_pev(id, pev_framerate, 1.0)
			
				velocity[2] = (velocity[2] + 40.0 < fallspeed) ? velocity[2] + 40.0 : fallspeed
				set_pev(id, pev_velocity, velocity)
				
				if (pev(para_ent[id],pev_sequence) == 0) 
				{
					pev(para_ent[id],pev_fuser1, frame)
					frame += 1.0
					set_pev(para_ent[id],pev_fuser1,frame)
					set_pev(para_ent[id],pev_frame,frame)
					
					if (frame > 100.0) 
					{
						set_pev(para_ent[id], pev_animtime, 0.0)
						set_pev(para_ent[id], pev_framerate, 0.4)
						set_pev(para_ent[id], pev_sequence, 1)
						set_pev(para_ent[id], pev_gaitsequence, 1)
						set_pev(para_ent[id], pev_frame, 0.0)
						set_pev(para_ent[id], pev_fuser1, 0.0)
					}
				}
			}
		}
		
		else if (para_ent[id] > 0) 
		{
			engfunc(EngFunc_RemoveEntity, para_ent[id])
			para_ent[id] = 0
		}
	}
	
	else if ((oldbutton & IN_USE) && para_ent[id] > 0 ) 
	{
		engfunc(EngFunc_RemoveEntity, para_ent[id])
		para_ent[id] = 0
	}
}