Daemon666 / CSB Extend Map Публичный

amx_extendmap adds minutes to mp_timelimit; players can vote once per map to extend, capped so a map cannot run forever.

v1.0.0 132 загрузок GPL-3.0 Обновлено Aug 24, 2026
csb_extend_map.sma v1.0.0 172 строк · 4.6 KB Исходный текст
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