/************************************************************************
**									*
** Weapon Lights (Beta) v.0.7.1 [20-Feb-2009]				*
**									*
** by HiSS & Arkshine							*
**									*
************************************************************************/

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

#define DLIGHT_LIFE 8
#define DLIGHT_DECAY 60
    
#define MAX_CLIENTS 32

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

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

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

new g_pEnable, g_pRadius, g_pColor, g_pSilenced;
new g_Enable, g_Red, g_Green, g_Blue, g_Radius, g_Silenced;

const m_iWeaponType = 43;
const m_iSilencerFireMode = 74;
const m_iZoomType = 363;
const m_pActiveItem = 373;

#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))
    
new const g_szGunsEvents[][]=
{
	"events/awp.sc","events/g3sg1.sc", "events/ak47.sc", "events/scout.sc",
	"events/m249.sc","events/m4a1.sc", "events/sg552.sc", "events/aug.sc",
	"events/sg550.sc", "events/m3.sc", "events/xm1014.sc", "events/usp.sc",
	"events/mac10.sc", "events/ump45.sc", "events/fiveseven.sc", "events/p90.sc",
	"events/deagle.sc", "events/p228.sc", "events/glock18.sc", "events/mp5n.sc",
	"events/tmp.sc", "events/elite_left.sc", "events/elite_right.sc",
	"events/galil.sc", "events/famas.sc"
}

new g_GunsEventidsBitsum, g_MaxClients, g_FwdId;

public plugin_precache ()
{
	g_FwdId = register_forward (FM_PrecacheEvent, "Forward_PrecacheEvent", 1)
}

public Forward_PrecacheEvent (const Type, const szName[])
{
	for (new i; i < sizeof g_szGunsEvents; ++i)
	{
		if (equal (g_szGunsEvents[i], szName))
		{
			g_GunsEventidsBitsum |= (1 << get_orig_retval())
			return FMRES_HANDLED;
		}
	}
	return FMRES_IGNORED;
}

public plugin_init()
{
	register_plugin ("Weapon Lights", "0.7.1", "HiSS & Arkshine");
        
	register_event ("HLTV", "Event_NewRound", "a", "1=0", "2=0");
	register_clcmd("weapon_lights_reload", "Event_NewRound")
	register_concmd("weapon_lights_reload", "Event_NewRound")
        
	g_pEnable   = register_cvar ("weapon_lights", "1")
	g_pRadius   = register_cvar ("weapon_lights_radius", "18");
	g_pColor    = register_cvar ("weapon_lights_color" , "255 150 15");
	g_pSilenced = register_cvar ("weapon_lights_silenced", "2");
        
	unregister_forward (FM_PrecacheEvent, g_FwdId, 1);
	register_forward (FM_PlaybackEvent, "Forward_PlaybackEvent");
        
	g_MaxClients = global_get (glb_maxClients);
	CacheCvarsValue ();
}

public Forward_PlaybackEvent (const Flags, const Invoker, const EventId)
{
	if (g_Enable && (g_GunsEventidsBitsum & (1 << EventId)) && 1 <= Invoker <= g_MaxClients)
	{
		static ActiveWeaponIndex; ActiveWeaponIndex = get_pdata_cbase (Invoker, m_pActiveItem);
            
		if (!(!g_Silenced && GetWeaponSilen (ActiveWeaponIndex)))
		{
			static Coord_e:vecOrigin [Coord_e];
			pev (Invoker,pev_origin, vecOrigin);

			message_begin_f (MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
			write_byte (TE_DLIGHT);
			write_coord_f (vecOrigin [x ]);
			write_coord_f (vecOrigin [y ]);
			write_coord_f (vecOrigin [z ]);
			write_byte (g_Silenced == 2 && GetWeaponSilen (ActiveWeaponIndex) ? floatround (g_Radius * 0.5) : g_Radius);
			write_byte (g_Red);
			write_byte (g_Green);
			write_byte (g_Blue);
			write_byte (DLIGHT_LIFE);
			write_byte (DLIGHT_DECAY);
			message_end();
        
			return FMRES_HANDLED;
		}
	}
	return FMRES_IGNORED;
}
    
public Event_NewRound ()
{
	CacheCvarsValue ();
}
    
CacheCvarsValue ()
{
	new szDLightColor [16];
	get_pcvar_string (g_pColor, szDLightColor, charsmax (szDLightColor));

	new szRed [4], szGreen [4], szBlue [4];
	parse (szDLightColor, szRed, charsmax (szRed), szGreen, charsmax (szGreen), szBlue, charsmax (szBlue));

	g_Red = clamp (str_to_num (szRed)  , 1, 255);
	g_Green = clamp (str_to_num (szGreen), 1, 255);
	g_Blue = clamp (str_to_num (szBlue) , 1, 255);

	g_Enable = get_pcvar_num (g_pEnable);
	g_Radius = get_pcvar_num (g_pRadius);
	g_Silenced = get_pcvar_num (g_pSilenced);
}
    
GetWeaponSilen (const WeaponIndex)
{
	switch (get_pdata_int (WeaponIndex, m_iWeaponType, EXTRAOFFSET_WEAPONS))
	{
		case CSW_M4A1 : return (get_pdata_int (WeaponIndex, m_iSilencerFireMode, EXTRAOFFSET_WEAPONS) & M4A1_SILENCED);
		case CSW_USP  : return (get_pdata_int (WeaponIndex, m_iSilencerFireMode, EXTRAOFFSET_WEAPONS) & USP_SILENCED);
		case CSW_TMP  : return 1;
	}
	return 0;
}
