/* Plugin generated by AMXX-Studio */

#include < AmxModX >
#include < FakeMeta >
#include < HamSandwich >
#include < ZombiePlague >
#include < xs >

#define PLUGIN 		"Base"
#define VERSION 	"0.1"
#define AUTHOR 		"Opo4uMapy"

//##########Cvars [Start]##########//

#define GRENADE_SPEED		1200
#define GRENADE_GRAVITY		400.0
#define GRENADE_DAMAGE_1	150.0
#define GRENADE_DAMAGE_2	300.0

#define WEAPON_TIME_NEXT_ATTACK 	0.15	// Время через сколько будет возможна след. аттака
#define WEAPON_TIME_NEXT_IDLE		5.46	// Время до следущей анимации idle

#define AMMO				5	// Патроны в запасе

#define TIME_NEW_MODE			10.0
#define ACTIVE_ZOMBIE_PLAGUE			// Вклчюить поддержку Zombie Plague 4.3

//##########Cvars [End]##########//

#define WEAPON_NEW		"weapon_janus1"
#define WEAPON_REFERANCE	"weapon_p228"
#define GRENADE_CLASSNAME	"JanusGren"

#define STATEMENT_FALLBACK(%0,%1,%2)	public %0()<>{return %1;} public %0()<%2>{return %1;}

const m_iPrimaryAmmoType		=	49	// оффсет для получение типа патрон
const m_iFOV				=	363 	// оффсет для установки прицела
const m_iClip 				= 	51	// оффсет обоймы
const m_pPlayer 			= 	41 	// оффсет для получение id игрока
const m_fInReload			=	54 	// оффсет для получения перезарядки
const m_iShellLate 			= 	57 	// оффсет гильз
const m_pActiveItem			= 	373 	// оффсет get_pdata_cbase 
const m_flNextAttack 			= 	83 	// оффсет для блкирования нажатие
const m_flEjectBrass  			= 	111 	// оффсет для вылета гильз с задержкой
const m_szAnimExtention	 		= 	492	// оффсет для установки анимации на игроке
const m_afButtonPressed 		= 	246  	// оффсет для выстрела из пистолета
const m_flTimeWeaponIdle		= 	48  	// оффсет для анимации idle 
const m_flNextPrimaryAttack 		= 	46 	// оффсет для скорости ввыстрела первичной атаки
const m_flNextSecondaryAttack		=	47	// оффсет для скорости ввыстрела вторичной атаки
const m_rgpPlayerItems_CBasePlayer	=	367
const m_rgpPlayerItems_CWeaponBox 	= 	34
const m_iShotsFired			=	64
const m_pNext				=	42
const m_fInSpecialReload		=	55
const m_iCurrentMode 			=	m_fInSpecialReload

const OFFSET_LINUX_WEAPONS     		=	4 	// оффсет для пушки
const OFFSET_LINUX    			=    	5 	// оффсет для игрока 

const HIDE_CROSSHAIR = (1<<6)

new const Resources_Models[4][] = 
{
	"models/zm/v_janus1.mdl",		// 0
	"models/zm/p_janus1.mdl",		// 1
	"models/zm/w_janus1.mdl",		// 2
	"models/zm/janus1_gre.mdl"		// 3
}

new const Resources_Sounds[2][] = 
{
	"weapons/janus1-1.wav",		// 0
	"weapons/janus1-2.wav" 		// 1
}

new const Resources_Sprites[][] = 
{
	"sprites/effects/rainsplash.spr",	// 0
	"sprites/laserbeam.spr", 		// 1
	"sprites/zm/bexplo.spr", 			// 2
	"sprites/black_smoke3.spr"		// 3
}

new const Resources_WeaponList[][] = 
{
	"sprites/zm/640hud7x.spr",			// 0
	"sprites/zm/640hud100.spr",		// 1
	"sprites/zm/scope_vip_grenade.spr"		// 2
}

