/*
* CSB Fireworks
* Copyright (C) 2026 counter-strike-boost.com
*
* Fires a short fireworks show - timed bursts of TE_EXPLOSION and TE_SPARKS
* tempents at random points above the players, each with an explosion sound -
* automatically at round end (a match/holiday celebration) or on the admin
* command amx_fireworks.
*
* 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
#include
#include
new const PLUGIN[] = "CSB Fireworks"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
#define SVC_TEMPENTITY 23
#define TE_EXPLOSION 3
#define TE_SPARKS 9
new g_iExploSpr
new g_pEnabled, g_pRoundEnd, g_pBursts
public plugin_precache()
{
g_iExploSpr = precache_model("sprites/zerogxplode.spr")
precache_sound("weapons/explode3.wav")
}
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_fw_enabled", "1")
g_pRoundEnd = register_cvar("csb_fw_roundend", "1")
g_pBursts = register_cvar("csb_fw_bursts", "10")
register_concmd("amx_fireworks", "cmdFireworks", ADMIN_LEVEL_A, "- launch a fireworks show")
register_logevent("eventRoundEnd", 2, "1=Round_End")
}
public eventRoundEnd()
{
if (get_pcvar_num(g_pEnabled) && get_pcvar_num(g_pRoundEnd))
startShow()
}
public cmdFireworks(id, level, cid)
{
if (!cmd_access(id, level, cid, 1))
return PLUGIN_HANDLED
if (!get_pcvar_num(g_pEnabled))
{
console_print(id, "[CSB] Fireworks are disabled (csb_fw_enabled 0).")
return PLUGIN_HANDLED
}
new aname[32]
if (id)
get_user_name(id, aname, charsmax(aname))
else
copy(aname, charsmax(aname), "CONSOLE")
log_amx("[CSB Fireworks] %s launched a show", aname)
startShow()
return PLUGIN_HANDLED
}
startShow()
{
new bursts = get_pcvar_num(g_pBursts)
if (bursts < 1)
bursts = 1
if (bursts > 40)
bursts = 40
for (new i = 0; i < bursts; i++)
set_task(0.3 * float(i) + 0.1, "taskBurst")
}
public taskBurst()
{
new players[32], num
get_players(players, num, "c")
new x, y, z
if (num)
{
new origin[3]
get_user_origin(players[random_num(0, num - 1)], origin)
x = origin[0] + random_num(-300, 300)
y = origin[1] + random_num(-300, 300)
z = origin[2] + random_num(160, 420)
}
else
{
x = random_num(-500, 500)
y = random_num(-500, 500)
z = random_num(200, 500)
}
/* the burst */
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_EXPLOSION)
write_coord(x)
write_coord(y)
write_coord(z)
write_short(g_iExploSpr)
write_byte(random_num(15, 30)) // scale
write_byte(20) // framerate
write_byte(2) // flags: no sound, no smoke (we handle sound)
message_end()
/* extra sparkle */
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_SPARKS)
write_coord(x)
write_coord(y)
write_coord(z)
message_end()
/* boom for everyone */
new pid
for (new i = 0; i < num; i++)
{
pid = players[i]
emit_sound(pid, CHAN_STATIC, "weapons/explode3.wav", 0.6, ATTN_NORM, 0, random_num(90, 120))
}
}