#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <fun>
#include <hamsandwich>
#include <xs>
#include <cstrike>
#include <zombieplague>
#include <fakemeta_util>
#include <amxmisc>

const USE_STOPPED = 0
const OFFSET_ACTIVE_ITEM = 373
const OFFSET_WEAPONOWNER = 41
const OFFSET_LINUX = 5
const OFFSET_LINUX_WEAPONS = 4
const UNIT_SECOND = (1<<12)

#define ENG_NULLENT				-1
#define EV_INT_WEAPONKEY			EV_INT_impulse
#define PLAYER_LINUX_XTRA_OFF		5
#define WEAP_LINUX_XTRA_OFF		4

#define m_fKnown				44
#define m_flNextPrimaryAttack 			46
#define m_flTimeweaponIdle			48
#define m_iClip					51
#define m_fInReload				54
#define m_flNextAttack				83
#define write_coord_f(%1)			engfunc(EngFunc_WriteCoord,%1)

#define ANIM_IDLE 				0
#define ANIM_IDLE_2 				6
#define ANIM_IDLE_LAST 				7

#define ANIM_SHOOT1 				3
#define ANIM_SHOOT2				4
#define ANIM_SHOOT3				5

#define ANIM_RELOAD				1
#define ANIM_RELOAD_2				14
#define ANIM_DRAW 				2
#define ANIM_DRAW_2 				15

#define SKULL3_DRAW_TIME	1.0

new const Fire_Sounds[][] = { "talrasha/weapons/skull3/skull3-1.wav"}
new const Zoom_Sounds[][] = { "weapons/zoom.wav" } 
new const Other_Sounds[][] = { "talrasha/weapons/skull3/skull3_boltpull.wav","talrasha/weapons/skull3/skull3_clipin.wav","talrasha/weapons/skull3/skull3_clipout.wav","talrasha/weapons/skull3/skull3_idle.wav"}
new const Weapon_Sprites[][] = { "sprites/talrasha/skull3/640hud68.spr", "sprites/talrasha/skull3/640hud2.spr" }
new const Weapon_Generic[][] = { "sprites/talrasha/skull3/weapon_skull3_geet.txt", "sprites/talrasha/skull3/weapon_skull3d_geet.txt"}

new const GUNSHOT_DECALS[] = { 41, 42, 43, 44, 45 }

new SKULL3_V_MODEL[64] = "models/talrasha/weapons/skull3/v_skull3.mdl"
new SKULL3_P_MODEL[64] = "models/talrasha/weapons/skull3/p_skull3.mdl"
new SKULL3_P_MODEL_2[64] = "models/talrasha/weapons/skull3/p_skull3dual.mdl"
new SKULL3_W_MODEL[64] = "models/talrasha/weapons/skull3/w_skull3.mdl"
new SKULL3_SHELL_MODEL[64] = "models/rshell.mdl"

new SKULL3_WEAPONKEY = 333

const SECONDARY_WEAPONS_BITSUM = (1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_UMP45)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
new const WEAPONENTNAMES[][] = { "", "weapon_p228", "", "weapon_scout", "weapon_hegrenade", "weapon_xm1014", "weapon_c4", "weapon_mac10",
			"weapon_aug", "weapon_smokegrenade", "weapon_elite", "weapon_fiveseven", "weapon_m3", "weapon_sg550",
			"weapon_galil", "weapon_famas", "weapon_usp", "weapon_glock18", "weapon_awp", "weapon_mp5navy", "weapon_ump45",
			"weapon_ump45", "weapon_m4a1", "weapon_tmp", "weapon_g3sg1", "weapon_flashbang", "weapon_ump45", "weapon_sg552",
			"weapon_ak47", "weapon_knife", "weapon_p90" }

new g_itemid_skull3 , cvar_clip, cvar_clip_2, cvar_ammo,  cvar_recoil, cvar_recoil_2, cvar_speed_shoot_1, cvar_speed_shoot_2,  cvar_time_reload, cvar_time_reload_2, cvar_time_change_mode, cvar_time_change_mode_2, cvar_bloodsizehs, cvar_bloodsize, cvar_bloodcolor, cvar_extra, cvar_extra_cost, cvar_shellslife, cvar_hits[8],
g_orig_event_skull3 , Shells_Model, Blood_Sprites[2], ump45_vars[10],
g_oldweap[33], g_skull3_tmpclip[33], g_has_skull3[33], g_primaryattack[33], g_reload[33], Float:g_dmg[33][33], Float:g_lastshoot[33], g_endround,
Float:g_zoom_time[33], g_zoomed[33],
g_mode[33], g_change[33], Float:g_change_time[33]

