Short invulnerability at spawn with a visible team-coloured glow, dropped when you shoot or move.
csb_spawn_protection.sma v1.0.0
1
/*
2
* CSB Spawn Protection
3
* Copyright (C) 2026 counter-strike-boost.com
4
*
5
* Gives players a short window of invulnerability when they spawn, with a
6
* visible glow shell so everyone can see who is still protected. Protection is
7
* dropped early when the player fires (cvar) or moves (cvar), and always ends
8
* when the timer runs out. Built for DM / CSDM style servers where players
9
* respawn constantly and spawn-camping is a real problem.
10
*
11
* This is an independent GPL implementation; it is not based on any other
12
* plugin's source.
13
*
14
* This program is free software: you can redistribute it and/or modify it
15
* under the terms of the GNU General Public License as published by the Free
16
* Software Foundation, either version 3 of the License, or (at your option)
17
* any later version. It is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
20
* Public License for more details: <https://www.gnu.org/licenses/>.
21
*/
22
23
#include <amxmodx>
24
#include <fakemeta>
25
#include <hamsandwich>
26
#include <fun>
27
28
new const PLUGIN[] = "CSB Spawn Protection"
29
new const VERSION[] = "1.0.0"
30
new const AUTHOR[] = "counter-strike-boost.com"
31
32
#define TASK_END 5000
33
34
new g_pEnabled, g_pTime, g_pBreakFire, g_pBreakMove, g_pAlpha
35
36
new bool:g_bProtected[33]
37
38
public plugin_init()
39
{
40
register_plugin(PLUGIN, VERSION, AUTHOR)
41
42
g_pEnabled = register_cvar("csb_spawnprot_enabled", "1")
43
g_pTime = register_cvar("csb_spawnprot_time", "3.0")
44
g_pBreakFire = register_cvar("csb_spawnprot_breakfire", "1")
45
g_pBreakMove = register_cvar("csb_spawnprot_breakmove", "0")
46
g_pAlpha = register_cvar("csb_spawnprot_alpha", "160")
47
48
RegisterHam(Ham_Spawn, "player", "fwdSpawnPost", 1)
49
register_forward(FM_CmdStart, "fwdCmdStart")
50
register_event("DeathMsg", "evDeath", "a")
51
}
52
53
public fwdSpawnPost(id)
54
{
55
if (!get_pcvar_num(g_pEnabled))
56
return
57
58
if (!is_user_alive(id) || !is_user_connected(id))
59
return
60
61
new Float:seconds = get_pcvar_float(g_pTime)
62
63
if (seconds <= 0.0)
64
return
65
66
startProtection(id, seconds)
67
}
68
69
startProtection(id, Float:seconds)
70
{
71
g_bProtected[id] = true
72
set_user_godmode(id, 1)
73
74
new r, g, b
75
teamColor(id, r, g, b)
76
77
set_user_rendering(id, kRenderFxGlowShell, r, g, b, kRenderNormal, 16)
78
79
/* also make the model itself slightly translucent */
80
new alpha = clamp(get_pcvar_num(g_pAlpha), 0, 255)
81
set_pev(id, pev_rendermode, kRenderTransColor)
82
set_pev(id, pev_renderamt, float(alpha))
83
84
remove_task(id + TASK_END)
85
set_task(seconds, "taskEnd", id + TASK_END)
86
87
client_print(id, print_center, "* Spawn protection active for %.1f seconds *", seconds)
88
}
89
90
teamColor(id, &r, &g, &b)
91
{
92
/* CS: team 1 = T (red), team 2 = CT (blue) */
93
switch (pev(id, pev_team))
94
{
95
case 1: { r = 255; g = 80; b = 80; }
96
case 2: { r = 80; g = 120; b = 255; }
97
default: { r = 200; g = 200; b = 200; }
98
}
99
}
100
101
public taskEnd(taskid)
102
{
103
new id = taskid - TASK_END
104
endProtection(id, true)
105
}
106
107
endProtection(id, bool:notify)
108
{
109
if (!g_bProtected[id])
110
return
111
112
g_bProtected[id] = false
113
remove_task(id + TASK_END)
114
115
if (is_user_connected(id))
116
{
117
set_user_godmode(id, 0)
118
set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderNormal, 16)
119
set_pev(id, pev_rendermode, kRenderNormal)
120
set_pev(id, pev_renderamt, 0.0)
121
122
if (notify && is_user_alive(id))
123
client_print(id, print_center, "* Spawn protection ended *")
124
}
125
}
126
127
public fwdCmdStart(id, uc_handle, seed)
128
{
129
if (!g_bProtected[id] || !is_user_alive(id))
130
return FMRES_IGNORED
131
132
new buttons = get_uc(uc_handle, UC_Buttons)
133
134
if (get_pcvar_num(g_pBreakFire) && (buttons & IN_ATTACK))
135
{
136
endProtection(id, true)
137
return FMRES_IGNORED
138
}
139
140
if (get_pcvar_num(g_pBreakMove))
141
{
142
new moveMask = IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT | IN_JUMP | IN_DUCK
143
144
if (buttons & moveMask)
145
endProtection(id, true)
146
}
147
148
return FMRES_IGNORED
149
}
150
151
public evDeath()
152
{
153
new victim = read_data(2)
154
155
if (1 <= victim <= 32)
156
endProtection(victim, false)
157
}
158
159
public client_disconnected(id)
160
{
161
g_bProtected[id] = false
162
remove_task(id + TASK_END)
163
}
164









