Daemon666 / CSB Admin Transfer Публичный

amx_transfer <target> <t|ct|spec> moves a player between teams keeping frags, optionally respawning; a menu version too.

v1.0.0 132 загрузок GPL-3.0 Обновлено Aug 22, 2026
csb_admin_transfer.sma v1.0.0 229 строк · 6.2 KB Исходный текст
1 /*
2 * CSB Admin Transfer
3 * Copyright (C) 2026 counter-strike-boost.com
4 *
5 * amx_transfer <target> <t|ct|spec> moves a player between teams with
6 * cs_set_user_team, keeping their frags, and optionally respawns them with
7 * Ham_CS_RoundRespawn. amx_transfermenu lists players by team. The team score
8 * is never touched and every move is announced.
9 *
10 * Inspired by the team commands in the AMX Mod X Admin Commands plugin.
11 * Independent GPL re-implementation.
12 *
13 * This program is free software: you can redistribute it and/or modify it under
14 * the terms of the GNU General Public License as published by the Free Software
15 * Foundation, either version 3 of the License, or (at your option) any later
16 * version. It is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 * FOR A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
19 */
20
21 #include <amxmodx>
22 #include <amxmisc>
23 #include <cstrike>
24 #include <hamsandwich>
25
26 new const PLUGIN[] = "CSB Admin Transfer"
27 new const VERSION[] = "1.0.0"
28 new const AUTHOR[] = "counter-strike-boost.com"
29
30 new g_pRespawn
31
32 public plugin_init()
33 {
34 register_plugin(PLUGIN, VERSION, AUTHOR)
35
36 g_pRespawn = register_cvar("csb_transfer_respawn", "1")
37
38 register_concmd("amx_transfer", "cmdTransfer", ADMIN_LEVEL_A, "<target> <t|ct|spec> - move a player to a team")
39 register_concmd("amx_transfermenu", "cmdMenu", ADMIN_LEVEL_A, "- pick a player and a team from a menu")
40 }
41
42 parseTeam(const arg[], &CsTeams:team)
43 {
44 if (equali(arg, "t") || equali(arg, "ter") || equali(arg, "terrorist"))
45 team = CS_TEAM_T
46 else if (equali(arg, "ct") || equali(arg, "counter"))
47 team = CS_TEAM_CT
48 else if (equali(arg, "spec") || equali(arg, "spectator"))
49 team = CS_TEAM_SPECTATOR
50 else
51 return 0
52
53 return 1
54 }
55
56 teamName(CsTeams:team, out[], len)
57 {
58 switch (team)
59 {
60 case CS_TEAM_T: copy(out, len, "Terrorists")
61 case CS_TEAM_CT: copy(out, len, "Counter-Terrorists")
62 case CS_TEAM_SPECTATOR: copy(out, len, "Spectator")
63 default: copy(out, len, "Unassigned")
64 }
65 }
66
67 doTransfer(admin, target, CsTeams:team)
68 {
69 new CsTeams:cur = cs_get_user_team(target)
70
71 if (cur == team)
72 {
73 client_print(admin, print_chat, "[CSB] That player is already on that team.")
74 return
75 }
76
77 /* cs_set_user_team keeps the player's frags and deaths intact */
78 cs_set_user_team(target, team)
79
80 if (team != CS_TEAM_SPECTATOR && get_pcvar_num(g_pRespawn) && is_user_alive(target))
81 ExecuteHamB(Ham_CS_RoundRespawn, target)
82
83 new aname[32], tname[32], tteam[24]
84 admName(admin, aname, charsmax(aname))
85 get_user_name(target, tname, charsmax(tname))
86 teamName(team, tteam, charsmax(tteam))
87
88 client_print(0, print_chat, "[CSB] %s moved %s to %s.", aname, tname, tteam)
89 log_amx("[CSB Transfer] %s moved %s to %s", aname, tname, tteam)
90 }
91
92 admName(id, out[], len)
93 {
94 if (id)
95 get_user_name(id, out, len)
96 else
97 copy(out, len, "CONSOLE")
98 }
99
100 public cmdTransfer(id, level, cid)
101 {
102 if (!cmd_access(id, level, cid, 3))
103 return PLUGIN_HANDLED
104
105 new arg[32], teamArg[16]
106 read_argv(1, arg, charsmax(arg))
107 read_argv(2, teamArg, charsmax(teamArg))
108
109 new target = cmd_target(id, arg, CMDTARGET_OBEY_IMMUNITY)
110
111 if (!target)
112 return PLUGIN_HANDLED
113
114 new CsTeams:team
115 if (!parseTeam(teamArg, team))
116 {
117 console_print(id, "[CSB] Team must be one of: t, ct, spec.")
118 return PLUGIN_HANDLED
119 }
120
121 doTransfer(id, target, team)
122 return PLUGIN_HANDLED
123 }
124
125 public cmdMenu(id, level, cid)
126 {
127 if (!cmd_access(id, level, cid, 1))
128 return PLUGIN_HANDLED
129
130 showPlayers(id)
131 return PLUGIN_HANDLED
132 }
133
134 showPlayers(id)
135 {
136 new menu = menu_create("\yTransfer - pick a player", "menuPlayers")
137
138 new players[32], num, pid, name[32], info[8], line[64], team[24]
139 get_players(players, num)
140
141 for (new i = 0; i < num; i++)
142 {
143 pid = players[i]
144 get_user_name(pid, name, charsmax(name))
145 teamName(cs_get_user_team(pid), team, charsmax(team))
146 num_to_str(pid, info, charsmax(info))
147 formatex(line, charsmax(line), "%s \r(%s)", name, team)
148 menu_additem(menu, line, info, 0)
149 }
150
151 menu_display(id, menu, 0)
152 }
153
154 public menuPlayers(id, menu, item)
155 {
156 if (item == MENU_EXIT || item < 0)
157 {
158 menu_destroy(menu)
159 return PLUGIN_HANDLED
160 }
161
162 new info[8], name[32], access, callback
163 menu_item_getinfo(menu, item, access, info, charsmax(info), name, charsmax(name), callback)
164 menu_destroy(menu)
165
166 new target = str_to_num(info)
167
168 if (target < 1 || !is_user_connected(target))
169 {
170 client_print(id, print_chat, "[CSB] That player left.")
171 return PLUGIN_HANDLED
172 }
173
174 showTeams(id, target)
175 return PLUGIN_HANDLED
176 }
177
178 showTeams(id, target)
179 {
180 new tname[32]
181 get_user_name(target, tname, charsmax(tname))
182
183 new title[64]
184 formatex(title, charsmax(title), "\yMove %s to:", tname)
185
186 new menu = menu_create(title, "menuTeams")
187
188 new info[16]
189 formatex(info, charsmax(info), "%d t", target)
190 menu_additem(menu, "\wTerrorists", info, 0)
191 formatex(info, charsmax(info), "%d ct", target)
192 menu_additem(menu, "\wCounter-Terrorists", info, 0)
193 formatex(info, charsmax(info), "%d spec", target)
194 menu_additem(menu, "\wSpectator", info, 0)
195
196 menu_display(id, menu, 0)
197 }
198
199 public menuTeams(id, menu, item)
200 {
201 if (item == MENU_EXIT || item < 0)
202 {
203 menu_destroy(menu)
204 return PLUGIN_HANDLED
205 }
206
207 new info[16], name[32], access, callback
208 menu_item_getinfo(menu, item, access, info, charsmax(info), name, charsmax(name), callback)
209 menu_destroy(menu)
210
211 new targetArg[8], teamArg[8]
212 strtok(info, targetArg, charsmax(targetArg), teamArg, charsmax(teamArg), ' ')
213
214 new target = str_to_num(targetArg)
215
216 if (target < 1 || !is_user_connected(target))
217 {
218 client_print(id, print_chat, "[CSB] That player left.")
219 return PLUGIN_HANDLED
220 }
221
222 new CsTeams:team
223 if (!parseTeam(teamArg, team))
224 return PLUGIN_HANDLED
225
226 doTransfer(id, target, team)
227 return PLUGIN_HANDLED
228 }
229