public plugin_init()
{
	register_plugin("[ZP] Extra Weapon: SKULL-3 [beta #2]", "1.0", "Crock / =)")

	register_message(get_user_msgid("DeathMsg"), "message_deathmsg")
	register_event("CurWeapon","ev_curweapon","be","1=1")
	register_forward(FM_SetModel, "fw_setmodel")
	register_forward(FM_UpdateClientData, "fw_updateclientdata_post", 1)
	register_forward(FM_PlaybackEvent, "fw_playbackevent")
	register_forward(FM_CmdStart, "fw_cmdstart")

	register_clcmd("weapon_skull3","client_cmd_skull3")
	register_clcmd("weapon_skull3d","client_cmd_skull3")

	for (new i = 1; i < sizeof WEAPONENTNAMES; i++)
		if (WEAPONENTNAMES[i][0]) RegisterHam(Ham_Item_Deploy, WEAPONENTNAMES[i], "fw_itemdeploy_post", 1)

	RegisterHam(Ham_Item_AddToPlayer, "weapon_ump45", "fw_skull3_addtoplayer")
	RegisterHam(Ham_Use, "func_tank", "fw_usestationary_post", 1)
	RegisterHam(Ham_Use, "func_tankmortar", "fw_usestationary_post", 1)
	RegisterHam(Ham_Use, "func_tankrocket", "fw_usestationary_post", 1)
	RegisterHam(Ham_Use, "func_tanklaser", "fw_usestationary_post", 1)

	RegisterHam(Ham_Weapon_Reload, "weapon_ump45", "fw_skull3_reload");
	RegisterHam(Ham_Weapon_Reload, "weapon_ump45", "fw_skull3_reload_post", 1);
	RegisterHam(Ham_Weapon_PrimaryAttack, "weapon_ump45", "fw_skull3_primaryattack_post",1)
	RegisterHam(Ham_Weapon_WeaponIdle,"weapon_ump45","fw_knifeidleanim")

	RegisterHam(Ham_Item_PostFrame, "weapon_ump45", "fw_skull3_itempostframe");

	RegisterHam(Ham_TakeDamage, "player", "fw_takedamage")
	RegisterHam(Ham_TakeDamage, "func_breakable", "fw_takedamageb")

	RegisterHam(Ham_Spawn, "player", "fw_playerspawn_post", 1)

	RegisterHam(Ham_TraceAttack, "player", "fw_traceattack", 1)
	RegisterHam(Ham_TraceAttack, "worldspawn", "fw_traceattack", 1)
	RegisterHam(Ham_TraceAttack, "func_breakable", "fw_traceattack", 1)
	RegisterHam(Ham_TraceAttack, "func_wall", "fw_traceattack", 1)
	RegisterHam(Ham_TraceAttack, "func_door", "fw_traceattack", 1)
	RegisterHam(Ham_TraceAttack, "func_door_rotating", "fw_traceattack", 1)
	RegisterHam(Ham_TraceAttack, "func_plat", "fw_traceattack", 1)
	RegisterHam(Ham_TraceAttack, "func_rotating", "fw_traceattack", 1)

	cvar_clip = register_cvar("zp_skull3_clip", "35")
	cvar_clip_2 = register_cvar("zp_skull3_clip_2", "70")
	cvar_ammo = register_cvar("zp_skull3_ammo", "210")

	cvar_recoil = register_cvar("zp_skull3_recoil", "1.5")
	cvar_recoil_2 = register_cvar("zp_skull3_recoil_zoom", "0.5")

	cvar_speed_shoot_1 = register_cvar("zp_skull3_speed_shoot_1", "1.0")
	cvar_speed_shoot_2 = register_cvar("zp_skull3_speed_shoot_2", "0.6")

        cvar_time_reload = register_cvar("zp_skull3_time_reload", "2.4")
        cvar_time_reload_2 = register_cvar("zp_skull3_time_reload_2", "3.0")

        cvar_time_change_mode = register_cvar("zp_skull3_time_change_mode", "2.7")
        cvar_time_change_mode_2 = register_cvar("zp_skull3_time_change_mode_2", "2.9")

	cvar_bloodsize = register_cvar("zp_skull3_bloodsize", "0")
	cvar_bloodsizehs = register_cvar("zp_skull3_bloodsizehs", "0")
	cvar_bloodcolor = register_cvar("zp_skull3_bloodcolor", "0")

	cvar_shellslife  = register_cvar("zp_skull3_shellslife", "5")

	cvar_extra = register_cvar("zp_skull3_extraitem", "1")
	cvar_extra_cost = register_cvar("zp_skull3_extraitem_cost", "14")

	cvar_hits[0] = register_cvar("zp_skull3_dmg","95")
	cvar_hits[1] = register_cvar("zp_skull3_dmghead","2.5")
	cvar_hits[2] = register_cvar("zp_skull3_dmgchest","1.5")
	cvar_hits[3] = register_cvar("zp_skull3_dmgstomach","1.0")
	cvar_hits[4] = register_cvar("zp_skull3_dmgleftarm","0.9")
	cvar_hits[5] = register_cvar("zp_skull3_dmgrightarm","0.9")
	cvar_hits[6] = register_cvar("zp_skull3_dmgleftleg","0.9")
	cvar_hits[7] = register_cvar("zp_skull3_dmgrightleg","0.9")

	if(get_pcvar_num(cvar_extra)) 
	{
		g_itemid_skull3 = zp_register_extra_item("\ySkull-\r3", get_pcvar_num(cvar_extra_cost), ZP_TEAM_HUMAN)
	}else{
		g_itemid_skull3 = -1
	}

	g_endround = 1
}

public plugin_precache()
{
	precache_model(SKULL3_V_MODEL)
	precache_model(SKULL3_P_MODEL)
	precache_model(SKULL3_P_MODEL_2)
	precache_model(SKULL3_W_MODEL)

	for(new i = 0; i < sizeof Fire_Sounds; i++)
		precache_sound(Fire_Sounds[i])

	for(new e = 0; e < sizeof Zoom_Sounds; e++)
		precache_sound(Zoom_Sounds[e])

	for(new s = 0; s < sizeof Other_Sounds; s++)
		precache_sound(Other_Sounds[s])

	for(new b = 0; b < sizeof Weapon_Sprites; b++)
		precache_model(Weapon_Sprites[b])

	for(new n = 0; n < sizeof Weapon_Generic; n++)
		precache_generic(Weapon_Generic[n])

	Blood_Sprites[0] = precache_model("sprites/blood.spr")
	Blood_Sprites[1] = precache_model("sprites/bloodspray.spr")

	Shells_Model = precache_model(SKULL3_SHELL_MODEL)

	register_forward(FM_PrecacheEvent, "fw_precachevent_post", 1)
	register_message( 78, "msg_weaplist" )
}