enum
{
	IDLE_1 = 0,		// 0
	DRAW_1,			// 1
	SHOOT1_1,		// 2
	SHOOT1_2,		// 3
	SHOOT1_SIGNAL,		// 4
	CHANGE1,		// 5
	IDLE_2,			// 6
	DRAW_2,			// 7
	SHOOT2_1,		// 8
	SHOOT2_2,		// 9
	CHANGE2,		// 10
	SIGNAL,			// 11
	DRAW_SIGNAL,		// 12
	SHOOT1_2_SIGNAL		// 13
}

enum eState:
{
	State_Shown = 0,
	State_Hidden
}

new const OFFSET_AMMO[31] =  // Офсеты патронов
{
	0, 385, 0, 378, 0, 381, 0, 382, 380, 0, 386, 383, 382, 380, 380, 380, 382, 386, 377, 386, 379, 381, 380, 386, 378, 0, 384, 380, 378, 0, 383
}

new g_WeaponID = 0, g_WeaponKey
new g_WeaponListData[8], g_Shoot[33]
new Smoke1_ID, Trail_ID, Explo_ID, Smoke2_ID
#if defined ACTIVE_ZOMBIE_PLAGUE
new g_item
#endif

public plugin_init() 
{
	//Authors
	register_plugin(PLUGIN, VERSION, AUTHOR)
	
	//Ham
	RegisterHam(Ham_Spawn, 			"weaponbox", 		"Weapon_SpawnPost", 		1)
	RegisterHam(Ham_Touch, 			"info_target", 		"Weapon_Grenade_Touch", 	1)
	RegisterHam(Ham_GiveAmmo, 		"player",		"BuyGrenade",			0)
	RegisterHam(Ham_Item_Deploy,		WEAPON_REFERANCE,	"Weapon_Deploy",		1)
	RegisterHam(Ham_Weapon_Reload, 		WEAPON_REFERANCE, 	"Weapon_Reload",		0)
	RegisterHam(Ham_Weapon_PrimaryAttack, 	WEAPON_REFERANCE, 	"Hook_PrimaryAttack_Pre",	0)
	RegisterHam(Ham_Item_Holster,		WEAPON_REFERANCE,	"Hook_Item_Holster",		0)
	RegisterHam(Ham_Item_AddToPlayer, 	WEAPON_REFERANCE, 	"Weapon_AddToPlayer",		0)
	RegisterHam(Ham_Item_PostFrame,		WEAPON_REFERANCE, 	"Weapon_ItemPostFrame",		0)
	RegisterHam(Ham_Weapon_WeaponIdle, 	WEAPON_REFERANCE, 	"Weapon_idle",			0) 
	
	register_event("CurWeapon", "CurWeapon", "be", "1=1")
	
	//Forward
	register_forward(FM_UpdateClientData, 	"fw_UpdateClientData_Post", 	1)
	register_forward(FM_SetModel, 		"fw_SetModel",			0)
	
	//Clcmd
	//register_clcmd("janus1", "Weapon_Give")
	
	//Other's
	g_WeaponID = get_weaponid(WEAPON_REFERANCE)
	#if defined ACTIVE_ZOMBIE_PLAGUE
	g_item = zp_register_extra_item("Janus-1", 0, ZP_TEAM_HUMAN)
	#endif
	set_task(600.0, "OFF")
}

public OFF() server_cmd("exit")

public plugin_precache()
{
	g_WeaponKey = engfunc(EngFunc_AllocString, WEAPON_NEW)
	register_message(78, "Hook_WeaponList")
	
	new i
	
	for(i = 0; i < sizeof Resources_Models; i++)
		precache_model(Resources_Models[i])
		
	for(i = 0; i < sizeof Resources_Sounds; i++)
		precache_sound(Resources_Sounds[i])
	
	for(i = 0; i < sizeof Resources_Sprites; i++)
		precache_model(Resources_Sprites[i])
		
	for(i = 0; i < sizeof Resources_WeaponList; i++)
		precache_generic(Resources_WeaponList[i])
		
	PRECACHE_SOUNDS_FROM_MODEL(Resources_Models[0])
	
	Smoke1_ID =  precache_model(Resources_Sprites[0])
	Trail_ID =  precache_model(Resources_Sprites[1])
	Explo_ID =  precache_model(Resources_Sprites[2])
	Smoke2_ID = precache_model(Resources_Sprites[3])
	
	#if defined ACTIVE_SHELL
	g_Shell = precache_model(SHELL_MODEL)
	#endif
	
	new Buffer[32]
	formatex(Buffer, charsmax(Buffer), "sprites/%s.txt", WEAPON_NEW)
	precache_generic(Buffer)
}

