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

// COMMENT THIS LINE IF YOU DONT WANT TO USE LANG FILE AND SEE HUD MESSAGES
#define HUD_MESSAGES

new Float:g_flLastTouch[ 33 ];
new g_Pointer_FriendlyFire;
new g_iMsg_DeathMsg;
new g_iHookedDeathMsg;
new g_Cvar_Enabled;
new g_iMaxplayers;

#define ERROR     0
#define HEGRENADE 1
#define FLASHBANG 2
#define SMOKENADE 3

new g_szGrenadeNames[ ][ ] = {
	"", // ERROR
	"weapon_hegrenade",
	"weapon_flashbang",
	"weapon_smokegrenade"
};

public plugin_init() {
	register_plugin( "Grenade Touch Damage", "1.3", "xPaw" );
	
	#if defined HUD_MESSAGES
		register_dictionary( "grenadetouchdmg.txt" );
	#endif
	
	g_Cvar_Enabled = register_cvar( "grenade_touch_dmg", "1", FCVAR_SERVER );
	
	g_iMaxplayers = get_maxplayers( );
	g_iMsg_DeathMsg = get_user_msgid( "DeathMsg" );
	
	if( cstrike_running( ) ) {
		g_Pointer_FriendlyFire = get_cvar_pointer( "mp_friendlyfire" );
		
		RegisterHam( Ham_Touch, "grenade", "FwdHamTouch_Grenade" );
	} else
		set_fail_state( "Only Counter-Strike Mod allowed!" );
}

public MsgDeathMsg( ) {
	set_msg_arg_int( 3, ARG_BYTE, 1 );
	set_msg_arg_string( 4, "grenade" );
	
	return PLUGIN_CONTINUE;
}

public FwdHamTouch_Grenade( iEntity, iTouched ) {
	if( !get_pcvar_num( g_Cvar_Enabled ) )
		return HAM_IGNORED;
	
	if( !( 1 <= iTouched <= g_iMaxplayers ) )
		return HAM_IGNORED;
	
	static Float:flGmTime;
	flGmTime = get_gametime();
	
	if( g_flLastTouch[iTouched] < flGmTime ) {
		new iOwner = pev( iEntity, pev_owner );
		
		if( iOwner == iTouched )
			return HAM_IGNORED;
		
		if( is_user_connected( iOwner ) ) {
			if( !get_pcvar_num( g_Pointer_FriendlyFire ) && ( get_user_team( iTouched ) == get_user_team( iOwner ) ) )
				return HAM_IGNORED;
			
			if( pev( iTouched, pev_takedamage ) == DAMAGE_NO )
				return HAM_IGNORED;
			
			new Float:flVelocity[ 3 ];
			pev( iEntity, pev_velocity, flVelocity );
			
			new Float:flSpeed = vector_length( flVelocity );
			new Float:flDamage = ( flSpeed * 0.15 ) / 13.0;
			
			if( flSpeed > 100.0 ) { // anti grenade stuck bug damage fix
				g_iHookedDeathMsg = register_message( g_iMsg_DeathMsg, "MsgDeathMsg" );
				
				new iType = GetGrenadeType( iEntity );
				if( iType != ERROR )
					set_pev( iEntity, pev_classname, g_szGrenadeNames[ iType ] );
				
				ExecuteHamB( Ham_TakeDamage, iTouched, iEntity, iOwner, flDamage, DMG_GENERIC );
				
				if( g_iHookedDeathMsg ) {
					unregister_message( g_iMsg_DeathMsg, g_iHookedDeathMsg );
					
					g_iHookedDeathMsg = 0;
				}
				
				if( iType != ERROR )
					set_pev( iEntity, pev_classname, "grenade" );
				
				#if defined HUD_MESSAGES
					new iReceivedDamage = pev( iTouched, pev_dmg_take );
					
					new szName[ 32 ], szNameOwner[ 32 ];
					get_user_name( iTouched, szName, 31 );
					get_user_name( iOwner, szNameOwner, 31 );
					
					set_hudmessage( 250, 150, 0, -1.0, 0.30, 0, 6.0, 6.0, 0.5, 0.4, 4 );
					
					if( !is_user_alive( iTouched ) ) {
						show_hudmessage( iOwner, "%L", iOwner, "GTD_KILLED", szName );
						show_hudmessage( iTouched, "%L", iTouched, "GTD_KILLED2", szNameOwner );
					} else {
						show_hudmessage( iOwner, "%L", iOwner, "GTD_MADEDMG", szName, iReceivedDamage );
						show_hudmessage( iTouched, "%L", iTouched, "GTD_LOSTHP", szNameOwner, iReceivedDamage );
					}
				#endif
			}
		}
		
		g_flLastTouch[iTouched] = flGmTime + 0.4;
	}
	
	return HAM_IGNORED;
}

stock GetGrenadeType( iEntity ) {
	if( !pev_valid( iEntity ) )
		return ERROR;
	
	new szModel[ 32 ];
	pev( iEntity, pev_model, szModel, charsmax( szModel ) );
	
	if( szModel[ 7 ] != 'w' && szModel[ 8 ] != '_' )
		return ERROR;
	
	switch( szModel[ 9 ] ) {
		case 'h': return HEGRENADE;
		case 'f': return FLASHBANG;
		case 's': return SMOKENADE;
		default : return ERROR;
	}
	
	return ERROR;
}