public fw_traceattack(ent, attacker, Float:damage, Float:direction[3], ptr, dmgtype)
{
	if(!is_user_alive(attacker) || zp_get_user_zombie(attacker)) 
		return HAM_IGNORED;

	if(get_user_weapon(attacker) != CSW_UMP45) 
		return HAM_IGNORED;

	if(!g_has_skull3[attacker]) 
		return HAM_IGNORED;

	make_shoot(attacker)

	if(!is_user_alive(ent))
	{
		static Float:flEnd[3]
		get_tr2(ptr, TR_vecEndPos, flEnd)
	
		if(ent)
		{
			// Put decal on an entity
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
			write_byte(TE_DECAL)
			write_coord_f(flEnd[0])
			write_coord_f(flEnd[1])
			write_coord_f(flEnd[2])
			write_byte(GUNSHOT_DECALS[random_num ( 0, sizeof GUNSHOT_DECALS -1 ) ] )
			write_short(ent)
			message_end()
		}
		else
		{
			// Put decal on "world" (a wall)
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
			write_byte(TE_WORLDDECAL)
			write_coord_f(flEnd[0])
			write_coord_f(flEnd[1])
			write_coord_f(flEnd[2])
			write_byte(GUNSHOT_DECALS[random_num ( 0, sizeof GUNSHOT_DECALS -1 ) ] )
			message_end()
		}
	
		// Show sparcles
		message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
		write_byte(TE_GUNSHOTDECAL)
		write_coord_f(flEnd[0])
		write_coord_f(flEnd[1])
		write_coord_f(flEnd[2])
		write_short(attacker)
		write_byte(GUNSHOT_DECALS[random_num ( 0, sizeof GUNSHOT_DECALS -1 ) ] )
		message_end()
	}

	if(is_user_alive(ent) && zp_get_user_zombie(ent) && !zp_get_user_zombie(attacker) && !g_endround)
	{
		new hitgroup = get_tr2(ptr, TR_iHitgroup)

		g_dmg[attacker][ent] = get_pcvar_float(cvar_hits[0])

		if(hitgroup != 0) g_dmg[attacker][ent] *= get_pcvar_float(cvar_hits[hitgroup])

		message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("ScreenShake"), _, ent)
		write_short(UNIT_SECOND * 4) // amplitude
		write_short(UNIT_SECOND * 2) // duration
		write_short(UNIT_SECOND * 10) // frequency
		message_end()

		new Float: end[3] 
		get_tr2(ptr, TR_vecEndPos, end)

		new bloodsize = 0
		if(hitgroup == 1) bloodsize = get_pcvar_num(cvar_bloodsizehs)
		if(hitgroup != 1 && hitgroup != 0) bloodsize = get_pcvar_num(cvar_bloodsize)

		if(!bloodsize) 
			return HAM_IGNORED;

		message_begin(MSG_BROADCAST,SVC_TEMPENTITY) 
		write_byte(TE_BLOODSPRITE) 
		engfunc(EngFunc_WriteCoord, end[0]) 
		engfunc(EngFunc_WriteCoord, end[1]) 
		engfunc(EngFunc_WriteCoord, end[2]) 
		write_short(Blood_Sprites[0]) 
		write_short(Blood_Sprites[1]) 
		write_byte(get_pcvar_num(cvar_bloodcolor))
		write_byte(bloodsize)
		message_end() 
	}

	return HAM_IGNORED;
}

public fw_knifeidleanim(weapon)
{
	new id = get_pdata_cbase(weapon, 41, 4)
	new iClip = get_pdata_int(weapon, m_iClip, 4)


	if(!is_user_alive(id) || zp_get_user_zombie(id) || !g_has_skull3[id] || get_user_weapon(id) != CSW_UMP45)
		return HAM_IGNORED;

	if(g_primaryattack[id]) 
		return HAM_SUPERCEDE;

	if(g_mode[id]) 
	{
		if(iClip > 2) UTIL_PlayweaponAnimation(id, 6)
                if(iClip < 2) UTIL_PlayweaponAnimation(id, 7) 
		return HAM_SUPERCEDE;
	}

	return HAM_IGNORED;
}

public make_shoot(id)
{
	if(!is_user_alive(id))
		return;

	if(zp_get_user_zombie(id))
		return;

	if(get_user_weapon(id) != CSW_UMP45)
		return;

	if(!g_has_skull3[id])
		return;

	new szClip
	get_user_weapon(id, szClip)

	replace_weapon_models(id,CSW_UMP45)

	remove_task(id)
        new b
        if(!g_mode[id]) b = 3
        else b = 1

	if(szClip >= b)
	{
		if(!g_mode[id]) UTIL_PlayweaponAnimation(id, random_num(3, 5))	
		else UTIL_PlayweaponAnimation(id, random_num(8, 12))

		if(get_pcvar_num(cvar_shellslife) > 0) make_shell(id)
	} 
        if(g_mode[id] && szClip == 2)
	{
		UTIL_PlayweaponAnimation(id, 10)	

		if(get_pcvar_num(cvar_shellslife) > 0) make_shell(id)

        }
        if(g_mode[id] && szClip == 1)
	{
		UTIL_PlayweaponAnimation(id, 13)	

		if(get_pcvar_num(cvar_shellslife) > 0) make_shell(id)

        }
	set_pev(id,pev_punchangle,{0.0,0.0,0.0})
	g_primaryattack[id] = 1
		
	engfunc(EngFunc_EmitSound, id, CHAN_WEAPON, Fire_Sounds[0], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)

	g_lastshoot[id] = get_gametime()
}

