#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <fakemeta_util>
#include <hamsandwich>
#include <cstrike>
#include <bmm>

#define PLUGIN "[ZP] Extra Item: Weapon Equipment"
#define VERSION "1.0"
#define AUTHOR "Asdian + BTE Team"

#define weapon_equip "weapon_m249"
#define CSW_EQUIP CSW_M249

// Enable this if u want (Airburster's Muzzleflash)
//define ENABLE_AIRBURSTER_MUZZ

// Damages
#define DAMAGE_AIRBURSTER 110.0
#define DAMAGE_AIRBURSTER2 196.0
#define DAMAGE_AT4EX 495.0
#define DAMAGE_CANNON 850.0
#define DAMAGE_DRILLGUN 487.3
#define DAMAGE_FGLAUNCHER_M32 492.6
#define DAMAGE_PETROL 300.0
#define DAMAGE_POWERSAW (30.0 * 1.19)
#define DAMAGE_POWERSAW2 (55.0 * 3.05)
#define DAMAGE_RPG7 450.0
#define DAMAGE_SALAMANDER 90.0
#define DAMAGE_SPEARGUN 596.0
#define DAMAGE_WATERCANNON 85.0

// Knockback
#define KNOCKBACK_AIRBURSTER 150.0
#define KNOCKBACK_AIRBURSTER2 950.0
#define KNOCKBACK_AT4EX 200.0
#define KNOCKBACK_CANNON 2000.0
#define KNOCKBACK_FGLAUNCHER 300.0
#define KNOCKBACK_M32 350.0
#define KNOCKBACK_POWERSAW 1565.0
#define KNOCKBACK_SPEARGUN 300.0

// Speed
#define SPEED_AT4EX 1335.0

#define WEAPON_TOTAL 12
const DEFAULT_DMGTYPE = (1<<3)|(1<<4)|(1<<5)

new g_type[33], g_special[33], Float:g_lastaim[33], g_aiming[33], is_reloading[33], g_iClip[33], s_exp, s_break, s_flame, Float:g_cache_frame_flame
new g_cache_smoke[2], g_exp[2], g_smoke_id, g_cache_trail, g_cache_flameburn, g_cache_blood, g_cache_bloodspray, g_cache_fg[2]
 
new g_itemid
 
new g_m32_reload[33], Float:g_cannon_timer[33], g_wpn_flame_isshooting[33], Float:g_wpn_flame_timer[33], g_had_weapon[33][WEAPON_TOTAL] // This just for give and model function
new g_ammo[33][4], g_zoom[33], g_mode[33], g_register[WEAPON_TOTAL], g_iEnt[33][3], Float:Null[3] = {0.0,0.0,0.0}

enum _:Code(+= 1902)
{
	CODE_AIRBURSTER = 23672,
	CODE_AT4EX,
	CODE_CANNON,
	CODE_DRILLGUN,
	CODE_FGLAUNCHER,
	CODE_FLAMETHROWER,
	CODE_M32,
	CODE_PETROLBOOMER,
	CODE_POWERSAW,
	CODE_RPG7,
	CODE_SPEARGUN,
	CODE_WATERCANNON
}

enum _:HadType
{
	HAD_AIRBURSTER = 0,
	HAD_AT4EX,
	HAD_CANNON,
	HAD_DRILLGUN,
	HAD_FGLAUNCHER,
	HAD_FLAMETHROWER,
	HAD_M32,
	HAD_PETROLBOOMER,
	HAD_POWERSAW,
	HAD_RPG7,
	HAD_SPEARGUN,
	HAD_WATERCANNON
}


enum _:HIT_RESULT
{
	RESULT_HIT_NONE = 0,
	RESULT_HIT_PLAYER,
	RESULT_HIT_WORLD
}

enum _:TYPE // Weapon Type
{
	TYPE_NONE = 0,
	TYPE_NADE,
	TYPE_FLAME,
	TYPE_SPRELOAD
}

enum _:SPECIAL // Special
{
	SP_NONE = 0,
	SP_AIRBURSTER,
	SP_AT4EX,
	SP_CANNON,
	SP_DRILLGUN,
	SP_FGLAUNCHER,
	SP_FLAMETHROWER,
	SP_M32,
	SP_PETROLBOOMER,
	SP_RPG7,
	SP_SPEARGUN,
	SP_WATERCANNON
}

enum _:ENTCLASS(+=999)
{
	ENTCLASS_NADE = 777, // at4, fglauncher, m32, petrol, rpg7
	ENTCLASS_FLAME, // flamethrower, watercannon, airbuster
	ENTCLASS_CANNON, // cannon
	ENTCLASS_METAL, // speargun, drillgun
	ENTCLASS_SMOKE,
	ENTCLASS_MUZZLE1,
	ENTCLASS_MUZZLE2,
	ENTCLASS_PETROL,
	ENTCLASS_FLAME_PETROL,
	ENTCLASS_FLAME_PETROL2
}

new const ShootSound[][] =
{
	"weapons/at4-1.wav", // 0
	"weapons/flamegun-1.wav",
	"weapons/watercannon_shoot1.wav", // 2
	"weapons/cannon-1.wav",
	"weapons/speargun-1.wav",
	
	"weapons/chainsaw_hit1.wav", // 5
	"weapons/chainsaw_hit2.wav", // 6
	"weapons/chainsaw_hit3.wav",
	"weapons/chainsaw_hit4.wav",
	
	"weapons/drillgun-1.wav", // 9
	"weapons/fglauncher-1.wav", // 10
	"weapons/m32-1.wav",
	"weapons/fgrenade_exp.wav", // 12
	"weapons/airburster_shoot.wav",
	"weapons/airburster_shoot2.wav",
	"weapons/petrolboomer_shoot.wav", // 15
	"weapons/rpg7_shoot.wav",
	"weapons/watercannon_shoot_start.wav"
}

new const Model_P[][] =
{
	"models/p_airburster.mdl",
	"models/p_at4ex.mdl",
	"models/p_cannon.mdl",
	"models/p_drillgun.mdl",
	"models/p_fglauncher.mdl",
	"models/p_flamethrower.mdl",
	"models/p_m32.mdl",
	"models/p_petrolboomer.mdl",
	"models/p_chainsaw.mdl",
	"models/p_rpg7.mdl",
	"models/p_speargun.mdl",
	"models/p_watercannon.mdl"
}

new const Model_V[][] = 
{
	"models/v_airburster.mdl",
	"models/v_at4ex.mdl",
	"models/v_cannon.mdl",
	"models/v_drillgun.mdl",
	"models/v_fglauncher.mdl",
	"models/v_flamethrower.mdl",
	"models/v_m32.mdl",
	"models/v_petrolboomer.mdl",
	"models/v_chainsaw.mdl",
	"models/v_rpg7.mdl",
	"models/v_speargun.mdl",
	"models/v_watercannon.mdl"
}
new const Model_W[] = "models/w_equip.mdl"

new const Model_S[][] = 
{
	"sprites/cso_flame.spr",	// 0
	"sprites/holybomb_exp.spr",
	"models/spear2.mdl",		// 2
	"sprites/spark2.spr",
	"sprites/spark3.spr",		// 4
	"sprites/ef_aircyclone.spr",
	"sprites/ef_airexplosion.spr",	// 6
	"sprites/muzzleflash35.spr",
	"sprites/muzzleflash36.spr",	// 8
	"models/s_petrolboomer.mdl",
	"sprites/flame3.spr",		// 10
	"sprites/fire2.spr",
	"models/s_test.mdl",		// 12
	
	// i cant combine these :3
	"models/s_grenade.mdl",
	"models/s_rocket.mdl"		// 14
}

new const spr[][] = 
{
	"weapon_airburster",
	"weapon_at4ex",
	"weapon_cannon",
	"weapon_drillgun",
	"weapon_fglauncher",
	"weapon_flamethrower",
	"weapon_m32",
	"weapon_petrolboomer",
	"weapon_chainsaw",
	"weapon_rpg7",
	"weapon_speargun",
	"weapon_watercannon"
}

public plugin_init() 
{
	register_plugin(PLUGIN, VERSION, AUTHOR)
	register_message(get_user_msgid("DeathMsg"), "message_DeathMsg")
	
	register_forward(FM_UpdateClientData, "fw_UpdateClientData_Post", 1)
	register_forward(FM_SetModel, "fw_SetModel")
	register_forward(FM_ClientCommand , "fw_ClientCommand")
	
	register_think("env_sprite", "fw_Think2")
	register_think("info_target", "fw_Think")
	register_touch("info_target", "*", "fw_Touch")
	
	RegisterHam(Ham_Item_Deploy, weapon_equip, "fw_Item_Deploy_Post", 1)
	RegisterHam(Ham_Item_Holster, weapon_equip, "fw_Item_Holster_Post", 1)
	RegisterHam(Ham_Item_PostFrame, weapon_equip, "fw_ItemPostFrame")
	RegisterHam(Ham_Weapon_Reload, weapon_equip, "fw_WeaponReload")
	RegisterHam(Ham_Weapon_Reload, weapon_equip, "fw_WeaponReload_Post", 1)
	RegisterHam(Ham_Item_AddToPlayer, weapon_equip, "fw_AddToPlayer", 1)
	
	for(new i = 0; i < sizeof(spr); i++) register_clcmd(spr[i], "hook_weapon")
	register_clcmd("drop", "cmd_drop")
	register_weapons()
}

public plugin_precache()
{
	new i, szSpr[32]
	for(i = 0; i < sizeof(Model_P); i++) engfunc(EngFunc_PrecacheModel, Model_P[i])
	for(i = 0; i < sizeof(Model_V); i++)
	{
		engfunc(EngFunc_PrecacheModel, Model_V[i])
		Stock_PrecacheSound(Model_V[i])
	}
	engfunc(EngFunc_PrecacheModel, Model_W)
	for(i = 0; i < sizeof(Model_S); i++)
	{
		if(i == 0) s_flame = engfunc(EngFunc_PrecacheModel, Model_S[i])
		else if(i == 2) s_break = engfunc(EngFunc_PrecacheModel, Model_S[i])
		else if(i == 3) g_cache_fg[0] = engfunc(EngFunc_PrecacheModel, Model_S[i])
		else if(i == 4) g_cache_fg[1] = engfunc(EngFunc_PrecacheModel, Model_S[i])
		else if(i == 6) s_exp = engfunc(EngFunc_PrecacheModel, Model_S[i])
		else engfunc(EngFunc_PrecacheModel, Model_S[i])
	}
	for(i = 0; i < sizeof(ShootSound); i++) engfunc(EngFunc_PrecacheSound, ShootSound[i])
	for(i = 0; i < sizeof(spr); i++)
	{
		format(szSpr, 31, "sprites/%s.txt", spr[i])
		engfunc(EngFunc_PrecacheGeneric, szSpr)
	}
	
	engfunc(EngFunc_PrecacheSound, "weapons/speargun_metal1.wav")
	engfunc(EngFunc_PrecacheSound, "weapons/speargun_metal2.wav")
	engfunc(EngFunc_PrecacheSound, "weapons/speargun_stone1.wav")
	engfunc(EngFunc_PrecacheSound, "weapons/speargun_stone2.wav")
	engfunc(EngFunc_PrecacheSound, "weapons/speargun_wood1.wav")
	engfunc(EngFunc_PrecacheSound, "weapons/speargun_wood2.wav")
	
	g_cache_blood = precache_model("sprites/blood.spr")
	g_cache_bloodspray = precache_model("sprites/bloodspray.spr")
	g_cache_flameburn = precache_model("sprites/flame_burn01.spr")
	g_cache_smoke[0] = engfunc(EngFunc_PrecacheModel, "sprites/smoke_ia.spr")
	g_cache_smoke[1] = engfunc(EngFunc_PrecacheModel, "sprites/steam1.spr")
	g_exp[0] = engfunc(EngFunc_PrecacheModel, "sprites/eexplo.spr")
	g_exp[1] = engfunc(EngFunc_PrecacheModel, "sprites/fexplo.spr")
	g_smoke_id = engfunc(EngFunc_PrecacheModel, "sprites/effects/rainsplash.spr")
	g_cache_trail = engfunc(EngFunc_PrecacheModel, "sprites/smoke.spr")
	g_cache_frame_flame = float(engfunc(EngFunc_ModelFrames, s_flame))
}

public message_DeathMsg()
{
	static Weapon[33], iAttacker
	get_msg_arg_string(4, Weapon, charsmax(Weapon))
	iAttacker = get_msg_arg_int(1)
	 
	if(!is_user_connected(iAttacker))
		return PLUGIN_CONTINUE
		
	if(equal(Weapon, "m249") && get_user_weapon(iAttacker) == CSW_EQUIP)
	{
		if(g_had_weapon[iAttacker][HAD_AIRBURSTER]) set_msg_arg_string(4, "airburster")
		else if(g_had_weapon[iAttacker][HAD_AT4EX]) set_msg_arg_string(4, "at4ex")
		else if(g_had_weapon[iAttacker][HAD_CANNON]) set_msg_arg_string(4, "cannon")
		else if(g_had_weapon[iAttacker][HAD_DRILLGUN]) set_msg_arg_string(4, "drillgun")
		else if(g_had_weapon[iAttacker][HAD_FGLAUNCHER]) set_msg_arg_string(4, "fglauncher")
		else if(g_had_weapon[iAttacker][HAD_FLAMETHROWER]) set_msg_arg_string(4, "flamethrower")
		else if(g_had_weapon[iAttacker][HAD_M32]) set_msg_arg_string(4, "m32")
		else if(g_had_weapon[iAttacker][HAD_PETROLBOOMER]) set_msg_arg_string(4, "petrolboomer")
		else if(g_had_weapon[iAttacker][HAD_POWERSAW]) set_msg_arg_string(4, "chainsaw")
		else if(g_had_weapon[iAttacker][HAD_RPG7]) set_msg_arg_string(4, "rpg7")
		else if(g_had_weapon[iAttacker][HAD_SPEARGUN]) set_msg_arg_string(4, "speargun")
		else if(g_had_weapon[iAttacker][HAD_WATERCANNON]) set_msg_arg_string(4, "watercannon")
	}
	return PLUGIN_CONTINUE
}

public hook_weapon(id) engclient_cmd(id, weapon_equip)
public register_weapons()
{
	g_itemid = bmm_add_item("Airburster", 0, BMM_TEAM_T, BMM_EQUIP)
	g_itemid = bmm_add_item("AT4CS", 0, BMM_TEAM_T, BMM_EQUIP)
	g_itemid = bmm_add_item("Dragoncannon", 0, BMM_TEAM_T, BMM_EQUIP)
	g_itemid = bmm_add_item("Drillgun", 0, BMM_TEAM_T, BMM_EQUIP)
	g_itemid = bmm_add_item("FG Launcher", 0, BMM_TEAM_T, BMM_EQUIP)
	g_itemid = bmm_add_item("Salamander", 0, BMM_TEAM_T, BMM_EQUIP)
	g_itemid = bmm_add_item("M32 MGL", 0, BMM_TEAM_T, BMM_EQUIP)
	g_itemid = bmm_add_item("Petrolboomer", 0, BMM_TEAM_T, BMM_EQUIP)
	g_itemid = bmm_add_item("Grim Reaper", 0, BMM_TEAM_T, BMM_EQUIP)
	g_itemid = bmm_add_item("RPG-7", 0, BMM_TEAM_T, BMM_EQUIP)
	g_itemid = bmm_add_item("Gae Bolg", 0, BMM_TEAM_T, BMM_EQUIP)
	g_itemid = bmm_add_item("Leviathan", 0, BMM_TEAM_T, BMM_EQUIP)
}

public bmm_item_selected(id, itemid)
{
	if(itemid = g_register[0]) Get_Weapons(id, HAD_AIRBURSTER, SP_AIRBURSTER, TYPE_FLAME, 100, 200)
	else if(itemid == g_register[1]) Get_Weapons(id, HAD_AT4EX, SP_AT4EX, TYPE_NADE, 1, 10)
	else if(itemid == g_register[2]) Get_Weapons2(id, HAD_CANNON, 0, 20, TYPE_NONE, SP_CANNON)
	else if(itemid == g_register[3]) Get_Weapons2(id, HAD_DRILLGUN, 1, 30, TYPE_SPRELOAD, SP_DRILLGUN)
	else if(itemid == g_register[4]) Get_Weapons(id, HAD_FGLAUNCHER, SP_FGLAUNCHER, TYPE_NADE, 10, 40)
	else if(itemid == g_register[5]) Get_Weapons(id, HAD_FLAMETHROWER, SP_FLAMETHROWER, TYPE_FLAME, 100, 200)
	else if(itemid == g_register[6]) Get_Weapons(id, HAD_M32, SP_M32, TYPE_NADE, 6, 36)
	else if(itemid == g_register[7]) Get_Weapons2(id, HAD_PETROLBOOMER, 3, 20, TYPE_SPRELOAD, SP_PETROLBOOMER)
	else if(itemid == g_register[8]) Get_Weapons(id, HAD_POWERSAW, SP_NONE, TYPE_NONE, 200, 200)
	else if(itemid == g_register[9]) Get_Weapons(id, HAD_RPG7, SP_RPG7, TYPE_NADE, 1, 10)
	else if(itemid == g_register[10]) Get_Weapons2(id, HAD_SPEARGUN, 2, 30, TYPE_SPRELOAD, SP_SPEARGUN)
	else if(itemid == g_register[11]) Get_Weapons(id, HAD_WATERCANNON, SP_WATERCANNON, TYPE_FLAME, 100, 200)
}
public Get_Weapons(id, WpnName, SpName, TypeName, iClip, iBpAmmo)
{
	if(!is_user_alive(id))
		return
	
	Stock_Drop_Slot(id, 1)
	
	g_had_weapon[id][WpnName] = 1
	g_special[id] = SpName
	is_reloading[id] = 0
	g_aiming[id] = 0
	g_type[id] = TypeName
	if(SpName == SP_RPG7) g_mode[id] = 0
	
	fm_give_item(id, weapon_equip)
	
	static ent; ent = fm_get_user_weapon_entity(id, CSW_EQUIP)
	if(pev_valid(ent)) cs_set_weapon_ammo(ent, iClip)
	cs_set_user_bpammo(id, CSW_EQUIP, iBpAmmo)
	UpdateClip(id, iClip, iBpAmmo)
}

public Get_Weapons2(id, WpnName, AmmoType, MaxAmmo, iType, iSpecial)
{
	if(!is_user_alive(id))
		return
		
	Stock_Drop_Slot(id, 1)
	
	g_had_weapon[id][WpnName] = 1
	g_ammo[id][AmmoType] = MaxAmmo
	g_type[id] = iType
	g_special[id] = iSpecial
	if(iSpecial == SP_PETROLBOOMER) Create_Flame(id, 0)
	
	fm_give_item(id, weapon_equip)
	update_ammo(id, g_ammo[id][AmmoType])
	client_printc(id, "!t[ZP]!n Press !gbuyammo1!n button to refill ammo")
}

