/*
* CSB Damage Report
* Copyright (C) 2026 counter-strike-boost.com
*
* Accumulates every hit in Ham_TakeDamage into per-attacker/per-victim tables
* that reset each round, then prints "who hit you for how much" and "who you
* hit" when a player dies, and on demand with /dmg. Optionally shows a short
* HUD summary of the exchange with the killer.
*
* Inspired by the "Damager / Hit Report" plugin by VEN. This is an independent
* GPL re-implementation; no original code is reused.
*
* 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 the GNU General
* Public License for more details: .
*/
#include
#include
new const PLUGIN[] = "CSB Damage Report"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
/* [attacker][victim] */
new g_iDamage[33][33]
new g_iHits[33][33]
new g_pEnabled, g_pHud, g_pOnDeath
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_dmg_enabled", "1")
g_pHud = register_cvar("csb_dmg_hud", "1")
g_pOnDeath = register_cvar("csb_dmg_ondeath", "1")
RegisterHam(Ham_TakeDamage, "player", "fwTakeDamage")
register_event("DeathMsg", "eDeath", "a")
register_event("HLTV", "eNewRound", "a", "1=0", "2=0")
register_clcmd("say /dmg", "cmdDmg")
register_clcmd("say_team /dmg", "cmdDmg")
register_clcmd("say /hp", "cmdDmg")
}
public eNewRound()
{
for (new i = 1; i <= 32; i++)
{
for (new j = 1; j <= 32; j++)
{
g_iDamage[i][j] = 0
g_iHits[i][j] = 0
}
}
}
public fwTakeDamage(victim, inflictor, attacker, Float:damage, damagebits)
{
if (!get_pcvar_num(g_pEnabled))
return HAM_IGNORED
if (attacker < 1 || attacker > 32 || victim < 1 || victim > 32)
return HAM_IGNORED
if (attacker == victim)
return HAM_IGNORED
new dmg = floatround(damage)
if (dmg <= 0)
return HAM_IGNORED
g_iDamage[attacker][victim] += dmg
g_iHits[attacker][victim]++
return HAM_IGNORED
}
public eDeath()
{
if (!get_pcvar_num(g_pEnabled) || !get_pcvar_num(g_pOnDeath))
return
new killer = read_data(1)
new victim = read_data(2)
if (victim < 1 || victim > 32 || !is_user_connected(victim))
return
printReport(victim)
if (get_pcvar_num(g_pHud) && killer >= 1 && killer <= 32 && killer != victim && is_user_connected(killer))
{
new kname[32]
get_user_name(killer, kname, charsmax(kname))
set_hudmessage(255, 80, 80, -1.0, 0.28, 0, 0.0, 4.0, 0.1, 0.2, -1)
show_hudmessage(victim, "Killed by %s^nHe hit you: %d dmg / %d hits^nYou hit him: %d dmg / %d hits",
kname,
g_iDamage[killer][victim], g_iHits[killer][victim],
g_iDamage[victim][killer], g_iHits[victim][killer])
}
}
public cmdDmg(id)
{
if (!get_pcvar_num(g_pEnabled))
return PLUGIN_HANDLED
printReport(id)
return PLUGIN_HANDLED
}
printReport(id)
{
new name[32], line[160], count
client_print(id, print_chat, "[CSB] ---- Damage you dealt this round ----")
count = 0
for (new v = 1; v <= 32; v++)
{
if (v == id || g_iHits[id][v] <= 0)
continue
if (is_user_connected(v))
get_user_name(v, name, charsmax(name))
else
copy(name, charsmax(name), "disconnected")
formatex(line, charsmax(line), " -> %s : %d damage in %d hit(s)", name, g_iDamage[id][v], g_iHits[id][v])
client_print(id, print_chat, line)
count++
}
if (!count)
client_print(id, print_chat, " (you dealt no damage)")
client_print(id, print_chat, "[CSB] ---- Damage you took this round ----")
count = 0
for (new a = 1; a <= 32; a++)
{
if (a == id || g_iHits[a][id] <= 0)
continue
if (is_user_connected(a))
get_user_name(a, name, charsmax(name))
else
copy(name, charsmax(name), "disconnected")
formatex(line, charsmax(line), " <- %s : %d damage in %d hit(s)", name, g_iDamage[a][id], g_iHits[a][id])
client_print(id, print_chat, line)
count++
}
if (!count)
client_print(id, print_chat, " (you took no damage)")
}