/* * CSB Death Effects * Copyright (C) 2026 counter-strike-boost.com * * Adds extra visual flair to kills: a blood burst and gib shower at the victim's * position, plus an optional explosion for headshot or knife kills. Everything * is sent as temp entities to nearby players, each effect is cvar-toggled, and a * short per-victim cooldown keeps the effects from spamming the network. * * 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 for details. */ #include new const PLUGIN[] = "CSB Death Effects" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" #define TE_EXPLOSION 3 #define TE_BLOODSPRITE 115 new const g_szExplode[] = "sprites/zerogxplode.spr" new const g_szBloodSpray[] = "sprites/bloodspray.spr" new const g_szBloodDrop[] = "sprites/blood.spr" new const g_szGibs[] = "models/hgibs.mdl" new g_pEnabled, g_pBlood, g_pGibs, g_pExplode new g_iSprExplode, g_iSprSpray, g_iSprDrop, g_iMdlGibs new Float:g_fLastFx[33] public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) g_pEnabled = register_cvar("csb_deathfx_enabled", "1") g_pBlood = register_cvar("csb_deathfx_blood", "1") g_pGibs = register_cvar("csb_deathfx_gibs", "1") g_pExplode = register_cvar("csb_deathfx_explode", "1") register_event("DeathMsg", "eventDeath", "a", "1>0") } public plugin_precache() { g_iSprExplode = precache_model(g_szExplode) g_iSprSpray = precache_model(g_szBloodSpray) g_iSprDrop = precache_model(g_szBloodDrop) g_iMdlGibs = precache_model(g_szGibs) } public eventDeath() { if (!get_pcvar_num(g_pEnabled)) return new victim = read_data(2) new hs = read_data(3) if (victim < 1 || victim > 32 || !is_user_connected(victim)) return /* rate limit per victim slot */ if (get_gametime() - g_fLastFx[victim] < 0.3) return g_fLastFx[victim] = get_gametime() new weapon[32] read_data(4, weapon, charsmax(weapon)) new bool:knife = (containi(weapon, "knife") != -1) static iOrigin[3], Float:fOrigin[3] get_user_origin(victim, iOrigin) fOrigin[0] = float(iOrigin[0]) fOrigin[1] = float(iOrigin[1]) fOrigin[2] = float(iOrigin[2]) if (get_pcvar_num(g_pBlood)) bloodBurst(fOrigin, iOrigin) if (get_pcvar_num(g_pGibs)) gibShower(fOrigin, iOrigin) if (get_pcvar_num(g_pExplode) && (hs || knife)) explosion(fOrigin, iOrigin) } bloodBurst(const Float:fOrigin[3], const iOrigin[3]) { message_begin_f(MSG_PVS, SVC_TEMPENTITY, fOrigin) write_byte(TE_BLOODSPRITE) write_coord(iOrigin[0]) write_coord(iOrigin[1]) write_coord(iOrigin[2] + 12) write_short(g_iSprSpray) write_short(g_iSprDrop) write_byte(70) /* red blood colour index */ write_byte(12) /* scale */ message_end() } gibShower(const Float:fOrigin[3], const iOrigin[3]) { message_begin_f(MSG_PVS, SVC_TEMPENTITY, fOrigin) write_byte(TE_BREAKMODEL) write_coord(iOrigin[0]) write_coord(iOrigin[1]) write_coord(iOrigin[2] + 24) write_coord(16) /* size x */ write_coord(16) /* size y */ write_coord(16) /* size z */ write_coord(0) /* velocity x */ write_coord(0) /* velocity y */ write_coord(80) /* velocity z */ write_byte(120) /* random velocity */ write_short(g_iMdlGibs) write_byte(12) /* count */ write_byte(25) /* life (*0.1s) */ write_byte(0x02) /* flags: BREAK_FLESH */ message_end() } explosion(const Float:fOrigin[3], const iOrigin[3]) { message_begin_f(MSG_PVS, SVC_TEMPENTITY, fOrigin) write_byte(TE_EXPLOSION) write_coord(iOrigin[0]) write_coord(iOrigin[1]) write_coord(iOrigin[2] + 16) write_short(g_iSprExplode) write_byte(10) /* scale */ write_byte(20) /* framerate */ write_byte(0x01) /* TE_EXPLFLAG_NOADDITIVE off / no sound flag stub */ message_end() }