/*
**
** Weapon Lights v.0.6 (03-feb-2009)
**
** by HiSS & Arkshine
**
*/

#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>

#define DLIGHT_LIFE  8
#define DLIGHT_DECAY 60

enum _:Coord_e{ Float:x, Float:y, Float:z };

new gp_Enable, gp_Radius, gp_Color, gp_Silenced;
new gi_Enable, gi_Red, gi_Green, gi_Blue, gi_Radius, gi_Silenced;

const m_iWeaponType = 43;
const m_iClip = 51;
const m_iSilencerFireMode = 74;
const m_iZoomType = 363;

#define message_begin_f(%1,%2,%3) (engfunc ( EngFunc_MessageBegin, %1, %2, %3))
#define write_coord_f(%1) (engfunc ( EngFunc_WriteCoord, %1))

#define EXTRAOFFSET_WEAPONS 4
#define IsWeaponNotEmpty(%1) (get_pdata_int ( %1, m_iClip, EXTRAOFFSET_WEAPONS))

public plugin_init ()

{
	register_plugin ("Weapon Lights", "0.6", "HiSS & Arkshine");

	gp_Enable = register_cvar ("weapon_lights", "1")
	gp_Radius = register_cvar ("weapon_lights_radius", "18");
	gp_Color = register_cvar ("weapon_lights_color" , "255 150 15");
	gp_Silenced = register_cvar ("weapon_lights_silenced", "2");
	
	register_event ("HLTV", "Event_NewRound", "a", "1=0", "2=0");
	
	RegisterHamsPrimaryAttack ();

	CacheCvarsValue ();
}

public Event_WeaponPrimaryAttack (const i_Ent)
{
	if (gi_Enable && IsWeaponNotEmpty (i_Ent) && !(!gi_Silenced && GetWeaponSilen (i_Ent)))
	{
		FX_DynamicLight (i_Ent);

	}
}

public Event_NewRound ()
{
	CacheCvarsValue ();
}

FX_DynamicLight (const i_Ent)
{
	static Float:vf_Origin [Coord_e];
	pev (pev (i_Ent, pev_owner), pev_origin, vf_Origin);
	message_begin_f (MSG_PVS, SVC_TEMPENTITY, vf_Origin, 0);

	write_byte (TE_DLIGHT);
	write_coord_f (vf_Origin[ x ]);
	write_coord_f (vf_Origin[ y ]);
	write_coord_f (vf_Origin[ z ]);
	write_byte (gi_Silenced == 2 && GetWeaponSilen (i_Ent) ? floatround (gi_Radius * 0.5) : gi_Radius);
	write_byte (gi_Red);
	write_byte (gi_Green);
	write_byte (gi_Blue);
	write_byte (DLIGHT_LIFE);
	write_byte (DLIGHT_DECAY);
	message_end ();
	}

CacheCvarsValue ()
{
	new s_DLightColor [16];
	get_pcvar_string (gp_Color, s_DLightColor, charsmax (s_DLightColor));
	new s_Red [4], s_Green [4], s_Blue [4];
	parse (s_DLightColor, s_Red, charsmax (s_Red), s_Green, charsmax (s_Green), s_Blue, charsmax (s_Blue));
	
	gi_Red = clamp (str_to_num (s_Red) , 1, 255);
	gi_Green = clamp (str_to_num (s_Green), 1, 255);
	gi_Blue = clamp (str_to_num (s_Blue) , 1, 255);

	gi_Enable = get_pcvar_num (gp_Enable);
	gi_Radius = get_pcvar_num (gp_Radius);
	gi_Silenced = get_pcvar_num (gp_Silenced);
}

#define MAX_WEAPONS 30
#define NOT_GUNS_BITSUM (1 << CSW_HEGRENADE | 1 << CSW_SMOKEGRENADE | 1 << CSW_FLASHBANG | 1 << CSW_KNIFE | 1 << CSW_C4)

RegisterHamsPrimaryAttack ()
{
	new s_WeaponName [24];
	for (new i_Weap = 1; i_Weap <= MAX_WEAPONS; i_Weap++)
	{
		if (!((1 << i_Weap) & NOT_GUNS_BITSUM) && get_weaponname (i_Weap, s_WeaponName, charsmax (s_WeaponName)))
		{
			RegisterHam (Ham_Weapon_PrimaryAttack, s_WeaponName, "Event_WeaponPrimaryAttack");
		}
	}
}

#define M4A1_SILENCED ( 1<<2 )
#define USP_SILENCED ( 1<<0 )

GetWeaponSilen (const i_WeaponIndex)
{
	switch (get_pdata_int (i_WeaponIndex, m_iWeaponType, EXTRAOFFSET_WEAPONS))
	{
	case CSW_M4A1 : return (get_pdata_int (i_WeaponIndex, m_iSilencerFireMode, EXTRAOFFSET_WEAPONS ) & M4A1_SILENCED);
	case CSW_USP : return (get_pdata_int (i_WeaponIndex, m_iSilencerFireMode, EXTRAOFFSET_WEAPONS ) & USP_SILENCED);
	case CSW_TMP : return 1;
	}
	return 0;
}
