Promouvoir serveur

Initial release 1.0.0

Browse Source
1.0.0 - Initial release.
Daemon666 committed commit eb8232aee2add813cf9e2045a27871df7691535b
4 changed files with 374 additions and 0 deletions
+3 -0 CHANGELOG.md A
@@ -0,0 +1,3 @@
1 +## 1.0.0 (2026-05-24)
2 +
3 +1.0.0 - Initial release.
+1 -0 README.md A
@@ -0,0 +1 @@
1 +<p><strong>CSB Base Builder</strong> is the classic build-then-fight mode. Each round opens with a build phase: the builder team can grab a brush prop with <code>/grab</code> (it pins in front of their crosshair and follows every frame in <code>PlayerPreThink</code>), spin it with <code>/rotate</code>, freeze it in place with <code>/lock</code>, or release it with <code>/drop</code>. Each builder is limited to a set number of locked props. When the build timer expires the fight phase begins, every prop is frozen, and the attacking team must break into the base.</p><p>Inspired by Base Builder (ConnorMcLeod / Kreedz community). Independent GPL re-implementation.</p><h2>Features</h2><ul><li>Grab / carry / rotate / lock / drop map props during the build phase.</li><li>Per-builder prop limit.</li><li>Timed build phase then a fight phase, announced on the HUD.</li><li>Builder team, build time and prop limit are cvars.</li></ul><h2>Installation</h2><ol><li>Enable the <code>fakemeta</code> module in <code>modules.ini</code>.</li><li>Compile <code>csb_base_builder.sma</code>, copy it to <code>addons/amxmodx/plugins/</code> and add it to <code>plugins.ini</code>.</li><li>Use a map that has movable brush props (func_pushable / func_breakable).</li><li>Change the map.</li></ol>
+303 -0 addons/amxmodx/scripting/csb_base_builder.sma A
@@ -0,0 +1,303 @@
1 +/*
2 + * CSB Base Builder
3 + * Copyright (C) 2026 counter-strike-boost.com
4 + *
5 + * Base Builder core. Each round opens with a build phase in which the builder
6 + * team can grab, carry, rotate and lock map props: /grab pins whatever brush
7 + * prop your crosshair is on in front of you (moved every frame in
8 + * PlayerPreThink), /rotate spins it, /lock freezes it in place, /drop releases
9 + * it. Each builder is limited to a number of locked props. When the build timer
10 + * expires the fight phase starts, every prop is frozen and the attacking team
11 + * must break in.
12 + *
13 + * Inspired by Base Builder (ConnorMcLeod / Kreedz community). Independent GPL
14 + * re-implementation.
15 + *
16 + * This program is free software: you can redistribute it and/or modify it under
17 + * the terms of the GNU General Public License as published by the Free Software
18 + * Foundation, either version 3 of the License, or (at your option) any later
19 + * version. It is distributed in the hope that it will be useful, but WITHOUT
20 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21 + * FOR A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
22 + */
23 +
24 +#include <amxmodx>
25 +#include <fakemeta>
26 +
27 +new const PLUGIN[] = "CSB Base Builder"
28 +new const VERSION[] = "1.0.0"
29 +new const AUTHOR[] = "counter-strike-boost.com"
30 +
31 +#define PHASE_BUILD 0
32 +#define PHASE_FIGHT 1
33 +
34 +new g_pEnabled, g_pBuildTime, g_pBuilderTeam, g_pPropLimit
35 +
36 +new g_iPhase
37 +new g_iGrab[33]
38 +new Float:g_fGrabDist[33]
39 +new Float:g_fGrabYaw[33]
40 +new g_iLockedCount[33]
41 +new g_iHudSync
42 +
43 +public plugin_init()
44 +{
45 + register_plugin(PLUGIN, VERSION, AUTHOR)
46 +
47 + g_pEnabled = register_cvar("csb_bb_enabled", "1")
48 + g_pBuildTime = register_cvar("csb_bb_buildtime", "45")
49 + g_pBuilderTeam = register_cvar("csb_bb_builderteam", "2") /* 1=T 2=CT */
50 + g_pPropLimit = register_cvar("csb_bb_proplimit", "6")
51 +
52 + register_clcmd("say /grab", "cmdGrab")
53 + register_clcmd("say /drop", "cmdDrop")
54 + register_clcmd("say /rotate", "cmdRotate")
55 + register_clcmd("say /lock", "cmdLock")
56 +
57 + register_forward(FM_PlayerPreThink, "fwPreThink")
58 + register_logevent("eventRoundStart", 2, "1=Round_Start")
59 +
60 + g_iHudSync = CreateHudSyncObj()
61 +
62 + set_task(1.0, "taskHud", 0, _, _, "b")
63 +}
64 +
65 +public client_putinserver(id)
66 +{
67 + g_iGrab[id] = 0
68 + g_iLockedCount[id] = 0
69 +}
70 +
71 +public client_disconnected(id)
72 +{
73 + g_iGrab[id] = 0
74 +}
75 +
76 +public eventRoundStart()
77 +{
78 + if (!get_pcvar_num(g_pEnabled))
79 + return
80 +
81 + g_iPhase = PHASE_BUILD
82 +
83 + for (new id = 1; id <= 32; id++)
84 + {
85 + g_iGrab[id] = 0
86 + g_iLockedCount[id] = 0
87 + }
88 +
89 + client_print(0, print_chat, "[CSB] BUILD PHASE - %d seconds. Builders: /grab /rotate /lock /drop", get_pcvar_num(g_pBuildTime))
90 +
91 + set_task(float(get_pcvar_num(g_pBuildTime)), "taskFightPhase", 9911)
92 +}
93 +
94 +public taskFightPhase()
95 +{
96 + g_iPhase = PHASE_FIGHT
97 +
98 + /* drop and freeze everything */
99 + for (new id = 1; id <= 32; id++)
100 + {
101 + if (g_iGrab[id] > 0)
102 + {
103 + freezeProp(g_iGrab[id])
104 + g_iGrab[id] = 0
105 + }
106 + }
107 +
108 + client_print(0, print_chat, "[CSB] FIGHT PHASE - break into the base!")
109 +}
110 +
111 +bool:isBuilder(id)
112 +{
113 + return get_user_team(id) == get_pcvar_num(g_pBuilderTeam)
114 +}
115 +
116 +bool:isGrabbable(ent)
117 +{
118 + if (ent <= 32 || !pev_valid(ent))
119 + return false
120 +
121 + static cls[32]
122 + pev(ent, pev_classname, cls, charsmax(cls))
123 +
124 + if (equal(cls, "worldspawn") || equal(cls, "player"))
125 + return false
126 +
127 + /* brush props and pushables only */
128 + if (equal(cls, "func_pushable") || equal(cls, "func_breakable")
129 + || equal(cls, "func_wall") || equal(cls, "func_door")
130 + || containi(cls, "func_") == 0)
131 + return true
132 +
133 + return false
134 +}
135 +
136 +public cmdGrab(id)
137 +{
138 + if (!get_pcvar_num(g_pEnabled) || g_iPhase != PHASE_BUILD)
139 + {
140 + client_print(id, print_chat, "[CSB] You can only build during the build phase.")
141 + return PLUGIN_HANDLED
142 + }
143 +
144 + if (!isBuilder(id) || !is_user_alive(id))
145 + return PLUGIN_HANDLED
146 +
147 + if (g_iGrab[id] > 0)
148 + {
149 + client_print(id, print_chat, "[CSB] You are already carrying a prop. /drop or /lock first.")
150 + return PLUGIN_HANDLED
151 + }
152 +
153 + new ent, body
154 + get_user_aiming(id, ent, body, 700)
155 +
156 + if (!isGrabbable(ent))
157 + {
158 + client_print(id, print_chat, "[CSB] No movable prop in your crosshair.")
159 + return PLUGIN_HANDLED
160 + }
161 +
162 + static Float:fMe[3], Float:fProp[3]
163 + pev(id, pev_origin, fMe)
164 + pev(ent, pev_origin, fProp)
165 +
166 + g_iGrab[id] = ent
167 + g_fGrabDist[id] = vector_distance(fMe, fProp)
168 +
169 + if (g_fGrabDist[id] > 200.0)
170 + g_fGrabDist[id] = 200.0
171 + else if (g_fGrabDist[id] < 80.0)
172 + g_fGrabDist[id] = 80.0
173 +
174 + static Float:fAng[3]
175 + pev(ent, pev_angles, fAng)
176 + g_fGrabYaw[id] = fAng[1]
177 +
178 + /* make it float freely while carried */
179 + set_pev(ent, pev_movetype, MOVETYPE_NOCLIP)
180 +
181 + client_print(id, print_chat, "[CSB] Prop grabbed. /rotate to spin, /lock to place.")
182 + return PLUGIN_HANDLED
183 +}
184 +
185 +public cmdDrop(id)
186 +{
187 + if (g_iGrab[id] > 0)
188 + {
189 + set_pev(g_iGrab[id], pev_movetype, MOVETYPE_TOSS)
190 + g_iGrab[id] = 0
191 + client_print(id, print_chat, "[CSB] Prop dropped.")
192 + }
193 +
194 + return PLUGIN_HANDLED
195 +}
196 +
197 +public cmdRotate(id)
198 +{
199 + if (g_iGrab[id] > 0)
200 + {
201 + g_fGrabYaw[id] += 45.0
202 +
203 + if (g_fGrabYaw[id] >= 360.0)
204 + g_fGrabYaw[id] -= 360.0
205 +
206 + client_print(id, print_chat, "[CSB] Rotated to %d degrees.", floatround(g_fGrabYaw[id]))
207 + }
208 +
209 + return PLUGIN_HANDLED
210 +}
211 +
212 +public cmdLock(id)
213 +{
214 + if (g_iGrab[id] <= 0)
215 + return PLUGIN_HANDLED
216 +
217 + if (g_iLockedCount[id] >= get_pcvar_num(g_pPropLimit))
218 + {
219 + client_print(id, print_chat, "[CSB] You reached your prop limit (%d).", get_pcvar_num(g_pPropLimit))
220 + return PLUGIN_HANDLED
221 + }
222 +
223 + new ent = g_iGrab[id]
224 + freezeProp(ent)
225 + set_pev(ent, pev_owner, id)
226 +
227 + g_iGrab[id] = 0
228 + g_iLockedCount[id]++
229 +
230 + client_print(id, print_chat, "[CSB] Prop locked in place (%d/%d).", g_iLockedCount[id], get_pcvar_num(g_pPropLimit))
231 + return PLUGIN_HANDLED
232 +}
233 +
234 +freezeProp(ent)
235 +{
236 + if (!pev_valid(ent))
237 + return
238 +
239 + static Float:fZero[3]
240 + set_pev(ent, pev_velocity, fZero)
241 + set_pev(ent, pev_movetype, MOVETYPE_PUSHSTEP)
242 +}
243 +
244 +public fwPreThink(id)
245 +{
246 + new ent = g_iGrab[id]
247 +
248 + if (ent <= 0)
249 + return
250 +
251 + if (!is_user_alive(id) || !pev_valid(ent))
252 + {
253 + g_iGrab[id] = 0
254 + return
255 + }
256 +
257 + static Float:fEye[3], Float:fOfs[3], Float:fAng[3], Float:fFwd[3], Float:fDest[3]
258 + pev(id, pev_origin, fEye)
259 + pev(id, pev_view_ofs, fOfs)
260 + fEye[0] += fOfs[0]
261 + fEye[1] += fOfs[1]
262 + fEye[2] += fOfs[2]
263 +
264 + pev(id, pev_v_angle, fAng)
265 + angle_vector(fAng, ANGLEVECTOR_FORWARD, fFwd)
266 +
267 + fDest[0] = fEye[0] + fFwd[0] * g_fGrabDist[id]
268 + fDest[1] = fEye[1] + fFwd[1] * g_fGrabDist[id]
269 + fDest[2] = fEye[2] + fFwd[2] * g_fGrabDist[id]
270 +
271 + static Float:fZero[3]
272 + set_pev(ent, pev_velocity, fZero)
273 + engfunc(EngFunc_SetOrigin, ent, fDest)
274 +
275 + static Float:fSet[3]
276 + fSet[0] = 0.0
277 + fSet[1] = g_fGrabYaw[id]
278 + fSet[2] = 0.0
279 + set_pev(ent, pev_angles, fSet)
280 +}
281 +
282 +public taskHud()
283 +{
284 + if (!get_pcvar_num(g_pEnabled))
285 + return
286 +
287 + new players[32], num
288 + get_players(players, num, "ch")
289 +
290 + for (new i = 0; i < num; i++)
291 + {
292 + new id = players[i]
293 +
294 + set_hudmessage(255, 180, 0, 0.02, 0.12, 0, 0.0, 1.1, 0.0, 0.0, -1)
295 +
296 + if (g_iPhase == PHASE_BUILD && isBuilder(id))
297 + ShowSyncHudMsg(id, g_iHudSync, "BUILD PHASE | props %d/%d", g_iLockedCount[id], get_pcvar_num(g_pPropLimit))
298 + else if (g_iPhase == PHASE_BUILD)
299 + ShowSyncHudMsg(id, g_iHudSync, "BUILD PHASE | wait for the fight")
300 + else
301 + ShowSyncHudMsg(id, g_iHudSync, "FIGHT PHASE")
302 + }
303 +}
+67 -0 csb.json A
@@ -0,0 +1,67 @@
1 +{
2 + "name": "CSB Base Builder",
3 + "category": "gameplay",
4 + "tags": "base builder, prop, build",
5 + "image": "",
6 + "original_author": "ConnorMcLeod / Kreedz community",
7 + "original_url": "",
8 + "license": "GPL-3.0",
9 + "title": "CSB Base Builder",
10 + "short_desc": "A build phase where builders grab, carry, rotate and lock map props, followed by a fight phase where the other team must break in.",
11 + "version": "1.0.0",
12 + "amxx_min": "1.9",
13 + "amxx_compile_default": "1.9",
14 + "rehlds_ok": true,
15 + "hlds_ok": true,
16 + "regamedll_required": false,
17 + "metamod_flavor": "any",
18 + "reapi_required": false,
19 + "modules": "fakemeta",
20 + "install_notes": "1. Enable the fakemeta module in addons/amxmodx/configs/modules.ini\n2. Put csb_base_builder.amxx in addons/amxmodx/plugins/ and add it to plugins.ini\n3. Use a build-friendly map and change map",
21 + "known_conflicts": "Needs a map with movable brush props; on maps without them there is nothing to build with.",
22 + "cvars": [
23 + {
24 + "name": "csb_bb_enabled",
25 + "default": "1",
26 + "description": "Enable or disable base builder."
27 + },
28 + {
29 + "name": "csb_bb_buildtime",
30 + "default": "45",
31 + "description": "Build phase length in seconds."
32 + },
33 + {
34 + "name": "csb_bb_builderteam",
35 + "default": "2",
36 + "description": "Builder team: 1 = Terrorist, 2 = CT."
37 + },
38 + {
39 + "name": "csb_bb_proplimit",
40 + "default": "6",
41 + "description": "Maximum locked props per builder."
42 + }
43 + ],
44 + "commands": [
45 + {
46 + "name": "say /grab",
47 + "access": "",
48 + "description": "Grab the prop in your crosshair (build phase)."
49 + },
50 + {
51 + "name": "say /rotate",
52 + "access": "",
53 + "description": "Rotate the carried prop 45 degrees."
54 + },
55 + {
56 + "name": "say /lock",
57 + "access": "",
58 + "description": "Freeze the carried prop in place."
59 + },
60 + {
61 + "name": "say /drop",
62 + "access": "",
63 + "description": "Release the carried prop."
64 + }
65 + ],
66 + "main": "addons/amxmodx/scripting/csb_base_builder.sma"
67 +}
0 68