public fw_takedamage(victim, inflictor, attacker, Float:damage)
{
	if(!is_user_alive(attacker) || !is_user_alive(victim) || !zp_get_user_zombie(victim) || zp_get_user_zombie(attacker) || !g_has_skull3[attacker] || get_user_weapon(attacker) != CSW_UMP45 || victim == attacker)
		return;

	SetHamParamFloat(4, g_dmg[attacker][victim])
}

public fw_takedamageb(ent, inflictor, attacker, Float:damage)
{
	if(!is_user_alive(attacker) || zp_get_user_zombie(attacker) || !g_has_skull3[attacker] || get_user_weapon(attacker) != CSW_UMP45 || ent == attacker)
		return;

	SetHamParamFloat(4, get_pcvar_float(cvar_hits[0]))
}

public fw_precachevent_post(type, const name[])
{
	if (equal("events/ump45.sc", name) )
	{
		g_orig_event_skull3 = get_orig_retval()
		return FMRES_HANDLED
	}

	return FMRES_IGNORED
}

public fw_setmodel(entity, model[])
{
	if(!is_valid_ent(entity))
		return FMRES_IGNORED;
	
	static szClassName[33]
	entity_get_string(entity, EV_SZ_classname, szClassName, charsmax(szClassName))
		
	if(!equal(szClassName, "weaponbox"))
		return FMRES_IGNORED;
	
	static owner
	
	owner = entity_get_edict(entity, EV_ENT_owner)
	
	if(equal(model, "models/w_ump45.mdl"))
	{
		static storeweaponid
		
		storeweaponid = find_ent_by_owner(ENG_NULLENT, "weapon_ump45", entity)
	
		if(!is_valid_ent(storeweaponid))
			return FMRES_IGNORED;
	
		if(g_has_skull3[owner])
		{
			entity_set_int(storeweaponid, EV_INT_WEAPONKEY, SKULL3_WEAPONKEY)

			remove_task(owner)
			g_has_skull3[owner] = false
                	set_weaplist(owner, 0)
			g_reload[owner] = 0
			g_primaryattack[owner] = 0
                        g_mode[owner] = 0
                        g_change[owner] = 0
			
			entity_set_model(entity, SKULL3_W_MODEL)
			
			return FMRES_SUPERCEDE;
		}
                return FMRES_IGNORED;
	}
	return FMRES_IGNORED;
}