public UpdateClip(id, iClip, BpAmmo)
{
	message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("CurWeapon"), _, id)
	write_byte(1)
	write_byte(CSW_EQUIP)
	write_byte(iClip)
	message_end()
	
	message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("AmmoX"), _, id)
	write_byte(1)
	write_byte(BpAmmo)
	message_end()
}

public remove(id, bool:perm)
{
	if(perm == true)
	{
		for(new i = 0; i < WEAPON_TOTAL; i++)
			g_had_weapon[id][i] = 0
	}
	cmd_drop(id)
}

public fw_Item_Deploy_Post(ent)
{
	static id
	id = get_pdata_cbase(ent, 41, 4)
	
	if(!is_user_connected(id) || !Stock_Check(id))
		return HAM_IGNORED
	
	static iClip
	iClip = get_pdata_int(ent, 51, 4)
	
	Set_Model(id)
	set_weapon_anim(id, Draw_Weapon(id, ent, iClip))
	set_pdata_float(id, 83, g_special[id] == SP_PETROLBOOMER ? 1.8 : 1.0)
	Update_SpAmmo(id)
	
	switch(g_special[id])
	{
		case SP_PETROLBOOMER:
		{
			fm_set_entity_visibility(g_iEnt[id][0], 1)
			set_pdata_float(ent, 48, 2.0)
		}
		case SP_RPG7: g_mode[id] = 0
		case SP_M32:
		{
			g_m32_reload[id] = 0
			g_zoom[id] = 0
		}
		case SP_AT4EX: g_aiming[id] = 0
	}
	if(Stock_CheckWeapons(id, 2)) Crosshair(id, 1)
	if(Stock_CheckWeapons(id, 3)) set_fov(id, 89)
	return HAM_IGNORED
}

public fw_Item_Holster_Post(ent)
{
	static id
	id = get_pdata_cbase(ent, 41, 4)
	
	if(!is_user_connected(id) || !Stock_Check(id))
		return HAM_IGNORED
	
	Crosshair(id, 0)
	set_fov(id, 90)
	fm_set_entity_visibility(g_iEnt[id][0], 0)
	return HAM_IGNORED
}

public Draw_Weapon(id, iEnt, iClip)
{
	static iState
	iState = pev(iEnt, pev_iuser3)
	
	if(g_had_weapon[id][HAD_CANNON] || g_special[id] == SP_FGLAUNCHER) return 3
	else if(g_special[id] == SP_DRILLGUN)
	{
		if(iState == 1) return 4
		else return g_ammo[id][1] > 0 ? 3 : 4
	} else if(g_special[id] == SP_AT4EX || g_special[id] == SP_FLAMETHROWER || g_special[id] == SP_AIRBURSTER) return 4
	else if(g_special[id] == SP_PETROLBOOMER)
	{
		if(iState == 1) return 4
		else return g_ammo[id][3] > 0 ? 3 : 4
	} else if(g_special[id] == SP_M32) return 6
	else if(g_had_weapon[id][HAD_POWERSAW]) return iClip > 0 ? 1 : 2
	else if(g_special[id] == SP_RPG7) return iClip > 0 ? 7 : 8
	else if(g_special[id] == SP_SPEARGUN)
	{
		if(iState == 1) return 4
		else return g_ammo[id][2] > 0 ? 3 : 4
	} else if(g_special[id] == SP_WATERCANNON) return 5
	return 0
}

public Update_SpAmmo(id)
{
	if(g_special[id] == SP_CANNON) update_ammo(id, g_ammo[id][0])
	else if(g_special[id] == SP_DRILLGUN) update_ammo(id, g_ammo[id][1])
	else if(g_special[id] == SP_SPEARGUN) update_ammo(id, g_ammo[id][2])
	else if(g_special[id] == SP_PETROLBOOMER) update_ammo(id, g_ammo[id][3])
}

public Set_Model(id)
{
	if(g_had_weapon[id][HAD_AIRBURSTER])
	{
		set_pev(id, pev_viewmodel2, Model_V[HAD_AIRBURSTER])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_AIRBURSTER])
	} else if(g_had_weapon[id][HAD_AT4EX]) {
		set_pev(id, pev_viewmodel2, Model_V[HAD_AT4EX])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_AT4EX])
	} else if(g_had_weapon[id][HAD_CANNON]) {
		set_pev(id, pev_viewmodel2, Model_V[HAD_CANNON])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_CANNON])
	} else if(g_had_weapon[id][HAD_DRILLGUN]) {
		set_pev(id, pev_viewmodel2, Model_V[HAD_DRILLGUN])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_DRILLGUN])
	} else if(g_had_weapon[id][HAD_FGLAUNCHER]) {
		set_pev(id, pev_viewmodel2, Model_V[HAD_FGLAUNCHER])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_FGLAUNCHER])
	} else if(g_had_weapon[id][HAD_FLAMETHROWER]) {
		set_pev(id, pev_viewmodel2, Model_V[HAD_FLAMETHROWER])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_FLAMETHROWER])
	} else if(g_had_weapon[id][HAD_M32]) {
		set_pev(id, pev_viewmodel2, Model_V[HAD_M32])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_M32])
	} else if(g_had_weapon[id][HAD_PETROLBOOMER]) {
		set_pev(id, pev_viewmodel2, Model_V[HAD_PETROLBOOMER])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_PETROLBOOMER])
	} else if(g_had_weapon[id][HAD_POWERSAW]) {
		set_pev(id, pev_viewmodel2, Model_V[HAD_POWERSAW])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_POWERSAW])
	} else if(g_had_weapon[id][HAD_RPG7]) {
		set_pev(id, pev_viewmodel2, Model_V[HAD_RPG7])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_RPG7])
	} else if(g_had_weapon[id][HAD_SPEARGUN]) {
		set_pev(id, pev_viewmodel2, Model_V[HAD_SPEARGUN])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_SPEARGUN])
	} else if(g_had_weapon[id][HAD_WATERCANNON]) {
		set_pev(id, pev_viewmodel2, Model_V[HAD_WATERCANNON])
		set_pev(id, pev_weaponmodel2, Model_P[HAD_WATERCANNON])
	}
}

public fw_UpdateClientData_Post(id, sendweapons, cd_handle)
{
	if(!is_user_alive(id) || !is_user_connected(id))
		return FMRES_IGNORED
	if(get_user_weapon(id) != CSW_EQUIP || !Stock_Check(id))
		return FMRES_IGNORED
		
	set_cd(cd_handle, CD_flNextAttack, halflife_time() + 0.001)
	return FMRES_IGNORED
}

public fw_ClientCommand(id)
{
	new sCmd[32]
	read_argv(0, sCmd, 31)
	
	if(equal(sCmd, "buyammo1"))
	{
		switch(g_special[id])
		{
			case SP_CANNON:
			{
				if(g_ammo[id][0] < 20)
				{
					g_ammo[id][0]++
					update_ammo(id, g_ammo[id][0])
					client_cmd(id, "spk items/9mmclip1.wav")
				}
			}
			case SP_DRILLGUN:
			{
				if(g_ammo[id][1] < 30)
				{
					g_ammo[id][1]++
					update_ammo(id, g_ammo[id][1])
					client_cmd(id, "spk items/9mmclip1.wav")
				}
			}
			case SP_SPEARGUN:
			{
				if(g_ammo[id][2] < 30)
				{
					g_ammo[id][2]++
					update_ammo(id, g_ammo[id][2])
					client_cmd(id, "spk items/9mmclip1.wav")
				}
			}
			case SP_PETROLBOOMER:
			{
				if(g_ammo[id][3] < 20)
				{
					g_ammo[id][3]++
					update_ammo(id, g_ammo[id][3])
					client_cmd(id, "spk items/9mmclip1.wav")
				}
			}
		}
	}
}

public cmd_drop(id)
{
	is_reloading[id] = 0
	g_aiming[id] = 0
	g_m32_reload[id] = 0
	g_zoom[id] = 0
	fm_set_entity_visibility(g_iEnt[id][0], 0)
	
	client_cmd(id, "spk common/null.wav")
	set_fov(id, 90)
	Crosshair(id, 0)
}

public fw_AddToPlayer(ent, id)
{
	if(!pev_valid(ent) || !is_user_alive(id))
		return
	
	if(pev(ent, pev_impulse) == CODE_AIRBURSTER)
	{
		g_had_weapon[id][HAD_AIRBURSTER] = 1
		set_pev(ent, pev_impulse, 0)
		cs_set_user_bpammo(id, CSW_EQUIP, pev(ent, pev_iuser3))
	} else if(pev(ent, pev_impulse) == CODE_AT4EX) {
		g_had_weapon[id][HAD_AT4EX] = 1
		set_pev(ent, pev_impulse, 0)
		cs_set_user_bpammo(id, CSW_EQUIP, pev(ent, pev_iuser3))
	} else if(pev(ent, pev_impulse) == CODE_CANNON) {
		g_had_weapon[id][HAD_CANNON] = 1
		set_pev(ent, pev_impulse, 0)
		g_ammo[id][0] = pev(ent, pev_iuser4)
	} else if(pev(ent, pev_impulse) == CODE_DRILLGUN) {
		g_had_weapon[id][HAD_DRILLGUN] = 1
		set_pev(ent, pev_impulse, 0)
		g_ammo[id][1] = pev(ent, pev_iuser4)
	} else if(pev(ent, pev_impulse) == CODE_FGLAUNCHER) {
		g_had_weapon[id][HAD_FGLAUNCHER] = 1
		set_pev(ent, pev_impulse, 0)
		cs_set_user_bpammo(id, CSW_EQUIP, pev(ent, pev_iuser3))
	} else if(pev(ent, pev_impulse) == CODE_FLAMETHROWER) {
		g_had_weapon[id][HAD_FLAMETHROWER] = 1
		set_pev(ent, pev_impulse, 0)
		cs_set_user_bpammo(id, CSW_EQUIP, pev(ent, pev_iuser3))
	} else if(pev(ent, pev_impulse) == CODE_M32) {
		g_had_weapon[id][HAD_M32] = 1
		set_pev(ent, pev_impulse, 0)
		cs_set_user_bpammo(id, CSW_EQUIP, pev(ent, pev_iuser3))
	} else if(pev(ent, pev_impulse) == CODE_PETROLBOOMER) {
		g_had_weapon[id][HAD_PETROLBOOMER] = 1
		set_pev(ent, pev_impulse, 0)
		g_ammo[id][3] = pev(ent, pev_iuser4)
	} else if(pev(ent, pev_impulse) == CODE_POWERSAW) {
		g_had_weapon[id][HAD_POWERSAW] = 1
		set_pev(ent, pev_impulse, 0)
		cs_set_user_bpammo(id, CSW_EQUIP, pev(ent, pev_iuser3))
	} else if(pev(ent, pev_impulse) == CODE_RPG7) {
		g_had_weapon[id][HAD_RPG7] = 1
		set_pev(ent, pev_impulse, 0)
		cs_set_user_bpammo(id, CSW_EQUIP, pev(ent, pev_iuser3))
	} else if(pev(ent, pev_impulse) == CODE_SPEARGUN) {
		g_had_weapon[id][HAD_SPEARGUN] = 1
		set_pev(ent, pev_impulse, 0)
		g_ammo[id][2] = pev(ent, pev_iuser4)
	} else if(pev(ent, pev_impulse) == CODE_WATERCANNON) {
		g_had_weapon[id][HAD_WATERCANNON] = 1
		set_pev(ent, pev_impulse, 0)
		cs_set_user_bpammo(id, CSW_EQUIP, pev(ent, pev_iuser3))
	}
	
	if(Stock_Check(id))
	{
		g_type[id] = CheckSpecial(id, 1)
		g_special[id] = CheckSpecial(id, 2)
		
		if(Stock_CheckWeapons(id, 2)) Crosshair(id, 1)
		if(Stock_CheckWeapons(id, 3)) set_fov(id, 89)		
	}
	set_spr(id)
}

public CheckSpecial(id, typ)
{
	switch(typ)
	{
		case 1:
		{
			if(g_had_weapon[id][HAD_FLAMETHROWER] || g_had_weapon[id][HAD_WATERCANNON] || g_had_weapon[id][HAD_AIRBURSTER]) return TYPE_FLAME
			else if(g_had_weapon[id][HAD_DRILLGUN] || g_had_weapon[id][HAD_SPEARGUN] || g_had_weapon[id][HAD_PETROLBOOMER]) return TYPE_SPRELOAD
			else if(g_had_weapon[id][HAD_AT4EX] || g_had_weapon[id][HAD_FGLAUNCHER] || g_had_weapon[id][HAD_M32]|| g_had_weapon[id][HAD_RPG7]) return TYPE_NADE
			else return TYPE_NONE
		}
		case 2:
		{
			if(g_had_weapon[id][HAD_AIRBURSTER]) return SP_AIRBURSTER
			else if(g_had_weapon[id][HAD_AT4EX]) return SP_AT4EX
			else if(g_had_weapon[id][HAD_CANNON]) return SP_CANNON
			else if(g_had_weapon[id][HAD_DRILLGUN]) return SP_DRILLGUN
			else if(g_had_weapon[id][HAD_FGLAUNCHER]) return SP_FGLAUNCHER
			else if(g_had_weapon[id][HAD_FLAMETHROWER]) return SP_FLAMETHROWER
			else if(g_had_weapon[id][HAD_M32]) return SP_M32
			else if(g_had_weapon[id][HAD_PETROLBOOMER]) return SP_PETROLBOOMER
			else if(g_had_weapon[id][HAD_RPG7]) return SP_RPG7
			else if(g_had_weapon[id][HAD_SPEARGUN]) return SP_SPEARGUN
			else if(g_had_weapon[id][HAD_WATERCANNON]) return SP_WATERCANNON
			else return SP_NONE
		}
	}
	return 0
}

public set_spr(id)
{
	if(g_had_weapon[id][HAD_AIRBURSTER]) set_weapon_list(id, spr[HAD_AIRBURSTER])
	else if(g_had_weapon[id][HAD_AT4EX]) set_weapon_list(id, spr[HAD_AT4EX])
	else if(g_had_weapon[id][HAD_CANNON]) set_weapon_list(id, spr[HAD_CANNON])
	else if(g_had_weapon[id][HAD_DRILLGUN]) set_weapon_list(id, spr[HAD_DRILLGUN])
	else if(g_had_weapon[id][HAD_FGLAUNCHER]) set_weapon_list(id, spr[HAD_FGLAUNCHER])
	else if(g_had_weapon[id][HAD_FLAMETHROWER]) set_weapon_list(id, spr[HAD_FLAMETHROWER])
	else if(g_had_weapon[id][HAD_M32]) set_weapon_list(id, spr[HAD_M32])
	else if(g_had_weapon[id][HAD_PETROLBOOMER]) set_weapon_list(id, spr[HAD_PETROLBOOMER])
	else if(g_had_weapon[id][HAD_POWERSAW]) set_weapon_list(id, spr[HAD_POWERSAW])
	else if(g_had_weapon[id][HAD_RPG7]) set_weapon_list(id, spr[HAD_RPG7])
	else if(g_had_weapon[id][HAD_SPEARGUN]) set_weapon_list(id, spr[HAD_SPEARGUN])
	else if(g_had_weapon[id][HAD_WATERCANNON]) set_weapon_list(id, spr[HAD_WATERCANNON])
	else set_weapon_list(id, weapon_equip)
}

public fw_SetModel(ent, const model[])
{
	if(!pev_valid(ent))
		return FMRES_IGNORED
	
	static szClassName[33]
	pev(ent, pev_classname, szClassName, charsmax(szClassName))
	
	if(!equal(szClassName, "weaponbox"))
		return FMRES_IGNORED
		
	static id
	id = pev(ent, pev_owner)
	
	if(equal(model, "models/w_m249.mdl"))
	{
		static iEnt
		iEnt = find_ent_by_owner(-1, weapon_equip, ent)
		
		if(!pev_valid(iEnt))
			return FMRES_IGNORED
		
		if(g_had_weapon[id][HAD_AIRBURSTER])
		{
			set_pev(iEnt, pev_impulse, CODE_AIRBURSTER)
			set_pev(iEnt, pev_iuser3, cs_get_user_bpammo(id, CSW_EQUIP))
			g_had_weapon[id][HAD_AIRBURSTER] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_AIRBURSTER)
			return FMRES_SUPERCEDE
		} else if(g_had_weapon[id][HAD_AT4EX]) {
			set_pev(iEnt, pev_impulse, CODE_AT4EX)
			set_pev(iEnt, pev_iuser3, cs_get_user_bpammo(id, CSW_EQUIP))
			g_had_weapon[id][HAD_AT4EX] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_AT4EX)
			return FMRES_SUPERCEDE
		} else if(g_had_weapon[id][HAD_CANNON]) {
			set_pev(iEnt, pev_impulse, CODE_CANNON)
			set_pev(iEnt, pev_iuser4, g_ammo[id][0])
			g_had_weapon[id][HAD_CANNON] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_CANNON)
			return FMRES_SUPERCEDE
		} else if(g_had_weapon[id][HAD_DRILLGUN]) {
			set_pev(iEnt, pev_impulse, CODE_DRILLGUN)
			set_pev(iEnt, pev_iuser4, g_ammo[id][1])
			g_had_weapon[id][HAD_DRILLGUN] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_DRILLGUN)
			return FMRES_SUPERCEDE
		} else if(g_had_weapon[id][HAD_FGLAUNCHER]) {
			set_pev(iEnt, pev_impulse, CODE_FGLAUNCHER)
			set_pev(iEnt, pev_iuser3, cs_get_user_bpammo(id, CSW_EQUIP))
			g_had_weapon[id][HAD_FGLAUNCHER] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_FGLAUNCHER)
			return FMRES_SUPERCEDE
		} else if(g_had_weapon[id][HAD_FLAMETHROWER]) {
			set_pev(iEnt, pev_impulse, CODE_FLAMETHROWER)
			set_pev(iEnt, pev_iuser3, cs_get_user_bpammo(id, CSW_EQUIP))
			g_had_weapon[id][HAD_FLAMETHROWER] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_FLAMETHROWER)
			return FMRES_SUPERCEDE
		} else if(g_had_weapon[id][HAD_M32]) {
			set_pev(iEnt, pev_impulse, CODE_M32)
			set_pev(iEnt, pev_iuser3, cs_get_user_bpammo(id, CSW_EQUIP))
			g_had_weapon[id][HAD_M32] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_M32)
			return FMRES_SUPERCEDE
		} else if(g_had_weapon[id][HAD_M32]) {
			set_pev(iEnt, pev_impulse, CODE_M32)
			set_pev(iEnt, pev_iuser3, cs_get_user_bpammo(id, CSW_EQUIP))
			g_had_weapon[id][HAD_M32] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_M32)
			return FMRES_SUPERCEDE
		}  else if(g_had_weapon[id][HAD_PETROLBOOMER]) {
			set_pev(iEnt, pev_impulse, CODE_PETROLBOOMER)
			set_pev(iEnt, pev_iuser4, g_ammo[id][3])
			g_had_weapon[id][HAD_PETROLBOOMER] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_PETROLBOOMER)
			return FMRES_SUPERCEDE
		} else if(g_had_weapon[id][HAD_POWERSAW]) {
			set_pev(iEnt, pev_impulse, CODE_POWERSAW)
			g_had_weapon[id][HAD_POWERSAW] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_POWERSAW)
			return FMRES_SUPERCEDE
		} else if(g_had_weapon[id][HAD_RPG7]) {
			set_pev(iEnt, pev_impulse, CODE_RPG7)
			set_pev(iEnt, pev_iuser3, cs_get_user_bpammo(id, CSW_EQUIP))
			g_had_weapon[id][HAD_RPG7] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_RPG7)
			return FMRES_SUPERCEDE
		} else if(g_had_weapon[id][HAD_SPEARGUN]) {
			set_pev(iEnt, pev_impulse, CODE_SPEARGUN)
			set_pev(iEnt, pev_iuser4, g_ammo[id][2])
			g_had_weapon[id][HAD_SPEARGUN] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_SPEARGUN)
			return FMRES_SUPERCEDE
		} else if(g_had_weapon[id][HAD_WATERCANNON]) {
			set_pev(iEnt, pev_impulse, CODE_WATERCANNON)
			set_pev(iEnt, pev_iuser3, cs_get_user_bpammo(id, CSW_EQUIP))
			g_had_weapon[id][HAD_WATERCANNON] = 0
			remove(id, false)
			
			engfunc(EngFunc_SetModel, ent, Model_W)
			set_pev(ent, pev_body, HAD_WATERCANNON)
			return FMRES_SUPERCEDE
		}
	}
	return FMRES_IGNORED
}

