/*
* CSB Snowball Fight
* Copyright (C) 2026 counter-strike-boost.com
*
* A winter event. While active, thrown grenades are re-skinned as snowballs,
* their blast does only light damage and slows whoever it catches (a temporary
* maxspeed reduction that ticks back to normal), and gentle snow falls from the
* sky as temp entities. The event is toggled by admin command and can auto-enable
* during December.
*
* 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
#include
#include
new const PLUGIN[] = "CSB Snowball Fight"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
#define SNOW_MODEL "models/snowball.mdl"
new g_pEnabled, g_pAuto, g_pDamage, g_pSlow
new bool:g_bActive
new g_iSnowSpr
new Float:g_fSlowUntil[33]
new bool:g_bSnowballModel
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_snow_enabled", "1")
g_pAuto = register_cvar("csb_snow_december", "1")
g_pDamage = register_cvar("csb_snow_damage", "10.0")
g_pSlow = register_cvar("csb_snow_slow", "3.0")
register_concmd("amx_snow", "cmdSnow", ADMIN_LEVEL_A, "<0|1> - toggle the snowball event")
RegisterHam(Ham_TakeDamage, "player", "fwTakeDamage", 0)
/* auto-enable in December */
new szDate[16]
get_time("%m", szDate, charsmax(szDate))
if (get_pcvar_num(g_pAuto) && str_to_num(szDate) == 12)
setActive(true)
set_task(0.6, "taskSnowfall", 0, _, _, "b")
set_task(0.5, "taskGrenades", 0, _, _, "b")
set_task(0.25, "taskSlow", 0, _, _, "b")
}
public plugin_precache()
{
if (file_exists("models/snowball.mdl"))
g_bSnowballModel = true
g_iSnowSpr = precache_model("sprites/laserbeam.spr")
}
setActive(bool:on)
{
g_bActive = on
if (on)
client_print(0, print_chat, "[CSB] Let it snow! Snowball fight is ON.")
else
client_print(0, print_chat, "[CSB] The snowball fight is over.")
}
public cmdSnow(id, level, cid)
{
if (!cmd_access(id, level, cid, 2))
return PLUGIN_HANDLED
new arg[4]
read_argv(1, arg, charsmax(arg))
setActive(str_to_num(arg) != 0)
return PLUGIN_HANDLED
}
/* skin live grenades as snowballs */
public taskGrenades()
{
if (!g_bActive || !g_bSnowballModel)
return
new ent = 0
while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "grenade")) > 0)
{
static model[64]
pev(ent, pev_model, model, charsmax(model))
if (!equal(model, SNOW_MODEL))
engfunc(EngFunc_SetModel, ent, SNOW_MODEL)
}
}
public fwTakeDamage(victim, inflictor, attacker, Float:damage, damagebits)
{
if (!g_bActive)
return HAM_IGNORED
if (!(damagebits & DMG_BLAST))
return HAM_IGNORED
if (!is_user_alive(victim))
return HAM_IGNORED
/* light damage from a snowball */
SetHamParamFloat(4, get_pcvar_float(g_pDamage))
/* slow the victim */
g_fSlowUntil[victim] = get_gametime() + get_pcvar_float(g_pSlow)
set_user_maxspeed(victim, 120.0)
return HAM_IGNORED
}
public taskSlow()
{
if (!g_bActive)
return
new players[32], num
get_players(players, num, "a")
for (new i = 0; i < num; i++)
{
new id = players[i]
if (g_fSlowUntil[id] > 0.0 && get_gametime() >= g_fSlowUntil[id])
{
g_fSlowUntil[id] = 0.0
set_user_maxspeed(id, 250.0)
}
}
}
public taskSnowfall()
{
if (!g_bActive)
return
new players[32], num
get_players(players, num, "a")
for (new i = 0; i < num; i++)
{
new id = players[i]
static Float:fOrigin[3]
pev(id, pev_origin, fOrigin)
static Float:top[3], Float:bot[3]
top[0] = fOrigin[0] + float(random_num(-200, 200))
top[1] = fOrigin[1] + float(random_num(-200, 200))
top[2] = fOrigin[2] + 400.0
bot[0] = top[0]
bot[1] = top[1]
bot[2] = fOrigin[2] - 100.0
message_begin(MSG_ONE, SVC_TEMPENTITY, _, id)
write_byte(TE_BEAMPOINTS)
engfunc(EngFunc_WriteCoord, top[0])
engfunc(EngFunc_WriteCoord, top[1])
engfunc(EngFunc_WriteCoord, top[2])
engfunc(EngFunc_WriteCoord, bot[0])
engfunc(EngFunc_WriteCoord, bot[1])
engfunc(EngFunc_WriteCoord, bot[2])
write_short(g_iSnowSpr)
write_byte(0)
write_byte(0)
write_byte(8)
write_byte(1)
write_byte(40)
write_byte(255)
write_byte(255)
write_byte(255)
write_byte(120)
write_byte(0)
message_end()
}
}