public fw_cmdstart(id, uc_handle, seed)
{
	if(!is_user_alive(id) || !is_user_connected(id))
		return FMRES_IGNORED
	
	if(zp_get_user_zombie(id) || zp_get_user_survivor(id))
		return FMRES_IGNORED
	
	if(get_user_weapon(id) != CSW_UMP45)
		return FMRES_IGNORED
	
	if(!g_has_skull3[id])
		return FMRES_IGNORED	
	
	if(g_reload[id] || g_change[id])
		return FMRES_IGNORED

	if((get_uc(uc_handle, UC_Buttons) & IN_USE) && !(pev(id, pev_oldbuttons) & IN_USE))
	{
		if(get_gametime() - 1.5 > g_change_time[id])
		{
			if(!g_mode[id]) make_mode_2(id)
                        else make_mode_1(id)

        		g_change_time[id] = get_gametime()
		}
	}


	if((get_uc(uc_handle, UC_Buttons) & IN_ATTACK2) && !(pev(id, pev_oldbuttons) & IN_ATTACK2))
	{
		if(g_mode[id])
			return FMRES_IGNORED

		if(get_gametime() - 0.5 > g_zoom_time[id])
		{
			if(!g_zoomed[id])
			{
				cs_set_user_zoom(id, CS_SET_AUGSG552_ZOOM, 1)
				engfunc(EngFunc_EmitSound, id, CHAN_WEAPON, Zoom_Sounds[0], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
				g_zoomed[id] = 1
			} 
			else 
			{
				cs_set_user_zoom(id, CS_RESET_ZOOM, 1)
				engfunc(EngFunc_EmitSound, id, CHAN_WEAPON, Zoom_Sounds[0], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
				g_zoomed[id] = 0
			}
			g_zoom_time[id] = get_gametime()
		}	
	}
	
	return HAM_SUPERCEDE;
}

public make_mode_1(id)
{
	g_change[id] = 1
	set_task(get_pcvar_float(cvar_time_change_mode), "set_mode_1", id)
	ExecuteHam(Ham_Weapon_Reload, find_ent_by_owner ( -1, "weapon_ump45", id ))
	UTIL_PlayweaponAnimation(id, 17)
	set_pdata_float(id, m_flNextAttack, get_pcvar_float(cvar_time_change_mode), PLAYER_LINUX_XTRA_OFF)

}

public make_mode_2(id)
{
        if(g_zoomed[id])
        {
		cs_set_user_zoom(id, CS_RESET_ZOOM, 1)
		g_zoomed[id] = 0
        }

	g_change[id] = 1
	set_task(get_pcvar_float(cvar_time_change_mode_2), "set_mode_2", id)
	ExecuteHam(Ham_Weapon_Reload, find_ent_by_owner ( -1, "weapon_ump45", id ))
	UTIL_PlayweaponAnimation(id, 16)
	set_pdata_float(id, m_flNextAttack, get_pcvar_float(cvar_time_change_mode_2), PLAYER_LINUX_XTRA_OFF)
}

public set_mode_1(id)
{
        if(!is_user_alive(id))
		return;

	if(get_user_weapon(id) != CSW_UMP45)
		return;

	if(g_change[id])
	{
		g_change[id] = 0
		g_mode[id] = 0
		replace_weapon_models(id, CSW_UMP45)
                set_weaplist(id , 1)
	}
}

public set_mode_2(id)
{
        if(!is_user_alive(id))
		return;

	if(get_user_weapon(id) != CSW_UMP45)
		return;

	if(g_change[id])
	{
		g_change[id] = 0
		g_mode[id] = 1
		replace_weapon_models(id, CSW_UMP45)
                set_weaplist(id , 1)
	}
}

public fw_skull3_addtoplayer(skull3, id)
{
	if(!is_valid_ent(skull3) || !is_user_alive(id) || zp_get_user_zombie(id))
		return HAM_IGNORED;

	if(entity_get_int(skull3, EV_INT_WEAPONKEY) == SKULL3_WEAPONKEY)
	{
		set_weaplist(id , 1)
		remove_task(id)
		g_has_skull3[id] = true
		g_primaryattack[id] = 0
                g_mode[id] = 0
		g_reload[id] = 0
                g_zoomed[id] = 0
		
		entity_set_int(skull3, EV_INT_WEAPONKEY, 0)
		
		return HAM_HANDLED;
	}
	
	return HAM_IGNORED;
}

public fw_skull3_primaryattack_post(weapon)
{
	new player = get_pdata_cbase(weapon, 41, 4)

	if(!is_user_alive(player) || zp_get_user_zombie(player) || !g_has_skull3[player] || !g_primaryattack[player])
		return;

	g_primaryattack[player] = 0

	set_pev(player,pev_punchangle,{0.0,0.0,0.0})
	make_punchangle(player)
}

public fw_skull3_itempostframe(weapon) 
{
	new player = get_pdata_cbase(weapon, 41, 4)

	if(!is_user_alive(player) || zp_get_user_zombie(player) || !g_has_skull3[player])
		return HAM_IGNORED;

	new Float:flNextAttack = get_pdata_float(player, m_flNextAttack, PLAYER_LINUX_XTRA_OFF)

	new iBpAmmo = cs_get_user_bpammo(player, CSW_UMP45)
	new iClip = get_pdata_int(weapon, m_iClip, WEAP_LINUX_XTRA_OFF)

	new fInReload = get_pdata_int(weapon, m_fInReload, WEAP_LINUX_XTRA_OFF) 

	if( fInReload && flNextAttack <= 0.0 )
	{
		new d, j
	        
                if(!g_mode[player]) d = get_pcvar_num(cvar_clip)
                else d = get_pcvar_num(cvar_clip_2)
                j = min(d - iClip, iBpAmmo)

		set_pdata_int(weapon, m_iClip, iClip + j, WEAP_LINUX_XTRA_OFF)
		cs_set_user_bpammo(player, CSW_UMP45, iBpAmmo - j);
		
		set_pdata_int(weapon, m_fInReload, 0, WEAP_LINUX_XTRA_OFF)
		fInReload = 0
	}

	return HAM_IGNORED;
}

public fw_usestationary_post(entity, caller, activator, use_type)
{
	if (use_type == USE_STOPPED && is_user_alive(caller))
		replace_weapon_models(caller, get_user_weapon(caller))
}

public fw_itemdeploy_post(weapon_ent)
{
	static owner
	owner = fm_cs_get_weapon_ent_owner(weapon_ent)
	
	static weaponid
	weaponid = cs_get_weapon_id(weapon_ent)
	
	replace_weapon_models(owner, weaponid)
}

public fw_updateclientdata_post(player, sendweapons, cd_handle)
{
	if(!is_user_alive(player) || get_user_weapon(player) != CSW_UMP45 || !g_has_skull3[player])
		return FMRES_IGNORED

	set_cd(cd_handle, CD_flNextAttack, halflife_time () + 0.001)

	return FMRES_HANDLED
}

public fw_playbackevent(flags, invoker, eventid, Float:delay, Float:origin[3], Float:angles[3], Float:fparam1, Float:fparam2, iParam1, iParam2, bParam1, bParam2)
{
	if (eventid != g_orig_event_skull3)
		return FMRES_IGNORED

	if (!(1 <= invoker <= 32))
		return FMRES_IGNORED

	if (!g_has_skull3[invoker])
		return FMRES_IGNORED

	playback_event(flags | FEV_HOSTONLY, invoker, eventid, delay, origin, angles, fparam1, fparam2, iParam1, iParam2, bParam1, bParam2)
	return FMRES_SUPERCEDE
}

public fw_skull3_reload(weapon)
{
	if(!is_valid_ent(weapon)) return HAM_IGNORED;

	new id = get_pdata_cbase(weapon, 41, 4)

	if (!is_user_alive(id) || !g_has_skull3[id] || g_change[id])
		return HAM_IGNORED;

	g_skull3_tmpclip[id] = -1

	new iBpAmmo = cs_get_user_bpammo(id, CSW_UMP45)
	new iClip = get_pdata_int(weapon, m_iClip, WEAP_LINUX_XTRA_OFF)
        new d;

        if(!g_mode[id]) d = get_pcvar_num(cvar_clip)
        else  d = get_pcvar_num(cvar_clip_2)

	if (iBpAmmo <= 0)
		return HAM_SUPERCEDE;

	if (iClip >= d)
		return HAM_SUPERCEDE;

	g_skull3_tmpclip[id] = iClip;

	if(g_zoomed[id])
	{ 
		cs_set_user_zoom(id, CS_RESET_ZOOM, 1)
		g_zoomed[id] = 0
	}

	return HAM_IGNORED;
}

public fw_skull3_reload_post(weapon) 
{
	if(!is_valid_ent(weapon)) return HAM_IGNORED;

	new id = get_pdata_cbase(weapon, 41, 4)

	if (!is_user_alive(id) || !g_has_skull3[id] || g_change[id])
		return HAM_IGNORED;

	if (g_skull3_tmpclip[id] == -1)
		return HAM_IGNORED;

	new iBpAmmo = cs_get_user_bpammo(id, CSW_UMP45)

	if (iBpAmmo <= 0)
		return HAM_IGNORED;

        if(g_change[id])
		return HAM_IGNORED;

        new Float:reload_time;
        if(!g_mode[id]) reload_time = get_pcvar_float(cvar_time_reload)
        else reload_time = get_pcvar_float(cvar_time_reload_2)

	set_pdata_int(weapon, m_iClip, g_skull3_tmpclip[id], WEAP_LINUX_XTRA_OFF)

	set_pdata_float(weapon, m_flTimeweaponIdle, reload_time, WEAP_LINUX_XTRA_OFF)

	set_pdata_float(id, m_flNextAttack, reload_time, PLAYER_LINUX_XTRA_OFF)

	set_pdata_int(weapon, m_fInReload, 1, WEAP_LINUX_XTRA_OFF)
	
	if(g_mode[id]) UTIL_PlayweaponAnimation(id, 14)
        else UTIL_PlayweaponAnimation(id, 1)

	remove_task(id)
	g_reload[id] = 1 
	set_task(reload_time, "reload_task", id)

	return HAM_IGNORED;
}

public fw_playerspawn_post(id)
{
	if(!is_user_alive(id) || zp_get_user_zombie(id))
		return;

	if(!return_has_weapon(id, "weapon_ump45")) 
	{
		set_weaplist(id , 0)
		g_has_skull3[id] = false
                g_mode[id] = 0
	}

	if(g_zoomed[id])
	{ 
		cs_set_user_zoom(id, CS_RESET_ZOOM, 1)
		g_zoomed[id] = 0
	}

	remove_task(id)
        g_reload[id] = 0
        g_change[id] = 0
	g_primaryattack[id] = 0
}

public reload_task(id)
{
	if(!is_user_alive(id) || zp_get_user_zombie(id))
		return;

        if(get_user_weapon(id) != CSW_UMP45)
		return;

        if(!g_has_skull3[id] || g_change[id]) 
		return;
        new d
        if(!g_mode[id]) d = get_pcvar_num(cvar_clip)
        else d = get_pcvar_num(cvar_clip_2)

	new weapon = find_ent_by_owner ( -1, "weapon_ump45", id)

	new iBpAmmo = cs_get_user_bpammo(id, CSW_UMP45);
	new iClip = get_pdata_int(weapon, m_iClip, WEAP_LINUX_XTRA_OFF)

	new j = min(d - iClip, iBpAmmo)
	
	set_pdata_int(weapon, m_iClip, iClip + j, WEAP_LINUX_XTRA_OFF)
	cs_set_user_bpammo(id, CSW_UMP45, iBpAmmo-j);

	g_reload[id] = 0
}

public give_skull3(id)
{
	if(!is_user_alive(id) || zp_get_user_zombie(id))
		return;

	drop_secweaps(id)
	set_weaplist(id , 1)
	remove_task(id)
	g_reload[id] = 0
        g_change[id] = 0
        g_mode[id] = 0

	if(g_zoomed[id])
	{ 
		cs_set_user_zoom(id, CS_RESET_ZOOM, 1)
		g_zoomed[id] = 0
	}

	g_primaryattack[id] = 0
	g_has_skull3[id] = true

	new weap = give_item(id,"weapon_ump45")

	cs_set_weapon_ammo(weap, get_pcvar_num(cvar_clip))
	cs_set_user_bpammo (id, CSW_UMP45, get_pcvar_num(cvar_ammo))

	if(g_oldweap[id] == CSW_UMP45)
	{
		replace_weapon_models(id, CSW_UMP45)
		if(g_mode[id]) UTIL_PlayweaponAnimation(id, 15)
		else UTIL_PlayweaponAnimation(id, 2)
		set_pdata_float(id, m_flNextAttack, SKULL3_DRAW_TIME , PLAYER_LINUX_XTRA_OFF)	
	}
}

public zp_extra_item_selected(id, itemid)
{
	if(itemid == -1)
		return;

	if(itemid != g_itemid_skull3)
		return;

	give_skull3(id)
}

public replace_weapon_models(id, weaponid)
{
	if(!is_user_alive(id))
		return;

	if(zp_get_user_zombie(id))
		return;

	if(!g_has_skull3[id])
		return;

	if(weaponid == CSW_UMP45)
	{
		set_pev(id, pev_viewmodel2, SKULL3_V_MODEL)
		set_pev(id, pev_weaponmodel2, g_mode[id] ? SKULL3_P_MODEL_2:SKULL3_P_MODEL)

	        // Hide the HL crosshair that's drawn
	        message_begin(MSG_ONE, get_user_msgid("Crosshair"), _, id)
	        write_byte(0) // toggle
	        message_end()

		if(g_oldweap[id] != CSW_UMP45) 
		{
			if(!g_mode[id]) UTIL_PlayweaponAnimation(id, ANIM_DRAW)
			else UTIL_PlayweaponAnimation(id, ANIM_DRAW_2)
			set_pdata_float(id, m_flNextAttack, SKULL3_DRAW_TIME , PLAYER_LINUX_XTRA_OFF)	
		}
	}

	if(weaponid != CSW_UMP45)
	{
		remove_task(id)
		g_reload[id] = 0
		g_change[id] = 0
	}

	g_oldweap[id] = weaponid
}

public make_punchangle(id)
{
	if(!is_user_alive(id) || zp_get_user_zombie(id))
		return;

        if(get_user_weapon(id) != CSW_UMP45)
		return;

        if(!g_has_skull3[id])
		return;

	static Float:punchAngle[3]

	if(g_zoomed[id]) punchAngle[0] = -1*get_pcvar_float(cvar_recoil_2)
        else  punchAngle[0] = -1*get_pcvar_float(cvar_recoil)
	set_pev(id, pev_punchangle, punchAngle);
}

public make_shell(id)
{
	if(!is_user_alive(id) || zp_get_user_zombie(id))
		return;

        if(get_user_weapon(id) != CSW_UMP45) 
		return;

        if(!g_has_skull3[id])
		return;

	static Float:player_origin[3],Float:origin[3],Float:origin2[3],Float:gunorigin[3], Float:oldangles[3],Float:v_forward[3], Float:v_forward2[3], Float:v_up[3],Float:v_up2[3],Float:v_right[3],Float:v_right2[3],Float:viewoffsets[3];
	pev(id,pev_v_angle, oldangles)
	pev(id,pev_origin,player_origin)
	pev(id, pev_view_ofs, viewoffsets);

	engfunc(EngFunc_MakeVectors, oldangles);

	global_get(glb_v_forward, v_forward);
	global_get(glb_v_up, v_up);
	global_get(glb_v_right, v_right);

	global_get(glb_v_forward, v_forward2);
	global_get(glb_v_up, v_up2);
	global_get(glb_v_right, v_right2);

	xs_vec_add(player_origin, viewoffsets, gunorigin);

	xs_vec_mul_scalar(v_forward, 10.3, v_forward);
	xs_vec_mul_scalar(v_right, 2.9, v_right);
	xs_vec_mul_scalar(v_up, -3.7, v_up);

	xs_vec_mul_scalar(v_forward2, random_float(10.0,11.0), v_forward2);
	xs_vec_mul_scalar(v_right2, random_float(3.0,3.1), v_right2);
	xs_vec_mul_scalar(v_up2, -4.0, v_up2);

	xs_vec_add(gunorigin, v_forward, origin);
	xs_vec_add(gunorigin, v_forward2, origin2);
	xs_vec_add(origin, v_right, origin);
	xs_vec_add(origin2, v_right2, origin2);
	xs_vec_add(origin, v_up, origin);
	xs_vec_add(origin2, v_up2, origin2);

	new Float:velocity[3]
	get_speed_vector(origin2,origin,random_float(140.0,160.0),velocity)
	
	new angle = random_num(0,360)

	message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY,_,id)
	write_byte(TE_MODEL)
	write_coord_f(origin[0])
	write_coord_f(origin[1])
	write_coord_f(origin[2])
	write_coord_f(velocity[0])
	write_coord_f(velocity[1])
	write_coord_f(velocity[2])
	write_angle(angle)
	write_short(Shells_Model)
	write_byte(1)
	write_byte(get_pcvar_num(cvar_shellslife) * 10)
	message_end()	

	new Float:origin3[3] //origin for spectate FP
	origin3 = origin

	xs_vec_mul_scalar(v_forward, 3.9, v_forward);
	xs_vec_add(origin, v_forward, origin);

	for(new i;i<=32;i++)
	{
		if(!is_user_connected(i) || i == id) continue;

		if(!is_user_alive(i) && pev(i,pev_iuser2) == id && pev(i, pev_iuser1) == 4)
		{
			message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY,_,i)
			write_byte(TE_MODEL)
			write_coord_f(origin3[0])
			write_coord_f(origin3[1])
			write_coord_f(origin3[2])
			write_coord_f(velocity[0])
			write_coord_f(velocity[1])
			write_coord_f(velocity[2])
			write_angle(angle)
			write_short(Shells_Model)
			write_byte(1)
			write_byte(get_pcvar_num(cvar_shellslife) * 10)
			message_end()	
		}else{
			message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY,_,i)
			write_byte(TE_MODEL)
			write_coord_f(origin[0])
			write_coord_f(origin[1])
			write_coord_f(origin[2])
			write_coord_f(velocity[0])
			write_coord_f(velocity[1])
			write_coord_f(velocity[2])
			write_angle(angle)
			write_short(Shells_Model)
			write_byte(1)
			write_byte(get_pcvar_num(cvar_shellslife) * 10)
			message_end()	
		}
	}
}

