Sunucu tanitimi

Initial release 1.0.0

Browse Source
1.0.0 - Initial release.
Daemon666 committed commit 30b4db7a4d8edd755b133607dee8ebd77810c4ef
4 changed files with 323 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 Map Spawn Editor</strong> lets an admin build a custom spawn list from inside the game &mdash; handy for DM and CSDM-style maps that need spawns the mapper never placed. <code>say /addspawn</code> records your current origin and view angles, <code>say /delspawn</code> removes the closest saved point, <code>say /savespawns</code> writes the list, and <code>say /listspawns</code> reports the count.</p><p>Spawns are stored per map in the AMXX data directory (<code>csb_spawns_&lt;map&gt;.txt</code>) and reloaded on map start. On respawn, a <code>Ham_Spawn</code> post hook teleports the player to a random saved point with <code>engfunc(EngFunc_SetOrigin)</code>, sets their view angles and zeroes their velocity. Inspired by the CSDM spawn editor by BAILOPAN; independent GPL re-implementation.</p><h2>Features</h2><ul><li><code>/addspawn</code>, <code>/delspawn</code>, <code>/savespawns</code>, <code>/listspawns</code> &mdash; admin only.</li><li>Per-map storage under the AMXX data directory, up to 64 points.</li><li>Random custom spawn applied on every respawn (toggle with <code>csb_spawn_override</code>).</li><li>View angles restored and residual velocity cleared on teleport.</li></ul><h2>Installation</h2><ol><li>Compile <code>csb_map_spawn_editor.sma</code> and copy it to <code>addons/amxmodx/plugins/</code>.</li><li>Add it to <code>plugins.ini</code> and change the map.</li><li>Walk to each spot, type <code>/addspawn</code>, then <code>/savespawns</code>.</li></ol><p>The editing commands need the <code>ADMIN_MAP</code> flag (<code>e</code>).</p>
+262 -0 addons/amxmodx/scripting/csb_map_spawn_editor.sma A
@@ -0,0 +1,262 @@
1 +/*
2 + * CSB Map Spawn Editor
3 + * Copyright (C) 2026 counter-strike-boost.com
4 + *
5 + * In-game spawn editor for admins. /addspawn stores your current origin and
6 + * angles, /delspawn removes the closest saved point, /savespawns writes them,
7 + * and /listspawns reports the count. Spawns are kept per map in the AMXX data
8 + * directory. On respawn the plugin teleports the player to a saved point with
9 + * engfunc(EngFunc_SetOrigin) - useful for DM and CSDM style maps.
10 + *
11 + * Inspired by the CSDM spawn editor by BAILOPAN. Independent GPL
12 + * re-implementation.
13 + *
14 + * This program is free software: you can redistribute it and/or modify it under
15 + * the terms of the GNU General Public License as published by the Free Software
16 + * Foundation, either version 3 of the License, or (at your option) any later
17 + * version. It is distributed in the hope that it will be useful, but WITHOUT
18 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 + * FOR A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
20 + */
21 +
22 +#include <amxmodx>
23 +#include <amxmisc>
24 +#include <fakemeta>
25 +#include <hamsandwich>
26 +
27 +#define MAX_SPAWNS 64
28 +
29 +new const PLUGIN[] = "CSB Map Spawn Editor"
30 +new const VERSION[] = "1.0.0"
31 +new const AUTHOR[] = "counter-strike-boost.com"
32 +
33 +new Float:g_fSpawn[MAX_SPAWNS][6]
34 +new g_iSpawnCount = 0
35 +
36 +new g_pEnabled, g_pOverride
37 +new g_szFile[192]
38 +
39 +public plugin_init()
40 +{
41 + register_plugin(PLUGIN, VERSION, AUTHOR)
42 +
43 + g_pEnabled = register_cvar("csb_spawn_enabled", "1")
44 + g_pOverride = register_cvar("csb_spawn_override", "1")
45 +
46 + register_clcmd("say /addspawn", "cmdAdd")
47 + register_clcmd("say /delspawn", "cmdDel")
48 + register_clcmd("say /savespawns", "cmdSave")
49 + register_clcmd("say /listspawns", "cmdList")
50 +
51 + RegisterHam(Ham_Spawn, "player", "fwdSpawnPost", 1)
52 +}
53 +
54 +public plugin_cfg()
55 +{
56 + new dir[128]
57 + get_localinfo("amxx_datadir", dir, charsmax(dir))
58 +
59 + new map[40]
60 + get_mapname(map, charsmax(map))
61 +
62 + formatex(g_szFile, charsmax(g_szFile), "%s/csb_spawns_%s.txt", dir, map)
63 +
64 + loadSpawns()
65 +}
66 +
67 +loadSpawns()
68 +{
69 + g_iSpawnCount = 0
70 +
71 + if (!file_exists(g_szFile))
72 + return
73 +
74 + new f = fopen(g_szFile, "rt")
75 +
76 + if (!f)
77 + return
78 +
79 + new line[128], p[6][16]
80 +
81 + while (!feof(f) && g_iSpawnCount < MAX_SPAWNS)
82 + {
83 + fgets(f, line, charsmax(line))
84 + trim(line)
85 +
86 + if (!line[0] || line[0] == ';')
87 + continue
88 +
89 + if (parse(line, p[0], 15, p[1], 15, p[2], 15, p[3], 15, p[4], 15, p[5], 15) < 6)
90 + continue
91 +
92 + for (new j = 0; j < 6; j++)
93 + g_fSpawn[g_iSpawnCount][j] = str_to_float(p[j])
94 +
95 + g_iSpawnCount++
96 + }
97 +
98 + fclose(f)
99 +
100 + log_amx("[CSB Spawn] loaded %d spawn(s) for this map.", g_iSpawnCount)
101 +}
102 +
103 +bool:hasAccess(id)
104 +{
105 + if (get_user_flags(id) & ADMIN_MAP)
106 + return true
107 +
108 + client_print(id, print_chat, "[CSB] You need the map admin flag (e) to edit spawns.")
109 + return false
110 +}
111 +
112 +public cmdAdd(id)
113 +{
114 + if (!hasAccess(id))
115 + return PLUGIN_HANDLED
116 +
117 + if (g_iSpawnCount >= MAX_SPAWNS)
118 + {
119 + client_print(id, print_chat, "[CSB] Spawn list is full (%d).", MAX_SPAWNS)
120 + return PLUGIN_HANDLED
121 + }
122 +
123 + new Float:origin[3], Float:angles[3]
124 + pev(id, pev_origin, origin)
125 + pev(id, pev_v_angle, angles)
126 +
127 + g_fSpawn[g_iSpawnCount][0] = origin[0]
128 + g_fSpawn[g_iSpawnCount][1] = origin[1]
129 + g_fSpawn[g_iSpawnCount][2] = origin[2]
130 + g_fSpawn[g_iSpawnCount][3] = angles[0]
131 + g_fSpawn[g_iSpawnCount][4] = angles[1]
132 + g_fSpawn[g_iSpawnCount][5] = angles[2]
133 +
134 + g_iSpawnCount++
135 +
136 + client_print(id, print_chat, "[CSB] Spawn #%d saved at your position. Use /savespawns to write to disk.", g_iSpawnCount)
137 + return PLUGIN_HANDLED
138 +}
139 +
140 +public cmdDel(id)
141 +{
142 + if (!hasAccess(id))
143 + return PLUGIN_HANDLED
144 +
145 + if (!g_iSpawnCount)
146 + {
147 + client_print(id, print_chat, "[CSB] No spawns to delete.")
148 + return PLUGIN_HANDLED
149 + }
150 +
151 + new Float:origin[3]
152 + pev(id, pev_origin, origin)
153 +
154 + new closest = -1
155 + new Float:best = 999999.0
156 +
157 + for (new i = 0; i < g_iSpawnCount; i++)
158 + {
159 + new Float:pt[3]
160 + pt[0] = g_fSpawn[i][0]
161 + pt[1] = g_fSpawn[i][1]
162 + pt[2] = g_fSpawn[i][2]
163 +
164 + new Float:d = get_distance_f(origin, pt)
165 +
166 + if (d < best)
167 + {
168 + best = d
169 + closest = i
170 + }
171 + }
172 +
173 + if (closest < 0)
174 + return PLUGIN_HANDLED
175 +
176 + /* shift the rest down */
177 + for (new i = closest; i < g_iSpawnCount - 1; i++)
178 + {
179 + for (new j = 0; j < 6; j++)
180 + g_fSpawn[i][j] = g_fSpawn[i + 1][j]
181 + }
182 +
183 + g_iSpawnCount--
184 +
185 + client_print(id, print_chat, "[CSB] Removed the closest spawn (%.0f units away). %d left.", best, g_iSpawnCount)
186 + return PLUGIN_HANDLED
187 +}
188 +
189 +public cmdSave(id)
190 +{
191 + if (!hasAccess(id))
192 + return PLUGIN_HANDLED
193 +
194 + new f = fopen(g_szFile, "wt")
195 +
196 + if (!f)
197 + {
198 + client_print(id, print_chat, "[CSB] Could not open the spawn file for writing.")
199 + return PLUGIN_HANDLED
200 + }
201 +
202 + fprintf(f, "; CSB Map Spawn Editor - x y z pitch yaw roll^n")
203 +
204 + for (new i = 0; i < g_iSpawnCount; i++)
205 + {
206 + fprintf(f, "%.2f %.2f %.2f %.2f %.2f %.2f^n",
207 + g_fSpawn[i][0], g_fSpawn[i][1], g_fSpawn[i][2],
208 + g_fSpawn[i][3], g_fSpawn[i][4], g_fSpawn[i][5])
209 + }
210 +
211 + fclose(f)
212 +
213 + client_print(id, print_chat, "[CSB] Wrote %d spawn(s) to disk.", g_iSpawnCount)
214 + log_amx("[CSB Spawn] admin saved %d spawn(s).", g_iSpawnCount)
215 + return PLUGIN_HANDLED
216 +}
217 +
218 +public cmdList(id)
219 +{
220 + if (!hasAccess(id))
221 + return PLUGIN_HANDLED
222 +
223 + client_print(id, print_chat, "[CSB] %d custom spawn(s) loaded for this map.", g_iSpawnCount)
224 + return PLUGIN_HANDLED
225 +}
226 +
227 +public fwdSpawnPost(id)
228 +{
229 + if (!get_pcvar_num(g_pEnabled) || !get_pcvar_num(g_pOverride))
230 + return
231 +
232 + if (!g_iSpawnCount || !is_user_alive(id))
233 + return
234 +
235 + set_task(0.1, "taskTeleport", id)
236 +}
237 +
238 +public taskTeleport(id)
239 +{
240 + if (!is_user_alive(id) || !g_iSpawnCount)
241 + return
242 +
243 + new pick = random_num(0, g_iSpawnCount - 1)
244 +
245 + new Float:origin[3], Float:angles[3]
246 + origin[0] = g_fSpawn[pick][0]
247 + origin[1] = g_fSpawn[pick][1]
248 + origin[2] = g_fSpawn[pick][2]
249 + angles[0] = g_fSpawn[pick][3]
250 + angles[1] = g_fSpawn[pick][4]
251 + angles[2] = g_fSpawn[pick][5]
252 +
253 + engfunc(EngFunc_SetOrigin, id, origin)
254 +
255 + set_pev(id, pev_angles, angles)
256 + set_pev(id, pev_v_angle, angles)
257 + set_pev(id, pev_fixangle, 1)
258 +
259 + /* stop any residual momentum from the map's default spawn */
260 + new Float:zero[3]
261 + set_pev(id, pev_velocity, zero)
262 +}
+57 -0 csb.json A
@@ -0,0 +1,57 @@
1 +{
2 + "name": "CSB Map Spawn Editor",
3 + "category": "admin",
4 + "tags": "spawns, editor, map",
5 + "image": "",
6 + "original_author": "BAILOPAN (CSDM)",
7 + "original_url": "",
8 + "license": "GPL-3.0",
9 + "title": "CSB Map Spawn Editor",
10 + "short_desc": "In-game spawn editor: /addspawn, /delspawn, /savespawns store points per map and override player spawns via SetOrigin.",
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,hamsandwich",
20 + "install_notes": "1. Put csb_map_spawn_editor.amxx in addons/amxmodx/plugins/\n2. Add it to addons/amxmodx/configs/plugins.ini\n3. Change map\n4. Files are saved as csb_spawns_<map>.txt in addons/amxmodx/data/",
21 + "known_conflicts": "Other spawn managers (CSDM spawn mode, spawn-protection teleporters) that also move players on Ham_Spawn will conflict.",
22 + "cvars": [
23 + {
24 + "name": "csb_spawn_enabled",
25 + "default": "1",
26 + "description": "Master enable for the editor and override."
27 + },
28 + {
29 + "name": "csb_spawn_override",
30 + "default": "1",
31 + "description": "Teleport players to a saved spawn on respawn."
32 + }
33 + ],
34 + "commands": [
35 + {
36 + "name": "say /addspawn",
37 + "access": "e (ADMIN_MAP)",
38 + "description": "Save your current position as a spawn point."
39 + },
40 + {
41 + "name": "say /delspawn",
42 + "access": "e (ADMIN_MAP)",
43 + "description": "Remove the closest saved spawn point."
44 + },
45 + {
46 + "name": "say /savespawns",
47 + "access": "e (ADMIN_MAP)",
48 + "description": "Write the spawn list to disk for this map."
49 + },
50 + {
51 + "name": "say /listspawns",
52 + "access": "e (ADMIN_MAP)",
53 + "description": "Report how many spawns are loaded."
54 + }
55 + ],
56 + "main": "addons/amxmodx/scripting/csb_map_spawn_editor.sma"
57 +}
0 58