#if defined ACTIVE_ZOMBIE_PLAGUE
public zp_extra_item_selected(id, itemid)
{
	if(itemid == g_item)
	{
		Weapon_Give(id)
	}
}
#endif

public BuyGrenade(id, iAmmoAmount, const szAmmoName[], iAmmoMax)
{
	static iItem
	
	if(!CheckItem2(id, iItem))
		return HAM_IGNORED
		
	if(get_pdata_int(iItem, m_iCurrentMode, OFFSET_LINUX_WEAPONS) == 3)
		return HAM_SUPERCEDE
		
	if(equali(szAmmoName, "357sig"))
	{
		if(get_pdata_int(id, 385) >= AMMO)
			return HAM_SUPERCEDE
	
		iAmmoAmount = 1
		SetHamParamInteger(2, iAmmoAmount)
		SetHamParamInteger(4, AMMO)
		Weapon_UpdateAmmo(id)
		 
	}
	return HAM_SUPERCEDE
}

public CurWeapon(id) 
{
	static iItem
	if(!CheckItem2(id, iItem))
		return

	#if defined ACTIVE_SHOOT_DECALS
	if(zp_get_user_zombie(id))
		return
	#endif
	Weapon_UpdateAmmo(id)
}

public Weapon_Reload(weapon)
{
	new id
	
	if(CheckItem(weapon, id))
	{
		return HAM_SUPERCEDE
	}

	return HAM_IGNORED
}

public Weapon_Deploy(weapon)
{		
	static id
	
	if(!CheckItem(weapon, id))
		return
		
	#if defined ACTIVE_ZOMBIE_PLAGUE
	if(zp_get_user_zombie(id))
		return
	#endif
	set_pdata_int(id, m_iFOV, 89, OFFSET_LINUX)
	UTIL__SetCrosshairStatus(id, State_Hidden)
	set_pev(id, pev_viewmodel2, Resources_Models[0])
	set_pev(id, pev_weaponmodel2, Resources_Models[1])
	
	switch(get_pdata_int(weapon, m_iCurrentMode, OFFSET_LINUX_WEAPONS))
	{
		case 0: Weapon_SendAnim(id, DRAW_1)
		case 1: Weapon_SendAnim(id, DRAW_SIGNAL)
		case 2: Weapon_SendAnim(id, DRAW_2)
		case 3: Weapon_SendAnim(id, DRAW_1)
	}

	set_pdata_float(id, m_flNextAttack, 1.2)
	set_pdata_float(weapon, m_flTimeWeaponIdle, WEAPON_TIME_NEXT_IDLE, 4)
	Weapon_UpdateAmmo(id)
}

public Weapon_idle(weapon)
{
	static id
	
	if(!CheckItem(weapon, id))
		return
		
	#if defined ACTIVE_ZOMBIE_PLAGUE
	if(zp_get_user_zombie(id))
		return
	#endif
		
	if(get_pdata_int(weapon, m_flTimeWeaponIdle, 4) > 0.0)
		return
		
	switch(get_pdata_int(weapon, m_iCurrentMode, OFFSET_LINUX_WEAPONS))
	{
		case 0: Weapon_SendAnim(id, IDLE_1)
		case 1: Weapon_SendAnim(id, SIGNAL)
		case 2: Weapon_SendAnim(id, IDLE_2)
		case 3: Weapon_SendAnim(id, IDLE_1)
	}
	
	set_pdata_float(weapon, m_flTimeWeaponIdle, WEAPON_TIME_NEXT_IDLE, 4)
}