public message_deathmsg(msg_id, msg_dest, id)
{
	static szTruncatedWeapon[33], iAttacker, iVictim
	
	get_msg_arg_string(4, szTruncatedWeapon, charsmax(szTruncatedWeapon))
	
	iAttacker = get_msg_arg_int(1)
	iVictim = get_msg_arg_int(2)
	
	if(!is_user_connected(iAttacker) || iAttacker == iVictim)
		return PLUGIN_CONTINUE
	
	if(equal(szTruncatedWeapon, "ump45") && get_user_weapon(iAttacker) == CSW_UMP45)
	{
		if(g_has_skull3[iAttacker])
			set_msg_arg_string(4, "skull3")
	}

	return PLUGIN_CONTINUE
}

public msg_weaplist(msg_id, msg_dest, msg_entity)
{
	if(get_msg_arg_int(8) == CSW_UMP45)
	{
		ump45_vars[2] = get_msg_arg_int(2)
		ump45_vars[3] = get_msg_arg_int(3)
		ump45_vars[4] = get_msg_arg_int(4)
		ump45_vars[5] = get_msg_arg_int(5)
		ump45_vars[6] = get_msg_arg_int(6)
		ump45_vars[7] = get_msg_arg_int(7)
		ump45_vars[8] = get_msg_arg_int(8)
		ump45_vars[9] = get_msg_arg_int(9)
	}
}