public fw_ItemPostFrame(ent)
{
	new id = pev(ent, pev_owner)
	
	if(!is_user_connected(id))
		return HAM_IGNORED
	if(get_user_weapon(id) != CSW_EQUIP || !Stock_Check(id))
		return HAM_IGNORED
		
	new Float:flNextAttack = get_pdata_float(id, 83, 5), iBpAmmo = cs_get_user_bpammo(id, CSW_EQUIP)
	new iClip = get_pdata_int(ent, 51, 4), fInReload = get_pdata_int(ent, 54, 4), iMax = Stock_CheckClip(id)
	
	if(Stock_CheckWeapons(id, 0) && !is_reloading[id] && get_pdata_float(ent, 48, 4) <= 0.25)
	{
		set_weapon_anim(id, AnimIdle(id, iClip))
		set_pdata_float(ent, 48, 20.0, 4)
	}
	
	if(!Stock_CheckWeapons(id, 1))
	{
		if(fInReload && flNextAttack <= 0.0)
		{
			new Clip = min(iMax - iClip, iBpAmmo)
			set_pdata_int(ent, 51, iClip + Clip, 4)
			cs_set_user_bpammo(id, CSW_EQUIP, iBpAmmo - Clip)
			set_pdata_int(ent, 54, 0, 4)
			is_reloading[id] = 0
			
			set_pdata_float(ent, 46, 0.01) // Fix bug
			set_pdata_float(ent, 47, 0.01)
		}
	}
	if(g_special[id] == SP_RPG7)
		if(g_mode[id] && pev(id, pev_weaponanim) == 0) set_weapon_anim(id, iClip > 0 ? 1 : 3)
	
	Set_Special(id, ent, iClip, pev(id,pev_button))
	return HAM_IGNORED
}

public AnimIdle(id, iClip)
{
	if(g_special[id] == SP_DRILLGUN) return g_ammo[id][1] > 0 ? 0 : 5
	else if(g_had_weapon[id][HAD_POWERSAW]) return iClip > 0 ? 0 : 11
	else if(g_special[id] == SP_PETROLBOOMER) return g_ammo[id][3] > 0 ? 0 : 5
	else if(g_special[id] == SP_SPEARGUN) return g_ammo[id][2] > 0 ? 0 : 5
	return 0
}

public Stock_CheckClip(id)
{
	if(g_had_weapon[id][HAD_AIRBURSTER] || g_had_weapon[id][HAD_FLAMETHROWER] || g_had_weapon[id][HAD_WATERCANNON]) return 100
	else if(g_had_weapon[id][HAD_AT4EX] || g_had_weapon[id][HAD_RPG7]) return 1
	else if(g_had_weapon[id][HAD_FGLAUNCHER]) return 10
	else if(g_had_weapon[id][HAD_POWERSAW]) return 200
	return 0
}

public fw_WeaponReload(ent)
{
	static id
	id = pev(ent, pev_owner)
	
	if(!is_user_alive(id) || !is_user_connected(id))
		return HAM_IGNORED
	if(get_user_weapon(id) != CSW_EQUIP || !Stock_Check(id))
		return HAM_IGNORED
	if(Stock_CheckWeapons(id, 1))
		return HAM_IGNORED
		
	g_iClip[id] = -1
	
	new iBpAmmo = cs_get_user_bpammo(id, CSW_EQUIP)
	new iClip = get_pdata_int(ent, 51, 4)
	
	if(iBpAmmo <= 0 || iClip >= Stock_CheckClip(id))
		return HAM_SUPERCEDE
		
	g_iClip[id] = iClip
	return HAM_IGNORED
}

public fw_WeaponReload_Post(ent)
{
	new id = pev(ent, pev_owner)
	
	if(!is_user_connected(id) || !Stock_Check(id))
		return HAM_IGNORED
	if(Stock_CheckWeapons(id, 1))
		return HAM_IGNORED
	if(g_iClip[id] == -1)
		return HAM_IGNORED
		
	new Float:Time = TimeReload(id)
	set_pdata_int(ent, 51, g_iClip[id], 4)
	set_pdata_int(ent, 54, 1, 4)
	
	set_pdata_float(ent, 46, Time, 4)
	set_pdata_float(ent, 47, Time, 4)
	set_pdata_float(ent, 48, Time, 4)
	set_pdata_float(id, 83, Time, 5)
	set_weapon_anim(id, AnimReload(id))
	
	cs_set_user_zoom(id, CS_RESET_ZOOM, 1)
	g_aiming[id] = 0
	is_reloading[id] = 1
	return HAM_IGNORED
}

public Float:TimeReload(id)
{
	new Float:Time
	if(g_special[id] == SP_AT4EX) Time = 3.7
	else if(g_special[id] == SP_FGLAUNCHER) Time = 4.93
	else if(g_special[id] == SP_FLAMETHROWER || g_special[id] == SP_AIRBURSTER) Time = 5.03
	else if(g_special[id] == SP_WATERCANNON) Time = 4.03
	else if(g_special[id] == SP_RPG7) Time = 2.1
	else if(g_had_weapon[id][HAD_POWERSAW]) Time = 3.15
	return Time
}

public AnimReload(id)
{
	if(g_special[id] == SP_AIRBURSTER || g_special[id] == SP_AT4EX || g_special[id] == SP_FLAMETHROWER) return 3
	else if(g_special[id] == SP_FGLAUNCHER) return 2
	else if(g_special[id] == SP_WATERCANNON) return 4
	else if(g_had_weapon[id][HAD_POWERSAW] || g_special[id] == SP_RPG7) return 6
	return 0
}

public fw_Think2(iEnt)
{
	if(!pev_valid(iEnt))
		return
	
	new Class = Get_Class(iEnt), id = pev(iEnt, pev_owner)
	
	if(Class == ENTCLASS_MUZZLE1 || Class == ENTCLASS_MUZZLE2)
	{
		if(!g_wpn_flame_isshooting[id])
		{
			engfunc(EngFunc_RemoveEntity, iEnt)
			return
		}
	} else if(Class == ENTCLASS_FLAME_PETROL) {
		new Float:fFrame
		pev(iEnt, pev_frame, fFrame)
		
		fFrame += 1.0
		if(fFrame > 15.0) fFrame = 0.0
	
		set_pev(iEnt, pev_frame, fFrame)
		set_pev(iEnt, pev_scale, 0.13)
		set_pev(iEnt, pev_nextthink, get_gametime() + 0.045)
	} else if(Class == ENTCLASS_FLAME_PETROL2) {
		// effect exp
		new Float:fFrame, Float:iEffect
		pev(iEnt, pev_frame, fFrame)
		pev(iEnt, pev_renderamt, iEffect)
		
		fFrame += 1.0
		if(fFrame > 15.0) fFrame = 0.0
	
		set_pev(iEnt, pev_frame, fFrame)
		set_pev(iEnt, pev_scale, 1.0)
		set_pev(iEnt, pev_nextthink, get_gametime() + 0.045)
		
		static Float:fTimeRemove
		pev(iEnt, pev_fuser1, fTimeRemove)
		
		if(get_gametime() < fTimeRemove - 0.6)
		{
			iEffect += 7.0
			iEffect = floatmin(iEffect, 150.0)
			set_pev(iEnt, pev_renderamt, iEffect)
		}
		
		if(get_gametime() >= fTimeRemove - 0.6)
		{
			iEffect -= 15.0
			iEffect = floatmax(iEffect, 0.0)
			set_pev(iEnt, pev_renderamt, iEffect)
		}
		
		if(get_gametime() >= fTimeRemove)
		{
			engfunc(EngFunc_RemoveEntity, iEnt)
			return
		}
	}
}

public fw_Think(iEnt)
{
	if(!pev_valid(iEnt))
		return
	
	new Class = Get_Class(iEnt), id = pev(iEnt, pev_owner)
	
	if(Class == ENTCLASS_CANNON)
	{
		static Float:fFrame, Float:fLtime
		pev(iEnt, pev_frame, fFrame)
		pev(iEnt, pev_ltime, fLtime)
		
		// Touch something
		fFrame += 1.0
		if(fFrame >= 22.00) 
		{
			set_pev(iEnt, pev_flags, pev(iEnt, pev_flags) | FL_KILLME)
			return
		}
		set_pev(iEnt, pev_frame, fFrame)
		
		if(fLtime < get_gametime())
		{
			set_pev(iEnt, pev_flags, pev(iEnt, pev_flags) | FL_KILLME)
			return
		}			
		set_pev(iEnt, pev_nextthink, get_gametime() + 0.05)
	} else if(Class == ENTCLASS_FLAME) {
		static Float:fSprFrame, Float:fFrameMax
		if(g_special[id] == SP_WATERCANNON) fSprFrame = 23.0
		else fSprFrame = 22.0
		fFrameMax = g_cache_frame_flame
		
		static Float:fFrame, Float:fScale
		pev(iEnt, pev_frame, fFrame)
		pev(iEnt, pev_scale, fScale)
		
		//Touch something
		if(Get_Sp_On(iEnt))
		{
			set_pev(iEnt, pev_velocity, Null)
			fFrame += (fFrameMax / fSprFrame)
			fScale += (fFrameMax / (fSprFrame * 10))
		} else { //not touch
			if(fFrame > (fFrameMax/3.0))
			{
				fFrame += (fFrameMax / fSprFrame)
				fScale += (fFrameMax / (fSprFrame * 10))
			} else {
				fFrame += (fFrameMax / (fSprFrame * 2))
				fScale += (fFrameMax / (fSprFrame * 20))
			}
		}
		
		if(fFrame >= fFrameMax) 
		{
			set_pev(iEnt, pev_flags, pev(iEnt, pev_flags) | FL_KILLME)
			return
		}
		
		set_pev(iEnt, pev_frame, fFrame)
		if(g_special[id] != SP_WATERCANNON) set_pev(iEnt, pev_scale, fScale)
		if(g_special[id] == SP_WATERCANNON) set_pev(iEnt, pev_nextthink, get_gametime() + 0.035)
		else set_pev(iEnt, pev_nextthink, get_gametime() + 0.05)
		return
	} else if(Class == ENTCLASS_METAL) {
		if(g_special[id] == SP_DRILLGUN)
		{
			static Float:vAngle[3]
			Stock_Get_Velocity_Angle(iEnt, vAngle)
			set_pev(iEnt, pev_angles, vAngle)
			set_pev(iEnt, pev_nextthink, get_gametime() + 0.03)
		} else if(g_special[id] == SP_SPEARGUN) {
			switch(Get_Sp_On(iEnt))
			{
				case 0:
				{
					message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
					write_byte(TE_BEAMFOLLOW)
					write_short(iEnt)
					write_short(g_cache_trail)
					write_byte(5)
					write_byte(1)
					write_byte(155)
					write_byte(255)
					write_byte(218)
					write_byte(100)
					message_end()
					
					set_pev(iEnt, pev_nextthink, get_gametime() + 0.9)
					Set_Sp_On(iEnt, 1)
				}
				case 1:
				{
					Pub_Grenade_Explode(iEnt, KNOCKBACK_SPEARGUN, DAMAGE_SPEARGUN * 1.2, 150.0, pev(iEnt, pev_aiment))
					RemoveEntity(iEnt)
				}
			}
		}
	} else if(Class == ENTCLASS_NADE) {
		if(g_special[id] == SP_FGLAUNCHER)
		{
			new Float:vOrigin[3]
			pev(iEnt, pev_origin, vOrigin)
			
			engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vOrigin, 0)
			write_byte(TE_EXPLOSION)
			engfunc(EngFunc_WriteCoord, vOrigin[0])
			engfunc(EngFunc_WriteCoord, vOrigin[1])
			engfunc(EngFunc_WriteCoord, vOrigin[2])
			write_short(g_cache_trail)
			write_byte(1)
			write_byte(99)
			write_byte(TE_EXPLFLAG_NODLIGHTS + TE_EXPLFLAG_NOSOUND)
			message_end()
			
			set_pev(iEnt, pev_nextthink, get_gametime() + 0.2)
		} else if(g_special[id] == SP_AT4EX || g_special[id] == SP_RPG7) {
			static Float:Origin[3]
			pev(iEnt, pev_origin, Origin)
			
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
			write_byte(TE_SPRITE)
			engfunc(EngFunc_WriteCoord, Origin[0])
			engfunc(EngFunc_WriteCoord, Origin[1])
			engfunc(EngFunc_WriteCoord, Origin[2])
			write_short(g_smoke_id) 
			write_byte(2) 
			write_byte(g_special[id] == SP_RPG7 ? 40 : 200)
			message_end()
			
			set_pev(iEnt, pev_nextthink, halflife_time() + 0.075)
			
			if(g_special[id] == SP_AT4EX)
			{
				if(Get_Sp_On(iEnt))
				{
					static iTarget
					iTarget = Get_Sp_On(iEnt)
					
					if(is_user_alive(iTarget))
					{
						static Float:vOri[3]
						pev(iTarget, pev_origin, vOri)
						Stock_Ent_Move_To(iEnt, vOri, floatround(SPEED_AT4EX))
					} else Set_Sp_On(iEnt, 0)
				}
			}
		}
	} else if(Class == ENTCLASS_SMOKE) {
		new Float:vOrigin[3]
		pev(iEnt,pev_origin,vOrigin)
		
		engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vOrigin, 0)
		write_byte(TE_SMOKE)
		engfunc(EngFunc_WriteCoord,vOrigin[0])
		engfunc(EngFunc_WriteCoord,vOrigin[1])
		engfunc(EngFunc_WriteCoord,vOrigin[2] + 55.0)
		write_short(g_cache_smoke[1])
		write_byte(40)
		write_byte(12)
		message_end()
		
		set_pev(iEnt, pev_flags, pev(iEnt, pev_flags) | FL_KILLME)
		return
	} else if(Class == ENTCLASS_PETROL) {
		set_pev(iEnt, pev_nextthink, get_gametime() + 0.5)
		
		static Float:Origin[3], Float:myOrigin[3], Float:fTimeRemove
		pev(iEnt, pev_fuser1, fTimeRemove)
		
		for(new i = 0; i < get_maxplayers(); i++)
		{
			if(!is_user_alive(i))
				continue
			if(entity_range(i, iEnt) > 80.0)
				continue
			if(!can_damage(i, id) || i == id)
				continue
			
			pev(i, pev_origin, Origin)
			pev(id, pev_origin, myOrigin)
			
			if(Stock_CheckWall(myOrigin, Origin, id))
				continue
					
			if(pev(iEnt, pev_fuser2) < get_gametime())
			{
				ExecuteHamB(Ham_TakeDamage, i, id, id, 150.0, DMG_BULLET)
				set_pev(iEnt, pev_fuser2, get_gametime() + 0.5)
			}
		}
		
		if(get_gametime() >= fTimeRemove)
		{
			engfunc(EngFunc_RemoveEntity, iEnt)
			return
		}
	}
}

