/*
* CSB Grenade Stats
* Copyright (C) 2026 counter-strike-boost.com
*
* Attributes utility usage to the thrower: HE damage is credited when a
* player takes DMG_BLAST damage from a "grenade" entity (owner read from the
* entity), flashbangs are caught by their explosion sound and blinded victims
* are detected through the ScreenFade message, and smoke throws are counted
* from the pin-pull sound while holding a smokegrenade. Totals are kept per
* round and per map; /nadestats prints your numbers.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version. It is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
*/
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
new const PLUGIN[] = "CSB Grenade Stats"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
#if !defined DMG_BLAST
#define DMG_BLAST (1<<6)
#endif
new g_iHeDmg[33]
new g_iBlinded[33]
new g_iSmokes[33]
new g_iMapHeDmg[33]
new g_iMapBlinded[33]
new g_iMapSmokes[33]
new g_iLastFlashOwner
new Float:g_fLastFlash
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_cvar("csb_nadestats_enabled", "1")
RegisterHam(Ham_TakeDamage, "player", "OnDamage", 1)
register_forward(FM_EmitSound, "fwEmitSound", 0)
register_message(get_user_msgid("ScreenFade"), "onScreenFade")
register_logevent("onRoundStart", 2, "1=Round_Start")
register_clcmd("say /nadestats", "cmdStats")
register_clcmd("say_team /nadestats", "cmdStats")
}
public client_putinserver(id)
{
g_iHeDmg[id] = 0
g_iBlinded[id] = 0
g_iSmokes[id] = 0
g_iMapHeDmg[id] = 0
g_iMapBlinded[id] = 0
g_iMapSmokes[id] = 0
}
public onRoundStart()
{
for (new id = 1; id <= 32; id++)
{
g_iHeDmg[id] = 0
g_iBlinded[id] = 0
g_iSmokes[id] = 0
}
g_iLastFlashOwner = 0
}
public OnDamage(victim, inflictor, attacker, Float:damage, damagetype)
{
if (!(damagetype & DMG_BLAST) || damage < 1.0)
return HAM_IGNORED
if (inflictor < 1 || victim < 1 || victim > 32)
return HAM_IGNORED
static cls[16]
pev(inflictor, pev_classname, cls, charsmax(cls))
if (!equal(cls, "grenade"))
return HAM_IGNORED
new owner = pev(inflictor, pev_owner)
if (owner < 1 || owner > 32 || owner == victim)
return HAM_IGNORED
if (get_user_team(owner) == get_user_team(victim))
return HAM_IGNORED
new dealt = floatround(damage)
g_iHeDmg[owner] += dealt
g_iMapHeDmg[owner] += dealt
return HAM_IGNORED
}
public fwEmitSound(ent, channel, const sample[])
{
/* flashbang detonation: remember who threw it and when */
if (equal(sample, "weapons/flashbang-1.wav"))
{
g_iLastFlashOwner = pev(ent, pev_owner)
g_fLastFlash = get_gametime()
return FMRES_IGNORED
}
/* smoke throw: pin pull while holding the smokegrenade */
if (equal(sample, "weapons/pinpull-1.wav"))
{
if (ent >= 1 && ent <= 32 && is_user_alive(ent)
&& get_user_weapon(ent) == CSW_SMOKEGRENADE)
{
g_iSmokes[ent]++
g_iMapSmokes[ent]++
}
}
return FMRES_IGNORED
}
public onScreenFade(msgid, dest, victim)
{
if (victim < 1 || victim > 32 || !is_user_connected(victim))
return PLUGIN_CONTINUE
new owner = g_iLastFlashOwner
if (owner < 1 || owner > 32 || owner == victim)
return PLUGIN_CONTINUE
/* only count fades right after a flashbang went off */
if (get_gametime() - g_fLastFlash > 2.0)
return PLUGIN_CONTINUE
if (get_user_team(owner) == get_user_team(victim))
return PLUGIN_CONTINUE
/* a fully blinded victim fades to near-white (arg 7 = alpha) */
new alpha = get_msg_arg_int(7)
if (alpha < 200)
return PLUGIN_CONTINUE
g_iBlinded[owner]++
g_iMapBlinded[owner]++
return PLUGIN_CONTINUE
}
public cmdStats(id)
{
client_print(id, print_console, "----- CSB Grenade Stats -----")
client_print(id, print_console, "this round: HE dmg %d enemies flashed %d smokes %d",
g_iHeDmg[id], g_iBlinded[id], g_iSmokes[id])
client_print(id, print_console, "this map: HE dmg %d enemies flashed %d smokes %d",
g_iMapHeDmg[id], g_iMapBlinded[id], g_iMapSmokes[id])
client_print(id, print_chat, "[CSB] Grenade stats printed to your console.")
return PLUGIN_HANDLED
}