public set_weaplist(id, num)
{
	if(!is_user_connected(id))
		return;
        if(!num){
	message_begin(MSG_ONE, get_user_msgid("WeaponList"), {0,0,0}, id) 
	write_string("weapon_ump45") 
	write_byte(ump45_vars[2]) 
	write_byte(ump45_vars[3]) 
	write_byte(ump45_vars[4]) 
	write_byte(ump45_vars[5]) 
	write_byte(ump45_vars[6]) 
	write_byte(ump45_vars[7]) 
	write_byte(ump45_vars[8]) 
	write_byte(ump45_vars[9]) 
	message_end()
        }else{
	message_begin(MSG_ONE, get_user_msgid("WeaponList"), {0,0,0}, id) 
	write_string(g_mode[id] ? "weapon_skull3d_geet":"weapon_skull3_geet") 
	write_byte(ump45_vars[2]) 
	write_byte(ump45_vars[3]) 
	write_byte(ump45_vars[4]) 
	write_byte(ump45_vars[5]) 
	write_byte(ump45_vars[6]) 
	write_byte(ump45_vars[7]) 
	write_byte(ump45_vars[8]) 
	write_byte(ump45_vars[9]) 
	message_end() 
        }
}

public client_cmd_skull3(id)
{
	if(!is_user_alive(id))
		return;

    	if(!g_has_skull3[id])
		return;

	engclient_cmd(id,"weapon_ump45")
}