public fw_Touch(iPtr, iPtd)
{
	if(!pev_valid(iPtr))
		return HAM_IGNORED
		
	new Class = Get_Class(iPtr), iOwner = pev(iPtr, pev_owner)
	if(Class == ENTCLASS_FLAME)
	{
		static name[32]
		pev(iPtd, pev_classname, name, 31)
		
		if(iOwner == iPtd)
			return HAM_IGNORED
			
		Set_Sp_On(iPtr, 1)
		if(iOwner != iPtd) set_pev(iPtr, pev_solid, SOLID_NOT)
		Pub_Fake_Damage_Guns(iOwner, iPtd, Damage(iOwner, 2), DEFAULT_DMGTYPE, 9999.0, iOwner, 0, DMG_CLUB)
		
		if(pev_valid(iPtd)) 
		{
			if(g_special[iOwner] == SP_FLAMETHROWER && can_damage(iOwner, iPtd))
			{
				if(task_exists(iPtd+2213))
				{
					remove_task(iPtd+2213)
					set_task(1.00, "Task_FlameThrower", iPtd+2213, "", 0, "a", 5)
				} else set_task(1.00, "Task_FlameThrower", iPtd+2213, "", 0, "a", 5)	
			} else if(g_special[iOwner] == SP_AIRBURSTER && can_damage(iOwner, iPtd)) Stock_Fake_KnockBack(iOwner, iPtd, Damage(iOwner, 1))
		}
	} else if(Class == ENTCLASS_METAL) {
		if(g_special[iOwner] == SP_DRILLGUN)
		{
			new iPenetration = pev(iPtr, pev_iuser2)
			if(iPtd == iOwner) return HAM_IGNORED
			
			new Float:vecAngle[3], Float:vecOrigin[3], Float:vecVelocity[3]
			pev(iPtr, pev_velocity, vecVelocity)
			pev(iPtr, pev_angles, vecAngle)
			pev(iPtr, pev_origin, vecOrigin)
			
			if(!iPtd)
			{
				message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
				write_byte(TE_GUNSHOTDECAL)
				engfunc(EngFunc_WriteCoord, vecOrigin[0])
				engfunc(EngFunc_WriteCoord, vecOrigin[1])
				engfunc(EngFunc_WriteCoord, vecOrigin[2])
				write_short(iOwner)
				write_byte(41)
				message_end()
			}
			
			if(iPtd == pev(iPtr, pev_iuser1) || iPenetration == 0)
			{
				RemoveEntity(iPtr)
				return HAM_IGNORED
			}
			
			EntityTouchDamage(iPtr, iOwner, DAMAGE_DRILLGUN)
			RemoveEntity(iPtr)
			
			new Float:vecDirection[3], Float:vecForward[3]
			xs_vec_normalize(vecVelocity, vecDirection)
			xs_vec_mul_scalar(vecDirection, 40.0, vecForward)
			xs_vec_add(vecOrigin, vecForward, vecOrigin)
	
			if(engfunc(EngFunc_PointContents, vecOrigin) == CONTENTS_SOLID)
				return HAM_IGNORED
			if(xs_vec_len(vecVelocity) < 100.0)
				return HAM_IGNORED
				
			new iArrow = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
			Set_Class(iArrow, ENTCLASS_METAL)
			engfunc(EngFunc_SetSize, iArrow, {-2.1, -2.1, -2.1}, {2.1, 2.1, 2.1})
			engfunc(EngFunc_SetModel, iArrow, Model_S[12])
			set_pev(iArrow, pev_body, 3)
			set_pev(iArrow, pev_origin, vecOrigin)
			set_pev(iArrow, pev_movetype, MOVETYPE_PUSHSTEP)
			set_pev(iArrow, pev_solid, SOLID_BBOX)
			set_pev(iArrow, pev_owner, iOwner)
			set_pev(iArrow, pev_gravity, 0.18)
			set_pev(iArrow, pev_velocity, vecVelocity)
			set_pev(iArrow, pev_angles, vecAngle)
			set_pev(iArrow, pev_nextthink, get_gametime() + 0.02)
			set_pev(iArrow, pev_iuser1, iPtd)
			set_pev(iArrow, pev_iuser2, iPenetration - 5)
			
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
			write_byte(TE_BEAMFOLLOW)
			write_short(iArrow)
			write_short(g_cache_trail)
			write_byte(1)
			write_byte(1)
			write_byte(244)
			write_byte(244)
			write_byte(244)
			write_byte(100)
			message_end()
			return HAM_IGNORED
		} else if(g_special[iOwner] == SP_SPEARGUN) {
			new Float:vecOrigin[3]
			pev(iPtr, pev_origin, vecOrigin)
	
			if(engfunc(EngFunc_PointContents, vecOrigin) == CONTENTS_SKY)
			{
				engfunc(EngFunc_RemoveEntity, iPtr)
				return HAM_IGNORED
			}
	
			if(!iPtd)
			{
				message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
				write_byte(TE_GUNSHOTDECAL)
				engfunc(EngFunc_WriteCoord,vecOrigin[0])
				engfunc(EngFunc_WriteCoord,vecOrigin[1])
				engfunc(EngFunc_WriteCoord,vecOrigin[2])
				write_short(iOwner)
				write_byte(41)
				message_end()
	
				new sound[32], iTtextureType = EntityTouchTraceTexture(iPtr)
				if(iTtextureType == 'M' || iTtextureType == 'V' || iTtextureType == 'P')
				{
					switch(random_num(0, 1))
					{
						case 0: format(sound, charsmax(sound), "weapons/speargun_metal1.wav")
						case 1: format(sound, charsmax(sound), "weapons/speargun_metal2.wav")
					}
				} else if(iTtextureType == 'W') {
					switch(random_num(0, 1))
					{
						case 0: format(sound, charsmax(sound), "weapons/speargun_wood1.wav")
						case 1: format(sound, charsmax(sound), "weapons/speargun_wood2.wav")
					}
				} else {
					switch(random_num(0, 1))
					{
						case 0: format(sound, charsmax(sound), "weapons/speargun_stone1.wav")
						case 1: format(sound, charsmax(sound), "weapons/speargun_stone2.wav")
					}
				}
				PlaySound(iPtr, CHAN_ITEM, sound)
			} else if(IsPlayer(iPtd)) {
				if(can_damage(iOwner, iPtd))
				{
					Stock_Fake_KnockBack(iOwner, iPtd, 2400.0)
					EntityTouchDamage(iPtr, iOwner, DAMAGE_SPEARGUN)
				}
				set_pev(iPtr, pev_velocity, Null)
				set_pev(iPtr, pev_aiment, iPtd)
				set_pev(iPtr, pev_movetype, MOVETYPE_NONE)
				set_pev(iPtr, pev_solid, SOLID_NOT)
				return HAM_IGNORED
			}
			set_pev(iPtr, pev_solid, SOLID_NOT)
			set_pev(iPtr, pev_movetype, MOVETYPE_NONE)
			return HAM_IGNORED
		}
	} else if(Class == ENTCLASS_NADE) {
		set_pev(iPtr, pev_movetype, MOVETYPE_NONE)
		Pub_Grenade_Explode(iPtr, Damage(iOwner, 1), Damage(iOwner, 2), Damage(iOwner, 3), 0)
		if(g_special[iOwner] == SP_PETROLBOOMER) RemoveEntity(g_iEnt[iOwner][1])
		
		new Float:Origin[3]
		pev(iPtr, pev_origin, Origin)
		
		new iEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
		Set_Class(iEnt, ENTCLASS_SMOKE)
		set_pev(iEnt, pev_origin, Origin[0])
		engfunc(EngFunc_SetModel, iEnt, "models/w_usp.mdl")
		set_pev(iEnt, pev_nextthink, get_gametime() + 0.55)
		Stock_SetRendering(iEnt, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, 0)
		
		set_pev(iPtr, pev_flags, pev(iPtr, pev_flags) | FL_KILLME)
		return HAM_IGNORED
	}
	return HAM_IGNORED
}

public Float:Damage(id, Type)
{
	switch(Type)
	{
		case 1: // Knockback
		{
			if(g_special[id] == SP_AT4EX) return KNOCKBACK_AT4EX
			else if(g_special[id] == SP_FGLAUNCHER) return KNOCKBACK_FGLAUNCHER
			else if(g_special[id] == SP_M32) return KNOCKBACK_M32
			else if(g_special[id] == SP_AIRBURSTER) return KNOCKBACK_AIRBURSTER
			else return 1.5
		}
		case 2: // Damage
		{
			if(g_special[id] == SP_AT4EX) return DAMAGE_AT4EX
			else if(g_special[id] == SP_FGLAUNCHER || g_special[id] == SP_M32) return DAMAGE_FGLAUNCHER_M32
			else if(g_special[id] == SP_FLAMETHROWER) return DAMAGE_SALAMANDER
			else if(g_special[id] == SP_AIRBURSTER) return DAMAGE_AIRBURSTER
			else if(g_special[id] == SP_WATERCANNON) return DAMAGE_WATERCANNON
			else if(g_special[id] == SP_PETROLBOOMER) return DAMAGE_PETROL
			else if(g_special[id] == SP_RPG7) return DAMAGE_RPG7
		}
		case 3: return 200.0 // Radius
	}
	return 1.0
}

public Set_Special(id, iEnt, iClip, iButton)
{
	if(is_reloading[id])
		return
	
	switch(g_type[id])
	{
		case TYPE_FLAME: Wpn_Flame(id, iEnt, iClip, iButton)
		case TYPE_SPRELOAD: Wpn_SpReload(id, iEnt, iButton)
		case TYPE_NADE: Wpn_Nade(id, iEnt, iClip, iButton)
	}
	if(g_had_weapon[id][HAD_CANNON]) Wpn_Cannon(id, iEnt, iButton)
	else if(g_had_weapon[id][HAD_POWERSAW]) Wpn_Chainsaw(id, iEnt, iClip, iButton)
}

public Wpn_Flame(id, iEnt, iClip, iButton)
{
	static iFlame, Float:Scale,Float:vRec[3], Float:vOrigin[3],Float:vAngle[3],Float:vVelocity[3],Float:vColor[3],Float:vRender
	pev(id, pev_v_angle, vAngle)
	
	if(iButton & IN_ATTACK)
	{
		iButton &= ~IN_ATTACK
		set_pev(id, pev_button, iButton &~ IN_ATTACK)	
		
		if(!g_wpn_flame_isshooting[id] && g_special[id] == SP_WATERCANNON)
		{
			if(!iClip) return
			set_pdata_float(iEnt, 46, 0.23, 4)
			set_weapon_anim(id, 1)
			PlaySound(id, CHAN_WEAPON, ShootSound[17])
			g_wpn_flame_isshooting[id] = 1
		}
		
		if(get_pdata_int(iEnt, 46) > 0.0)
			return
		
		if(!iClip)
		{
			set_weapon_anim(id, 0)
			g_wpn_flame_isshooting[id] = 0
			return
		}	
		
		if(g_wpn_flame_timer[id] < get_gametime())
		{
			switch(g_special[id])
			{
				case SP_WATERCANNON: 
				{
					g_wpn_flame_timer[id] = get_gametime()
					PlaySound(id, CHAN_WEAPON, ShootSound[2])
					set_weapon_anim(id, 2)
				}
				case SP_FLAMETHROWER:
				{
					g_wpn_flame_timer[id] = get_gametime() + 0.895
					PlaySound(id, CHAN_WEAPON, ShootSound[1])
					set_weapon_anim(id, 1)
				}
				case SP_AIRBURSTER:
				{
					g_wpn_flame_timer[id] = get_gametime() + 0.675
					PlaySound(id, CHAN_WEAPON, ShootSound[13])
					set_weapon_anim(id, 1)
				}
			}
		}
		set_pdata_int(iEnt, 51, iClip - 1)
		set_pdata_float(iEnt, 48, 10.0, 4)
		
		g_wpn_flame_isshooting[id] = 1
		
		vRec[0] = random_float(-0.42, 0.42)
		vRec[1] = random_float(-0.42, 0.42)
		set_pev(id, pev_punchangle, vRec)
		
		static Model[32], Float:Pos[3], Float:Spd[2], Float:Vel, bool:Color, Float:vVel[3]
		switch(g_special[id])
		{
			case SP_FLAMETHROWER:
			{
				Pos[0] = 20.0 // Forward
				Pos[1] = 2.0 // Right
				Pos[2] = -3.0 // Up
				
				Spd[0] = 0.0
				Spd[1] = 380.0
				
				Vel = 0.1185
				vRender = 254.0
				Scale = 0.1
				format(Model, charsmax(Model),  Model_S[0])
			}
			case SP_WATERCANNON:
			{
				Pos[0] = 48.0
				Pos[1] = 6.2
				Pos[2] = -5.8
				
				Spd[0] = 0.0
				Spd[1] = 300.0
				
				vColor[0] = 180.0
				vColor[1] = 180.0
				vColor[2] = 180.0
				
				Color = true
				Vel = 0.1085
				vRender = 200.0
				Scale = 0.35
				format(Model, charsmax(Model),  Model_S[1])
			}
			case SP_AIRBURSTER:
			{
				Pos[0] = 48.0
				Pos[1] = 6.2
				Pos[2] = -5.8
				
				Spd[0] = 0.0
				Spd[1] = 400.0
				
				Vel = 0.1025
				vRender = 254.0
				Scale = 0.15
				format(Model, charsmax(Model),  Model_S[5])
				
				#if defined ENABLE_AIRBURSTER_MUZZ
				Create_Muzzleflash(id, ENTCLASS_MUZZLE1, Model_S[7])
				Create_Muzzleflash(id, ENTCLASS_MUZZLE2, Model_S[8])
				#endif
			}
		}
		set_pdata_float(iEnt, 46, Vel, 4)
		
		if(g_special[id] != SP_WATERCANNON)
		{
			vAngle[0] = random_float(-180.0, 180.0)
			vAngle[1] = random_float(-180.0, 180.0)
			vAngle[2] = random_float(-180.0, 180.0)
		}
		pev(id, pev_velocity, vVel)
		
		vVel[0] *= 0.95
		vVel[1] *= 0.95
		vVel[2] *= 0.95
		xs_vec_add(vVel, vVelocity, vVelocity)
		
		iFlame = CreateEntity(id, true, Pos[0], Pos[1], Pos[2], Spd[0], Spd[1], ENTCLASS_FLAME, Model, MOVETYPE_FLY, SOLID_TRIGGER, 0.0, vAngle, vOrigin, vVelocity, Scale, 1.0, vRender, 0, 0)
		engfunc(EngFunc_SetSize, iFlame, Null, Null)
		set_pev(iFlame, pev_animtime, get_gametime())
		if(Color) set_pev(iFlame, pev_rendercolor, vColor)
		set_pev(iFlame, pev_nextthink, get_gametime() + 0.05)
	} else if(iButton & IN_ATTACK2) {
		if(g_special[id] != SP_AIRBURSTER || !iClip)
			return
		
		static Float:iDelay
		pev(iEnt, pev_fuser2, iDelay)
		
		if(iDelay < get_gametime())
		{
			iDelay = get_gametime() + 1.5
			set_pev(iEnt, pev_fuser2, iDelay)
			
			set_pdata_float(iEnt, 46, 1.55)
			set_pdata_float(iEnt, 47, 1.55)
			set_pdata_float(iEnt, 48, 1.3)
			
			if(iClip > 9) set_pdata_int(iEnt, 51, iClip - 10)
			else set_pdata_int(iEnt, 51, 0)
			
			PlaySound(id, CHAN_WEAPON, ShootSound[14])
			set_weapon_anim(id, 5)
			
			new Float:vecOrigin[3]
			Stock_Get_Postion(id, 55.0, 6.2, -5.8, vecOrigin)
			Pub_Fake_Melee_Attack(id, 150.0, 130.0, 2, DAMAGE_AIRBURSTER2, KNOCKBACK_AIRBURSTER2)
			
			engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0)
			write_byte(TE_EXPLOSION)
			engfunc(EngFunc_WriteCoord, vecOrigin[0])
			engfunc(EngFunc_WriteCoord, vecOrigin[1])
			engfunc(EngFunc_WriteCoord, vecOrigin[2])
			write_short(s_exp)
			write_byte(10)
			write_byte(30)
			write_byte(TE_EXPLFLAG_NODLIGHTS | TE_EXPLFLAG_NOSOUND | TE_EXPLFLAG_NOPARTICLES)
			message_end()
		}
	} else if(g_wpn_flame_isshooting[id]) {
		switch(g_special[id])
		{
			case SP_WATERCANNON: set_weapon_anim(id, 3)
			case SP_FLAMETHROWER, SP_AIRBURSTER: set_weapon_anim(id, 2)
		}
		static Float:Time
		if(g_special[id] == SP_AIRBURSTER) Time = 3.1
		else Time = 2.0
		
		set_pdata_float(iEnt, 48, Time, 4)
		g_wpn_flame_isshooting[id] = 0
	}	
	iButton &= ~IN_ATTACK
	set_pev(id,pev_button,iButton &~ IN_ATTACK)	
}

public Wpn_SpReload(id, iEnt, iButton) // Hard
{
	static pEntity, Float:Timer, Float:CurTime, iState
	pEntity = pev(iEnt, pev_iuser1)
	pev(iEnt, pev_fuser3, Timer)
	global_get(glb_time, CurTime)
	iState = pev(iEnt, pev_iuser3)
	
	if((iButton & IN_ATTACK) && !iState && get_pdata_float(iEnt, 46) <= 0.0)
	{
		iButton &= ~IN_ATTACK
		set_pev(id, pev_button, iButton &~ IN_ATTACK)	
		
		static iClass, iBody, Float:Vel, Float:Pos[3], Float:vRec[3], iModel, Sound[32], Float:Mins[3], Float:Maxs[3], Float:Gravity, iType, Float:vecOrigin[3], Float:vecVelocity[3], Float:vecAngle[3]
		pev(id, pev_punchangle, vRec)
		
		switch(g_special[id])
		{
			case SP_DRILLGUN:
			{
				if(!g_ammo[id][1])
					return
				
				g_ammo[id][1]--
				update_ammo(id, g_ammo[id][1])
				
				if(g_ammo[id][1]) set_pev(iEnt, pev_iuser3, 1)
				Pos[0] = Pos[1] = 6.5
				Pos[2] = -5.5
				
				Mins[0] = Mins[1] = Mins[2] = -1.1
				Maxs[0] = Maxs[1] = Maxs[2] = 1.1
				Gravity = 0.18
				iType = MOVETYPE_PUSHSTEP
				iClass = ENTCLASS_METAL
				
				Vel = 2100.0
				vRec[0] -= 4.0
				iModel = 12
				iBody = 3
				format(Sound, charsmax(Sound), ShootSound[9])
			}
			case SP_SPEARGUN:
			{
				if(!g_ammo[id][2])
					return
				
				g_ammo[id][2]--
				update_ammo(id, g_ammo[id][2])
				
				if(g_ammo[id][2]) set_pev(iEnt, pev_iuser3, 1)
				Pos[0] = Pos[1] = 6.5
				Pos[2] = -5.5
				
				Gravity = 0.03
				iType = MOVETYPE_TOSS
				iClass = ENTCLASS_METAL
				
				Vel = 2100.0
				vRec[0] -= 6.5
				iModel = 12
				iBody = 4
				format(Sound, charsmax(Sound), ShootSound[4])
			}
			case SP_PETROLBOOMER:
			{
				if(!g_ammo[id][3])
					return
				
				g_ammo[id][3]--
				update_ammo(id, g_ammo[id][3])
				
				if(g_ammo[id][3]) set_pev(iEnt, pev_iuser3, 1)
				Pos[0] = 2.0
				Pos[1] = 4.0
				Pos[2] = -1.0
				
				Vel = 850.0
				Gravity = 0.5
				vRec[0] -= 1.0
				
				iModel = 9
				format(Sound, charsmax(Sound), ShootSound[15])
				
				Mins[0] = Mins[1] = Mins[2] = -1.1
				Maxs[0] = Maxs[1] = Maxs[2] = 1.1
				iType = MOVETYPE_TOSS
				iClass = ENTCLASS_NADE
			}
		}
		set_weapon_anim(id, 1)
		PlaySound(id, CHAN_WEAPON, Sound)
		set_pev(id, pev_punchangle, vRec)
		
		set_pdata_float(iEnt, 46, 1.05)
		set_pdata_float(iEnt, 47, 1.05)
		set_pdata_float(iEnt, 48, 1.28)
		
		set_pev(iEnt, pev_fuser3, CurTime + 1.03)
		pEntity = CreateEntity(id, false, Pos[0], Pos[1], Pos[2], 0.0, Vel, iClass, Model_S[iModel], iType, SOLID_BBOX, Gravity, vecAngle, vecOrigin, vecVelocity, 0.0, 0.0, 0.0, 0, iBody)
		engfunc(EngFunc_SetSize, pEntity, Mins, Maxs)
		
		if(g_special[id] == SP_DRILLGUN || g_special[id] == SP_PETROLBOOMER)
		{
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
			write_byte(TE_BEAMFOLLOW)
			write_short(pEntity)
			write_short(g_cache_trail)
			write_byte(g_special[id] == SP_PETROLBOOMER ? 11 : 1)
			write_byte(g_special[id] == SP_PETROLBOOMER ? 3 : 1)
			write_byte(g_special[id] == SP_PETROLBOOMER ? 255 : 244)
			write_byte(g_special[id] == SP_PETROLBOOMER ? 255 : 244)
			write_byte(g_special[id] == SP_PETROLBOOMER ? 255 : 244)
			write_byte(g_special[id] == SP_PETROLBOOMER ? 50 : 100)
			message_end()
			
			if(g_special[id] == SP_DRILLGUN)
			{
				set_pev(pEntity, pev_iuser2, 5)
				set_pev(pEntity, pev_nextthink, get_gametime() + 0.02)
			} else if(g_special[id] == SP_PETROLBOOMER) Create_Flame(id, pEntity)
		} else {
			set_pev(pEntity, pev_nextthink, get_gametime() + 0.1)
			set_pev(pEntity, pev_iuser2, 1)
			set_pev(iEnt, pev_iuser1, pEntity)
		}
	} else {
		if(CurTime > Timer && iState == 1)
		{
			set_weapon_anim(id, 2)
			
			set_pdata_float(iEnt, 46, g_special[id] == SP_PETROLBOOMER ? 3.85 : 2.25, 4)
			set_pdata_float(iEnt, 47, g_special[id] == SP_PETROLBOOMER ? 3.85 : 2.25, 4)
			set_pdata_float(iEnt, 48, g_special[id] == SP_PETROLBOOMER ? 3.88 : 2.58, 4)
			
			set_pev(iEnt, pev_fuser3, CurTime + (g_special[id] == SP_PETROLBOOMER ? 3.75 : 2.05))
			set_pev(iEnt, pev_iuser3, 2)
		} else if(CurTime > Timer && iState == 2) set_pev(iEnt, pev_iuser3, 0)
	}

	if(iButton & IN_ATTACK2)
	{
		if(!pev_valid(pEntity) || g_special[id] != SP_SPEARGUN)
			return
		if(!(pev(pEntity, pev_iuser2)))
			return

		Pub_Grenade_Explode(pEntity, KNOCKBACK_SPEARGUN, DAMAGE_SPEARGUN, 150.0, pev(pEntity, pev_aiment))
		RemoveEntity(pEntity)
	}
}

