amx_extendmap adds minutes to mp_timelimit; players can vote once per map to extend, capped so a map cannot run forever.
csb_extend_map.sma v1.0.0
1
/*
2
* CSB Extend Map
3
* Copyright (C) 2026 counter-strike-boost.com
4
*
5
* amx_extendmap adds N minutes to mp_timelimit and re-broadcasts the new time
6
* left. Players can also start a vote (say /extend) to extend the current map
7
* once, capped by a max-extensions cvar so a map can never run forever.
8
*
9
* Inspired by the map-extension commands from the AMX Mod X map management
10
* plugin (AMX Mod X Development Team). Independent GPL re-implementation.
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 <amxmisc>
22
23
new const PLUGIN[] = "CSB Extend Map"
24
new const VERSION[] = "1.0.0"
25
new const AUTHOR[] = "counter-strike-boost.com"
26
27
new g_pTimeLimit
28
new g_pDefaultMin, g_pMaxExtends, g_pVoteMin
29
30
new g_iExtends = 0
31
new bool:g_bVoteRunning = false
32
new g_iYes, g_iNo
33
34
public plugin_init()
35
{
36
register_plugin(PLUGIN, VERSION, AUTHOR)
37
38
g_pTimeLimit = get_cvar_pointer("mp_timelimit")
39
40
g_pDefaultMin = register_cvar("csb_extend_minutes", "15")
41
g_pMaxExtends = register_cvar("csb_extend_max", "3")
42
g_pVoteMin = register_cvar("csb_extend_votemin", "15")
43
44
register_concmd("amx_extendmap", "cmdExtend", ADMIN_MAP, "[minutes] - add time to mp_timelimit")
45
register_clcmd("say /extend", "cmdVote")
46
register_clcmd("say_team /extend", "cmdVote")
47
}
48
49
public plugin_cfg()
50
{
51
g_iExtends = 0
52
}
53
54
extendBy(minutes)
55
{
56
new cur = g_pTimeLimit ? get_pcvar_num(g_pTimeLimit) : get_cvar_num("mp_timelimit")
57
new next = cur + minutes
58
59
if (g_pTimeLimit)
60
set_pcvar_num(g_pTimeLimit, next)
61
else
62
set_cvar_num("mp_timelimit", next)
63
64
g_iExtends++
65
66
new left = get_timeleft() / 60
67
client_print(0, print_chat, "[CSB] Map extended by %d minute(s). New limit: %d min, about %d min left.",
68
minutes, next, left)
69
}
70
71
public cmdExtend(id, level, cid)
72
{
73
if (!cmd_access(id, level, cid, 1))
74
return PLUGIN_HANDLED
75
76
new minutes = get_pcvar_num(g_pDefaultMin)
77
78
if (read_argc() > 1)
79
{
80
new arg[8]
81
read_argv(1, arg, charsmax(arg))
82
new n = str_to_num(arg)
83
84
if (n > 0)
85
minutes = n
86
}
87
88
extendBy(minutes)
89
90
new aname[32]
91
if (id)
92
get_user_name(id, aname, charsmax(aname))
93
else
94
copy(aname, charsmax(aname), "CONSOLE")
95
96
log_amx("[CSB Extend] %s extended the map by %d min", aname, minutes)
97
return PLUGIN_HANDLED
98
}
99
100
public cmdVote(id)
101
{
102
if (g_bVoteRunning)
103
{
104
client_print(id, print_chat, "[CSB] A vote is already running.")
105
return PLUGIN_HANDLED
106
}
107
108
if (g_iExtends >= get_pcvar_num(g_pMaxExtends))
109
{
110
client_print(id, print_chat, "[CSB] This map has already been extended the maximum number of times.")
111
return PLUGIN_HANDLED
112
}
113
114
g_bVoteRunning = true
115
g_iYes = 0
116
g_iNo = 0
117
118
new menu = menu_create("\yExtend the map?^n\wIt will add time to the current map.", "voteHandler")
119
menu_additem(menu, "\wYes, extend", "1", 0)
120
menu_additem(menu, "\wNo", "2", 0)
121
menu_setprop(menu, MPROP_EXIT, MEXIT_NEVER)
122
123
new players[32], num, pid
124
get_players(players, num, "ch")
125
126
for (new i = 0; i < num; i++)
127
{
128
pid = players[i]
129
menu_display(pid, menu, 0)
130
}
131
132
client_print(0, print_chat, "[CSB] Vote started: extend the current map?")
133
set_task(15.0, "voteEnd")
134
return PLUGIN_HANDLED
135
}
136
137
public voteHandler(id, menu, item)
138
{
139
if (item == MENU_EXIT || item < 0)
140
{
141
menu_destroy(menu)
142
return PLUGIN_HANDLED
143
}
144
145
new info[4], name[32], access, callback
146
menu_item_getinfo(menu, item, access, info, charsmax(info), name, charsmax(name), callback)
147
menu_destroy(menu)
148
149
if (str_to_num(info) == 1)
150
g_iYes++
151
else
152
g_iNo++
153
154
return PLUGIN_HANDLED
155
}
156
157
public voteEnd()
158
{
159
g_bVoteRunning = false
160
161
if (g_iYes > g_iNo)
162
{
163
client_print(0, print_chat, "[CSB] Vote passed (%d yes / %d no). Extending the map.", g_iYes, g_iNo)
164
extendBy(get_pcvar_num(g_pVoteMin))
165
log_amx("[CSB Extend] player vote passed (%d/%d), map extended", g_iYes, g_iNo)
166
}
167
else
168
{
169
client_print(0, print_chat, "[CSB] Vote failed (%d yes / %d no). The map will not be extended.", g_iYes, g_iNo)
170
}
171
}
172