public zero_values(id)
{
	set_weaplist(id , 0)

	remove_task(id)

	g_reload[id] = 0
	g_mode[id] = 0
	g_change[id] = 0
	g_primaryattack[id] = 0

	if(g_zoomed[id])
	{ 
		cs_set_user_zoom(id, CS_RESET_ZOOM, 1)
		g_zoomed[id] = 0
	}

	g_has_skull3[id] = false
}

stock fm_cs_get_current_weapon_ent(id)
{
	return get_pdata_cbase(id, OFFSET_ACTIVE_ITEM, OFFSET_LINUX);
}

stock fm_cs_get_weapon_ent_owner(ent)
{
	return get_pdata_cbase(ent, OFFSET_WEAPONOWNER, OFFSET_LINUX_WEAPONS);
}

stock UTIL_PlayweaponAnimation(const player, const Sequence)
{
	set_pev(player, pev_weaponanim, Sequence)
	
	message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = player)
	write_byte(Sequence)
	write_byte(pev(player, pev_body))
	message_end()
}

stock get_speed_vector(const Float:origin1[3],const Float:origin2[3],Float:speed, Float:new_velocity[3])
{
	new_velocity[0] = origin2[0] - origin1[0]
	new_velocity[1] = origin2[1] - origin1[1]
	new_velocity[2] = origin2[2] - origin1[2]
	new Float:num = floatsqroot(speed*speed / (new_velocity[0]*new_velocity[0] + new_velocity[1]*new_velocity[1] + new_velocity[2]*new_velocity[2]))
	new_velocity[0] *= num
	new_velocity[1] *= num
	new_velocity[2] *= num
       
	return 1;
}

stock ent_move_to(Float:target[3], speed , vec)
{
	static Float:vec[3]
	aim_at_origin(ent,target,vec)
	engfunc(EngFunc_MakeVectors, vec)
	global_get(glb_v_forward, vec)
	vec[0] *= speed
	vec[1] *= speed
	vec[2] *= speed 
}

stock aim_at_origin(id, Float:target[3], Float:angles[3])
{
	static Float:vec[3]
	pev(id,pev_origin,vec)
	vec[0] = target[0] - vec[0]
	vec[1] = target[1] - vec[1]
	vec[2] = target[2] - vec[2]
	engfunc(EngFunc_VecToAngles,vec,angles)
	angles[0] *= -1.0
}

stock drop_secweaps(id)
{
	static weapons[32], num, i, weaponid
	num = 0
	get_user_weapons(id, weapons, num)
	
	for (i = 0; i < num; i++)
	{
		weaponid = weapons[i]
		
		if ((1<<weaponid) & SECONDARY_WEAPONS_BITSUM)
		{
			static wname[32]
			get_weaponname(weaponid, wname, sizeof wname - 1)
			engclient_cmd(id, "drop", wname)
		}
	}
}

stock return_has_weapon(id, const findstring[])
{
	static weapons[32], num, i, weaponid
	num = 0
	get_user_weapons(id, weapons, num)
	
	for (i = 0; i < num; i++)
	{
		weaponid = weapons[i]
		
		static wname[32]
		get_weaponname(weaponid, wname, sizeof wname - 1)
		if(equal(wname,findstring)) return 1;
	}

	return 0;
}

public ev_curweapon(id) 
{
	replace_weapon_models(id, read_data(2))

	if(read_data(2) != CSW_UMP45 || !g_has_skull3[id])
		return
     
	static Float:iSpeed

	if(g_mode[id])
		iSpeed = get_pcvar_float(cvar_speed_shoot_2)
        else
		iSpeed = get_pcvar_float(cvar_speed_shoot_1)


	static weapon[32],Ent
	get_weaponname(read_data(2),weapon,31)
	Ent = find_ent_by_owner(-1,weapon,id)

	if(Ent)
	{
		static Float:Delay
		Delay = get_pdata_float( Ent, 46, 4) * iSpeed

		if (Delay > 0.0)
		{
			set_pdata_float(Ent, 46, Delay, 4)
		}
	}

}


public zp_user_infected_post(id) zero_values(id)
public client_connect(id) zero_values(id)
public client_disconnect(id) zero_values(id)
public plugin_natives() register_native("give_weapon_skull3", "native_give_SKULL3", 1)
public native_give_SKULL3(id) give_skull3(id)
public zp_round_started() g_endround = 0
public zp_round_ended() g_endround = 1