public Wpn_Nade(id, iEnt, iClip, iButton)
{
	static Float:vOrigin[3], Float:CurTime, Float:vAngle[3], Float:vVelocity[3], Float:vRec[3]
	pev(id, pev_punchangle, vRec)
	pev(id, pev_v_angle, vAngle)
	new iAmmo = cs_get_user_bpammo(id, CSW_EQUIP)
	global_get(glb_time, CurTime)
	
	if(g_special[id] == SP_M32)
	{
		if((iButton & IN_RELOAD) && iClip < 6 && get_pdata_int(iEnt, 46) < 0.1 && !g_m32_reload[id])
		{
			set_pev(id, pev_button, (iButton &~IN_RELOAD))		
			g_m32_reload[id] = 1
			set_fov(id, 89)
		} else if(!iClip && iAmmo && get_pdata_int(iEnt, 46) < 0.1 && !g_m32_reload[id]) {
			g_m32_reload[id] = 1
			set_fov(id, 89)
		}
	
		if(iAmmo && iClip < 6 && get_pdata_int(iEnt, 46) < 0.1 && g_m32_reload[id] == 1)
		{
			// Start Reload
			g_m32_reload[id] = 2
			set_pdata_float(iEnt, 46, 0.7)
			set_pdata_float(iEnt, 47, 0.7)
			set_weapon_anim(id, 5)
		}
		
		// Loop
		if(g_m32_reload[id] == 2 && get_pdata_int(iEnt, 46) < 0.1 && iAmmo && iClip < 6)
		{
			set_pdata_float(iEnt, 46, 0.9)
			set_pdata_float(iEnt, 47, 0.5)
			g_m32_reload[id] = 3
			set_weapon_anim(id, 3)
		}
		if(g_m32_reload[id] == 3 && get_pdata_int(iEnt, 46) < 0.1)
		{
			iClip++
			iAmmo--
			set_pdata_int(iEnt, 51, iClip)
			cs_set_user_bpammo(id, CSW_EQUIP, iAmmo)
			g_m32_reload[id] = 2
		}
		if((!iAmmo || iClip == 6) && g_m32_reload[id] == 2)
		{
			g_m32_reload[id] = 0
			set_weapon_anim(id, 4)
			set_pdata_float(iEnt, 46, 0.8)
			set_pdata_float(iEnt, 47, 0.9)
			set_pdata_float(iEnt, 48, 0.9)
		}
	}
	
	if(iButton & IN_ATTACK)
	{
		iButton &= ~IN_ATTACK
		set_pev(id, pev_button, iButton &~ IN_ATTACK)
		
		if(is_reloading[id] || get_pdata_int(iEnt, 46) > 0.0 || !iClip)
			return
		
		set_pdata_int(iEnt, 51, iClip - 1)
		
		static iModel, iBody, iAnim, Float:Gravity, Float:Mins[3], Float:Maxs[3], Float:Pos[3], Float:Vel[2], iType, Float:Timer
		switch(g_special[id])
		{
			case SP_FGLAUNCHER:
			{
				Timer = 0.7515
				PlaySound(id, CHAN_WEAPON, ShootSound[10])
				iAnim = 1
				
				Pos[0] = 22.5
				Pos[1] = 4.0
				Pos[2] = -4.0
				
				Vel[0] = -6.0
				Vel[1] = 855.0
				
				Gravity = 0.405
				vRec[0] = -15.0
				
				Mins[0] = Mins[1] = Mins[2] = -3.0
				Maxs[0] = Maxs[1] = Maxs[2] = 3.0
				iType = MOVETYPE_TOSS
				iModel = 13
			}
			case SP_M32:
			{
				Timer = 0.7515
				PlaySound(id, CHAN_WEAPON, ShootSound[11])
				iAnim = 2
				g_m32_reload[id] = 0
				
				Pos[0] = 60.0
				Pos[1] = 12.0
				Pos[2] = -10.0
				
				Vel[0] = -13.1
				Vel[1] = 765.0
				
				Gravity = 0.475
				vRec[0] = -15.0
				
				Mins[0] = Mins[1] = Mins[2] = -3.0
				Maxs[0] = Maxs[1] = Maxs[2] = 3.0
				iType = MOVETYPE_TOSS
				iModel = 13
			}
			case SP_AT4EX:
			{
				Timer = 0.3
				PlaySound(id, CHAN_WEAPON, ShootSound[0])
				iAnim = random_num(1, 2)
				
				Pos[0] = 15.0
				Pos[1] = 1.0
				Pos[2] = -3.5
				
				Vel[0] = 0.0
				Vel[1] = SPEED_AT4EX
				
				Gravity = 0.0
				vRec[0] = random_float(-6.5, 6.5)
				
				Mins[0] = Mins[1] = Mins[2] = -1.0
				Maxs[0] = Maxs[1] = Maxs[2] = 1.0
				iType = MOVETYPE_FLYMISSILE
				iModel = 14
				
				message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("ScreenShake"), _, id)
				write_short((1<<12) * 9) 
				write_short((1<<12) * 1) 
				write_short((1<<12) * 9) 
				message_end()
			}
			case SP_RPG7:
			{
				Timer = 1.0
				PlaySound(id, CHAN_WEAPON, ShootSound[16])
				iAnim = g_mode[id] ? 5 : 4
				set_fov(id, 90)
				
				Pos[0] = 30.0
				Pos[1] = g_mode[id] ? 1.0 : 8.0
				Pos[2] = g_mode[id] ? -15.0 : -8.0
				
				Vel[0] = 0.0
				Vel[1] = 1650.0
				
				Gravity = g_mode[id] ? 0.01 : -0.63
				vRec[0] = random_float(-9.5, 9.5)
				
				Mins[0] = Mins[1] = Mins[2] = -3.0
				Maxs[0] = Maxs[1] = Maxs[2] = 3.0
				iType = g_mode[id] ? MOVETYPE_FLY : MOVETYPE_TOSS
				iBody = 2
				iModel = 12
			}
		}
		set_weapon_anim(id, iAnim)
		set_pdata_float(iEnt, 46, Timer, 4)
		set_pev(id, pev_punchangle, vRec)
		
		if(g_special[id] == SP_AT4EX || g_special[id] == SP_FGLAUNCHER || g_special[id] == SP_RPG7)
		{
			Stock_Get_Postion(id, Pos[0], Pos[1], Pos[2], vOrigin)
			vOrigin[2] -= 10.0
				
			message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
			write_byte(TE_EXPLOSION)
			engfunc(EngFunc_WriteCoord, vOrigin[0])
			engfunc(EngFunc_WriteCoord, vOrigin[1])
			engfunc(EngFunc_WriteCoord, vOrigin[2])
			write_short(g_cache_smoke[0])
			write_byte(g_special[id] == SP_RPG7 ? 9 : 1)
			write_byte(g_special[id] == SP_RPG7 ? 20 : 10)
			write_byte(TE_EXPLFLAG_NODLIGHTS | TE_EXPLFLAG_NOSOUND |TE_EXPLFLAG_NOPARTICLES)
			message_end()
		}
		
		new iEntity = CreateEntity(id, false, Pos[0], Pos[1], Pos[2], Vel[0], Vel[1], ENTCLASS_NADE, Model_S[iModel], iType, SOLID_BBOX, Gravity, vAngle, vOrigin, vVelocity, 0.0, 0.0, 0.0, 0, iBody)
		engfunc(EngFunc_SetSize, iEntity, Mins, Maxs)
		set_pev(iEntity, pev_nextthink, halflife_time() + 0.1)
		
		if(g_special[id] == SP_AT4EX)
		{
			set_pev(iEntity, pev_effects, EF_LIGHT)
			
			for(new i = 1; i < 33; i++)
			{
				if(g_aiming[id] && i != id && is_user_alive(i) && can_damage(i, id) && Stock_CheckAngle(id, i) > floatcos(20.0, degrees) && Stock_Is_Direct(id, i))
				{
					Set_Sp_On(iEntity, i)
					break
				}
			}
		} else if(g_special[id] != SP_RPG7) {
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
			write_byte(TE_BEAMFOLLOW)
			write_short(iEntity)
			write_short(g_cache_trail)
			write_byte(g_special[id] == SP_FGLAUNCHER ? 3 : 7)
			write_byte(g_special[id] == SP_FGLAUNCHER ? 4 : 6)
			write_byte(g_special[id] == SP_FGLAUNCHER ? 255 : 224)
			write_byte(g_special[id] == SP_FGLAUNCHER ? 110 : 224)
			write_byte(g_special[id] == SP_FGLAUNCHER ? 110 : 255)
			write_byte(g_special[id] == SP_FGLAUNCHER ? 220 : 220)
			message_end()
			
			if(g_special[id] == SP_FGLAUNCHER) Set_Sp_On(iEntity, 1)
		} else g_mode[id] = 0
	}
	
	if((iButton & IN_ATTACK2) && g_lastaim[id] < get_gametime())
	{
		g_lastaim[id] = get_gametime() + 0.5
		switch(g_special[id])
		{
			case SP_RPG7:
			{
				set_weapon_anim(id, g_mode[id] ? (iClip == 1 ? 10 : 12) : (iClip == 1 ? 9 : 11))
				set_pdata_float(iEnt, 46, 0.65)
				set_pdata_float(iEnt, 48, 0.65)
				
				set_pdata_int(id, 363, g_mode[id] ? 90 : 65)
				g_mode[id] = 1 - g_mode[id]
			}
			case SP_AT4EX:
			{
				if(!is_reloading[id])
				{
					g_aiming[id] = 1 - g_aiming[id]
					cs_set_user_zoom(id, g_aiming[id] ? CS_SET_FIRST_ZOOM : CS_RESET_ZOOM, 1)
				}
			}
			case SP_M32:
			{
				if(!g_m32_reload[id])
				{
					g_zoom[id] = 1 - g_zoom[id]
					if(g_zoom[id]) cs_set_user_zoom(id, CS_SET_AUGSG552_ZOOM, 1)
					else set_fov(id, 89)
				}
			}
		}
	}
}

public Wpn_Cannon(id, ent, iButton)
{
	if(iButton & IN_ATTACK && g_cannon_timer[id] < get_gametime() && g_ammo[id][0] > 0)
	{
		static Float:fOrigin[3]
		Stock_Get_Postion(id, 10.0, 0.0, -10.0, fOrigin)
			
		message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
		write_byte(TE_EXPLOSION)
		engfunc(EngFunc_WriteCoord, fOrigin[0])
		engfunc(EngFunc_WriteCoord, fOrigin[1])
		engfunc(EngFunc_WriteCoord, fOrigin[2])
		write_short(g_cache_smoke[0])
		write_byte(1)
		write_byte(20)
		write_byte(TE_EXPLFLAG_NODLIGHTS | TE_EXPLFLAG_NOSOUND |TE_EXPLFLAG_NOPARTICLES)
		message_end()
		
		g_cannon_timer[id] = get_gametime() + 3.2
		set_pdata_float(ent, 46, 3.53, 4)
		set_pdata_float(ent, 47, 3.53, 4)
		set_pdata_float(ent, 48, g_ammo[id][0] > 1 ? 3.53 : 0.3, 4)
		if(g_ammo[id][0] == 1) set_task(1.85, "removesound", id)
		
		if(g_ammo[id][0] > 1)
		{
			switch(random_num(0, 9))
			{
				case 0..4: CannonEffect(id)
				case 5..9:
				{
					CannonEffect(id)
					set_task(0.1, "CannonEffect", id)
				}
				
			}
		} else CannonEffect(id)
		
		g_ammo[id][0]--
		update_ammo(id, g_ammo[id][0])
	}
	iButton &= ~IN_ATTACK
	set_pev(id, pev_button, iButton)
}

public CannonEffect(id)
{
	set_weapon_anim(id, random_num(1, 2))
	PlaySound(id, CHAN_WEAPON, ShootSound[3])
	
	static Float:VirtualVec[3]
	VirtualVec[0] = random_float(-3.5, -7.0)
	VirtualVec[1] = random_float(3.0, -3.0)
	VirtualVec[2] = 0.0
	set_pev(id, pev_punchangle, VirtualVec)	
	
	// Effect
	new iEnt, Float:fSpeed = 320.0, Float:vStart[3], Float:iAngle[3], Float:vVelocity[3], Float:vPlrAngle[3]
	Stock_Get_Postion(id, 55.0, 2.0, -1.0, vStart)
	pev(id, pev_v_angle, vPlrAngle)
	vPlrAngle[1] -= 18.0
	
	for(new i = 0; i < 6; i++)
	{
		vPlrAngle[1] += random_float(2.0, 10.0)
		angle_vector(vPlrAngle, ANGLEVECTOR_FORWARD, vVelocity)
		xs_vec_mul_scalar(vVelocity, fSpeed, vVelocity)
		
		iEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
		Set_Class(iEnt, ENTCLASS_CANNON)
		set_pev(iEnt, pev_origin, vStart)
		set_pev(iEnt, pev_rendermode, kRenderTransAdd)
		set_pev(iEnt, pev_renderamt, 254.0)
		set_pev(iEnt, pev_animtime, get_gametime())
		set_pev(iEnt, pev_frame, 0.0)
		set_pev(iEnt, pev_scale, 1.6)
		engfunc(EngFunc_SetModel, iEnt, Model_S[0])
		engfunc(EngFunc_SetSize, iEnt, Float:{-1.0, -1.0, -1.0}, Float:{1.0, 1.0, 1.0})
		dllfunc(DLLFunc_Spawn, iEnt)
		
		iAngle[0] = random_float(-180.0, 180.0)
		iAngle[1] = random_float(-180.0, 180.0)
		iAngle[2] -= random_num(1, 360)
		
		set_pev(iEnt, pev_angles, iAngle)
		set_pev(iEnt, pev_movetype, MOVETYPE_FLY)
		set_pev(iEnt, pev_solid, SOLID_NOT)
		set_pev(iEnt, pev_velocity, vVelocity)
		set_pev(iEnt, pev_owner, id)
		set_pev(iEnt, pev_ltime, get_gametime() + 1.2)
		set_pev(iEnt, pev_nextthink, get_gametime() + 0.05)
	}
	
	// Effect End
	new iVictim = -1
	while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, vStart, 250.0)) != 0)
	{
		if(id == iVictim || !pev_valid(iVictim))
			continue
		
		if(iVictim > 33)
		{
			if(!pev(iVictim,pev_takedamage))
				continue
			if(pev(iVictim,pev_spawnflags) & SF_BREAK_TRIGGER_ONLY)
				continue
			
			Pub_Fake_Damage_Guns(id, iVictim, DAMAGE_CANNON, 0, 250.0, id, 0, DMG_CLUB)
		} else {
			if(!can_damage(id, iVictim))
				continue
			
			if(Stock_CheckAngle(id, iVictim) > floatcos(25.0, degrees) && Stock_Is_Direct(id, iVictim))
			{
				Stock_Buff(iVictim, 0, g_cache_flameburn, 10)
				Pub_Fake_Damage_Guns(id, iVictim, DAMAGE_CANNON, (1<<3)|(1<<4), 250.0, id)
				Stock_Fake_KnockBack(id, iVictim, KNOCKBACK_CANNON)
			}
		}
	}
}
public removesound(id) PlaySound(id, CHAN_WEAPON, "common/null.wav")