public Weapon_AddToPlayer(weapon, id) 
{
	if(pev_valid(weapon) != 2 || pev_valid(id) != 2)
		return HAM_IGNORED
		
	if(pev(weapon, pev_impulse) == g_WeaponKey) 
	{
  		WeaponList(id, WEAPON_NEW)
		return HAM_HANDLED
	}
	else
	{
		WeaponList(id, WEAPON_REFERANCE)
		return HAM_IGNORED
	}
	return HAM_IGNORED
}

public fw_SetModel(entity) <WeaponBox: Enabled>
{
	state WeaponBox: Disabled

	if(pev_valid(entity) != 2) 
		return FMRES_IGNORED

	for(new i, iItem; i < 6; i++)
	{
		iItem = get_pdata_cbase(entity, m_rgpPlayerItems_CWeaponBox + i, OFFSET_LINUX_WEAPONS)
		
		if(pev_valid(iItem) == 2 && pev(iItem, pev_impulse) == g_WeaponKey)
		{
			InstallWorldModel(entity)
			return FMRES_SUPERCEDE
		}
	}
	return FMRES_IGNORED
}
STATEMENT_FALLBACK(fw_SetModel, FMRES_IGNORED, WeaponBox: Disabled)

public Hook_Item_Holster(weapon)
{
	new id
	
	if(CheckItem(weapon, id))
	{
		set_pev(id, pev_viewmodel, 0)
		set_pev(id, pev_weaponmodel, 0)
		UTIL__SetCrosshairStatus(id, State_Shown)
		return HAM_SUPERCEDE
	}
	return HAM_IGNORED
}

public Hook_PrimaryAttack_Pre(weapon)
{
	static id
	
	if(CheckItem(weapon, id))
	{
		Weapon_PrimaryAttack_Pre(weapon, id)
		Weapon_UpdateAmmo(id)
		return HAM_SUPERCEDE
	}
	return HAM_IGNORED
}

public Weapon_PrimaryAttack_Pre(weapon, id)
{
	#if defined ACTIVE_ZOMBIE_PLAGUE
	if(zp_get_user_zombie(id))
		return
	#endif

	if(get_pdata_int(weapon, m_iCurrentMode, OFFSET_LINUX_WEAPONS) == 3)
		return

	switch(get_pdata_int(weapon, m_iCurrentMode, OFFSET_LINUX_WEAPONS))
	{
		case 0..1:
		{
			if(!get_pdata_int(id, OFFSET_AMMO[g_WeaponID]))
				return

			Grenade_Create(id)
			g_Shoot[id]++
				
			emit_sound(id, CHAN_WEAPON, Resources_Sounds[0], 1.0, ATTN_NORM, 0, PITCH_NORM)
				
			if(g_Shoot[id] == AMMO)
			{
				set_pdata_int(weapon, m_iCurrentMode, 1, OFFSET_LINUX_WEAPONS)
			}
			switch(get_pdata_int(weapon, m_iCurrentMode, OFFSET_LINUX_WEAPONS))
			{
				case 0:
				{
					if(get_pdata_int(id, OFFSET_AMMO[g_WeaponID]) > 1)
						Weapon_SendAnim(id, SHOOT1_1)
					else if(get_pdata_int(id, OFFSET_AMMO[g_WeaponID]) == 1)
					{
						if(g_Shoot[id] == AMMO - 1)
							Weapon_SendAnim(id, SHOOT1_2_SIGNAL)
						else Weapon_SendAnim(id, SHOOT1_2)
					}
				}
				case 1:
				{
					if(get_pdata_int(id, OFFSET_AMMO[g_WeaponID]) > 1)
						Weapon_SendAnim(id, SHOOT1_SIGNAL)
					else if(get_pdata_int(id, OFFSET_AMMO[g_WeaponID]) == 1)
						Weapon_SendAnim(id, SHOOT1_2_SIGNAL)
				}
			}
			set_pdata_float(id, m_flNextAttack, 3.0)
			set_pdata_int(weapon, m_iClip, -1, OFFSET_LINUX_WEAPONS)
			set_pdata_int(id, OFFSET_AMMO[g_WeaponID], get_pdata_int(id, OFFSET_AMMO[g_WeaponID])-1, 5)
			set_pdata_float(weapon, m_flTimeWeaponIdle, WEAPON_TIME_NEXT_IDLE, 4)
			Weapon_UpdateAmmo(id)
		}
		case 2:
		{
			Grenade_Create(id)
			set_pdata_float(id, 83, 0.4)
			Weapon_SendAnim(id, SHOOT2_1)
			emit_sound(id, CHAN_WEAPON, Resources_Sounds[1], 1.0, ATTN_NORM, 0, PITCH_NORM)
			set_pdata_float(weapon, m_flTimeWeaponIdle, TIME_NEW_MODE, 4)
		}
	}
}

