/* * CSB Spawn Protection * Copyright (C) 2026 counter-strike-boost.com * * Gives players a short window of invulnerability when they spawn, with a * visible glow shell so everyone can see who is still protected. Protection is * dropped early when the player fires (cvar) or moves (cvar), and always ends * when the timer runs out. Built for DM / CSDM style servers where players * respawn constantly and spawn-camping is a real problem. * * This is an independent GPL implementation; it is not based on any other * plugin's source. * * 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 #include #include new const PLUGIN[] = "CSB Spawn Protection" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" #define TASK_END 5000 new g_pEnabled, g_pTime, g_pBreakFire, g_pBreakMove, g_pAlpha new bool:g_bProtected[33] public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) g_pEnabled = register_cvar("csb_spawnprot_enabled", "1") g_pTime = register_cvar("csb_spawnprot_time", "3.0") g_pBreakFire = register_cvar("csb_spawnprot_breakfire", "1") g_pBreakMove = register_cvar("csb_spawnprot_breakmove", "0") g_pAlpha = register_cvar("csb_spawnprot_alpha", "160") RegisterHam(Ham_Spawn, "player", "fwdSpawnPost", 1) register_forward(FM_CmdStart, "fwdCmdStart") register_event("DeathMsg", "evDeath", "a") } public fwdSpawnPost(id) { if (!get_pcvar_num(g_pEnabled)) return if (!is_user_alive(id) || !is_user_connected(id)) return new Float:seconds = get_pcvar_float(g_pTime) if (seconds <= 0.0) return startProtection(id, seconds) } startProtection(id, Float:seconds) { g_bProtected[id] = true set_user_godmode(id, 1) new r, g, b teamColor(id, r, g, b) set_user_rendering(id, kRenderFxGlowShell, r, g, b, kRenderNormal, 16) /* also make the model itself slightly translucent */ new alpha = clamp(get_pcvar_num(g_pAlpha), 0, 255) set_pev(id, pev_rendermode, kRenderTransColor) set_pev(id, pev_renderamt, float(alpha)) remove_task(id + TASK_END) set_task(seconds, "taskEnd", id + TASK_END) client_print(id, print_center, "* Spawn protection active for %.1f seconds *", seconds) } teamColor(id, &r, &g, &b) { /* CS: team 1 = T (red), team 2 = CT (blue) */ switch (pev(id, pev_team)) { case 1: { r = 255; g = 80; b = 80; } case 2: { r = 80; g = 120; b = 255; } default: { r = 200; g = 200; b = 200; } } } public taskEnd(taskid) { new id = taskid - TASK_END endProtection(id, true) } endProtection(id, bool:notify) { if (!g_bProtected[id]) return g_bProtected[id] = false remove_task(id + TASK_END) if (is_user_connected(id)) { set_user_godmode(id, 0) set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderNormal, 16) set_pev(id, pev_rendermode, kRenderNormal) set_pev(id, pev_renderamt, 0.0) if (notify && is_user_alive(id)) client_print(id, print_center, "* Spawn protection ended *") } } public fwdCmdStart(id, uc_handle, seed) { if (!g_bProtected[id] || !is_user_alive(id)) return FMRES_IGNORED new buttons = get_uc(uc_handle, UC_Buttons) if (get_pcvar_num(g_pBreakFire) && (buttons & IN_ATTACK)) { endProtection(id, true) return FMRES_IGNORED } if (get_pcvar_num(g_pBreakMove)) { new moveMask = IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT | IN_JUMP | IN_DUCK if (buttons & moveMask) endProtection(id, true) } return FMRES_IGNORED } public evDeath() { new victim = read_data(2) if (1 <= victim <= 32) endProtection(victim, false) } public client_disconnected(id) { g_bProtected[id] = false remove_task(id + TASK_END) }