public Wpn_Chainsaw(id, iEnt, iClip, iButton)
{
	if(get_pdata_float(iEnt, 46) > 0.0)
		return

	static iState, Float:iTimer
	iState = pev(iEnt, pev_iuser1)
	pev(iEnt, pev_fuser4, iTimer)
	
	if((!iClip || !(iButton & IN_ATTACK) && !(iButton & IN_ATTACK2)) && iState == 1)
	{
		iState = 2
		set_weapon_anim(id, 5)
		
		if(!iClip) set_pdata_float(iEnt, 46, 1.53)
		set_pdata_float(iEnt, 48, 1.53)
		set_pev(iEnt, pev_iuser1, iState)
		return
	}

	if(iButton & IN_ATTACK && !(iButton & IN_ATTACK2))
	{
		switch(iState)
		{
			case 0:
			{
				iState = 1
				set_weapon_anim(id,3)
				
				set_pdata_float(iEnt, 46, 0.53)
				set_pdata_float(iEnt, 48, 1.53)
				
				set_pev(iEnt, pev_iuser1, iState)
				set_pev(iEnt, pev_iuser2, 0)
				return
			}
			case 1:
			{
				if(!iClip)
				{
					iState = 2
					set_weapon_anim(id, 5)
					
					set_pdata_float(iEnt, 48, 1.53)
					set_pev(iEnt, pev_iuser1, iState)
					return
				}
				
				if(!pev(iEnt, pev_iuser2))
				{
					set_weapon_anim(id, 4)
					set_pev(iEnt,pev_iuser2, 1)
				}
				
				if(iTimer < get_gametime())
				{
					iTimer = get_gametime() + 0.05545
					set_pev(iEnt, pev_fuser4, iTimer)
					
					iClip--
					set_pdata_int(iEnt, 51, iClip)
				}
				
				new iCallBack = Pub_Fake_Melee_Attack(id, 115.0, 0.0, 2, DAMAGE_POWERSAW, 0.0, 0, 0)
				if(iCallBack == RESULT_HIT_PLAYER) PlaySound(id, CHAN_WEAPON, ShootSound[5])
				else if(iCallBack == RESULT_HIT_WORLD)
				{
					new Float:vecOrigin[3], Float:start[3], Float:view_ofs[3]
					pev(id, pev_origin, start)
					pev(id, pev_view_ofs, view_ofs)
					xs_vec_add(start, view_ofs, start)
					
					pev(id, pev_v_angle, vecOrigin)
					engfunc(EngFunc_MakeVectors, vecOrigin)
					global_get(glb_v_forward, vecOrigin)
					xs_vec_mul_scalar(vecOrigin, 100.0, vecOrigin)
					xs_vec_add(start, vecOrigin, vecOrigin)
					
					new ptr = create_tr2()
					engfunc(EngFunc_TraceLine, start, vecOrigin, DONT_IGNORE_MONSTERS, id, ptr)
					get_tr2(ptr, TR_vecEndPos, vecOrigin)
					free_tr2(ptr)
					
					message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
					write_byte(TE_GUNSHOTDECAL)
					engfunc(EngFunc_WriteCoord, vecOrigin[0])
					engfunc(EngFunc_WriteCoord, vecOrigin[1])
					engfunc(EngFunc_WriteCoord, vecOrigin[2])
					write_short(id)
					switch(random_num(0, 4))
					{
						case 0: write_byte(engfunc(EngFunc_DecalIndex, "{shot1"))
						case 1: write_byte(engfunc(EngFunc_DecalIndex, "{shot2"))
						case 2: write_byte(engfunc(EngFunc_DecalIndex, "{shot3"))
						case 3: write_byte(engfunc(EngFunc_DecalIndex, "{shot4"))
						case 4: write_byte(engfunc(EngFunc_DecalIndex, "{shot5"))
					}
					message_end()
				}
				set_pdata_float(iEnt, 46, 0.03545)
				set_pdata_float(iEnt, 48, 9999.0)
				
				message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("ScreenShake"), _, id)
				write_short((1<<12) * 5) 
				write_short((1<<12) * 1) 
				write_short((1<<12) * 5) 
				message_end()
				return
			}
			case 2:
			{
				iState = 0
				set_pev(iEnt, pev_iuser1, iState)
			}
		}		
	}

	if(iButton & IN_ATTACK2)
	{
		new iCallBack2 = Pub_Fake_Melee_Attack(id, 125.0, 120.0, 2, DAMAGE_POWERSAW2, KNOCKBACK_POWERSAW, 0, 13)
		new iAnim = pev(iEnt, pev_iuser3)
		iAnim = 1 - iAnim

		if(!iClip)
		{
			set_weapon_anim(id, iAnim ? 9 : 10)
			if(iCallBack2 == RESULT_HIT_PLAYER) PlaySound(id, CHAN_WEAPON, ShootSound[random_num(7, 8)])
		} else {
			set_weapon_anim(id, iAnim ? 7 : 8) 
			if(iCallBack2 == RESULT_HIT_PLAYER) PlaySound(id, CHAN_WEAPON, ShootSound[random_num(5, 6)])
		}
		set_pdata_float(iEnt, 46, 1.0)
		set_pdata_float(iEnt, 48, 1.53, 4)

		set_pev(iEnt, pev_iuser1, 0)
		set_pev(iEnt, pev_iuser3, iAnim)
	}
	iButton &= ~IN_ATTACK
	iButton &= ~IN_ATTACK2
	set_pev(id, pev_button, iButton)
}

////////// Entities
public CreateEntity(id, bool:Flame, Float:X, Float:Y, Float:Z, Float:angle, Float:Speed, Class, model[], MoveType, Solid, Float:Gravity, Float:vAngle[3], Float:vOrigin[3], Float:vVelocity[3], Float:Scale, Float:Frame, Float:vRender, iType, iBody)
{
	static iEnt
	iEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, iType == 1 ? "env_sprite" : "info_target"))
	
	Set_Class(iEnt, Class)
	engfunc(EngFunc_SetModel, iEnt, model)
	
	if(!Stock_CheckPetrol_Ent(iEnt))
	{
		Stock_Get_Postion(id, X, Y, Z, vOrigin)
		if(angle == 0.0)
		{
			new Float:vecEndPos[3]
			Stock_Get_Aiming(id, vecEndPos)
			Stock_GetSpeedVector(vOrigin, vecEndPos, Speed, vVelocity) // Should up to 3000.0
		} else Stock_Velocity_By_Aim(vAngle, angle, Speed, vVelocity)
		if(equal(model, Model_S[12])) set_pev(iEnt, pev_body, iBody)
		
		engfunc(EngFunc_VecToAngles, vVelocity, vAngle)
		if(vAngle[0] > 90.0) vAngle[0] = -(360.0 - vAngle[0])
	}
	set_pev(iEnt ,pev_angles, vAngle)
	if(Flame == true) Create_FlameEntity(iEnt, Scale, Frame, vRender, true)
	set_pev(iEnt, pev_gravity, Gravity)
	set_pev(iEnt, pev_movetype, MoveType)
	set_pev(iEnt, pev_solid, Solid)
	set_pev(iEnt, pev_owner, id)
	set_pev(iEnt, pev_origin, vOrigin)
	set_pev(iEnt, pev_velocity, vVelocity)
	return iEnt
}

public Create_FakeEntity(id, Float:Origin[3])
{
	static Ent
	Ent = CreateEntity(id, true, 0.0,0.0,0.0,0.0,0.0, ENTCLASS_PETROL, "models/w_usp.mdl", MOVETYPE_TOSS, SOLID_NOT, 0.6, Null, Null, Null, 1.0, 0.0, 1.0, 0, 0)
	set_pev(Ent, pev_owner, id)
	set_pev(Ent, pev_origin, Origin)
	set_pev(Ent, pev_fuser1, get_gametime() + 7.0)
	set_pev(Ent, pev_nextthink, get_gametime() + 0.5)
	Create_Flame2(id, Ent)
}

public Create_Flame(id, iEnt)
{
	new num = (iEnt ? 1 : 0)
	g_iEnt[id][num] = CreateEntity(id, false, 0.0,0.0,0.0,0.0,0.0, ENTCLASS_FLAME_PETROL, Model_S[10], MOVETYPE_FOLLOW, SOLID_NOT, iEnt ? 0.01 : 0.0, Null, Null, Null, 0.0, 0.0, 0.0, 1, 0)
	set_pev(g_iEnt[id][0], pev_body, 2)
	if(iEnt)
	{
		engfunc(EngFunc_SetSize, iEnt, Float:{-0.1, -0.1, -0.1}, Float:{0.1, 0.1, 0.1})
		set_pev(iEnt, pev_owner, id)
	}
	set_pev(g_iEnt[id][num], pev_nextthink, get_gametime() + 0.05)
	set_pev(g_iEnt[id][num], pev_aiment, iEnt ? iEnt : id)
	Create_FlameEntity(g_iEnt[id][num], 100.0, 0.0, iEnt ? 200.0 : 190.0, iEnt ? false : true)
}

public Create_Flame2(id, iEnt)
{
	static iEnt2
	iEnt2 = CreateEntity(id, false, 0.0,0.0,0.0,0.0,0.0, ENTCLASS_FLAME_PETROL2, Model_S[11], MOVETYPE_FOLLOW, SOLID_TRIGGER, 0.0, Null, Null, Null, 0.0, 0.0, 0.0, 1, 0)
	
	set_pev(iEnt2, pev_body, 2)
	engfunc(EngFunc_SetSize, iEnt2, {-10.1,-10.1,-10.1}, {10.1,10.1,10.1})
	set_pev(iEnt2, pev_fuser1, get_gametime() + 7.0)
	set_pev(iEnt2, pev_nextthink, get_gametime() + 0.4)
	set_pev(iEnt2, pev_aiment, iEnt)
	Create_FlameEntity(iEnt2, 10.0, 0.0, 0.0, true)
}

public Create_FlameEntity(iEnt, Float:Scale, Float:Frame, Float:vRender, bool:iSpawn)
{
	set_pev(iEnt, pev_scale, Scale)
	set_pev(iEnt, pev_frame, Frame)
	set_pev(iEnt, pev_rendermode, kRenderTransAdd)
	set_pev(iEnt, pev_renderamt, vRender)
	if(iSpawn == true) dllfunc(DLLFunc_Spawn, iEnt)
}

public Create_Muzzleflash(id, Class, model[])
{
	static iMuz
	iMuz = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_sprite"))

	Set_Class(iMuz, Class)
	engfunc(EngFunc_SetModel, iMuz, model)
	set_pev(iMuz, pev_nextthink, get_gametime() + 0.15)
	set_pev(iMuz, pev_body, 1)
	set_pev(iMuz, pev_movetype, MOVETYPE_FOLLOW)
	set_pev(iMuz, pev_aiment, id)
	set_pev(iMuz, pev_solid, SOLID_NOT)
	Create_FlameEntity(iMuz, 0.1, 1.0, 255.0, true)
}

public Pub_Grenade_Explode(iEnt, Float:fKnockBack, Float:fNadeDmg, Float:fRadius, aiment)
{
	static iAttacker, Float:vEntOrigin[3]
	iAttacker = pev(iEnt, pev_owner)
	pev(aiment ? aiment : iEnt, pev_origin, vEntOrigin)
	vEntOrigin[2] += 1.0
	
	if(g_special[iAttacker] == SP_PETROLBOOMER) MakeCoord(iAttacker, iEnt, vEntOrigin)
	Stock_RadiusDamage(iEnt, vEntOrigin, 0, iAttacker, fNadeDmg, fRadius, fKnockBack, (1<<24), g_special[iAttacker] == SP_PETROLBOOMER ? true : false, true)
	
	if(g_special[iAttacker] != SP_SPEARGUN)
	{
		message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
		write_byte(TE_WORLDDECAL)
		engfunc(EngFunc_WriteCoord, vEntOrigin[0])
		engfunc(EngFunc_WriteCoord, vEntOrigin[1])
		engfunc(EngFunc_WriteCoord, vEntOrigin[2])
		switch(random_num(0, 2))
		{
			case 0: write_byte(engfunc(EngFunc_DecalIndex, "{scorch1"))
			case 1: write_byte(engfunc(EngFunc_DecalIndex, "{scorch2"))
			case 2: write_byte(engfunc(EngFunc_DecalIndex, "{scorch3"))
		}
		message_end()	
	}
	
	if(g_special[iAttacker] == SP_FGLAUNCHER)
	{
		new Origin[3]
		FVecIVec(vEntOrigin, Origin)
		set_task(0.3, "Task_FG_Effect", 0, Origin, 3, "a", 3)
		
		engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vEntOrigin, 0)
		write_byte(TE_EXPLOSION)
		engfunc(EngFunc_WriteCoord,vEntOrigin[0])
		engfunc(EngFunc_WriteCoord,vEntOrigin[1])
		engfunc(EngFunc_WriteCoord,vEntOrigin[2] + 20.0)
		write_short(g_cache_fg[1])
		write_byte(10)
		write_byte(17)
		write_byte(TE_EXPLFLAG_NONE)
		message_end()
	} else {
		engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vEntOrigin, 0)
		write_byte(TE_EXPLOSION)
		engfunc(EngFunc_WriteCoord, vEntOrigin[0])
		engfunc(EngFunc_WriteCoord, vEntOrigin[1])
		engfunc(EngFunc_WriteCoord, vEntOrigin[2] + 20.0)
		write_short(g_exp[1])
		write_byte(25)
		write_byte(30)
		write_byte(TE_EXPLFLAG_NOSOUND)
		message_end()
		
		engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vEntOrigin, 0)
		write_byte(TE_EXPLOSION)
		engfunc(EngFunc_WriteCoord, vEntOrigin[0] + random_float(-64.0, 64.0))
		engfunc(EngFunc_WriteCoord, vEntOrigin[1] + random_float(-64.0, 64.0))
		engfunc(EngFunc_WriteCoord, vEntOrigin[2] + random_float(30.0, 35.0))
		write_short(g_exp[0])
		write_byte(30)
		write_byte(30)
		write_byte(TE_EXPLFLAG_NONE)
		message_end()
		
		if(g_special[iAttacker] == SP_SPEARGUN)
		{	
			message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
			write_byte(TE_BREAKMODEL)
			engfunc(EngFunc_WriteCoord, vEntOrigin[0])
			engfunc(EngFunc_WriteCoord, vEntOrigin[1])
			engfunc(EngFunc_WriteCoord, vEntOrigin[2])
			engfunc(EngFunc_WriteCoord, 150)
			engfunc(EngFunc_WriteCoord, 150)
			engfunc(EngFunc_WriteCoord, 150)
			engfunc(EngFunc_WriteCoord, random_num(-50, 50))
			engfunc(EngFunc_WriteCoord, random_num(-50, 50))
			engfunc(EngFunc_WriteCoord, random_num(-50, 50))
			write_byte(30)
			write_short(s_break)
			write_byte(random_num(15, 20))
			write_byte(20)
			write_byte(0)
			message_end()
		}
	}
}

public MakeCoord(id, iEnt, Float:Origin[3])
{
	static Float:Origin2[4][3]
	Stock_Get_Postion(iEnt, -100.0, 0.0, 0.0, Origin2[0])
	Stock_Get_Postion(iEnt, 100.0, 0.0, 0.0, Origin2[1])
	Stock_Get_Postion(iEnt, 0.0, -100.0, 0.0, Origin2[2])
	Stock_Get_Postion(iEnt, 0.0, 100.0, 0.0, Origin2[3])
	
	for(new i = 0; i < 4; i++)
	{
		Create_FakeEntity(id, Origin)
		if(!Stock_CheckWall(Origin, Origin2[i], id)) Create_FakeEntity(id, Origin2[i])
	}
}

public Task_FG_Effect(Origin[3])
{
	static Float:vOrigin[3]
	IVecFVec(Origin, vOrigin)
	
	Stock_FgLauncher_Effect(vOrigin)
}

stock Stock_FgLauncher_Effect(Float:vEntOrigin[3])
{
	static Float:vColor[5][3]
	new iEntity = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_sprite"))
	
	new Float:vOrigin[3]
	vOrigin[0] = vEntOrigin[0] + random_float(-35.0, 35.0)
	vOrigin[1] = vEntOrigin[1] + random_float(-35.0, 35.0)
	vOrigin[2] = vEntOrigin[2] + random_float(30.0, 120.0)

	Stock_Set_Kvd(iEntity, "model", Model_S[3], "cycle_sprite")
	Stock_Set_Kvd(iEntity, "framerate", "29.0", "cycle_sprite")
	set_pev(iEntity, pev_spawnflags, SF_SPRITE_ONCE)
	dllfunc(DLLFunc_Spawn, iEntity)
	set_pev(iEntity, pev_scale, 0.9)
	
	vColor[0][0] = 92.0
	vColor[0][1] = 35.0
	vColor[0][2] = 78.0
	
	vColor[1][0] = 73.0
	vColor[1][1] = 101.0
	vColor[1][2] = 164.0
	
	vColor[2][0] = 30.0
	vColor[2][1] = 71.0
	vColor[2][2] = 31.0
	
	vColor[3][0] = 179.0
	vColor[3][1] = 63.0
	vColor[3][2] = 64.0
	
	vColor[4][0] = 229.0
	vColor[4][1] = 210.0
	vColor[4][2] = 118.0
	
	set_pev(iEntity, pev_rendercolor, vColor[random_num(0, 4)])
	set_pev(iEntity, pev_rendermode, kRenderTransAdd)
	set_pev(iEntity, pev_renderamt, 254.0)
	set_pev(iEntity, pev_origin, vOrigin)	
	
	emit_sound(iEntity, CHAN_VOICE, ShootSound[12], 1.0, ATTN_NORM, 0, random_num(95, 120))
	engfunc(EngFunc_RemoveEntity, iEntity)
	
	message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
	write_byte(TE_EXPLOSION)
	engfunc(EngFunc_WriteCoord, vOrigin[0])
	engfunc(EngFunc_WriteCoord, vOrigin[1])
	engfunc(EngFunc_WriteCoord, vOrigin[2])
	write_short(g_cache_fg[0])
	write_byte(9)
	write_byte(29)
	write_byte(TE_EXPLFLAG_NOSOUND + TE_EXPLFLAG_NODLIGHTS)
	message_end()
}

stock Stock_Set_Kvd(entity, key[], value[], classname[])
{
	set_kvd(0, KV_ClassName, classname)
	set_kvd(0, KV_KeyName, key)
	set_kvd(0, KV_Value, value)
	set_kvd(0, KV_fHandled, 0)

	dllfunc(DLLFunc_KeyValue, entity, 0)
}

public Stock_RadiusDamage(iEnt, Float:vecSrc[3], pevInflictor, pevAttacker, Float:flDamage, Float:flRadius, Float:fKnockBack, bitsDamageType, bool:bSkipAttacker, bool:bCheckTeam)
{
	new pEntity = -1
	new bInWater = (engfunc(EngFunc_PointContents, vecSrc) == CONTENTS_WATER)
	vecSrc[2] += 1.0
	if(!pevAttacker) pevAttacker = pevInflictor
	
	while((pEntity = engfunc(EngFunc_FindEntityInSphere, pEntity, vecSrc, flRadius)) != 0)
	{
		if(pev(pEntity, pev_takedamage) == DAMAGE_NO)
			continue
		if(bInWater && !pev(pEntity, pev_waterlevel))
			continue
		if(!bInWater && pev(pEntity, pev_waterlevel) == 3)
			continue
		if(bCheckTeam && IsPlayer(pEntity) && pEntity != pevAttacker)
			if(!can_damage(pEntity, pevAttacker))
				continue
		
		if(g_special[pevAttacker] == SP_SPEARGUN)
		{	
			static Float:vecVelocity[2][3]
			pev(pEntity, pev_velocity, vecVelocity[0])
			
			vecVelocity[1][0] = vecVelocity[0][0]
			vecVelocity[1][1] = vecVelocity[0][1]
			vecVelocity[1][2] = 250.0
			set_pev(pEntity, pev_velocity, vecVelocity[1])
		}
		
		if(bSkipAttacker && pEntity == pevAttacker)
			continue
		
		static Float:fDmg
		if(bSkipAttacker == false && pEntity == pevAttacker) fDmg = 1.1
		else fDmg = flDamage
		ExecuteHamB(Ham_TakeDamage, pEntity, pevAttacker, pevAttacker, fDmg, bitsDamageType)
		Stock_Fake_KnockBack(pevAttacker, pEntity, fKnockBack)
	}
}

stock set_weapon_anim(id, anim)
{
	set_pev(id, pev_weaponanim, anim)

	message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, _, id)
	write_byte(anim)
	write_byte(pev(id,pev_body))
	message_end()
}

// Check neccessary items
stock Stock_Check(id)
{
	for(new i = 0; i < WEAPON_TOTAL; i++)
	{
		if(g_had_weapon[id][i])
			return 1
	}
	return 0
}

stock Stock_CheckPetrol_Ent(iEnt)
{
	if(Get_Class(iEnt) == ENTCLASS_PETROL || Get_Class(iEnt) == ENTCLASS_FLAME_PETROL || Get_Class(iEnt) == ENTCLASS_FLAME_PETROL2)
		return 1
	if(Get_Class(iEnt) == ENTCLASS_MUZZLE1 || Get_Class(iEnt) == ENTCLASS_MUZZLE2)
		return 1
	return 0
}