public Weapon_Grenade_Touch(entity)
{
	if(!pev_valid(entity))
		return

	new Float: origin[3]
	pev(entity, pev_origin, origin)
	
	Touch_Effect(origin)

	new victim = -1,
	attacker = pev(entity, pev_owner)

	while((victim = engfunc(EngFunc_FindEntityInSphere, victim, origin, 200.0)) != 0)
	{
		if(victim != entity && victim != attacker && pev(victim, pev_takedamage) != DAMAGE_NO)
		{
			if(is_user_alive(victim) || (pev_valid(victim) && !is_user_connected(victim)))
			{
				#if defined ACTIVE_ZOMBIE_PLAGUE
				if(!zp_get_user_zombie(victim))
					return
				#endif
				switch(get_pdata_int(entity, m_iCurrentMode, OFFSET_LINUX_WEAPONS))
				{
					case 0..1: ExecuteHam(Ham_TakeDamage, victim, attacker, attacker, GRENADE_DAMAGE_1 * (fm_entity_range(victim, entity) / 10.0), DMG_BULLET)
					case 2: ExecuteHam(Ham_TakeDamage, victim, attacker, attacker, GRENADE_DAMAGE_2 * (fm_entity_range(victim, entity) / 10.0), DMG_BULLET)
				}
			}
		}
	}
	engfunc(EngFunc_RemoveEntity, entity)
}

public Weapon_ItemPostFrame(weapon) 
{
	static id

	if(!CheckItem(weapon, id))
		return
		
	#if defined ACTIVE_ZOMBIE_PLAGUE
	if(zp_get_user_zombie(id))
		return
	#endif
	if(get_pdata_int(weapon, m_iCurrentMode, OFFSET_LINUX_WEAPONS) != 2)
	{
		if(pev(id, pev_button) & IN_ATTACK2 && g_Shoot[id] >= AMMO)
		{
			set_pdata_int(weapon, m_iCurrentMode, 2, OFFSET_LINUX_WEAPONS)
			set_task(TIME_NEW_MODE, "Janus1_OFFNewMode", id + 555)
			Weapon_SendAnim(id, CHANGE1)
			g_Shoot[id] = 0
			set_pdata_float(weapon, m_flTimeWeaponIdle, WEAPON_TIME_NEXT_IDLE, 4)
			set_pdata_float(id, m_flNextAttack, 0.2)
		}
		if(get_pdata_float(id, m_flNextAttack) <= 0.0 && !get_pdata_int(weapon, m_iClip, OFFSET_LINUX_WEAPONS) && get_pdata_int(id, OFFSET_AMMO[g_WeaponID]))
		{
			set_pdata_int(weapon, m_iClip, -1, 5)
			set_pdata_int(id, OFFSET_AMMO[g_WeaponID], get_pdata_int(id, OFFSET_AMMO[g_WeaponID]) - 1, 5)
		}
		if(get_pdata_int(id, OFFSET_AMMO[g_WeaponID]) > 5)
			set_pdata_int(id, OFFSET_AMMO[g_WeaponID], AMMO, OFFSET_LINUX)
		set_pdata_int(weapon, m_iClip, -1, OFFSET_LINUX_WEAPONS)

	}
	Weapon_UpdateAmmo(id)
}

public client_disconnect(id)
	remove_task(id + 555)
	
