amx_transfer <target> <t|ct|spec> moves a player between teams keeping frags, optionally respawning; a menu version too.
csb_admin_transfer.sma v1.0.0
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