stock Stock_CheckWeapons(id, iNum)
{
	switch(iNum)
	{
		case 0: // Idle
		{
			if(g_special[id] == SP_PETROLBOOMER || g_special[id] == SP_DRILLGUN || g_had_weapon[id][HAD_POWERSAW] || g_special[id] == SP_RPG7 || g_special[id] == SP_SPEARGUN)
				return 1
		}
		case 1: // No use reload
		{
			if(g_special[id] == SP_PETROLBOOMER || g_special[id] == SP_CANNON || g_special[id] == SP_DRILLGUN || g_special[id] == SP_M32 || g_special[id] == SP_SPEARGUN)
				return 1
		}
		case 2: // Hide Crosshair
		{
			if(g_special[id] == SP_FGLAUNCHER || g_special[id] == SP_M32 || g_special[id] == SP_PETROLBOOMER || g_special[id] == SP_RPG7 || (g_special[id] == SP_AT4EX && !g_aiming[id]))
				return 1
		}
		case 3: // Custom FOV
		{
			if(g_special[id] == SP_FGLAUNCHER || (g_special[id] == SP_M32 && !g_zoom[id]) || g_special[id] == SP_PETROLBOOMER)
				return 1
		}
	}
	return 0
}

public Set_Class(ent, num) set_pdata_int(ent, 19, num, 4)
public Get_Class(ent) return get_pdata_int(ent, 19, 4)

public Set_Sp_On(ent, Num) set_pdata_int(ent, 21, Num, 4)
public Get_Sp_On(ent) return get_pdata_int(ent, 21, 4)

public PlaySound(id, chan, sound[]) emit_sound(id, chan, sound, 1.0, ATTN_NORM, 0, random_num(95, 120))

public set_weapon_list(id, sName[])
{
	message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("WeaponList"), _, id)
	write_string(sName)    // WeaponName
	write_byte(3)                  // PrimaryAmmoID
	write_byte(200)                  // PrimaryAmmoMaxAmount
	write_byte(-1)                   // SecondaryAmmoID
	write_byte(-1)                   // SecondaryAmmoMaxAmount
	write_byte(0)                    // SlotID (0...N)
	write_byte(4)                    // NumberInSlot (1...N)
	write_byte(CSW_EQUIP)            // WeaponID
	write_byte(0)                   // Flags
	message_end()
}

public set_fov(id, fov) set_pdata_int(id, 363, fov, 5)
public Crosshair(id, iHide)
{
	message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("HideWeapon"), _, id)
	write_byte(iHide == 1 ? (1<<6) : (1>>6))
	message_end()
}

public update_ammo(id, ammo)
{
	if(!is_user_alive(id))
		return
	
	message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("CurWeapon"), _, id)
	write_byte(1)
	write_byte(CSW_EQUIP)
	write_byte(-1)
	message_end()
	
	message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("AmmoX"), _, id)
	write_byte(3)
	write_byte(ammo)
	message_end()
}

stock Float:Stock_CheckWall(Float:start[3], Float:end[3], ignore_ent)
{
	static ptr
	ptr = create_tr2()

	engfunc(EngFunc_TraceLine, start, end, IGNORE_MONSTERS, ignore_ent, ptr)
	
	static Float:EndPos[3]
	get_tr2(ptr, TR_vecEndPos, EndPos)

	free_tr2(ptr)
	return get_distance_f(end, EndPos)
}

stock Pub_Fake_Melee_Attack(iAttacker, Float:fRange, Float:fAngle, iBtn, Float:fDamage, Float:fKB, iCheckAccshoot = 0, iBloodScale = 0)
{
	new Float:vecOri1[3], Float:fDmg
	pev(iAttacker, pev_origin, vecOri1)
	
	if(fAngle > 180.0) //all
	{
		new aimvictim,body
		get_user_aiming(iAttacker, aimvictim, body, floatround(fRange))
		new iVictim = -1
		new hitplayer = 0, hitwall = 0;
		hitwall = Stock_is_aiming_wall(iAttacker, fRange)
		
		while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, vecOri1, fRange)) != 0)
		{
			fDmg = fDamage
			
			if(iAttacker == iVictim || !pev_valid(iVictim)) continue
			if(!pev(iVictim, pev_takedamage)) continue
			if(!(Stock_CheckAngle(iAttacker, iVictim) > floatcos(fAngle, degrees))) continue
			if(pev(iVictim, pev_spawnflags) & SF_BREAK_TRIGGER_ONLY) continue
			if(!Stock_Is_Direct(iAttacker, iVictim)) continue
			
			if(iVictim >= 1 && iVictim <= 32)
			{
				hitplayer = 1
				if(fKB) Stock_Fake_KnockBack(iAttacker, iVictim, fKB);
			}
			if(iBtn == 2) fDmg *= 1.8905
			
			if(aimvictim == iVictim && body == 1) Pub_Fake_Damage_Guns(iAttacker, iVictim, fDmg, (1<<7)|(1<<4))
			else
			{
				new iDamageType
				if(iCheckAccshoot) iDamageType = (1<<7)|(1<<4)
				else iDamageType = DEFAULT_DMGTYPE
				Pub_Fake_Damage_Guns(iAttacker, iVictim, fDmg, iDamageType)
			}
		}
		if(Stock_Damage(iAttacker, iBtn, Float:fRange, Float:fDmg)) return RESULT_HIT_WORLD
		
		if(hitplayer) return RESULT_HIT_PLAYER
		else if(hitwall) return RESULT_HIT_WORLD
		else return RESULT_HIT_NONE
	} else if(0.0 < fAngle <= 180.0) {
		fAngle /= 2.0
		new aimvictim, body
		get_user_aiming(iAttacker, aimvictim, body, floatround(fRange))
		new iVictim = -1, hitplayer = 0, hitwall = 0
		hitwall = Stock_is_aiming_wall(iAttacker, fRange)
		
		while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, vecOri1, fRange)) != 0)
		{
			fDmg = fDamage
			
			if(iAttacker == iVictim || !pev_valid(iVictim)) continue
			if(!pev(iVictim, pev_takedamage)) continue
			if(!(Stock_CheckAngle(iAttacker, iVictim) > floatcos(fAngle,degrees))) continue
			if(pev(iVictim, pev_spawnflags) & SF_BREAK_TRIGGER_ONLY) continue
			if(!Stock_Is_Direct(iAttacker, iVictim)) continue		
			if(iBtn == 2) fDmg *= 1.8905
			
			if(aimvictim == iVictim && body == 1) Pub_Fake_Damage_Guns(iAttacker, iVictim, fDmg, (1<<7)|(1<<4))
			else
			{
				new iDamageType
				if(iCheckAccshoot) iDamageType = (1<<7)|(1<<4)
				else iDamageType = DEFAULT_DMGTYPE
				Pub_Fake_Damage_Guns(iAttacker, iVictim, fDmg, iDamageType)
			}

			if(iVictim >= 1 && iVictim <= 32)
			{
				hitplayer = 1
				if(fKB)
				{					
					fKB *= 5.0
					Stock_Fake_KnockBack(iAttacker, iVictim, fKB)		
				}
				if(can_damage(iAttacker, iVictim))
				{
					if(aimvictim == iVictim)
					{
						new iScale = body == 1 ? 12 : 8
						if(iBloodScale) iScale = iBloodScale
						Stock_TraceBlood(iAttacker, iScale)
					} else Stock_TraceBlood2(iAttacker, iVictim, 8)
				}
			}
		}
		if(Stock_Damage(iAttacker, iBtn, Float:fRange, Float:fDmg)) return RESULT_HIT_WORLD
		
		if(hitplayer) return RESULT_HIT_PLAYER
		else if(hitwall) return RESULT_HIT_WORLD
		else return RESULT_HIT_NONE
	} else { //angle = 0.0
		new Float:vecStart[3], Float:vecTarget[3]
		new trRes = Stock_TrRes(iAttacker, fRange, vecStart, vecTarget)
		new Float:flFraction
		get_tr2(trRes, TR_flFraction, flFraction)
		
		new pHit = get_tr2(trRes, TR_pHit)
		
		if(pev_valid(pHit))
		{
			if(is_user_alive(pHit))
			{
				fDmg = fDamage
				new hit=get_tr2(trRes, TR_iHitgroup), Float:dmg = fDmg, Float:endPos[3]
				get_tr2(trRes, TR_vecEndPos, endPos)

				set_tr2(trRes, TR_flFraction, get_distance_f(vecStart, vecTarget) / fRange)
				set_pdata_int(pHit, 75, get_tr2(trRes, TR_iHitgroup))
				dmg *= Stock_Get_Body_Dmg(hit)
				if(iBtn == 2) dmg *= 1.8905

				ExecuteHamB(Ham_TakeDamage, pHit, iAttacker, iAttacker, dmg, DMG_CLUB)
				
				if(can_damage(iAttacker, pHit)) Stock_BloodEffect(endPos, get_tr2(trRes, TR_iHitgroup) == 1 ? 12 : 7);
				return RESULT_HIT_PLAYER
			} else {
				if(!pev(pHit, pev_takedamage)) return RESULT_HIT_WORLD
				if(pev(pHit, pev_spawnflags)&SF_BREAK_TRIGGER_ONLY) return RESULT_HIT_WORLD
				
				new Float:dmg = 30.0 
				if(iBtn == 2) dmg *= 1.8905

				ExecuteHamB(Ham_TakeDamage, pHit, iAttacker, iAttacker, dmg, DMG_CLUB)
				return RESULT_HIT_WORLD
			}
				
		} else if(flFraction < 1.0) return RESULT_HIT_WORLD
		else
		{ //use tracehull now
			new trRes2
			engfunc(EngFunc_TraceHull, vecStart, vecTarget, 0,HULL_HEAD, iAttacker, trRes2)
			new pHit = get_tr2(trRes2, TR_pHit)
			
			if(pev_valid(pHit))
			{
				if(is_user_alive(pHit))
				{
					new hit = get_tr2(trRes2,TR_iHitgroup), Float:dmg = fDmg, Float:endPos[3]
					get_tr2(trRes2, TR_vecEndPos, endPos)
					set_tr2(trRes2, TR_flFraction, get_distance_f(vecStart, vecTarget) / fRange)
					set_pdata_int(pHit, 75, get_tr2(trRes2, TR_iHitgroup))
					dmg *= Stock_Get_Body_Dmg(hit)
					if(iBtn == 2) dmg *= 1.8905
					ExecuteHamB(Ham_TakeDamage, pHit, iAttacker, iAttacker, dmg, DMG_CLUB)
					
					if(can_damage(pHit, iAttacker)) Stock_BloodEffect(endPos, get_tr2(trRes, TR_iHitgroup) == 1 ? 12 : 7)
					return RESULT_HIT_PLAYER
				} else {
					if(!pev(pHit,pev_takedamage)) return RESULT_HIT_WORLD
					if(pev(pHit,pev_spawnflags) & SF_BREAK_TRIGGER_ONLY) return RESULT_HIT_WORLD
					
					new Float:dmg = fDmg
					if(iBtn == 2) dmg *= 1.8905
					
					ExecuteHamB(Ham_TakeDamage, pHit, iAttacker, iAttacker, dmg, DMG_CLUB)
					return RESULT_HIT_WORLD
				}
			} else {
				get_tr2(trRes2, TR_flFraction, flFraction)
				if(flFraction < 1.0) return RESULT_HIT_WORLD
				else return RESULT_HIT_NONE
			}
		}
	}
	return RESULT_HIT_NONE
}

stock Stock_is_aiming_wall(id, Float:fRange)
{
	new Float:vecStart[3], Float:vecTarget[3]
	new trRes = Stock_TrRes(id, fRange, vecStart, vecTarget)
	new Float:flFraction
	get_tr2(trRes, TR_flFraction, flFraction)
	
	new pHit = get_tr2(trRes, TR_pHit)
	if(pev_valid(pHit))
	{
		if(!is_user_alive(pHit)) return 1
	} else if(flFraction < 1.0) return 1
	return 0
}

stock Stock_Damage(iAttacker, iBtn, Float:fRange, Float:Fdmg)
{
	new Float:vecStart[3], Float:vecTarget[3]
	new trRes = Stock_TrRes(iAttacker, fRange, vecStart, vecTarget)
	new pHit = get_tr2(trRes, TR_pHit)
	
	if(pev_valid(pHit))
	{
		if(!is_user_alive(pHit))
		{
			if(!pev(pHit, pev_takedamage)) return RESULT_HIT_WORLD
			if(pev(pHit, pev_spawnflags) & SF_BREAK_TRIGGER_ONLY) return RESULT_HIT_WORLD
			
			new Float:dmg = Fdmg
			if(iBtn == 2) dmg *= 1.8905

			ExecuteHamB(Ham_TakeDamage, pHit, iAttacker, iAttacker, dmg, DMG_CLUB)
			return RESULT_HIT_WORLD
		}
	}
	return RESULT_HIT_NONE
}

stock Stock_TrRes(id, Float:fRange, Float:vecStart[3], Float:vecTarget[3])
{
	new Float:vecViewOfs[3], trRes
	pev(id, pev_origin, vecStart) 
	pev(id, pev_view_ofs, vecViewOfs) 
	xs_vec_add(vecStart, vecViewOfs, vecStart) 
	
	new Float:angle[3], Float:Forw[3]
	pev(id, pev_v_angle, angle)
	engfunc(EngFunc_MakeVectors, angle)
	global_get(glb_v_forward, Forw)
	xs_vec_mul_scalar(Forw, fRange, Forw)
	
	xs_vec_add(vecStart, Forw, vecTarget)
	engfunc(EngFunc_TraceLine, vecStart, vecTarget, 0, id, trRes)
	return trRes
}

stock Stock_Fake_KnockBack(id,iVic,Float:iKb)
{
	if(iVic > 32) return
	if(!can_damage(id, iVic)) return

	new Float:vAttacker[3], Float:vVictim[3], Float:vVelocity[3], flags
	pev(id, pev_origin, vAttacker)
	pev(iVic, pev_origin, vVictim)
	vAttacker[2] = vVictim[2] = 0.0
	flags=pev(id, pev_flags)
	
	xs_vec_sub(vVictim, vAttacker, vVictim)
	new Float:fDistance
	fDistance = xs_vec_len(vVictim)
	xs_vec_mul_scalar(vVictim, 1 / fDistance, vVictim)
	pev(iVic, pev_velocity, vVelocity)
	xs_vec_mul_scalar(vVictim, iKb, vVictim)
	xs_vec_mul_scalar(vVictim, 1.0, vVictim)
	vVictim[2] = xs_vec_len(vVictim) * 0.15

	if(flags &~FL_ONGROUND)
	{
		xs_vec_mul_scalar(vVictim, 1.5, vVictim)
		vVictim[2] *= 0.4
	}
	if(xs_vec_len(vVictim) > xs_vec_len(vVelocity)) set_pev(iVic, pev_velocity, vVictim)
}

stock Stock_Velocity_By_Aim(Float:vAngle[3], Float:fAngleOffset, Float:fMulti, Float:vVelocity[3])
{
	static Float:vForward[3], Float:vAngleTemp[3]
	xs_vec_copy(vAngle, vAngleTemp)
	vAngleTemp[0] += fAngleOffset
	angle_vector(vAngleTemp, ANGLEVECTOR_FORWARD, vForward)
	xs_vec_mul_scalar(vForward, fMulti, vVelocity)
}

stock Float:Stock_CheckAngle(id,iTarget)
{
	new Float:vOricross[2],Float:fRad,Float:vId_ori[3],Float:vTar_ori[3],Float:vId_ang[3],Float:fLength,Float:vForward[3]
	pev(id, pev_origin, vId_ori)
	pev(iTarget, pev_origin, vTar_ori)
	pev(id, pev_angles, vId_ang)
	
	for(new i = 0; i < 2; i++) vOricross[i] = vTar_ori[i] - vId_ori[i]
	fLength = floatsqroot(vOricross[0] * vOricross[0] + vOricross[1] * vOricross[1])
	
	if(fLength <= 0.0)
	{
		vOricross[0] = 0.0
		vOricross[1] = 0.0
	} else {
		vOricross[0] = vOricross[0] * (1.0 / fLength)
		vOricross[1] = vOricross[1] * (1.0 / fLength)
	}
	engfunc(EngFunc_MakeVectors, vId_ang)
	global_get(glb_v_forward, vForward)
	
	fRad = vOricross[0] * vForward[0] + vOricross[1] * vForward[1]
	return fRad
}

stock Stock_Is_Direct(id, id2)
{
	new Float:v1[3],Float:v2[3], Float:hit_origin[3], tr
	pev(id, pev_origin, v1)
	pev(id2, pev_origin, v2)
	
	engfunc(EngFunc_TraceLine, v1, v2, 1, -1, tr)
	get_tr2(tr, TR_vecEndPos, hit_origin)

	if(!vector_distance(hit_origin, v2))
		return 1
	return 0
}

stock Stock_Ent_Move_To(ent, Float:target[3], speed)
{
	static Float:vec[3]
	Stock_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
	set_pev(ent, pev_velocity, vec)
		
	new Float:angle[3]
	Stock_Aim_At_Origin(ent, target, angle)
	angle[0] = 0.0
	set_pev(ent, pev_angles, angle)
}

stock 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, angles[2] = 0.0
}

stock Stock_GetSpeedVector(const Float:origin1[3], const Float:origin2[3], Float:speed, Float:new_velocity[3])
{
	xs_vec_sub(origin2, origin1, new_velocity)
	new Float:num = floatsqroot(speed * speed / (new_velocity[0] * new_velocity[0] + new_velocity[1] * new_velocity[1] + new_velocity[2] * new_velocity[2]))
	xs_vec_mul_scalar(new_velocity, num, new_velocity)
}

stock Stock_Create_Tr(id, Float:end[3])
{
	new Float:start[3], Float:view_ofs[3]
	pev(id, pev_origin, start)
	pev(id, pev_view_ofs, view_ofs)
	xs_vec_add(start, view_ofs, start)
	
	pev(id, pev_v_angle, end)
	engfunc(EngFunc_MakeVectors, end)
	global_get(glb_v_forward, end)
	xs_vec_mul_scalar(end, 8120.0, end)
	xs_vec_add(start, end, end)
	
	new ptr = create_tr2()
	engfunc(EngFunc_TraceLine, start, end, DONT_IGNORE_MONSTERS, id, ptr)
	return ptr
}

stock Stock_Get_Aiming(id, Float:vecEnd[3])
{
	new Float:end[3]
	new ptr = Stock_Create_Tr(id, end)
	get_tr2(ptr, TR_vecEndPos, vecEnd)
	free_tr2(ptr)
}

stock Stock_Get_Velocity_Angle(entity, Float:output[3])
{
	static Float:velocity[3]
	pev(entity, pev_velocity, velocity)
	engfunc(EngFunc_VecToAngles, velocity, output)
	if(output[0] > 90.0) output[0] = -(360.0 - output[0])
}

stock Stock_TraceBlood(id, iScale)
{
	new Float:end[3]
	new ptr = Stock_Create_Tr(id, end)
	get_tr2(ptr, TR_vecEndPos, end)
	free_tr2(ptr)

	engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, end, 0);
	write_byte(TE_BLOODSPRITE)
	engfunc(EngFunc_WriteCoord,end[0])
	engfunc(EngFunc_WriteCoord,end[1])
	engfunc(EngFunc_WriteCoord,end[2])
	write_short(g_cache_bloodspray)
	write_short(g_cache_blood)
	write_byte(75)
	write_byte(iScale)
	message_end()
}