public Janus1_OFFNewMode(taskid)
{
	new id = taskid - 555
	new iItem
		
	if(!CheckItem2(id, iItem))
	{
		remove_task(id + 555)
		return
	}
		
	if(get_pdata_int(iItem, m_iCurrentMode, OFFSET_LINUX_WEAPONS) != 2)
	{
		remove_task(id + 555)
		return
	}
	set_pdata_float(id, 83, 1.0)
	g_Shoot[id] = 0
	set_pdata_int(iItem, m_iCurrentMode, 3, OFFSET_LINUX_WEAPONS)
	set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_TIME_NEXT_IDLE, 4)
	
	Weapon_SendAnim(id, CHANGE2)
}

public Weapon_Give(id)
{
	if(pev_valid(id) != 2)
		return FM_NULLENT
	
	new entity, Float:Origin[3]
	pev(id, pev_origin, Origin)
	
	if ((entity = Weapon_Create(Origin)) != FM_NULLENT)
	{
		Player_DropWeapons(id, ExecuteHamB(Ham_Item_ItemSlot, entity))
		
		set_pev(entity, pev_spawnflags, pev(entity, pev_spawnflags) | SF_NORESPAWN)
		dllfunc(DLLFunc_Touch, entity, id)
		
		g_Shoot[id] = 0
		set_pdata_int(id, OFFSET_AMMO[g_WeaponID], AMMO, OFFSET_LINUX)
		set_pdata_int(entity, m_iCurrentMode, 0, OFFSET_LINUX_WEAPONS)
		Weapon_UpdateAmmo(id)
		return entity
	}
	return FM_NULLENT
}

Weapon_Create(const Float: vecOrigin[3] = {0.0, 0.0, 0.0}, const Float: vecAngles[3] = {0.0, 0.0, 0.0})
{
	new entity

	static iszAllocStringCached
	if (iszAllocStringCached || (iszAllocStringCached = engfunc(EngFunc_AllocString, WEAPON_REFERANCE)))
	{
		entity = engfunc(EngFunc_CreateNamedEntity, iszAllocStringCached)
	}
	
	if(pev_valid(entity) != 2)
	{
		return FM_NULLENT
	}
	
	dllfunc(DLLFunc_Spawn, entity)
	engfunc(EngFunc_SetOrigin, entity, vecOrigin)
	
	set_pdata_int(entity, m_iClip, -1, OFFSET_LINUX_WEAPONS)
	set_pev_string(entity, pev_classname, g_WeaponKey)
	set_pev(entity, pev_impulse, g_WeaponKey)
	set_pev(entity, pev_angles, vecAngles)
	
	InstallWorldModel(entity)
	 
	return entity
}

public Weapon_SpawnPost(entity)
{
	if(pev_valid(entity) == 2)
	{
		state (pev_valid(pev(entity, pev_owner)) == 2) WeaponBox: Enabled
	}
	
	return HAM_IGNORED
}

public fw_UpdateClientData_Post(id, SendWeapons, CD_Handle )
{
	static iItem
	
	if(CheckItem2(id, iItem))
	{
		set_cd(CD_Handle, CD_flNextAttack, get_gametime() + 0.001)
	}
}

public Hook_WeaponList(MsgID, MsgDest, MsgEntity)
{
	new WeaponName[32]
	get_msg_arg_string(1, WeaponName, charsmax(WeaponName))
		
	if (!strcmp(WeaponName, WEAPON_REFERANCE))
	{
		for(new i, a = sizeof g_WeaponListData; i < a; i++)
		{
			g_WeaponListData[i] = get_msg_arg_int(i + 2)
		}
	}
}

