Promote server

Initial release 1.0.0

Browse Source
1.0.0 - Initial release.
Daemon666 committed commit efa61df0e92a5357b26700c4cee6cb3ba333cbae
4 changed files with 181 additions and 0 deletions
+3 -0 CHANGELOG.md A
@@ -0,0 +1,3 @@
1 +## 1.0.0 (2025-07-15)
2 +
3 +1.0.0 - Initial release.
+1 -0 README.md A
@@ -0,0 +1 @@
1 +<p><strong>CSB Random Spawns</strong> collects every <code>info_player_deathmatch</code>, <code>info_player_start</code> and <code>info_vip_start</code> at map start and picks a random free point at each respawn. A point is only used when a player hull fits there (hull trace) and no living player stands within <code>csb_rspawns_mindist</code> units, which removes most spawn-camping on deathmatch and gungame servers.</p><h2>Features</h2><ul><li>Works on any map without extra config.</li><li>Occupied and blocked points are skipped automatically.</li><li>Spawn view angles are preserved from the entity.</li></ul><h2>Installation</h2><ol><li>Enable the <code>hamsandwich</code> and <code>engine</code> modules in <code>modules.ini</code>.</li><li>Compile, copy to <code>addons/amxmodx/plugins/</code>, add to <code>plugins.ini</code>, change map.</li></ol>
+141 -0 addons/amxmodx/scripting/csb_random_spawns.sma A
@@ -0,0 +1,141 @@
1 +/*
2 + * CSB Random Spawns
3 + * Copyright (C) 2026 counter-strike-boost.com
4 + *
5 + * Overrides the map's normal spawn assignment with a randomized pick from all
6 + * info_player_deathmatch / info_player_start / info_vip_start entities. Before
7 + * a point is used it is validated with a hull trace (must not start in solid)
8 + * and a distance check against living players, so nobody spawns inside a
9 + * teammate or in front of an enemy's crosshair. Designed for deathmatch and
10 + * gungame servers to reduce spawn camping.
11 + *
12 + * This program is free software: you can redistribute it and/or modify it under
13 + * the terms of the GNU General Public License as published by the Free Software
14 + * Foundation, either version 3 of the License, or (at your option) any later
15 + * version. It is distributed in the hope that it will be useful, but WITHOUT
16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 + * FOR A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
18 + */
19 +
20 +#include <amxmodx>
21 +#include <hamsandwich>
22 +#include <fakemeta>
23 +#include <engine>
24 +
25 +new const PLUGIN[] = "CSB Random Spawns"
26 +new const VERSION[] = "1.0.0"
27 +new const AUTHOR[] = "counter-strike-boost.com"
28 +
29 +#define MAX_SPAWNS 128
30 +
31 +new g_iSpawnCount
32 +new Float:g_fSpawnOrigin[MAX_SPAWNS][3]
33 +new Float:g_fSpawnAngles[MAX_SPAWNS][3]
34 +
35 +new g_pEnabled, g_pMinDist
36 +
37 +public plugin_init()
38 +{
39 + register_plugin(PLUGIN, VERSION, AUTHOR)
40 +
41 + g_pEnabled = register_cvar("csb_rspawns_enabled", "1")
42 + g_pMinDist = register_cvar("csb_rspawns_mindist", "70.0")
43 +
44 + RegisterHam(Ham_Spawn, "player", "OnPlayerSpawn", 1)
45 +
46 + collectSpawns("info_player_deathmatch")
47 + collectSpawns("info_player_start")
48 + collectSpawns("info_vip_start")
49 +
50 + log_amx("[CSB] Random Spawns: collected %d spawn point(s).", g_iSpawnCount)
51 +}
52 +
53 +collectSpawns(const className[])
54 +{
55 + new ent = -1
56 +
57 + while ((ent = find_ent_by_class(ent, className)) > 0)
58 + {
59 + if (g_iSpawnCount >= MAX_SPAWNS)
60 + break
61 +
62 + new Float:orig[3], Float:ang[3]
63 + pev(ent, pev_origin, orig)
64 + pev(ent, pev_angles, ang)
65 +
66 + /* lift slightly so the hull never clips the floor */
67 + orig[2] += 2.0
68 +
69 + g_fSpawnOrigin[g_iSpawnCount][0] = orig[0]
70 + g_fSpawnOrigin[g_iSpawnCount][1] = orig[1]
71 + g_fSpawnOrigin[g_iSpawnCount][2] = orig[2]
72 + g_fSpawnAngles[g_iSpawnCount][0] = ang[0]
73 + g_fSpawnAngles[g_iSpawnCount][1] = ang[1]
74 + g_fSpawnAngles[g_iSpawnCount][2] = ang[2]
75 + g_iSpawnCount++
76 + }
77 +}
78 +
79 +public OnPlayerSpawn(id)
80 +{
81 + if (!get_pcvar_num(g_pEnabled) || !is_user_alive(id) || g_iSpawnCount < 1)
82 + return
83 +
84 + new team = get_user_team(id)
85 + if (team != 1 && team != 2)
86 + return
87 +
88 + new start = random_num(0, g_iSpawnCount - 1)
89 + new Float:minDist = get_pcvar_float(g_pMinDist)
90 +
91 + for (new i = 0; i < g_iSpawnCount; i++)
92 + {
93 + new idx = (start + i) % g_iSpawnCount
94 +
95 + if (!spawnFree(idx, id, minDist))
96 + continue
97 +
98 + new Float:orig[3], Float:ang[3]
99 + orig[0] = g_fSpawnOrigin[idx][0]
100 + orig[1] = g_fSpawnOrigin[idx][1]
101 + orig[2] = g_fSpawnOrigin[idx][2]
102 + ang[0] = g_fSpawnAngles[idx][0]
103 + ang[1] = g_fSpawnAngles[idx][1]
104 + ang[2] = g_fSpawnAngles[idx][2]
105 +
106 + set_pev(id, pev_origin, orig)
107 + set_pev(id, pev_angles, ang)
108 + set_pev(id, pev_v_angle, ang)
109 + set_pev(id, pev_fixangle, 1)
110 + return
111 + }
112 +}
113 +
114 +bool:spawnFree(idx, id, Float:minDist)
115 +{
116 + static Float:orig[3]
117 + orig[0] = g_fSpawnOrigin[idx][0]
118 + orig[1] = g_fSpawnOrigin[idx][1]
119 + orig[2] = g_fSpawnOrigin[idx][2]
120 +
121 + /* bit 1 (StartSolid) means a player hull does not fit here */
122 + if (trace_hull(orig, HULL_HUMAN, id) & 1)
123 + return false
124 +
125 + static players[32], num
126 + get_players(players, num, "a")
127 +
128 + for (new i = 0; i < num; i++)
129 + {
130 + if (players[i] == id)
131 + continue
132 +
133 + static Float:o2[3]
134 + pev(players[i], pev_origin, o2)
135 +
136 + if (get_distance_f(orig, o2) < minDist)
137 + return false
138 + }
139 +
140 + return true
141 +}
+36 -0 csb.json A
@@ -0,0 +1,36 @@
1 +{
2 + "name": "CSB Random Spawns",
3 + "category": "movement",
4 + "tags": "spawns, random, dm",
5 + "image": "",
6 + "original_author": "",
7 + "original_url": "",
8 + "license": "GPL-3.0",
9 + "title": "CSB Random Spawns",
10 + "short_desc": "Randomizes which spawn point a player gets each respawn, validating points with a hull trace and distance check.",
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": "hamsandwich,fakemeta,engine",
20 + "install_notes": "1. Compile the .sma (or use the site compiler)\n2. Put the .amxx in addons/amxmodx/plugins/\n3. Add it to addons/amxmodx/configs/plugins.ini\n4. Change map",
21 + "known_conflicts": "Conflicts with CSDM-style spawn managers that also move players at spawn; run only one.",
22 + "cvars": [
23 + {
24 + "name": "csb_rspawns_enabled",
25 + "default": "1",
26 + "description": "Enable randomized spawn assignment."
27 + },
28 + {
29 + "name": "csb_rspawns_mindist",
30 + "default": "70.0",
31 + "description": "Minimum distance to the nearest living player for a spawn to be used."
32 + }
33 + ],
34 + "commands": [],
35 + "main": "addons/amxmodx/scripting/csb_random_spawns.sma"
36 +}
0 37