stock Stock_TraceBlood2(id, id2, iScale)
{
	new Float:v1[3],Float:v2[3]
	pev(id,pev_origin,v1)
	pev(id2,pev_origin,v2)

	new Float:end[3], ptr = create_tr2()
	engfunc(EngFunc_TraceLine, v1, v2, 1, -1, ptr)	
	get_tr2(ptr, TR_vecEndPos, end)
	free_tr2(ptr)

	engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, end, 0)
	write_byte(TE_BLOODSPRITE)
	engfunc(EngFunc_WriteCoord,end[0])
	engfunc(EngFunc_WriteCoord,end[1])
	engfunc(EngFunc_WriteCoord,end[2])
	write_short(g_cache_bloodspray)
	write_short(g_cache_blood)
	write_byte(75)
	write_byte(iScale)
	message_end()
}

stock Stock_BloodEffect(Float:vecOri[3], scale)
{
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY) 
	write_byte(TE_BLOODSPRITE)
	engfunc(EngFunc_WriteCoord,vecOri[0])
	engfunc(EngFunc_WriteCoord,vecOri[1])
	engfunc(EngFunc_WriteCoord,vecOri[2])
	write_short(g_cache_bloodspray)
	write_short(g_cache_blood)
	write_byte(75)
	write_byte(scale)
	message_end()
}

stock Float:Stock_Get_Body_Dmg(iBody)
{
	switch (iBody)
	{
		case HIT_GENERIC: return 0.75
		case 1: return 4.0
		case 2: return 1.0
		case 3: return 1.25
		case 4,5,6,7: return 0.75
		default: return 0.75
	}
	return 1.0
}

public Task_FlameThrower(iTask)
{
	new id = iTask-2213
	Stock_Buff(id, 30, g_cache_flameburn, 5)	
	if(!is_user_alive(id)) remove_task(iTask)
}

stock Stock_Buff(id, damage, spr, scale)
{
	if(id < 33 && pev_valid(id))
	{
		static Float:vOri[3], health
		pev(id, pev_origin, vOri)
		
		if(is_user_alive(id))
		{
			health = get_user_health(id)
			health -= damage
			
			if(health > 0) set_pev(id, pev_health, float(health))
			else user_kill(id)
			
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
			write_byte(TE_SPRITE)
			engfunc(EngFunc_WriteCoord, vOri[0])
			engfunc(EngFunc_WriteCoord, vOri[1])
			engfunc(EngFunc_WriteCoord, vOri[2])
			write_short(spr)
			write_byte(scale)
			write_byte(255)
			message_end()
		}
	}
}

stock Stock_SetRendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16)
{
	static Float:color[3]
	color[0] = float(r)
	color[1] = float(g)
	color[2] = float(b)
	
	set_pev(entity, pev_renderfx, fx)
	set_pev(entity, pev_rendercolor, color)
	set_pev(entity, pev_rendermode, render)
	set_pev(entity, pev_renderamt, float(amount))
}

stock Stock_Get_Postion(id, Float:forw, Float:right, Float:up, Float:vStart[])
{
	static Float:vOrigin[3], Float:vAngle[3], Float:vForward[3], Float:vRight[3], Float:vUp[3]
	pev(id, pev_origin, vOrigin)
	pev(id, pev_view_ofs,vUp)
	xs_vec_add(vOrigin,vUp,vOrigin)
	pev(id, pev_v_angle, vAngle)
	
	engfunc(EngFunc_AngleVectors, vAngle, vForward, vRight, vUp)
	
	vStart[0] = vOrigin[0] + vForward[0] * forw + vRight[0] * right + vUp[0] * up
	vStart[1] = vOrigin[1] + vForward[1] * forw + vRight[1] * right + vUp[1] * up
	vStart[2] = vOrigin[2] + vForward[2] * forw + vRight[2] * right + vUp[2] * up
}

stock EntityTouchDamage(pevInflictor, pevAttacker, Float:flDamage)
{
	new Float:vecOrigin[3], Float:vecVelocity[3], Float:vecDirection[3], Float:vecForward[3]
	pev(pevInflictor, pev_origin, vecOrigin)
	pev(pevInflictor, pev_velocity, vecVelocity)

	new Float:vecStart[3], Float:vecEnd[3]
	xs_vec_normalize(vecVelocity, vecDirection)
	xs_vec_mul_scalar(vecDirection, 8196.0, vecForward)
	xs_vec_copy(vecOrigin, vecStart)
	xs_vec_add(vecOrigin, vecForward, vecEnd)

	new tr = create_tr2()
	engfunc(EngFunc_TraceLine, vecStart, vecEnd, 0, pevInflictor, tr)

	new pEntity = get_tr2(tr, TR_pHit)
	Pub_Fake_Damage_Guns(pevAttacker, pEntity, flDamage, DEFAULT_DMGTYPE)
	free_tr2(tr)
}

stock EntityTouchTraceTexture(pEntity)
{
	new Float:vecOrigin[3], Float:vecVelocity[3], Float:vecDirection[3], Float:vecForward[3];
	pev(pEntity, pev_origin, vecOrigin)
	pev(pEntity, pev_velocity, vecVelocity)

	new Float:vecStart[3], Float:vecEnd[3]
	xs_vec_normalize(vecVelocity, vecDirection)

	if(xs_vec_len(vecDirection) <= 0.0)
		return 0

	xs_vec_mul_scalar(vecDirection, 8196.0, vecForward)
	xs_vec_copy(vecOrigin, vecStart)
	xs_vec_add(vecOrigin, vecForward, vecEnd)

	new tr = create_tr2()
	engfunc(EngFunc_TraceLine, vecStart, vecEnd, 0, pEntity, tr)

	new Float:flFraction
	get_tr2(tr, TR_flFraction, flFraction)

	new iTtextureType
	if(flFraction != 1.0)
	{
		new pTextureName[64]
		engfunc(EngFunc_TraceTexture, 0, vecStart, vecEnd, pTextureName, charsmax(pTextureName))
		iTtextureType = dllfunc(DLLFunc_PM_FindTextureType, pTextureName)
	}
	free_tr2(tr)
	return iTtextureType
}

stock RemoveEntity(pEntity)
{
	set_pev(pEntity, pev_solid, SOLID_NOT)
	set_pev(pEntity, pev_movetype, MOVETYPE_NONE)
	set_pev(pEntity, pev_effects, EF_NODRAW)
	
	engfunc(EngFunc_RemoveEntity, pEntity)
}

stock can_damage(id1, id2)
{
	if(id1 <= 0 || id1 >= 33 || id2 <= 0 || id2 >= 33)
		return 1
		
	// Check team
	return(get_pdata_int(id1, 114) != get_pdata_int(id2, 114))
}

stock IsPlayer(pEntity) return is_user_connected(pEntity)
stock IsAlive(pEntity)
{
	if(pEntity < 1) return 0
	return(pev(pEntity, pev_deadflag) == DEAD_NO && pev(pEntity, pev_health) > 0);
}

stock Pub_Fake_Damage_Guns(iAttacker, iVictim, Float:fDamage, iDamagetype, Float:fDistance = 9999.0, iEntity = 0, iHit = 0, DmgType = DMG_CLUB)
{
	static Float:fDamagerange
	fDamagerange = 1.0
	
	new Float:fCurTime
	global_get(glb_time, fCurTime)

	if(iVictim > 32)
	{
		if(!pev(iVictim, pev_takedamage))
			return RESULT_HIT_WORLD
		if(pev(iVictim, pev_spawnflags) & SF_BREAK_TRIGGER_ONLY)
			return RESULT_HIT_WORLD
		
		ExecuteHamB(Ham_TakeDamage, iVictim, iEntity ? iEntity : iAttacker, iAttacker, fDamage, DmgType)
		return RESULT_HIT_WORLD
	}
	
	// Prepare Data
	static Float:vecStart[3], Float:vecTarget[3], Float:vecViewOfs[3], Float:vecVictim[3], trRes, Float:vAngle[3], Float:vForw[3], iBody, Float:fDamageTemp, Float:vDirection[3], trRes2
	pev(iAttacker, pev_origin, vecStart) 
	pev(iAttacker, pev_view_ofs, vecViewOfs) 
	xs_vec_add(vecStart, vecViewOfs, vecStart) 
	pev(iVictim, pev_origin, vecVictim)
	
	if(get_distance_f(vecVictim, vecStart) > fDistance)
		return RESULT_HIT_NONE
		
	if((iDamagetype & (1<<7)) && iVictim && iVictim < 33) // Make Sure Player
	{
		fDamageTemp = fDamage * random_float(1.0 - fDamagerange, 1.0 + fDamagerange)
		fDamageTemp *= 4.0
		
		set_pdata_int(iVictim, 75, 1)
		ExecuteHamB(Ham_TakeDamage, iVictim, iEntity ? iEntity : iAttacker, iAttacker, fDamageTemp, DmgType)
		return RESULT_HIT_PLAYER
	}
	
	pev(iAttacker, pev_v_angle, vAngle)
	engfunc(EngFunc_MakeVectors, vAngle)
	global_get(glb_v_forward, vForw)
	xs_vec_mul_scalar(vForw, fDistance, vForw)
	xs_vec_add(vecStart, vForw, vecTarget)
	engfunc(EngFunc_TraceLine, vecStart, vecTarget, 0, iAttacker, trRes)
	
	if(get_tr2(trRes, TR_pHit) == iVictim && (iDamagetype & (1<<6)))
	{
		set_tr2(trRes, TR_flFraction, get_distance_f(vecStart, vecTarget) / fDistance)
		if(iDamagetype & (1<<3)) set_tr2(trRes, TR_iHitgroup, random_num(HIT_CHEST, HIT_RIGHTLEG))
		
		iBody = get_tr2(trRes, TR_iHitgroup)
		fDamageTemp = fDamage * random_float(1.0 - fDamagerange, 1.0 + fDamagerange)
		fDamageTemp *= Stock_Get_Body_Dmg(iBody)
		if(iHit != 0) iBody = iHit
		set_pdata_int(iVictim, 75, iBody)
		ExecuteHamB(Ham_TakeDamage, iVictim, iEntity ? iEntity : iAttacker, iAttacker, fDamageTemp, DmgType)
		get_tr2(trRes, TR_vecEndPos, vecTarget)
		
		if(iDamagetype & (1<<4))
		{
			if(0 < get_tr2(trRes,TR_pHit) < 33)
			{
				if(can_damage(iAttacker, iVictim))
				{
					Stock_TraceBleed(iVictim, fDamage, vecTarget, trRes)
					Stock_BloodEffect(vecTarget, iBody == 1 ? 12 : 7)
				}
			}
		}
		return RESULT_HIT_PLAYER
	} else {
		pev(iVictim, pev_origin, vecTarget)
		engfunc(EngFunc_TraceLine, vecStart, vecTarget, 0, iAttacker, trRes2)
	
		xs_vec_sub(vecStart, vecTarget, vDirection)
		set_tr2(trRes2, TR_flFraction, get_distance_f(vecStart, vecTarget) / fDistance)
		
		if(iDamagetype & (1<<3)) set_tr2(trRes2, TR_iHitgroup, random_num(HIT_CHEST, HIT_RIGHTLEG))
		
		fDamageTemp = fDamage * random_float(1.0 - fDamagerange, 1.0 + fDamagerange)
		iBody = get_tr2(trRes2, TR_iHitgroup)
		if(iHit!=0) iBody = iHit
		set_pdata_int(iVictim,75, iBody)
		
		if(iDamagetype & (1<<5) && !Stock_Is_Direct(iAttacker, iVictim))
			return RESULT_HIT_NONE
			
		ExecuteHamB(Ham_TakeDamage, iVictim, iEntity ? iEntity : iAttacker, iAttacker, fDamageTemp, DmgType)
		
		if(iDamagetype & (1<<4))
		{
			if(0 < get_tr2(trRes,TR_pHit) < 33)
			{
				if(can_damage(iAttacker, iVictim))
				{
					Stock_TraceBleed(iVictim, fDamage, vecTarget, trRes)
					Stock_BloodEffect(vecTarget, iBody == 1 ? 12 : 7)
				}
			}
		}
		return RESULT_HIT_PLAYER
	}
	return RESULT_HIT_WORLD
}

stock Stock_TraceBleed(iPlayer, Float:fDamage, Float:vecDir[3], iTr)
{
	if(fDamage == 0)
		return
		
	new Float:vecTraceDir[3], Float:fNoise,iCount, iBloodTr
	if(fDamage < 10)
	{
		fNoise = 0.1
		iCount = 1
	} else if (fDamage < 25) {
		fNoise = 0.2
		iCount = 2
	} else {
		fNoise = 0.3
		iCount = 4
	}

	for(new i = 0; i < iCount; i++)
	{		
		xs_vec_mul_scalar(vecDir, -1.0, vecTraceDir)

		vecTraceDir[0] += random_float(-fNoise, fNoise)
		vecTraceDir[1] += random_float(-fNoise, fNoise)
		vecTraceDir[2] += random_float(-fNoise, fNoise)

		static Float:vecEndPos[3]
		get_tr2(iTr, TR_vecEndPos, vecEndPos)
		xs_vec_mul_scalar(vecTraceDir, -0.5, vecTraceDir)
		xs_vec_add(vecTraceDir, vecEndPos, vecTraceDir)
		engfunc(EngFunc_TraceLine, vecEndPos, vecTraceDir, IGNORE_MONSTERS, iPlayer, iBloodTr)

		static Float:flFraction
		get_tr2(iBloodTr, TR_flFraction, flFraction)
		if(flFraction != -1.0) Stock_BloodDecalTrace(iBloodTr)
	}
}

stock Stock_BloodDecalTrace(iTrace)
{
	switch(random_num(0, 5))
	{
		case 0: Stock_DecalTrace(iTrace, engfunc(EngFunc_DecalIndex, "{blood1"))
		case 1: Stock_DecalTrace(iTrace, engfunc(EngFunc_DecalIndex, "{blood2"))
		case 2: Stock_DecalTrace(iTrace, engfunc(EngFunc_DecalIndex, "{blood3"))
		case 3: Stock_DecalTrace(iTrace, engfunc(EngFunc_DecalIndex, "{blood4"))
		case 4: Stock_DecalTrace(iTrace, engfunc(EngFunc_DecalIndex, "{blood5"))
		case 5: Stock_DecalTrace(iTrace, engfunc(EngFunc_DecalIndex, "{blood6"))
	}
}

stock Stock_DecalTrace(iTrace, iDecalNumber)
{
	if(iDecalNumber < 0)
		return
		
	static Float:flFraction
	get_tr2(iTrace, TR_flFraction, flFraction)
	
	if(flFraction == 1.0)
		return
		
	new iHit = get_tr2(iTrace, TR_pHit)
	
	if(pev_valid(iHit))
	{
		if((pev(iHit, pev_solid) != SOLID_BSP && pev(iHit, pev_movetype) != MOVETYPE_PUSHSTEP))
			return	
	} else iHit = 0
	
	new iMessage = TE_DECAL
	if(iHit != 0)
	{
		if(iDecalNumber > 255)
		{
			iDecalNumber -= 256
			iMessage = TE_DECALHIGH
		}
	} else {
		iMessage = TE_WORLDDECAL
		
		if(iDecalNumber > 255)
		{
			iDecalNumber -= 256
			iMessage= TE_WORLDDECALHIGH
		}
	}
	static Float:vecEndPos[3]
	get_tr2(iTrace, TR_vecEndPos, vecEndPos)
	
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(iMessage)
	engfunc(EngFunc_WriteCoord, vecEndPos[0])
	engfunc(EngFunc_WriteCoord, vecEndPos[1])
	engfunc(EngFunc_WriteCoord, vecEndPos[2])
	write_byte(iDecalNumber)
	if(iHit) write_short(iHit)
	message_end()
}

stock Stock_PrecacheSound(const model[])
{
	new file, i, k
	if((file = fopen(model, "rt")))
	{
		new szsoundpath[64], NumSeq, SeqID, Event, NumEvents, EventID
		fseek(file, 164, SEEK_SET)
		fread(file, NumSeq, BLOCK_INT)
		fread(file, SeqID, BLOCK_INT)
		
		for(i = 0; i < NumSeq; i++)
		{
			fseek(file, SeqID + 48 + 176 * i, SEEK_SET)
			fread(file, NumEvents, BLOCK_INT)
			fread(file, EventID, BLOCK_INT)
			fseek(file, EventID + 176 * i, SEEK_SET)

			for(k = 0; k < NumEvents; k++)
			{
				fseek(file, EventID + 4 + 76 * k, SEEK_SET)
				fread(file, Event, BLOCK_INT)
				fseek(file, 4, SEEK_CUR)
				
				if(Event != 5004)
					continue
				
				fread_blocks(file, szsoundpath, 64, BLOCK_CHAR)
				
				if(strlen(szsoundpath))
				{
					strtolower(szsoundpath)
					engfunc(EngFunc_PrecacheSound, szsoundpath)
				}
			}
		}
	}
	fclose(file)
}

stock Stock_Drop_Slot(id, iSlot) 
{
	new weapons[32], num = 0
	get_user_weapons(id, weapons, num)
	
	for(new i = 0; i < num; i++)
	{
		new slot = Stock_Get_Wpn_Slot(weapons[i])

		if(iSlot == slot)
		{
			static wname[32]
			get_weaponname(weapons[i], wname, charsmax(wname))
			engclient_cmd(id, "drop", wname)
		}
	}
}

stock Stock_Get_Wpn_Slot(iWpn)
{
	const PRIMARY_WEAPONS_BIT_SUM = (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_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
	const SECONDARY_WEAPONS_BIT_SUM = (1<<CSW_P228)|(1<<CSW_ELITE)|(1<<CSW_FIVESEVEN)|(1<<CSW_USP)|(1<<CSW_GLOCK18)|(1<<CSW_DEAGLE)

	if(PRIMARY_WEAPONS_BIT_SUM & (1<<iWpn)) return 1
	else if(SECONDARY_WEAPONS_BIT_SUM & (1<<iWpn)) return 2
	else if(iWpn == CSW_KNIFE) return 3
	else if(iWpn == CSW_HEGRENADE) return 4
	else if(iWpn == CSW_C4) return 5
	return 6 //FLASHBANG SMOKEBANG
}

// Colour Chat
stock client_printc(const id, const input[], any:...)
{
	new count = 1, players[32], msg[191]
	vformat(msg, 190, input, 3)
    
	replace_all(msg, 190, "!g", "^x04") // Green Color
	replace_all(msg, 190, "!n", "^x01") // Default Color
	replace_all(msg, 190, "!t", "^x03") // Team Color
    
	if(id) players[0] = id; else get_players(players, count, "ch")
	{
		for(new i = 0; i < count; i++)
		{
			if(is_user_connected(players[i]))
			{
				message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("SayText"), _, players[i])
				write_byte(players[i])
				write_string(msg)
				message_end()
			}
		}
	}
}  