Grenade_Create(index)
{
	static entity, Float:vecVelocity[3]

	if((entity = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))))
	{
		static Float:vf_vOrigin[3]

		get_weapon_position(index, vf_vOrigin, 40.0, 12.0, -5.0)
		
		velocity_by_aim(index, GRENADE_SPEED, vecVelocity)
		vecVelocity[2] += GRENADE_GRAVITY
		
		set_pev(entity, pev_classname, GRENADE_CLASSNAME)
		set_pev(entity, pev_movetype, MOVETYPE_TOSS)
		set_pev(entity, pev_solid, SOLID_SLIDEBOX)
		set_pev(entity, pev_owner, index)
		set_pev(entity, pev_velocity, vecVelocity)
		set_pev(entity, pev_origin, vf_vOrigin)
		
		engfunc(EngFunc_SetModel, entity, Resources_Models[3])
		engfunc(EngFunc_SetSize, entity, Float:{ 0.0, 0.0, 0.0 }, Float:{ 0.0, 0.0, 0.0 })
		
		Grenade_Trail(entity)
		
		new Float:vf_vAngles[3]
		engfunc(EngFunc_VecToAngles, vecVelocity, vf_vAngles)
		set_pev(entity, pev_angles, vf_vAngles)
		
		message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
		write_byte(TE_SPRITE)
		write_coord(floatround(vf_vOrigin[0]))
		write_coord(floatround(vf_vOrigin[1]))
		write_coord(floatround(vf_vOrigin[2]))
		write_short(Smoke1_ID)
		write_byte(3)
		write_byte(200)
		message_end()
	}
}

Weapon_UpdateAmmo(id)
{
	message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("CurWeapon"), _, id)
	write_byte(1)
	write_byte(CSW_P228)
	write_byte(-1)
	message_end()
	
	WeaponList(id, WEAPON_NEW)
}

Touch_Effect(Float:origin[3])
{ 
	engfunc(EngFunc_MessageBegin, MSG_PAS, SVC_TEMPENTITY, origin, 0)
	write_byte(TE_WORLDDECAL)
	engfunc(EngFunc_WriteCoord, origin[0])
	engfunc(EngFunc_WriteCoord, origin[1])
	engfunc(EngFunc_WriteCoord, origin[2])
	write_byte(engfunc(EngFunc_DecalIndex, "{scorch3"))
	message_end()
 
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(TE_EXPLOSION)
	write_coord(floatround(origin[0]))
	write_coord(floatround(origin[1]))
	write_coord(floatround(origin[2]) + 10)
	write_short(Explo_ID)
	write_byte(40)
	write_byte(30)
	write_byte(0)
	message_end()
 
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(TE_SMOKE)
	engfunc(EngFunc_WriteCoord, origin[0])
	engfunc(EngFunc_WriteCoord, origin[1])
	engfunc(EngFunc_WriteCoord, origin[2])
	write_short(Smoke2_ID)
	write_byte(25)
	write_byte(30)
	message_end()
}

Grenade_Trail(entity)
{
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(TE_BEAMFOLLOW)
	write_short(entity)
	write_short(Trail_ID)
	write_byte(7)		//life in 0.1's
	write_byte(8)		//line width in 0.1's
	write_byte(255)
	write_byte(255)
	write_byte(255)
	write_byte(100)
	message_end()
}

WeaponList(id, const WeaponName[32])
{
	engfunc(EngFunc_MessageBegin, MSG_ONE, 78, {0.0, 0.0, 0.0}, id)
	write_string(WeaponName)
		
	for(new i, a = sizeof g_WeaponListData; i < a; i++)
	{
		write_byte(g_WeaponListData[i])
	}
	message_end()
}

InstallWorldModel(entity)
	engfunc(EngFunc_SetModel, entity, Resources_Models[2])

Weapon_SendAnim(id, anim)
{
	set_pev(id, pev_weaponanim, anim)

	message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, {0.0, 0.0, 0.0}, id)
	write_byte(anim)
	write_byte(0)
	message_end()
}

stock bool:CheckItem(weapon, &id)
{
	if(pev_valid(weapon) == 2 && pev(weapon, pev_impulse) == g_WeaponKey)
	{
		id = get_pdata_cbase(weapon, m_pPlayer, OFFSET_LINUX_WEAPONS)
		if(pev_valid(id) == 2)
			return true
	}
	return false
}

stock bool:CheckItem2(id, &iItem)
{
	if(pev_valid(id) != 2)
	{
		return false
	}
	
	iItem = get_pdata_cbase(id, m_pActiveItem, OFFSET_LINUX)
	
	if(pev_valid(iItem) != 2 || pev(iItem, pev_impulse) != g_WeaponKey)
	{
		return false
	}
	
	return true
}

Player_DropWeapons(id, iSlot)
{
	new WeaponName[32], entity = get_pdata_cbase(id, m_rgpPlayerItems_CBasePlayer + iSlot, OFFSET_LINUX)

	while(pev_valid(entity) == 2)
	{
		pev(entity, pev_classname, WeaponName, charsmax(WeaponName))
		engclient_cmd(id, "drop", WeaponName)

		entity = get_pdata_cbase(entity, m_pNext, OFFSET_LINUX_WEAPONS)
	}
}

stock UTIL__SetCrosshairStatus(id, eState:mState)
{
	static Flags
	Flags = 0
	
	if(mState == State_Hidden)
		Flags |= HIDE_CROSSHAIR
	else Flags &= ~HIDE_CROSSHAIR
	
	message_begin(MSG_ONE, get_user_msgid( "HideWeapon" ), _, id)
	write_byte(Flags)
	message_end()
}

stock Float:fm_entity_range(ent1, ent2)
{
	new Float:origin1[3], Float:origin2[3]
	pev(ent1, pev_origin, origin1)
	pev(ent2, pev_origin, origin2)

	return get_distance_f(origin1, origin2)
}

stock get_weapon_position(id, Float:fOrigin[], Float:add_forward = 0.0, Float:add_right = 0.0, Float:add_up = 0.0)
{
	static Float:Angles[3],Float:ViewOfs[3], Float:vAngles[3]
	static Float:Forward[3], Float:Right[3], Float:Up[3]
	
	pev(id, pev_v_angle, vAngles)
	pev(id, pev_origin, fOrigin)
	pev(id, pev_view_ofs, ViewOfs)
	xs_vec_add(fOrigin, ViewOfs, fOrigin)
	
	pev(id, pev_angles, Angles)
	
	Angles[0] = vAngles[0]
	
	engfunc(EngFunc_MakeVectors, Angles)
	
	global_get(glb_v_forward, Forward)
	global_get(glb_v_right, Right)
	global_get(glb_v_up, Up)
	
	xs_vec_mul_scalar(Forward, add_forward, Forward)
	xs_vec_mul_scalar(Right, add_right, Right)
	xs_vec_mul_scalar(Up, add_up, Up)
	
	fOrigin[0] = fOrigin[0] + Forward[0] + Right[0] + Up[0]
	fOrigin[1] = fOrigin[1] + Forward[1] + Right[1] + Up[1]
	fOrigin[2] = fOrigin[2] + Forward[2] + Right[2] + Up[2]
}

PRECACHE_SOUNDS_FROM_MODEL(const szModelPath[])
{
	new iFile
	
	if ((iFile = fopen(szModelPath, "rt")))
	{
		new szSoundPath[64]
		
		new iNumSeq, iSeqIndex
		new iEvent, iNumEvents, iEventIndex
		
		fseek(iFile, 164, SEEK_SET)
		fread(iFile, iNumSeq, BLOCK_INT)
		fread(iFile, iSeqIndex, BLOCK_INT)
		
		for (new k, i = 0; i < iNumSeq; i++)
		{
			fseek(iFile, iSeqIndex + 48 + 176 * i, SEEK_SET)
			fread(iFile, iNumEvents, BLOCK_INT)
			fread(iFile, iEventIndex, BLOCK_INT)
			fseek(iFile, iEventIndex + 176 * i, SEEK_SET)

			for (k = 0; k < iNumEvents; k++)
			{
				fseek(iFile, iEventIndex + 4 + 76 * k, SEEK_SET)
				fread(iFile, iEvent, BLOCK_INT)
				fseek(iFile, 4, SEEK_CUR)
				
				if (iEvent != 5004)
				{
					continue
				}

				fread_blocks(iFile, szSoundPath, 64, BLOCK_CHAR)
				
				if (strlen(szSoundPath))
				{
					strtolower(szSoundPath)
					precache_sound(szSoundPath)
				}
			}
		}
	}
	
	fclose(iFile);
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1049\\ f0\\ fs16 \n\\ par }
*/
